使用 OpenCV / Python 绘制二值掩模轮廓

2023-12-27

使用 Python 和 OpenCV,我正在检测二进制掩模的轮廓:

import numpy as np
import cv2
import matplotlib.pyplot as plt

mask = np.zeros(20000, dtype=np.uint8).reshape(100, 200)
mask[5:-5,5:-5] = 255
mask[10:70,40:80] = 0
plt.subplot(121)
plt.imshow(mask, cmap='Greys_r', interpolation='none')

_, contours, hierarchy = cv2.findContours(mask.copy(), 
                                          cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE,
                                          offset=(0, 0))

产生预期的行为:

plt.subplot(122)
cv2.drawContours(mask, contours, -1, (127, 127, 127), 2)
plt.imshow(mask, cmap='Greys_r',  interpolation='none')
plt.show()

但是,我似乎无法理解完全激活面罩的结果:

mask = np.ones(20000, dtype=np.uint8).reshape(100, 200)
mask *=255
_, contours, hierarchy = cv2.findContours(mask.copy(),
                                            cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE,
                                            offset=(0, 0))

print contours[0]

其产生:

(1   1), (1  98), (198 98), (198 1)

代替(0 0), (0 99), (199, 99), (199, 0)

为什么 opencv findcontours 的行为是这样的,偏移量为 1?


直到 OpenCV 3.1findContours has 这种奇怪的行为 https://github.com/opencv/opencv/issues/4374关于边界,也在文档 http://docs.opencv.org/3.1.0/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a:

通过此函数修改源图像。此外,该函数不考虑图像的 1 像素边界(它用 0 填充并用于算法中的邻居分析),因此接触图像边界的轮廓将被剪切。

这有在 OpenCV 3.2 中已得到纠正,也不会修改源图像 http://docs.opencv.org/master/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a:

自 opencv 3.2 起,此函数不修改源图像。


作为以前版本的解决方法,您可以使用copyMakeBorder创建 1 像素的黑色 (0) 边框,​​并使用findContours偏移量为(-1,-1):

border = cv2.copyMakeBorder(mask, 1, 1, 1, 1, cv2.BORDER_CONSTANT, value=0 )
_, contours, hierarchy = cv2.findContours(border, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE, offset=(-1, -1))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 OpenCV / Python 绘制二值掩模轮廓 的相关文章

随机推荐