使用numpy meshgrid python切割边界框 [英] Cut a bounding box using numpy meshgrid python

查看:95
本文介绍了使用numpy meshgrid python切割边界框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Meshgrid从以下尺寸中创建一个边界框,但无法获得正确的框.

I want to create a bounding box out of the following dimensions using meshgrid but just not able to get the right box.

我的父尺寸是x = 0 to 19541y = 0 to 14394.除此之外,我想将一个框从x'= 4692剪切为12720和y' = 4273 to 10117.

My parent dimensions are x = 0 to 19541 and y = 0 to 14394. Out of that, I want to cut a box from x' = 4692 to 12720 and y' = 4273 to 10117.

但是,我没有得到正确的界限.有人可以帮我吗?

However, I am not getting the right bounds. Could someone please help me here?

from matplotlib.path import Path

        xmin, xmax = 4692, 12720
        ymin, ymax = 4273, 10117
        sar_ver = [(4692, 10117), (12720, 10117), (12658, 4274), (4769, 4273), (4692, 10117)]

        x, y = np.meshgrid(np.arange(xmin, xmax + 1), np.arange(ymin, ymax + 1))
        shx = x
        x, y = x.flatten(), y.flatten()
        points = np.vstack((x, y)).T

        path = Path(sar_ver)
        grid = path.contains_points(points)

        grid.shape = shx.shape # 5845 X 8029

        print grid

更新:这是我尝试过的,并且接近我想要的,但不完全是.我想将原点从0更改为图像的周围框,如预期输出所示.

UPDATE: This is what I tried and I am close to what I want but not exactly. I want to change the original origin from 0 to the image's surrounding box as shown in expected output.

我正在使用的更新代码是

The updated code that I am using is this

from matplotlib.path import Path
    nx, ny = 16886, 10079
    sar_ver = [(16886, 1085), (15139, 2122), (14475, 5226), (8419, 5601), (14046, 6876), (14147, 10079), (16816, 3748), (16886, 1085)]
    x, y = np.meshgrid(np.arange(nx), np.arange(ny))
    x, y = x.flatten(), y.flatten()
    points = np.vstack((x,y)).T
    path = Path(sar_ver)
    grid = path.contains_points(points)

    grid.shape = (10079, 16886)
    grid = np.multiply(grid,255)
    int_grid = grid.astype(np.uint8)
    grid_img = Image.fromarray(int_grid)
    grid_img.save('grid_image.png')  # ACTUAL OUTPUT IMAGE WITH ORIGIN NOT SHIFTED

输入几何:

预期的输出结果是:图像是否以其他方式旋转并不重要,但是如果图像正确对齐,则顶部会变成樱桃形.

Expected output is this: Doesn't matter if the image is rotated the other way round but will be a cherry on top if its aligned correctly.

但是我现在正在得到这个,所以我发布的更新代码中的ACTUAL OUTPUT是这个:

However I am getting right now this so my ACTUAL OUTPUT from the updated code posted is this:

所以我想在盒子周围移动原点.

So I want to shift the origin around the box.

获取掩码后的绑定框问题详细信息:此代码位于第二次更新grid_img.save('grid_image.png') # ACTUAL OUTPUT IMAGE WITH ORIGIN NOT SHIFTED

BOUNDING BOX PROBLEM DETAILS AFTER GETTING THE MASK: This code comes after the line posted in the second update grid_img.save('grid_image.png') # ACTUAL OUTPUT IMAGE WITH ORIGIN NOT SHIFTED

此处im是实际图像的矩阵.具有与遮罩相同形状的im的x-y min,max应该是多少,并将它们两者相乘以获得像素值,其余部分用0s抵消.

Here im is the matrix of the actual image. What should be the x-y min, max of im to have the same shape as mask and multiply both of them to get pixel values and the rest cancelled out with 0s.

        img_x = 19541 # 0 - 19541
        img_y = 14394 # 0 - 14394
        im = np.fromfile(binary_file_path, dtype='>f4')
        im = np.reshape(im.astype(np.float32), (img_x, img_y))
        im = im[:10079, :16886]
        bb_list = np.multiply(grid, im)
        # slice and dice
        slice_rows = np.any(bb_list, axis=1)
        slice_cols = np.any(bb_list, axis=0)
        ymin, ymax = np.where(slice_rows)[0][[0, -1]]
        xmin, xmax = np.where(slice_cols)[0][[0, -1]]
        answer = bb_list[ymin:ymax + 1, xmin:xmax + 1]
        # convert to unit8
        int_ans = answer.astype(np.uint8)
        fin_img = Image.fromarray(int_ans)
        fin_img.save('test_this.jpeg')

我的目标是从给定图像中切出给定几何图形的多边形.所以我要从该多边形中取出蒙版,然后使用该蒙版将其从原始图像中剪切出来.因此,将蒙版的1和0与图像​​中的像素值相乘即可得到1 *像素值.

My GOAL is to cut out a polygon of a given geom out of a given image. So I am taking the mask out of that polygon and then using that mask to cut the same out of the original image. So multiplying mask's 1's and 0's with the pixel values in the image to just get 1*pixel values.

