too many values to unpack calling cv2.findContours

Question:

I am a python beginner . I was trying to run this code :

#applying closing function 
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
closed = cv2.morphologyEx(th3, cv2.MORPH_CLOSE, kernel)

#finding_contours 
(cnts, _) = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for c in cnts:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.02 * peri, True)
    cv2.drawContours(frame, [approx], -1, (0, 255, 0), 2)

when I summon the mask.py I got this ValueError :

Traceback (most recent call last):
  File "mask.py", line 22, in <module>
    (cnts, _) = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
ValueError: too many values to unpack

what is wrong with this code ?

Asked By: aku putri

||

Answers:

It appears that you’re using OpenCV version 3.x, while writing code intended for the 2.x branch. There were some API changes between those two branches. Since you’re using Python, you have a handy help available — make sure to use it, along with the documentation.

OpenCV 2.x:

>>> import cv2
>>> help(cv2.findContours)
Help on built-in function findContours in module cv2:

findContours(...)
    findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> contours, hierarchy

OpenCV 3.x:

>>> import cv2
>>> help(cv2.findContours)
Help on built-in function findContours:

findContours(...)
    findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> image, contours, hierarchy

This means that in your script the correct way to call findContours when using OpenCV 3.x would be something like

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

UPDATE (Dec 2018)

In OpenCV 4.x, findContours returns 2 values only.

>>> help(cv2.findContours)
Help on built-in function findContours:

findContours(...)
    findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> contours, hierarchy
    .   @brief Finds contours in a binary image.
Answered By: Dan MaĊĦek

You can use cv2.findContours() irrespective of the version with following code snippet:

import cv2 as cv
version = cv.__version__
version = version[0]

if version == '4' or version == '2':
    contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
elif version == '3':
    im2, contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

OpenCV 2.x and 4.x returns 2 variables, while 3.x return 3 variables

Answered By: Jeru Luke
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.