Want to find contours -> ValueError: not enough values to unpack (expected 3, got 2), this appears [duplicate]
Asked Answered
M

2

66

My simple Python code is this

import cv2

img=cv2.imread('Materials/shapes.png')

blur=cv2.GaussianBlur(img,(3,3),0)
gray=cv2.cvtColor(blur,cv2.COLOR_BGR2GRAY)
returns,thresh=cv2.threshold(gray,80,255,cv2.THRESH_BINARY)

ret,contours,hierachy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

for cnt in contours:

    area=cv2.contourArea(cnt) #contour area
    
    if (area>1220):
        cv2.drawContours(img,[cnt],-1,(0,255,0),2)
        cv2.imshow('RGB',img)
        cv2.waitKey(1000)
        print(len(cnt))

import numpy as np

contours=np.array(contours)

print(contours)

This worked fine. But recently without me even making any changes. This was throwed to me

ret,contours,hierachy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

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

Mistrial answered 12/1, 2019 at 22:56 Comment(1)
Does this answer your question? too many values to unpack calling cv2.findContoursTroudeloup
U
143

the function cv2.findContours() has been changed to return only the contours and the hierarchy and not ret

you should change it to:

contours,hierachy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
Unpriced answered 13/1, 2019 at 7:36 Comment(4)
Thanks, but in what version was this change introduced?Hernia
so, they've broken compatibility again, but python module is still cv2.Hernia
@Hernia who is "they" in this context? Also the 2 in cv2 is just a namespace and has nothing to do with the actual version. They, as in the developers of OpenCV do in fact follow semantic versioning, and this change was introduced when changing major version from 3.x to 4.x, which is fine. The tone you set in "broken compatibility again" suggests you might not appreciate the correct way in which it was handled. So to answer your question, it was introduced in version 4.0, and yes, it still uses the cv2 namespace.Silin
@Silin Yes, you get my point well. You see, a lot of examples on the internet do not mention what OpenCV version is used and just tell you to pip install opencv (or say nothing at all). And all of a sudden, the examples don't work because the API has changed. Had they (yes, OpenCV developers) used cv2 for OpenCV 2, cv3 for OpenCV 3, etc, there would be no such confusion, because it would be clear from code what major version to use. I'm sure they had their reasons to keep cv2 and it's more related to C++ API then to major version, but retrospectively to me this seems to be a bad descision.Hernia
P
15

Well explained in this python code example, the best way to make your code version-proof is with this following syntax:

# check OpenCV version
major = cv2.__version__.split('.')[0]
if major == '3':
    ret, contours, hierarchy = cv2.findContours(im.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
else:
    contours, hierarchy = cv2.findContours(im.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

This provides you with a code that could run on either last or older version of OpenCV.

Petiole answered 23/4, 2019 at 7:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.