你所拥有的几乎是正确的。如果你查看阈值图像,它无法工作的原因是你的鞋物体在图像中
存在间隙。具体而言,你需要的是期望鞋子的周长是
全部相连的。如果这种情况发生,那么如果你提取最外部的轮廓(这就是你的代码正在执行的操作),你应该只有一个轮廓,代表对象的外周。一旦你填充了轮廓,那么你的鞋子应该完全实心。
由于你的鞋子周长不完整且断裂,这导致白色区域不连续。如果您使用
findContours
查找所有轮廓,它将仅找到每个白色形状的轮廓,而不是最外面的周长。因此,如果您尝试使用
findContours
,它将给出与原始图像相同的结果,因为您只是找到图像内每个白色区域的周长,然后使用
findContours
填充这些区域。
你需要做的是确保图像
完全闭合。我建议你使用
形态学将所有断开的区域连接在一起,然后在这张新图像上运行
findContours
。具体而言,执行二值形态学闭合。它将靠近一起的不连续白色区域连接起来。使用形态学闭合,也许使用类似于7 x 7的方形结构元素来闭合鞋子。你可以把这个结构元素看作是认为它们相连的白色区域之间的最小分离。
因此,做如下操作:
import numpy as np
import cv2
image = cv2.imread('...')
image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 45, 0)
se = np.ones((7,7), dtype='uint8')
image_close = cv2.morphologyEx(image, cv2.MORPH_CLOSE, se)
cnt = cv2.findContours(image_close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
mask = np.zeros(image.shape[:2], np.uint8)
cv2.drawContours(mask, cnt, -1, 255, -1)
这段代码基本上是将您的二值图像进行形态学闭运算。然后,我们找到该图像的外部轮廓,并用白色填充。顺便说一下,我下载了您的二值图像,并在自己的计算机上尝试了这个操作。以下是我使用您的图像得到的结果:
![enter image description here](https://istack.dev59.com/MZHGl.webp)
drawing.cpp:2380: error: (-215) npoints > 0 in function cv::drawContours
- 我正在使用OpenCV 3.1和Python 2.7。你有什么建议吗? - g491