Python 如果与黑白图像一起使用,OpenCV findContours() 会抱怨
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30757273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
OpenCV findContours() complains if used with black-white image
提问by dgrat
I want to perform edge detection with the following code. However I get an error because of the image color depth. This error in my eyes, makes no sense, as I convert the image properly to a gray-scale image, and in a subsequent step to a black and white image, which is definitely working correctly. When I call findContours
I get an error.
我想使用以下代码执行边缘检测。但是,由于图像颜色深度,我收到错误消息。这个错误在我看来是没有意义的,因为我将图像正确转换为灰度图像,并在后续步骤中转换为黑白图像,这绝对可以正常工作。当我打电话时,findContours
我收到一个错误。
import cv2
def bw_scale(file_name, tresh_min, tresh_max):
image = cv2.imread(file_name)
image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
#(thresh, im_bw) = cv2.threshold(image, tresh_min, tresh_max, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
(thresh, im_bw) = cv2.threshold(image, tresh_min, tresh_max, 0)
cv2.imwrite('bw_'+file_name, im_bw)
return (thresh, im_bw)
def edge_detect(file_name, tresh_min, tresh_max):
(thresh, im_bw) = bw_scale(file_name, tresh_min, tresh_max)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
if __name__ == '__main__':
edge_detect('test.jpg', 128, 255)
I get this error:
我收到此错误:
dgrat@linux-v3pk:~> python aoi.py
OpenCV Error: Unsupported format or combination of formats ([Start]FindContours support only 8uC1 and 32sC1 images) in cvStartFindContours, file /home/abuild/rpmbuild/BUILD/opencv-2.4.9/modules/imgproc/src/contours.cpp, line 196
Traceback (most recent call last):
File "aoi.py", line 25, in <module>
edge_detect('test.jpg', 128, 255)
File "aoi.py", line 19, in edge_detect
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.error: /home/abuild/rpmbuild/BUILD/opencv-2.4.9/modules/imgproc/src/contours.cpp:196: error: (-210) [Start]FindContours support only 8uC1 and 32sC1 images in function cvStartFindContours
采纳答案by Tomas Camin
The problem in your code is that you're misusing the return values of cv2.threshold()
.
您代码中的问题是您滥用了cv2.threshold()
.
cv2.thresholdreturns 2 parameters:
cv2.threshold返回 2 个参数:
retval
is used when thresholding using the OTSU method (returning the optimal threshold value) otherwise it returns the same threshold value you passed to the function, 128.0 in your case.
dst
is the thresholded result image
返回值
在使用 OTSU 方法(返回最佳阈值)进行阈值处理时使用,否则它返回您传递给函数的相同阈值,在您的情况下为 128.0。
天文台
是阈值化的结果图像
In your code thresh
is a float not a Mat.
在您的代码中thresh
是一个浮点数而不是一个垫子。
Change:
改变:
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
to
到
contours, hierarchy = cv2.findContours(im_bw, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours, hierarchy = cv2.findContours(im_bw, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
EDIT
编辑
Below find a refactored and simplified version of your original code using the following test image.
下面使用以下测试图像找到原始代码的重构和简化版本。
import cv2
def edge_detect(file_name, tresh_min, tresh_max):
image = cv2.imread(file_name)
im_bw = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
(thresh, im_bw) = cv2.threshold(im_bw, tresh_min, tresh_max, 0)
cv2.imwrite('bw_'+file_name, im_bw)
contours, hierarchy = cv2.findContours(im_bw, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(image, contours, -1, (0,255,0), 3)
cv2.imwrite('cnt_'+file_name, image)
if __name__ == '__main__':
edge_detect('test.jpg', 128, 255)
This produces the following bw_test.jpg
这会产生以下 bw_test.jpg
With the following contours highlighted in cnt_test.jpg
在 cnt_test.jpg 中突出显示以下轮廓
回答by Yan Foto
UPDATE
更新
Considering that you already convert you image to gray scale, the problem should be with the channel range. FindContours
support only 32s
and 8u
. You could use image.dtype
to make sure that you get something like uint8
. If not cv2.convertScaleAbs(image)
shouldsolve your problem.
考虑到您已经将图像转换为灰度,问题应该出在通道范围上。FindContours
仅支持32s
和8u
. 你可以image.dtype
用来确保你得到类似uint8
. 如果不是cv2.convertScaleAbs(image)
应该解决你的问题。
ORIGINAL ANSWER
原答案
As the error mentions FindContours support only 8uC1 and 32sC1 images
. So might want to use something like cv.CvtColor
to convert your image to a supported color space.
正如错误所提到的FindContours support only 8uC1 and 32sC1 images
。所以可能想要使用类似的东西cv.CvtColor
将您的图像转换为支持的色彩空间。