Recapture/reset the first frame from a motion detector every N seconds

Marciano Ng
  • Recapture/reset the first frame from a motion detector every N seconds Marciano Ng

    I am doing a project based on a motion based detection program.

    It detects changes in the background as "motion" so I'd like a way to recapture a new first frame every few minutes to replace the current one to fix this issue.

    I am using a Raspberry Pi 2B and a Logitech Webcam.

    The code I am using is based on Pyimagesearch.

    This is my version of the code:

    import sys
    sys.path.append('/usr/local/lib/python3.4/site-packages')
    import numpy as np
    import cv2
    import imutils
    from imutils import contours
    from skimage import measure
    import datetime
    import time
    
    #capture feed from webcam    
    cap = cv2.VideoCapture(0)    
    #intialize first frame of video stream    
    firstframe = None    
    avg = None
    
    #loop frames of video/stream    
    while (cap.isOpened()):    
        #grab the current frame and initialize the occupied and unoccupied    
        (grabbed, frame) = cap.read()    
        text = "Unoccupied"
    
        #if the frame could not be grabbed, then we have reached the end of the vid    
        if not grabbed:    
            break
    
        #resize the frame, convert it to grayscale, and blur it    
        frame = imutils.resize(frame, width=500)    
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)    
        gray = cv2.GaussianBlur(gray, (21,21), 0)    
        gray = cv2.medianBlur(gray, 5)   
    
        #if first frame is None, initialize it    
        if firstframe is None:    
            firstframe = gray    
            continue
    
        if avg is None:    
            print ("[INFO] starting background model...")
            avg = gray.copy().astype("float")    
            cap    
            continue
    
        #compute the absolute difference between the current frame and the firstframe    
        cv2.accumulateWeighted(gray, avg, 0.5)
        frameDelta = cv2.absdiff(firstframe, gray)    
        thresh = cv2.threshold(frameDelta, 70, 255, cv2.THRESH_BINARY)[1]   
    
        #perform a series of erosions and dilations to remove any small    
        # blobs of noise from the thresholded image    
        # then from the threshold image find contours    
        thresh = cv2.erode(thresh, None, iterations=2)    
        thresh = cv2.dilate(thresh, None, iterations=4)    
        (_,cnts,hierarchy) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)        
    
        #loop over the contours    
        for (i,c) in enumerate(cnts):    
            #if the contour is too small, ignore it    
            if cv2.contourArea(c) < 500:    
                continue  
    
            #compute the bounding box for the contour, draw it on frame, and update the text    
            #And print the time of object detection    
            (x, y, w, h) = cv2.boundingRect(c)    
            cv2.rectangle(frame, (x,y), (x+w,y+h), (0,255,0), 2)    
            cv2.putText(frame, "#{}".format(i + 1), (x, y - 15),    
            cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)    
            text = "Occupied"    
            print("Object detected at " + time.strftime("%I:%M:%S"))
    
        #draw the text and timestamp on the frame    
        cv2.putText(frame, "Room Status: {}". format(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), cv2.FONT_HERSHEY_SIMPLEX, 0.35,(0,0,255), 1)    
        #show the frame and record if the user presses a key    
        cv2.imshow('frame',frame)    
        cv2.imshow('Thresh',thresh)    
        cv2.imshow('FrameDelta',frameDelta)    
    
        #if 'q' is pressed break from loop    
        if cv2.waitKey(1) & 0xFF == ord('q'):    
            break    
    
    #cleanup the capture and close any open windows    
    cap.release()    
    cv2.destroyAllWindows()
    

  • I'd do something like this (untested):

    # loop frames of video/stream and count them
    counter = 0   
    while cap.isOpened():    
    
        # Stripped for brevity
    
        #if first frame is None or too old, initialize it    
        if firstframe is None or counter > 3000:    
            firstframe = gray    
            counter = 0
            continue
    
        # Stripped for brevity
    
        #if 'q' is pressed break from loop    
        if cv2.waitKey(1) & 0xFF == ord('q'):    
            break   
    
        # Increment the frame counter
        counter += 1
    

    I'm not a python developer, so my syntax here may not be correct.
    The idea is to increment a counter at each frame, and set the firstframe to current frame when the counter exceed 3000, so it should be reset every 120 second at 25 frame per seconds (3000 / 25).

