【问题标题】:Python - convert binary mask to polygonPython - 将二进制掩码转换为多边形
【发布时间】:2020-03-12 00:49:19
【问题描述】:

给定一个简单的二进制掩码(例如矩形的边界)。

如何使用多边形获取 x-y 坐标?

这是我迄今为止尝试过的:

coords = np.transpose(np.nonzero(mask))

但是,这种方法会生成一个填充的对象,而不是所需的边界。

plt.plot(coords[:, 1], coords[:,0])

基本上,我想要一个白色像素的 x-y 坐标列表,以使用该列表重新绘制矩形(未填充)。

【问题讨论】:

    标签: python numpy coordinates polygon mask


    【解决方案1】:

    您可以使用np.column_stack() + np.where()。这个想法是确定二进制图像中的白色像素,然后按相应的(x, y) 顺序进行排序

    coords = np.column_stack(np.where(image > 0))
    

    另一种方法是使用 OpenCV 的cv2.boundingRect() 查找边界矩形的坐标。这将为您提供宽度、高度和左上角(x,y) 坐标。这是一个找到坐标然后将多边形绘制到空白蒙版上的示例

    import cv2
    import numpy as np
    
    image = cv2.imread('1.png', 0)
    x,y,w,h = cv2.boundingRect(image)
    mask = np.ones(image.shape, dtype=np.uint8) * 255
    mask = cv2.merge([mask,mask,mask])
    cv2.rectangle(mask, (x, y), (x + w, y + h), (36,255,12), 2)
    
    cv2.imshow('mask', mask)
    cv2.waitKey()
    

    【讨论】:

    • 感谢内森西。我尝试了您的解决方案,但得到了相同的“坐标”输出结果。您能否指定 (x,y) 坐标的含义?
    • 我的意思是获取多边形的 (x,y) 坐标。也许我没有正确理解您的问题,您能否详细说明“不是所需的边界”是什么意思。也许添加预期的输出图像
    • 我用错误的输出编辑了原始帖子。预期的输出图像应该与原始输出相同(矩形的边界 - 未填充)。我希望这会有所帮助。
    • 检查更新,你可以找到边界矩形坐标然后用它在另一个图像上绘制它
    【解决方案2】:

    您可以将正方形视为对象并使用skimage.measure.regionprops 函数访问其属性。

    我强烈建议您查看文档,因为它在许多情况下非常有用:

    https://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.regionprops

    此外,还有skimage.measure.regionprops_table,它为您提供了一个字典,可以将其转换为 pandas 数据框。

    这是我的解决方案:

    from skimage.io import imread
    from skimage.measure import regionprops_table
    from pandas import DataFrame
    
    import numpy as np
    import matplotlib.pyplot as plt
    
    rectangle = imread('rectangle_img.png')    
    props_rect = DataFrame(regionprops_table(rectangle, properties=['coords']))
    
    new_img = np.zeros((rectangle.shape[0], rectangle.shape[1]))
    
    for point in props_rect['coords'][0]:
    
        new_img[point[0], point[1]] = 1
    
    
    plt.imshow(new_img)
    

    【讨论】:

      【解决方案3】:

      使用cv2.findContours 既适用于复杂的形状,也适用于多个对象。 Polygons 列表包含 coords 列表,每个列表看起来像这样 [x1, y1, x2, y2, x3, y3, ...]。

      contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
      polygons = []
      
          for object in contours:
              coords = []
              
              for point in object:
                  coords.append(int(point[0][0]))
                  coords.append(int(point[0][1]))
      
              polygons.append(coords)
      

      【讨论】:

      • 我喜欢这个解决方案,但函数的输入是二进制掩码,但如果我的图像有多个类并且我知道每个类的调色板,那么我将如何处理。
      • 我可以想到两种方法。 1.您可以找到一种方法,根据平均像素值或其坐标为每个多边形分配其相应的类(该函数应识别所有类)。 2.您可以遍历类并为每个类生成二进制掩码,然后运行该函数。一种方法是通过 numpy.where()
      猜你喜欢
      • 1970-01-01
      • 2017-06-29
      • 2021-08-14
      • 2019-02-13
      • 2014-08-24
      • 2011-02-15
      • 2021-05-29
      • 1970-01-01
      • 2017-02-04
      相关资源
      最近更新 更多