用OpenCV/Python轮廓化二进制掩码 [英] Contouring a binary mask with OpenCV / Python
问题描述
使用Python和OpenCV,我正在检测二进制掩码的轮廓:
With Python and OpenCV I am detecting contours of a binary mask:
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()
但是,我似乎无法理解完全激活的遮罩的结果:
However, I cannot seem to understand the result of a full activated mask :
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?
Why is opencv findcontours behaving like that, with an offset of 1?
推荐答案
直到OpenCV 3.1 findContours
具有文档:
Until OpenCV 3.1 findContours
has this wierd behaviour on borders, also stated in the documentation:
此功能修改了源图像.此外,该功能未考虑到图像的1像素边界(它用0填充并在算法中用于邻居分析),因此将剪切与图像边界接触的轮廓.
Source image is modified by this function. Also, the function does not take into account 1-pixel border of the image (it's filled with 0's and used for neighbor analysis in the algorithm), therefore the contours touching the image border will be clipped.
由于opencv 3.2源映像未被此功能修改.
Since opencv 3.2 source image is not modified by this function.
作为以前版本的一种解决方法,可以使用copyMakeBorder
创建1像素的黑色(0)边框,并使用偏移量为(-1,-1)
的findContours
:
As a workaround for previous releases, you can use copyMakeBorder
to create a black (0) border of 1 pixel, and use findContours
with an offset of (-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))
这篇关于用OpenCV/Python轮廓化二进制掩码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!