【问题标题】:Contouring a binary mask with OpenCV / Python使用 OpenCV / Python 对二进制掩码进行轮廓处理
【发布时间】:2017-05-26 07:30:07
【问题描述】:

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

【问题讨论】:

  • 通过准确执行你最后的 sn-p 代码,我得到 (0 0), (0 99), (199, 99), (199, 0)

标签: python opencv contour opencv-contour


【解决方案1】:

直到 OpenCV 3.1 findContours 的边框上有this wierd behaviour,在documentation 中也有说明:

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

这里有been corrected in OpenCV 3.2, which also doesn't modify the source image:

由于opencv 3.2源图像没有被这个函数修改。


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

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

【讨论】:

  • 感谢您提供这两种方法。我期待在 python 上使用 opencv3.2,同时坚持你的第一种方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-15
  • 2019-03-15
  • 2016-03-27
  • 2012-11-09
  • 2015-11-30
  • 1970-01-01
  • 2020-01-01
相关资源
最近更新 更多