Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly use cv2.findContours() on opencv version 4.4.0.?

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. Here's some background:

According to OpenCV the syntax for cv2.findContours() is as follows: Python: contours, hierarchy = cv.findContours(image, mode, method[, contours[, hierarchy[, offset]]])

I looked for some examples to make sure how to properly implement it, heres what I found:

  • example 1

    (_, contours, _) = cv2.findContours(binary_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

  • example 2

    (_, cnts, _) = cv2.findContours(thresholded.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

Those are from working projects I found online, there are plenty examples like those. So, Im trying to implement some code I got from a video to gain some understanding on the topic but it does not seem to work for me and I cant find why. Heres the code:

import cv2 
import numpy as np 

imagen =cv2.imread('lettuce.jpg')
gray = cv2.cvtColor(imagen,cv2.COLOR_BGR2GRAY)
_,binary = cv2.threshold(gray,100,255,cv2.THRESH_BINARY)

image,contours,hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

cv2.drawContours(image,contours, -1, (0,255,0),3)

Error:

Traceback (most recent call last):
  line 8, in <module>
    image,contours,hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
ValueError: not enough values to unpack (expected 3, got 2)
like image 917
Jason Avatar asked Dec 30 '22 20:12

Jason


1 Answers

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.

like image 125
fmw42 Avatar answered Jan 02 '23 08:01

fmw42