在使用Python的cv2.findContours()时出现ValueError -> 解包的值不足(期望3个,但只有2个)

4

出现错误:

Traceback (most recent call last):
    File "motion_detector.py", line 21, in <module>
        (_, cnts, _) = cv2.findContours(thresh_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 
ValueError: not enough values to unpack (expected 3, got 2)

在图像中检测轮廓时遇到了问题。已经仔细查看了教程并从Stack Overflow上寻找答案,但仍然无法找到解决方案。使用的是Python 3.6.4和OpenCV 4.0.0。感谢您的帮助!

代码如下:

import cv2, time

first_frame = None

video = cv2.VideoCapture(0)

while True:
    check, frame = video.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray,(21,21),0) 

    if first_frame is None:
        first_frame = gray 

    delta_frame = cv2.absdiff(first_frame, gray)
    thresh_frame = cv2.threshold(delta_frame, 30, 255, cv2.THRESH_BINARY)[1]
    thresh_frame = cv2.dilate(thresh_frame, None, iterations = 2) 

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

    for contour in cnts:
        if cv2.contourArea(contour) < 1000: 
            continue
        (x, y, w, h) = cv2.boundingRect(contour)
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)

    cv2.imshow("Gray Frame", gray)
    cv2.imshow("Delta Frame", delta_frame)
    cv2.imshow("Threshold Frame", thresh_frame)
    cv2.imshow("Color Frame", frame)

    key = cv2.waitKey(1)
    print(gray)
    print(delta_frame)

    if key == ord('q'):
        break

video.release()
cv2.destroyAllWindows
4个回答

11

我也遇到了同样的问题,如果您使用的是旧的教程,cv2.findContours()函数将返回3个值,但如果您使用较新版本,则返回2个值,因此您可以删除第一个变量赋值并像这样使用。

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

3

在Python 2版本中,findContours()函数返回3个值,因此我们将其保存在(_,cnts,_)中。然而,在Python 3中,它只返回2个值,即轮廓和层次结构。因此,我们需要将其保存在(cnts,_)中。对于Python 2用户,代码如下:

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

对于Python 3的使用者,代码应该如下:

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

这只是版本的问题,不用担心,只需按照以下方式进行更改,我相信您会得到期望的输出结果。


2
如果您正在使用cv 4.0,则findContours会返回两个值。请参见此处的示例或findContours的文档。函数签名如下: contours,hierarchy = cv.findContours(image,mode,method [,contours [,hierarchy [,offset]]])

2
(_, cnts, _)更改为contours, hierarchy有所帮助。谢谢。 - Egon

0

问题在于那一行代码:

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

根据文档cv2.findCountours返回两个值:contours, hierarchy,因此当您尝试将其解包为(_, cnts, _)时,会出现3个元素的错误。请尝试使用以下代码替换上述行:
cnts = cv2.findContours(thresh_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]

并检查是否能解决您的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接