使用OpenCV / Python对二进制掩码进行轮廓绘制

时间:2017-01-11 13:19:33

标签: python opencv contour opencv-contour

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

Simple opencv contouring

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

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?

1 个答案:

答案 0 :(得分:3)

直到OpenCV 3.1 findContours在边界上有this wierd behaviourdocumentation中也有说明:

  

此图像功能修改了源图像。此外,该功能没有考虑图像的1像素边界(它用0&#s填充并用于算法中的邻域分析),因此将剪切触摸图像边界的轮廓。

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

  

由于opencv 3.2源图像未被此函数修改。

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

(-1,-1)