[英]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
如果您需要一个图像有一个通道,则用一个通道而不是三个通道生成它。 所以代替:
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
。
您可以使用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.