Im trying to use cv2.findContours() on opencv version 4.4.0. (Im using Python version 3.8.5) but it throws an error, I cant figure out. Im not sure whats wrong with the code. He
The problem was the cv2.findContour function will return two things not three.
This cv2.findContours function takes three input arguments. The first argument is an image that should be a grayscale image. The second is a retrieval mode and the third one is the approximation mode. When we apply the findContours
method the original image will be affected. The best practice is to take a copy of the image before processing the findContours
method.
OpenCV stores the contours in a list of the list. Each list represents a different contour. within the list, all the coordinates of that contour are added to that list.
We can store these coordinates differently. How can we store that? The approximation mode
comes to play.
Using cv2.CHAIN_APPROX_NONE
stores all the boundary points. But we don't necessarily need all the boundary points. If the points form a straight line we only need the start and ending points of that line. Using cv2.CHAIN_APPROX_SIMPLE
instead only provides these start and endpoints of bounding contours, thus resulting in much more efficient storage of contour information.
what is retrieval mode? Retrieval mode essentially defines the hierarchy of the contour as so hierarchy being like do you want sub contours or external contours or all contours.
There are four types in retrieval mode in OpenCV.
Hierarchy is stored in the following format [next, previous, First child, parent].
In Python/OpenCV 4.4.0, findContours returns only 2 values, you list 3.
You show:
image,contours,hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
OpenCV 4.4.0, lists:
contours, hierarchy = cv.findContours(image, mode, method[, contours[, hierarchy[, offset]]])
Please always check the documentation. See
https://docs.opencv.org/4.4.0/d3/dc0/group__imgproc__shape.html#gadf1ad6a0b82947fa1fe3c3d497f260e0
One way to handle this in a version independent way, if all you want are the contours, is (credit to @nathancy):
contours = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
If you do not want all nested contours, then use RETR_EXTERNAL and not RETR_LIST.