0

I followed a video online about motion detection using openCV however I came across the problem that the findContours function is not returning a value. Any help is appreceated.

Here is the code:

import cv2
import time
import datetime
import imutils



def motion_detection():
    video_capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)
    time.sleep(2)

    first_frame = None

    while True:
        frame = video_capture.read()[1]
        text = 'Unoccupied'

        greyscale_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        gaussian_frame = cv2.GaussianBlur(greyscale_frame, (21, 21), 0)

        blur_frame = cv2.blur(gaussian_frame, (5, 5))
        greyscale_image = blur_frame

        if first_frame is None:
            first_frame = greyscale_image

        else:
            pass

        frame = imutils.resize(frame, width=500)
        frame_delta = cv2.absdiff(first_frame, greyscale_image)

        # edit the ** thresh ** depending on the light/dark in room,
        # change the 100(anything pixel value over 100 will become 255(white)
        thresh = cv2.threshold(frame_delta, 100, 255, cv2.THRESH_BINARY)[1]

        dilate_image = cv2.dilate(thresh, None, iterations=2)

        cnt = cv2.findContours(dilate_image.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1]

        for c in cnt:
            if cv2.contourArea(c) > 800:
                (x, y, w, h) = cv2.boundingRect(
                    c)

                cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

                text = 'Occupied'
                # text that appears when there is motion in video feed
            else:
                pass

        ''' now draw text and timestamp on security feed '''
        font = cv2.FONT_HERSHEY_SIMPLEX

        cv2.putText(frame, '{+} Room Status: %s' % text, (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

        cv2.putText(frame, datetime.datetime.now().strftime('%A %d %B %Y %I:%M:%S%p'),
                    (10, frame.shape[0] - 10), font, 0.35, (0, 0, 255), 1)

        cv2.imshow('Security Feed', frame)
        cv2.imshow('Threshold(foreground mask)', dilate_image)
        cv2.imshow('Frame_delta', frame_delta)

        key = cv2.waitKey(1) & 0xFF
        if key == ord('q'):
            cv2.destroyAllWindows()
            break


if __name__ == '__main__':
    motion_detection()

I have tried to debug and find the problem the code is exactly what the video said to write and I have had no luck.

Toby
  • 1
  • 1
    What version of OpenCV? If it's 4.x, then `cnt` is the hierarchy, not a list of contours: https://stackoverflow.com/a/43960384/3962537 – Dan Mašek Nov 29 '22 at 16:41
  • 1
    Please don't rely on outdated videos, but also consult the [docs](https://docs.opencv.org/4.6.0/df/d0d/tutorial_find_contours.html) of the version you are actually using. Index for `cnt` should be 0 not 1 for opencv 4.x. I prefer to write `cnt, _ = cv2.findContours(...)` if I don't need the hierarchy. – Markus Nov 29 '22 at 17:13
  • Thank you so much i was stuck on this for ages – Toby Nov 29 '22 at 17:43

0 Answers0