88

I'm writing an opencv program and I found a script on another stackoverflow question: Computer Vision: Masking a human hand

When I run the scripted answer, I get the following error:

Traceback (most recent call last):
    File "skinimagecontour.py", line 13, in <module>
    contours, _ = cv2.findContours(skin_ycrcb, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
ValueError: too many values to unpack

The code:

import sys
import numpy
import cv2

im = cv2.imread('Photos/test.jpg')
im_ycrcb = cv2.cvtColor(im, cv2.COLOR_BGR2YCR_CB)

skin_ycrcb_mint = numpy.array((0, 133, 77))
skin_ycrcb_maxt = numpy.array((255, 173, 127))
skin_ycrcb = cv2.inRange(im_ycrcb, skin_ycrcb_mint, skin_ycrcb_maxt)
cv2.imwrite('Photos/output2.jpg', skin_ycrcb) # Second image

contours, _ = cv2.findContours(skin_ycrcb, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for i, c in enumerate(contours):
    area = cv2.contourArea(c)
    if area > 1000:
        cv2.drawContours(im, contours, i, (255, 0, 0), 3)
cv2.imwrite('Photos/output3.jpg', im)

Any help is appreciated!

0

9 Answers 9

160

I got the answer from the OpenCV Stack Exchange site. Answer

THE ANSWER:

I bet you are using the current OpenCV's master branch: here the return statements have changed, see http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours.

Thus, change the corresponding line to read:

_, contours, _= cv2.findContours(skin_ycrcb, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

Or: since the current trunk is still not stable and you probably will run in some more problems, you may want to use OpenCV's current stable version 2.4.9.

Sign up to request clarification or add additional context in comments.

2 Comments

I don't understand how to fix it?
@grep there is that 3rd return statement. compare the one in question and the answer lines
50

This works in all cv2 versions:

contours, hierarchy = cv2.findContours(
    skin_ycrcb, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:]

Explanation: By using [-2:], we are basically taking the last two values from the tuple returned by cv2.findContours. Since in some versions, it returns (image, contours, hierarchy) and in other versions, it returns (contours, hierarchy), contours, hierarchy are always the last two values.

3 Comments

ahh-mazinnnnnnn
Worked for me as well.
It's amazing hack
15

You have to change this line;

image, contours, _ = cv2.findContours(skin_ycrcb, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

1 Comment

Welcome to StackOverflow! While answers are always appreciated, this question was asked 2 years ago, and already had an accepted solution. And at that, you don't tell him what he has to change the line to. Please try to avoid 'bumping' questions to the top by providing answers to them, unless the question was not already marked as resolved, or you found a dramatically better alternative approach to the problem :)
6

I'm using python3.x and opencv 4.1.0 i was getting error in the following code :

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

ERROR : too many values to Unpack

then i came to know that above code is used in python2.x SO i just replaced above code with below one(IN python3.x) by adding one more '_' in the left most side have a look

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

1 Comment

The simplest solution
5

The thing you need to do is just add '_' where you are not using the required var , originally given by:

im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

to

_ , contours, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

Here the original doc is given: https://docs.opencv.org/3.1.0/d4/d73/tutorial_py_contours_begin.html

Comments

2

python is right.
you cannot unpack 3 values from the turple and place them in a turple of two contours, _ = cv2.findContours(skin_ycrcb, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

use

img, contours, _ = cv2.findContours(skin_ycrcb, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

Comments

2

@Safwan has provided a simple hack by choosing the last two tuples returned by cv2.findContours() function. But what if you want all the values returned from every tuple of the function independent of the version of cv2?

The following snippet will work irrespective of the OpenCV version (2, 3 or 4) installed in your system/environment and will also store all the tuples in individual variables.

  • OpenCV version 2 & 4, return 2 variables: contours and its hierarchy
  • OpenCV version 3, returns 3 variables: input image, contours and its hierarchy

First, get the version of OpenCV installed (we don't want the entire version just the major number either 2, 3 or 4) :

import cv2
major_version = cv2.__version__[0]

Based on the version either of the following two statements will be executed and the corresponding variables will be populated:

if major_version == '4' or major_version == '2':
    contours, hierarchy = cv2.findContours(img_binary, cv2.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

elif major_version == '3':
    im2, contours, hierarchy = cv2.findContours(img_binary, cv2.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

The contours can be used for further processing.

Comments

0

No big deal, just you might be using open-cv 3.something, which returns 3 values at the point of error and you must be catching only 2, just add any random variable before the contours variable -

_,contours,_ = cv2.findContours(skin_ycrcb, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

Comments

0

If the error is:

not enough values to unpack (expected 3, got 2)

then use:

ctrs,hier=cv2.findContours(im_th.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

instead of

_,ctrs,hier=cv2.findContours(im_th.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.