给定一个简单的二进制掩码(例如矩形的边界)。
如何使用多边形获取x-y坐标?
这是我迄今为止尝试过的:
coords = np.transpose(np.nonzero(mask))
但是,这种方法会生成填充的对象,而不是所需的边界。
plt.plot(coords[:, 1], coords[:,0])
基本上,我想要一个白色像素的 x-y 坐标列表,以使用此列表重新绘制矩形(未填充)。
使用
cv2.findContours
适用于复杂形状和多个对象。 Polygons
列表包含 coords
列出每个看起来像这样的 [x1, y1, x2, y2, x3, y3, ...]。
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
polygons = []
for obj in contours:
coords = []
for point in obj:
coords.append(int(point[0][0]))
coords.append(int(point[0][1]))
polygons.append(coords)
您可以使用
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()
您可以将正方形视为一个对象,并使用
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)
contours, _ = cv2.findContours(binary_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
polygons = [np.array(polygon).squeeze() for polygon in contours]
polygons
是一个 list
,其中 arrays
的形状为 N, 2
,其中 N
对应于点数,2
对应于 x
和 y
坐标
我在我的项目中基于这个项目做了一个功能[1]。无需调整参数即可完美运行!