Python 如何在图像中找到矩形

Python 如何在图像中找到矩形,python,arrays,numpy,python-imaging-library,Python,Arrays,Numpy,Python Imaging Library,这是这段代码在中生成的图像,后面我画的绿色圆圈除外: 形状为7071028,3,因此每个像素有三个通道RGB,但仅填充白色和黑色。如果将其转换为8位图像会更好 我需要得到图像中每个矩形的位置和大小。我有一些使用PIL和.load访问每个像素的代码,但是太慢了。在PIL版本中,我查找起始角和结束角。代码类似于像素[x,y]==255和像素[x-1,y]==0和像素[x,y-1]==01。使用单个通道制作图像 如果您需要一个图像只有一个通道,那么使用一个通道而不是三个通道生成它。因此,不是: out

这是这段代码在中生成的图像,后面我画的绿色圆圈除外:

形状为7071028,3,因此每个像素有三个通道RGB,但仅填充白色和黑色。如果将其转换为8位图像会更好

我需要得到图像中每个矩形的位置和大小。我有一些使用PIL和.load访问每个像素的代码,但是太慢了。在PIL版本中,我查找起始角和结束角。代码类似于像素[x,y]==255和像素[x-1,y]==0和像素[x,y-1]==0

1。使用单个通道制作图像 如果您需要一个图像只有一个通道,那么使用一个通道而不是三个通道生成它。因此,不是:

output = numpy.zeros(img.shape) # (height, width, 3)
output[~mask] = (255, 255, 255)
写:

output = numpy.zeros(img.shape[:2]) # just (height, width)
output[~mask] = 255
或者,如果已加载多通道图像,并且只想拾取一个通道进行处理,请将其切片:

img = img[...,0] # red channel
但如果您正在进行进一步的处理,如特征检测,则不需要在此处保存或重新加载输出图像。你可以继续用面具工作

2.寻找相邻区域 可以使用查找图像的连续区域。默认情况下,仅查找正交连接的区域;如果还需要对角连接的区域,请传递相应的结构参数:

labels, n = scipy.ndimage.measurements.label(mask, numpy.ones((3, 3)))
结果是标记一个与掩码形状相同的数组,该数组包含不同的整数,用于标记掩码的相邻区域,n表示找到的区域数。然后调用以获取边界框:

>>> bboxes = scipy.ndimage.measurements.find_objects(labels)
>>> bboxes[0]
(slice(0, 2, None), slice(19, 23, None))
这个物体是在x=19-23,y=0-2的位置发现的,它是沿着图像上边缘的一小片黑色。通过使用这对切片索引原始图像,可以获得包含对象的子图像。这是对象3中最上面的矩形:

>>> bboxes[3]
(slice(33, 60, None), slice(10, 86, None))
>>> img[bboxes[3]]
array([[255, 255,   0, ...,   0, 255, 255],
       [255,   0,   0, ...,   0,   0, 255],
       [  0,   0, 255, ...,   0,   0, 255],
       ..., 
       [  0,   0,   0, ...,   0,   0, 255],
       [255,   0,   0, ...,   0, 255, 255],
       [255, 255, 255, ..., 255, 255, 255]], dtype=uint8)
其他矩形是对象4、5和8。有一种方法可以将它们形象化:

boxed = numpy.dstack((img,) * 3)
for y, x in bboxes:
    if y.stop - y.start == 27: # is this the right criterion?
        boxed[(y.start, y.stop-1), x] = (0, 255, 0)
        boxed[y, (x.start, x.stop-1)] = (0, 255, 0)
imsave('boxed.png', boxed)
1.使用单个通道制作图像 如果您需要一个图像只有一个通道,那么使用一个通道而不是三个通道生成它。因此,不是:

output = numpy.zeros(img.shape) # (height, width, 3)
output[~mask] = (255, 255, 255)
写:

output = numpy.zeros(img.shape[:2]) # just (height, width)
output[~mask] = 255
或者,如果已加载多通道图像,并且只想拾取一个通道进行处理,请将其切片:

img = img[...,0] # red channel
但如果您正在进行进一步的处理,如特征检测,则不需要在此处保存或重新加载输出图像。你可以继续用面具工作

2.寻找相邻区域 可以使用查找图像的连续区域。默认情况下,仅查找正交连接的区域;如果还需要对角连接的区域,请传递相应的结构参数:

labels, n = scipy.ndimage.measurements.label(mask, numpy.ones((3, 3)))
结果是标记一个与掩码形状相同的数组,该数组包含不同的整数,用于标记掩码的相邻区域,n表示找到的区域数。然后调用以获取边界框:

>>> bboxes = scipy.ndimage.measurements.find_objects(labels)
>>> bboxes[0]
(slice(0, 2, None), slice(19, 23, None))
这个物体是在x=19-23,y=0-2的位置发现的,它是沿着图像上边缘的一小片黑色。通过使用这对切片索引原始图像,可以获得包含对象的子图像。这是对象3中最上面的矩形:

>>> bboxes[3]
(slice(33, 60, None), slice(10, 86, None))
>>> img[bboxes[3]]
array([[255, 255,   0, ...,   0, 255, 255],
       [255,   0,   0, ...,   0,   0, 255],
       [  0,   0, 255, ...,   0,   0, 255],
       ..., 
       [  0,   0,   0, ...,   0,   0, 255],
       [255,   0,   0, ...,   0, 255, 255],
       [255, 255, 255, ..., 255, 255, 255]], dtype=uint8)
其他矩形是对象4、5和8。有一种方法可以将它们形象化:

boxed = numpy.dstack((img,) * 3)
for y, x in bboxes:
    if y.stop - y.start == 27: # is this the right criterion?
        boxed[(y.start, y.stop-1), x] = (0, 255, 0)
        boxed[y, (x.start, x.stop-1)] = (0, 255, 0)
imsave('boxed.png', boxed)

在true中,我需要提取矩形的位置和尺寸。img=np.asarrayImage.openss_path.convert'RGB'up=img[1:,1:!=img[:-1,1:]任意轴=2左=img[1:,1:!]img[1:,:-1].anyaxis=2 mask=np.zerosimg.shape[:2],dtype=bool mask[1:,1:=left | up output=np.zerosimg.shape,dtype=int output[~mask]=255打印输出imsavess_path_dest,输出为:[[255 255 255][255]…,实际上,我需要提取矩形的位置和尺寸。img=np.asarrayImage.openss_path.convert'RGB'up=img[1:,1:]!=img[:-1,1:]。anyaxis=2 left=img[1:,1:!=img[1:,:-1]。anyaxis=2 mask=np.zerosimg.shape[:2],dtype=bool mask[1:,1:];left | up output=np.zerosimg.shape,dtype=int output[~mask]=255打印输出imsavess\u path\u dest,输出输出为:[[255 255 255][255 255 255 255][255 255 255]。。。,