Python - 将二进制掩码转换为多边形

Python - convert binary mask to polygon

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

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

这是我目前尝试过的方法:

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

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

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

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

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

排序
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()

您可以像对待对象一样对待正方形,并使用 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)

使用 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)