Tags
raspberry-pi digital-cameras
Related questions and answers
  • : continue #compute the bounding box for the contour, draw it on frame, and update the text #And print the time of object detection (x, y, w, h) = cv2.boundingRect(c) cv2.rectangle(frame, (x,y), (x+w,y+h), (0,255,0), 2) cv2.putText(frame, "#{}".format(i + 1), (x, y - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2) text...), 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

  • something the wrong here but I cannot find what it is. Below I attach 2 pictures of what I get in the browser's tab and the HTML code I send from the esp-12e server for a photo capture void...I have an arducam mini 2MP camera connected to an ESP8266 (12-E) module and I am trying to implement video streaming inside a window with some text and control buttons around it, all in the same browser tab /page. I have created two HTML pages for the server to use. The first is the home webpage with no image streaming, just a simple page with text buttons and some CSS. The second HTML page

  • something the wrong here but I cannot find what it is. Below I attach 2 pictures of what I get in the browser's tab and the HTML code I send from the esp-12e server for a photo capture void...I have an arducam mini 2MP camera connected to an ESP8266 (12-E) module and I am trying to implement video streaming inside a window with some text and control buttons around it, all in the same browser tab /page. I have created two HTML pages for the server to use. The first is the home webpage with no image streaming, just a simple page with text buttons and some CSS. The second HTML page

  • " through the API? This is the code of my lambda function: from __future__ import print_function import boto3 import json import time print('Loading function') def lambda_handler(event, context): print("Received event: ") print(type(event)) print(""+json.dumps(event, indent=2)) id = event['Id'] dynamo = boto3.resource('dynamodb').Table('Table1') dynamo.put_item...An AWS lambda function has an "event" and a "context" as in parameters. The "event" is a json object. I try to connect an API (manager through the AWS API Gateway) to my lambda function, sending

  • " through the API? This is the code of my lambda function: from __future__ import print_function import boto3 import json import time print('Loading function') def lambda_handler(event, context): print("Received event: ") print(type(event)) print(""+json.dumps(event, indent=2)) id = event['Id'] dynamo = boto3.resource('dynamodb').Table('Table1') dynamo.put_item...An AWS lambda function has an "event" and a "context" as in parameters. The "event" is a json object. I try to connect an API (manager through the AWS API Gateway) to my lambda function, sending

  • This question is related to this one, I created the code below: import paho.mqtt.client as mqtt import time import serial # Open grbl serial port s = serial.Serial('COM3',9600) # Wake up grbl s.write("\r\n\r\n") time.sleep(2) # Wait for grbl to initialize s.flushInput() # Flush startup text in serial input f = """ O1000 T1 M6 (Linear / Feed - Absolute) G0 G90 G40 G21 G17 G94 G80 G54 X-75..._code): print "Successful connection." # Subscribe to your topics here. client.subscribe("hi") # Runs when a message is PUBLISHed from the broker. Any messages you receive # will run

  • This question is related to this one, I created the code below: import paho.mqtt.client as mqtt import time import serial # Open grbl serial port s = serial.Serial('COM3',9600) # Wake up grbl s.write("\r\n\r\n") time.sleep(2) # Wait for grbl to initialize s.flushInput() # Flush startup text in serial input f = """ O1000 T1 M6 (Linear / Feed - Absolute) G0 G90 G40 G21 G17 G94 G80 G54 X-75..._code): print "Successful connection." # Subscribe to your topics here. client.subscribe("hi") # Runs when a message is PUBLISHed from the broker. Any messages you receive # will run

  • I am working on a home automation project. The basic objective of my project is to control relays and other sensors located at different locations. I have set up my Raspberry Pi as an MQTT broker. Mosquitto is running fine. For now, what I am trying to do is trigger a relay wired up with esp8266 (GPIO2). Here is my Python web server code: import paho.mqtt.client as mqtt from flask import Flask... the Python script on the terminal, for the first click I receive HTTP/1.1" 404 at the terminal, and on every other click I receive HTTP/1.1" 200 My Pi is working on dynamic IP right now. But I've made sure

  • I am working on a home automation project. The basic objective of my project is to control relays and other sensors located at different locations. I have set up my Raspberry Pi as an MQTT broker. Mosquitto is running fine. For now, what I am trying to do is trigger a relay wired up with esp8266 (GPIO2). Here is my Python web server code: import paho.mqtt.client as mqtt from flask import Flask... the Python script on the terminal, for the first click I receive HTTP/1.1" 404 at the terminal, and on every other click I receive HTTP/1.1" 200 My Pi is working on dynamic IP right now. But I've made sure

Data information