繁体   English   中英

如何在图像中找到矩形

[英]How to find the rectangles in an image

这是此代码在此答案中生成的图像(绿色圆圈除外,我随后在其上画了绿色圆圈):

富

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

我需要获取图像中每个矩形的位置和大小。 我有一些使用PIL和.load()访问每个像素的代码,但是速度太慢。 在PIL版本中,我寻找起点和终点。 代码类似于pixels[x, y] == 255 and pixels[x-1, y] == 0 and pixels[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

但是,如果您要进行诸如特征检测之类的进一步处理,则无需在此处保存输出图像或重新加载它。 您可以继续使用mask

2.查找连续区域

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

labels, n = scipy.ndimage.measurements.label(mask, numpy.ones((3, 3)))

结果是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))

因此,可以在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)

矩形盒装成绿色

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM