2

I have started out my simple security camera project. I am able to take a picture and email it so far. Allegedly most people are using PIR sensors. Do I need a PIR sensor for motion detection?

How can I detect motion with my "Raspberry Pi Camera Module V2"?

I have the Raspberry Pi 3 Model B, any simple scripts appreciated.

droid192
  • 119
  • 6
Adam
  • 31
  • 2
  • 4

1 Answers1

1

download the latest os, and check if libcamera-* is available in terminal via autocomplete. Several options are available

  • libcamera-hello libcamera-jpeg libcamera-raw libcamera-still libcamera-vid libcamerify
    If you wonder where raspistill and raspivid went the got replaced by a new stack and i confirm it works well. Python lib not out yet, still you can do motion detection.

Start by reading doc and then build the binaries into python via subprocess

Example:
before: mkdir /home/user/camera; paste motion_detect.json to dir
run via python capture.py

$ cat motion_detect.json
{
    "motion_detect" :
    {
    "roi_x" : 0,
    "roi_y" : 0,
    "roi_width" : 1,
    "roi_height" : 1,
    "difference_m" : 0.2,
    "difference_c" : 20,
    "region_threshold" : 0.005,
    "frame_period" : 30,
    "hskip" : 2,
    "vskip" : 2,
    "verbose" : 1
    }
}
import subprocess
import shutil
from datetime import datetime as dt
import os

def printc(s): print('\033[1;36mINFO\033[0m ' + s)

def get_sorted_filenames(): filenames = [s for s in os.listdir('/home/user/camera') if s.startswith('vid')] filenames.sort() return filenames

def get_last_filenr(): filenames = get_sorted_filenames() if len(filenames) == 0: return 0 return int(filenames[-1].partition('_')[0].removeprefix('vid'))

def start_detect(): return subprocess.Popen(['libcamera-still', '--timeout', '0', '--nopreview', '--lores-width', '1280', '--lores-height', '720', '--post-process-file', '/home/user/camera/motion_detect.json'], stderr=subprocess.PIPE, stdout=subprocess.DEVNULL, text=True)

def start_recording(): filename = f'vid{get_last_filenr() + 1}_{dt.utcnow().strftime("%Y-%m-%d-%H:%M:%S")}.h264' return subprocess.run(['libcamera-vid', '--timeout', '10000', '--framerate', '3', '-o', filename], text=True, timeout=15, capture_output=True, check=True)

def free_disk_space(): filenames = get_sorted_filenames() if len(filenames) > 100: to_delete = filenames[:len(filenames) // 4] for filename in to_delete: os.remove('/home/user/camera/' + filename) print(to_delete) printc('Delete done.')

p1 = start_detect() p2 = None while True: s = p1.stderr.readline() print(s, end='') if 'Motion detected' in s: printc('Motion detected, recording...') try: p1.terminate() except Exception as e: print(e) p1.kill() try: p2 = start_recording() printc('Video recorded.') print(p2) except Exception as e: print(e) p1 = start_detect() printc('Motion checking...')

stats = shutil.disk_usage('/')
if stats.used / stats.total > 0.9:
    printc('Disk almost full!')
    free_disk_space()

The specific motion capture used is found in https://github.com/raspberrypi/libcamera-apps/blob/main/post_processing_stages/motion_detect_stage.cpp

droid192
  • 119
  • 6