问题
Getting an error:
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)
Having problems with detecting contours in an image. Have been double checking from the tutorial and also looking from stack overflow to understand where I miss something, but can't find the solution. Using Python 3.6.4 and OpenCV 4.0.0. Thanks for the help!
Code here:
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
回答1:
I also encountered same problem, if you are using an old tutorial cv2.findContours()
function returns 3 value but if you are using later versions it returns 2 value so you can remove first variable assignment and use like that
cnts, _ = cv2.findContours(thresh_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
回答2:
Well in Python version 2 findContours()
used to return 3 values so we save it in (_,cnts,_)
however in python 3 it returns 2 values which are countours and hierarchy. so we need to save it in (cnts,_)
.
So for python 2 people the code goes like:
(_,cnts,_) = cv2.findContours(thresh_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
And for Python 3 people the code goes like :
(cnts,_) = cv2.findContours(thresh_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
Its just about version guys,nothing to worry just change it this way and I am sure you will get the desired output.
回答3:
If you are using cv 4.0 then findContours
is returning two values. See the example here or the documentation for findContours. The function signature looks like this:
contours, hierarchy = cv.findContours(image, mode, method[, contours[, hierarchy[, offset]]])
回答4:
As pointed problem is with that line:
(_, cnts, _) = cv2.findContours(thresh_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
According to documentation cv2.findCountours
returns two things: contours, hierarchy
, so when you try to unpack it to (_, cnts, _)
having 3 elements error appears. Please try to replace mentioned line with
cnts = cv2.findContours(thresh_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
and check if that would solve you problem.
来源:https://stackoverflow.com/questions/54275633/valueerror-while-using-cv2-findcontours-in-python-not-enough-values-to-unp