【问题标题】:How to find the rectangles in an image如何在图像中找到矩形
【发布时间】:2014-03-01 05:52:13
【问题描述】:

这是this answer中这段代码生成的图片(除了绿圈,我后来画的):

形状是(707, 1028, 3),所以每个像素都有三个通道(RGB),但是只填充了白色和黑色。如果转成8位图就更好了。

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

【问题讨论】:

    标签: python arrays numpy python-imaging-library


    【解决方案1】:

    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)
    

    【讨论】:

    • 实际上我需要提取矩形的位置和尺寸。
    • img = np.asarray(Image.open(ss_path).convert('RGB')) up = (img[1:,1:] != img[:-1,1:] ).any(axis=2) left = (img[1:,1:] != img[1:,:-1]).any(axis=2) mask = np.zeros(img.shape[:2 ], dtype=bool) 掩码[1:,1:] = 左 | up output = np.zeros(img.shape, dtype=int) output[~mask] = 255 print output imsave(ss_path_dest, output) 输出为:[[[255 255 255] [255 255 255] [255 255 255 ] ...,
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    • 2021-11-10
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多