用OpenCV/Python轮廓化二进制掩码 [英] Contouring a binary mask with OpenCV / Python

查看:148
本文介绍了用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中已得到纠正修改源图像:

由于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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