2
votes

ValueError lors de l'utilisation de cv2.findContours () en python. -> pas assez de valeurs pour décompresser (attendu 3, obtenu 2)

Obtention d'une erreur:

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

Problèmes de détection des contours dans une image. J'ai vérifié le didacticiel et j'ai également cherché à partir du débordement de pile pour comprendre où je manquais quelque chose, mais je ne trouvais pas la solution. Utilisation de Python 3.6.4 et OpenCV 4.0.0. Merci pour l'aide!

Code ici:

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)


0 commentaires

4 Réponses :


0
votes

Comme pointé du problème, c'est avec cette ligne:

cnts = cv2.findContours(thresh_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]

Selon documentation cv2.findCountours renvoie deux choses: contours, hiérarchie , donc lorsque vous essayez de le décompresser en ( _, cnts, _) ayant une erreur de 3 éléments apparaît. Veuillez essayer de remplacer la ligne mentionnée par

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

et vérifiez si cela résoudrait votre problème.


0 commentaires

1
votes

Si vous utilisez cv 4.0, findContours renvoie deux valeurs. Consultez l'exemple ici ou la documentation pour findContours . La signature de la fonction ressemble à ceci:

contours, hierarchy = cv.findContours (image, mode, méthode [ contours [ hiérarchie [ offset]]])


1 commentaires

La modification de (_, cnts, _) en contours, hiérarchie a aidé. Merci.



7
votes

J'ai également rencontré le même problème, si vous utilisez un ancien tutoriel, la fonction cv2.findContours () renvoie 3 valeur, mais si vous utilisez des versions ultérieures, elle renvoie 2 valeur afin que vous puissiez supprimer la première affectation de variable et utilisez comme ça

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


0 commentaires

3
votes

Eh bien dans la version 2 de Python findContours () utilisé pour renvoyer 3 valeurs donc nous le sauvegardons dans (_, cnts, _) mais en python 3 il renvoie 2 valeurs qui sont les contours et la hiérarchie. nous devons donc l'enregistrer dans (cnts, _) . Donc, pour les personnes python 2, le code va comme:

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

Et pour les personnes Python 3, le code va comme:

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

C'est à peu près la version les gars, rien à craindre, changez-le de cette façon et je suis sûr que vous obtiendrez le résultat souhaité.


0 commentaires