我尝试了以下方法,将实际图像切成相同的尺寸,以便我可以乘以np.multiply(im, mask),但是由于图像的形状没有切成与蒙版相同的形状,所以它不起作用.我在下面尝试了您的最小值和最大值,但是没有用!

I tried the following to cut out the actual image to have the same dimensions so that I can multiply np.multiply(im, mask) but it didn't work as image's shape is not cut into same shape as mask's. I tried your min and max below but didn't work!

im = im[xmin:xmax, ymin:ymax]
ipdb> im.shape
(5975, 8994)
ipdb> mask.shape
(8994, 8467) 

很明显,我现在不能同时屏蔽多个蒙版.

Clearly I cannot multiple mask and im now.

推荐答案

我认为您在第一次尝试中就完全正确了,而在第二次尝试中,您正在为完整图像构建meshgrid,而您只想要形状的面具,不是吗?

I think you got it almost right in the first attempt, in the second one you're building a meshgrid for the full image while you just want the shape mask, don't you?

import numpy as np
import matplotlib as mpl
from matplotlib.path import Path
from matplotlib import patches
import matplotlib.pyplot as plt

from PIL import Image

sar_ver = [(16886, 1085), (15139, 2122), (14475, 5226), (8419, 5601),
           (14046, 6876), (14147, 10079), (16816, 3748), (16886, 1085)]

path = Path(sar_ver)
xmin, ymin, xmax, ymax = np.asarray(path.get_extents(), dtype=int).ravel()

x, y = np.mgrid[xmin:xmax, ymin:ymax]
points = np.transpose((x.ravel(), y.ravel()))

mask = path.contains_points(points)
mask = mask.reshape(x.shape).T

img = Image.fromarray((mask * 255).astype(np.uint8))
img.save('mask.png')


# plot shape and mask for debug purposes
fig = plt.figure(figsize=(8,4))

gs = mpl.gridspec.GridSpec(1,2)
gs.update(wspace=0.2, hspace= 0.01)

ax = plt.subplot(gs[0])
patch = patches.PathPatch(path, facecolor='orange', lw=2)
ax.add_patch(patch)

ax.set_xlim(xmin, xmax)
ax.set_ylim(ymin, ymax)

ax = plt.subplot(gs[1])
ax.imshow(mask, origin='lower')

plt.savefig("shapes.png", bbox_inches="tight", pad_inches=0)

它会产生面具:

并同时绘制掩码和路径以进行调试:

And also plots both the mask and the path for debugging purposes:

不同的方向来自matplotlib绘图和图像中的不同原点位置,但应该足够琐碎以按您想要的方式进行更改.

The different orientation comes from the different origin position in matplotlib plots and images, but it should be trivial enough to change it the way you want.

编辑

这是一个更新的脚本,用于拍摄图像,为您的路径生成蒙版并将其剪切掉.我使用的是虚拟图像,并缩小了一些形状,因此更易于使用.

Here's an updated script that takes an image, generates a mask for your path and cuts it out. I'm using a dummy image and scaling down shapes a bit so they're easier to work with.

import numpy as np
import matplotlib as mpl
from matplotlib.path import Path
from matplotlib import patches
import matplotlib.pyplot as plt

import skimage.transform
import skimage.data

from PIL import Image

sar_ver = np.asarray([(16886, 1085), (15139, 2122), (14475, 5226), (8419, 5601),
           (14046, 6876), (14147, 10079), (16816, 3748), (16886, 1085)])

# reshape into smaller path for faster debugging
sar_ver = sar_ver // 20

# create dummy image
img = skimage.data.chelsea()
img = skimage.transform.rescale(img, 2)

# matplotlib path
path = Path(sar_ver)
xmin, ymin, xmax, ymax = np.asarray(path.get_extents(), dtype=int).ravel()

# create a mesh grid of the shape of the final mask
x, y = np.mgrid[:img.shape[1], :img.shape[0]]
# mesh grid to points
points = np.vstack((x.ravel(), y.ravel())).T

# mask for the point included in the path
mask = path.contains_points(points)
mask = mask.reshape(x.shape).T

# plots
fig = plt.figure(figsize=(8,6))
gs = mpl.gridspec.GridSpec(2,2)
gs.update(wspace=0.2, hspace= 0.2)

# image + patch
ax = plt.subplot(gs[0])
ax.imshow(img)
patch = patches.PathPatch(path, facecolor="None", edgecolor="cyan", lw=3)
ax.add_patch(patch)

# mask
ax = plt.subplot(gs[1])
ax.imshow(mask)

# filter image with mask
ax = plt.subplot(gs[2])
ax.imshow(img * mask[..., np.newaxis])

# remove mask from image
ax = plt.subplot(gs[3])
ax.imshow(img * ~mask[..., np.newaxis])

# plt.show()
plt.savefig("shapes.png", bbox_inches="tight", pad_inches=0)

这篇关于使用numpy meshgrid python切割边界框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