I want to run the following site
Link content
Please write your question in detail here.
I want to make a camera that can detect motion with Raspberry Pi.

When I checked the error statement, it said that "the number of variables and the number of elements do not match" and this error appears.
I don't know if I should edit it.

Error message
Traceback (most recent call last): File "security_cam_motion.py", line87, in<module>image, contours, hierarchy = cv.findContours (thresh.copy (), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) ValueError: not enough values to unpack (expected 3, got 2)
Corresponding source code
Source code
 #-*-coding: utf-8-*-
import time
import datetime
import cv2 as cv
# A program that realizes a surveillance camera using a WEB camera
# Motion detection, save the jpg file with the date and time embedded at that time

#Directory to save images
save_dir ='./image/'
#File name should be a character string including date and time
#Specify the file name to be added after the date and time
fn_suffix ='motion_detect.jpg'
Create an instance of #VideoCapture.
cap = cv.VideoCapture (0)
#Specify vertical and horizontal resolution
cap.set (cv.CAP_PROP_FRAME_WIDTH, 640)
cap.set (cv.CAP_PROP_FRAME_HEIGHT, 480)
# 2 Pixel value when binarized
#Threshold for detecting changes in each dot
DOT_TH = 20
#Motion factor (how many points have changed)
#How much more do I want to record?
#Store data for comparison
avg = None
while True:
    ret, frame = cap.read () # 1 Read frame
    motion_detected = False # Flag indicating whether motion was detected
    dt_now = datetime.datetime.now () # Time when the data was acquired
    #File name and date and time to embed in the image
    dt_format_string = dt_now.strftime ('% Y-% m-% d% H:% M:% S')
    f_name = dt_now.strftime ('% Y% m% d% H% M% S% f') + "_" + fn_suffix

    # Make it monochrome
    gray = cv.cvtColor (frame, cv.COLOR_BGR2GRAY)
    #Get a frame for comparison
    if avg is None:
        avg = gray.copy (). astype ("float")

    #Calculate the difference between the current frame and the moving average
    cv.accumulateWeighted (gray, avg, 0.6)
    frameDelta = cv.absdiff (gray, cv.convertScaleAbs (avg))
    # Threshold processing the delta image
    thresh = cv.threshold (frameDelta, DOT_TH, DELTA_MAX, cv.THRESH_BINARY) [1]
    #Calculate the motion factor. How much has changed as a whole?
    motion_factor = thresh.sum () * 1.0/thresh.size/DELTA_MAX
    motion_factor_str ='{: .08f}'. format (motion_factor)
    # Write the date and time on the image
    cv.putText (frame, dt_format_string, (25,50), cv.FONT_HERSHEY_SIMPLEX, 1.5, (0,0,255), 2)
   #Write the motion_factor value in the image
    cv.putText (frame, motion_factor_str, (25,470), cv.FONT_HERSHEY_SIMPLEX, 1.5, (0,0,255), 2)
    If the #motion factor exceeds the threshold value, motion is detected.
    if motion_factor>MOTHON_FACTOR_TH:
        motion_detected = True
    # Save the image if motion is detected
    if motion_detected == True:
        cv.imwrite (save_dir + f_name, frame)
        print ("DETECTED:" + f_name)

    # From here, processing the image to be displayed on the screen
    # Put a contour line on the threshold of the image
    image, contours, hierarchy = cv.findContours (thresh.copy (), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    frame = cv.drawContours (frame, contours, -1, (0, 255, 0), 3)

    # Display the resulting image
    cv.imshow ('camera', frame)

    # Wait until any key is pressed
    k = cv.waitKey (1000) # Argument is wait time (ms)
    if k == 27: End when #Esc is entered

print ("Bye! \ N")
# Close the displayed window
cap.release ()
cv.destroyAllWindows ()
What I tried

I'm still new to python and didn't know what to do.

Supplementary information (FW/tool version, etc.)

Raspberry Pi 4

  • Answer # 1

    It seems that the number of return values ​​differs depending on the version of cv2 (opencv). Please check the version you are using.

    In findContours (), pass the target image in the first argument, specify the contour extraction mode in the second argument, and specify the contour approximation method (detection method) in the third argument. The output returns contour image, contour, and contour hierarchy information, so store it in the image, contours, and hierarchy variables. (When using with OpenCV4, the difference is that contours, hierarchy = cv2.findContours () are returned.)

    [Python] Contour detection with OpenCV – findContours (), drawContours ()