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.
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
The problem in your code is that you're misusing the return values of cv2.threshold()
.
cv2.threshold returns 2 parameters:
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
In your code thresh
is a float not a Mat.
Change:
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)
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
With the following contours highlighted in cnt_test.jpg
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With