我有一个小项目,我需要计算头发部分的面积,并告诉其中哪个覆盖了两个图像中更大的区域。我还有另一个用于拔毛的代码。但是它也没有给出预期的结果。您可能已经从下图猜到了。我会在稍后处理。
我正在尝试从轮廓计算面积,这给了我这样的错误:
OpenCV(3.4.4) C:\projects\opencv-python\opencv\modules\imgproc\src\contours.cpp:195: error: (-210:Unsupported format or combination of formats) [Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only in function 'cvStartFindContours_Impl'
所以,findContours
为什么不支持我的图片?
我只需要查找头发部分的区域。因此,我想到了计算所有白色像素覆盖的面积,然后再从整个图像的面积中减去它。在这种情况下,我不知道如何计算所有白色像素覆盖的面积。我这样想是因为,头发的颜色可以变化,但是背景永远是白色的。
那么,这种技术可行吗?还是请针对上述错误提出一些解决方案?
我的图片
我的代码:
import cv2
import numpy as np
img = cv2.imread("Hair.jpg")
_, contours, _ = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
c = max(contours, key = cv2.contourArea)
cv2.drawContours(img, [c], -1, (255,255, 255), -1)
area = cv2.contourArea(c)
print(area)
cv2.imshow("contour", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
答案 0 :(得分:1)
您的错误已经告诉您哪里出了问题,特别是这一部分:
FindContours supports only CV_8UC1 images when mode
这意味着它必须是灰度图像。您传递的图片加载有:
img = cv2.imread("Hair.jpg")
默认情况下,该图片以CV_8UC3
或简单的形式返回图像,即BGR颜色空间。即使您的图像只有黑白。解决方案,以灰度加载:
img = cv2.imread("Hair.jpg", cv2.IMREAD_GRAYSCALE)
此外,我注意到这是一个.jpg
文件,它可能会引入一些您可能不喜欢/想要的构件。要删除它们,请使用阈值:
ret,thresh1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
我希望这对您有帮助,如果不能,请发表评论
findContours
函数将黑色作为背景,将白色作为前景。在你的情况是相反的。但是有一种简单的方法可以解决此问题,只需在传递图像时将其反转即可:
_, contours, _ = cv2.findContours(255-img, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
255是图像可以具有的最大值,它将变成黑色,变成白色,白色变成黑色,为您提供正确的轮廓。