如何在图像中找到矩形

use*_*112 1 python arrays numpy python-imaging-library

这是此答案中此代码生成的图像(绿色圆圈除外,我之后提到):

FOO

形状为(707,1028,3),因此每个像素有三个通道(RGB),但只填充白色和黑色.如果它被转换为8位图像会更好.

我需要获取图像中每个矩形的位置和大小.我有一些代码使用PIL并.load()访问每个像素,但速度太慢.在PIL版本中,我寻找开始角落和结束角落.代码就像pixels[x, y] == 255 and pixels[x-1, y] == 0 and pixels[x, y-1] == 0

Gar*_*ees 12

1.使用单个通道制作图像

如果您需要图像具有单个通道,则使用一个通道而不是三个通道生成它.所以代替:

output = numpy.zeros(img.shape) # (height, width, 3)
output[~mask] = (255, 255, 255)
Run Code Online (Sandbox Code Playgroud)

写:

output = numpy.zeros(img.shape[:2]) # just (height, width)
output[~mask] = 255
Run Code Online (Sandbox Code Playgroud)

或者,如果您已加载多通道图像并且只想选择一个通道进行处理,请将其切片:

img = img[...,0] # red channel
Run Code Online (Sandbox Code Playgroud)

但是,如果您正在进行功能检测等进一步处理,则无需在此处保存输出图像或重新加载它.你可以继续工作mask.

2.寻找连续的区域

您可以使用找到图像的连续区域scipy.ndimage.measurements.label.默认情况下,它仅查找正交连接的区域; 如果你也想要对角连接的区域,那么传递适当的structure参数:

labels, n = scipy.ndimage.measurements.label(mask, numpy.ones((3, 3)))
Run Code Online (Sandbox Code Playgroud)

结果是labels(与mask包含标记连续区域的不同整数的形状相同的阵列mask)和n(找到的区域数).然后调用scipy.ndimage.measurements.find_objects以获取边界框:

>>> bboxes = scipy.ndimage.measurements.find_objects(labels)
>>> bboxes[0]
(slice(0, 2, None), slice(19, 23, None))
Run Code Online (Sandbox Code Playgroud)

因此,该对象位于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)
Run Code Online (Sandbox Code Playgroud)

(其他矩形是对象#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)
Run Code Online (Sandbox Code Playgroud)

长方形盒装绿色