Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home Raspberry Pi

Raspberry Pi CCTV with OpenCV Motion Detection Alerts

Raspberry Pi CCTV with OpenCV Motion Detection Alerts

March 11, 2026 /Posted byJayesh Jain / 0

A Raspberry Pi combined with OpenCV makes a surprisingly capable CCTV and motion detection system. Unlike commercial security cameras that lock you into subscription cloud plans, a Pi-based system gives you full privacy control, local storage, and the flexibility to trigger any kind of alert — email, Telegram, SMS, or even a siren — when motion is detected.

In this tutorial, we’ll build a complete Raspberry Pi CCTV system that uses OpenCV’s background subtraction algorithms to detect motion, records video clips when activity is detected, and sends instant alerts to your phone via Telegram. No cloud subscriptions required.

Hardware You Need

Before writing a single line of code, gather your hardware:

  • Raspberry Pi: Pi 4B, Pi 5, or Pi Zero 2 W (Pi 5 highly recommended for smoother video processing)
  • Camera: Raspberry Pi Camera Module (CSI interface) or USB camera — CSI cameras are preferred for lower CPU overhead
  • Storage: MicroSD card (32GB+) or USB drive for recording footage
  • Power supply: Official Pi power supply or 5V/3A USB-C adapter
  • Housing: Weatherproof enclosure if mounting outdoors
Recommended: Arducam 12MP IMX477 Pan Tilt Zoom IR-Cut Camera — a premium PTZ camera with IR-cut filter for Raspberry Pi, offering 12MP resolution, motorized pan/tilt/zoom, and switchable IR-cut for day/night CCTV applications.
Recommended: Raspberry Pi 5 Model 4GB RAM — OpenCV video processing is CPU-intensive. The Pi 5’s faster CPU handles 1080p motion detection at 30fps without frame drops, while the Pi 4 struggles above 720p.

Installing OpenCV on Raspberry Pi

OpenCV installation on Raspberry Pi has gotten much simpler. We’ll use the pre-built wheels via pip, which avoids a 2-4 hour compilation process.

Step 1: Update and install dependencies

sudo apt update && sudo apt upgrade -y
sudo apt install -y python3-pip python3-venv libopencv-dev python3-opencv
sudo apt install -y libatlas-base-dev libhdf5-dev libhdf5-serial-dev
sudo apt install -y libjasper-dev libqtgui4 libqt4-test 2>/dev/null || true

Step 2: Create a virtual environment

python3 -m venv ~/cctv-env
source ~/cctv-env/bin/activate
pip install opencv-python-headless numpy Pillow requests python-telegram-bot

Step 3: Enable the camera interface

sudo raspi-config
# Navigate to: Interface Options → Camera → Enable
# Then reboot: sudo reboot

For Pi 5 with newer Pi OS (Bookworm), the camera is enabled by default via libcamera. No raspi-config step needed.

Step 4: Verify camera access

# For USB camera:
python3 -c "import cv2; cap=cv2.VideoCapture(0); print('Camera OK' if cap.isOpened() else 'FAILED')"

# For Pi Camera Module:
libcamera-hello --timeout 2000

Motion Detection Algorithm: Background Subtraction

OpenCV offers multiple motion detection approaches. We’ll use MOG2 (Mixture of Gaussians 2), which is OpenCV’s most reliable background subtraction algorithm for CCTV use:

  • Automatically models the background by observing multiple frames
  • Adapts to gradual lighting changes (day/night, clouds)
  • Distinguishes moving foreground objects from static background
  • Built into OpenCV — no additional libraries needed

Here’s the core motion detection logic:

import cv2
import numpy as np

# Initialize background subtractor
# history=500: frames to model background
# varThreshold=16: sensitivity (lower = more sensitive)
# detectShadows=True: ignore shadows
bg_subtractor = cv2.createBackgroundSubtractorMOG2(
    history=500, varThreshold=16, detectShadows=True
)

def detect_motion(frame, min_area=500):
    """
    Returns True and list of bounding boxes if motion detected.
    min_area: minimum contour area in pixels (filters noise)
    """
    # Apply background subtraction
    fg_mask = bg_subtractor.apply(frame)
    
    # Remove shadows (gray pixels, value 127)
    _, fg_mask = cv2.threshold(fg_mask, 200, 255, cv2.THRESH_BINARY)
    
    # Morphological operations to remove noise
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    fg_mask = cv2.morphologyEx(fg_mask, cv2.MORPH_OPEN, kernel)
    fg_mask = cv2.dilate(fg_mask, kernel, iterations=2)
    
    # Find contours of moving objects
    contours, _ = cv2.findContours(
        fg_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
    )
    
    motion_detected = False
    boxes = []
    for contour in contours:
        if cv2.contourArea(contour) > min_area:
            motion_detected = True
            x, y, w, h = cv2.boundingRect(contour)
            boxes.append((x, y, w, h))
    
    return motion_detected, boxes, fg_mask

Complete CCTV Script with Telegram Alerts

Here is the full script that combines motion detection, video recording, and Telegram alerting:

#!/usr/bin/env python3
"""
Raspberry Pi CCTV with OpenCV Motion Detection
Sends Telegram alerts with snapshot on motion detected.
"""

import cv2
import numpy as np
import time
import requests
import os
from datetime import datetime

# --- CONFIGURATION ---
CAMERA_INDEX = 0          # 0 for USB cam, change for Pi camera
FRAME_WIDTH = 640
FRAME_HEIGHT = 480
FPS = 20
MIN_MOTION_AREA = 800     # px² — increase to reduce false triggers
COOLDOWN_SECONDS = 30     # min seconds between alerts
SAVE_DIR = "/home/pi/cctv-recordings"

# Telegram bot settings
TELEGRAM_TOKEN = "YOUR_BOT_TOKEN"
TELEGRAM_CHAT_ID = "YOUR_CHAT_ID"

def send_telegram_photo(image_path, caption):
    url = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendPhoto"
    with open(image_path, 'rb') as f:
        requests.post(url, data={"chat_id": TELEGRAM_CHAT_ID, "caption": caption},
                     files={"photo": f}, timeout=10)

def main():
    os.makedirs(SAVE_DIR, exist_ok=True)
    cap = cv2.VideoCapture(CAMERA_INDEX)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, FRAME_WIDTH)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, FRAME_HEIGHT)
    cap.set(cv2.CAP_PROP_FPS, FPS)

    bg_sub = cv2.createBackgroundSubtractorMOG2(
        history=500, varThreshold=16, detectShadows=True
    )
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    last_alert = 0

    print("CCTV started. Monitoring for motion...")
    while True:
        ret, frame = cap.read()
        if not ret:
            time.sleep(1)
            continue

        fg = bg_sub.apply(frame)
        _, fg = cv2.threshold(fg, 200, 255, cv2.THRESH_BINARY)
        fg = cv2.morphologyEx(fg, cv2.MORPH_OPEN, kernel)
        fg = cv2.dilate(fg, kernel, iterations=2)

        contours, _ = cv2.findContours(
            fg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
        )
        motion = any(cv2.contourArea(c) > MIN_MOTION_AREA for c in contours)

        now = time.time()
        if motion and (now - last_alert) > COOLDOWN_SECONDS:
            last_alert = now
            ts = datetime.now().strftime("%Y%m%d_%H%M%S")
            snap_path = f"{SAVE_DIR}/motion_{ts}.jpg"
            cv2.imwrite(snap_path, frame)
            print(f"Motion detected! Saved: {snap_path}")
            try:
                send_telegram_photo(snap_path, f"Motion detected at {ts}")
            except Exception as e:
                print(f"Telegram error: {e}")

        time.sleep(1.0 / FPS)

if __name__ == "__main__":
    main()

Before running, set up your Telegram bot: message @BotFather on Telegram to create a new bot, get your token, then message your bot once and check https://api.telegram.org/bot{TOKEN}/getUpdates to find your chat_id.

Recommended: Arducam 5MP 1080p Pan Tilt Zoom PTZ Camera — motorized PTZ means your CCTV can automatically follow movement or cover a wide area. Compatible with Raspberry Pi 4 and 3B+, with the Pan Tilt Hat for servo control.

Running as a Systemd Service

To make the CCTV system start automatically on boot, create a systemd service:

sudo tee /etc/systemd/system/cctv-monitor.service << 'EOF'
[Unit]
Description=Raspberry Pi CCTV OpenCV Monitor
After=network.target

[Service]
User=pi
WorkingDirectory=/home/pi
ExecStart=/home/pi/cctv-env/bin/python3 /home/pi/cctv-monitor.py
Restart=always
RestartSec=10
Environment=DISPLAY=:0

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable cctv-monitor
sudo systemctl start cctv-monitor
sudo systemctl status cctv-monitor

Storage Management: Auto-Delete Old Recordings

CCTV recordings will fill your SD card quickly. Add a cron job to clean up recordings older than 7 days:

crontab -e
# Add:
0 2 * * * find /home/pi/cctv-recordings -name "*.jpg" -mtime +7 -delete
0 2 * * * find /home/pi/cctv-recordings -name "*.mp4" -mtime +7 -delete

For longer retention, consider mounting a USB drive or external SSD. With Raspberry Pi 5’s USB 3.0 port, an external SSD provides much faster write speeds than an SD card — important when continuously recording video.

Recommended: 1/4 CMOS 640×480 USB Camera with Collapsible Cable for Raspberry Pi — a compact and affordable USB camera for Raspberry Pi CCTV projects. The collapsible cable allows flexible positioning in enclosures.

Advanced Features: Zones and Sensitivity

One of the advantages of OpenCV over commercial cameras is fine-grained control over detection zones and sensitivity:

Region of Interest (ROI): Only process a specific portion of the frame to avoid false triggers from trees, passing cars, etc.:

# Define ROI: only monitor the doorway area
ROI_X, ROI_Y, ROI_W, ROI_H = 200, 100, 300, 250
roi_frame = frame[ROI_Y:ROI_Y+ROI_H, ROI_X:ROI_X+ROI_W]
fg = bg_sub.apply(roi_frame)  # Apply subtraction only to ROI

Time-based arming: Only monitor at night or during work hours:

from datetime import datetime
def is_armed():
    now = datetime.now()
    # Monitor between 10pm and 7am
    return now.hour >= 22 or now.hour < 7

Frequently Asked Questions

What is the best camera for a Raspberry Pi CCTV system?

For best results, use the official Raspberry Pi Camera Module v2 or v3 via the CSI interface — it uses hardware encoding and consumes less CPU than USB cameras. For PTZ functionality or higher resolution, the Arducam IMX477 12MP PTZ camera is excellent. For a budget setup, any USB UVC-compatible camera works with OpenCV via cv2.VideoCapture(0).

Can Raspberry Pi run CCTV 24/7?

Yes, Raspberry Pi is designed for continuous operation. However, use quality SD cards (endurance-rated) or boot from SSD/USB to avoid SD card wear from continuous writes. Enable log rotation and limit recording to motion events only to reduce write cycles. Monitor CPU temperature — add a heatsink and small fan if it exceeds 70°C regularly.

How do I reduce false motion detections?

Increase MIN_MOTION_AREA to filter small objects like insects. Use ROI masking to exclude areas with frequent movement like trees or roads. Increase the history parameter in MOG2 to let the background model adapt longer before triggering. You can also add a frame differencing threshold — only trigger if motion persists for 3+ consecutive frames.

Can I view the live stream remotely?

Yes. The simplest approach is to run an MJPEG stream server using Flask or MotionEye. MotionEye is a popular web interface for Raspberry Pi cameras that handles streaming, motion detection, and recording through a browser UI. Install it via pip: pip install motioneye. Access the stream via your Pi’s IP address on port 8765 over your home network (or VPN for remote access).

Does this work with Raspberry Pi Zero 2 W?

Yes, but with limitations. The Pi Zero 2 W can run OpenCV motion detection at 320×240 resolution smoothly, but struggles at 640×480 or above. Use lower resolution and reduce FPS to 10-15 for stable operation. The Zero 2 W’s 512MB RAM is also a constraint when using heavy OpenCV features. For a capable headless motion detection node, it works well at lower resolutions.

Conclusion

A Raspberry Pi CCTV system with OpenCV motion detection is more capable, more private, and more customizable than any off-the-shelf security camera. With background subtraction, you get reliable detection that adapts to lighting changes, and by routing alerts through Telegram, you get instant smartphone notifications without any cloud subscription fees.

The system described in this tutorial is a solid foundation — you can extend it with face recognition (OpenCV’s Haar cascades or a deep learning model), license plate reading, multiple camera support, or a full NVR (Network Video Recorder) using MotionEye or Frigate.

Ready to build your security camera? Browse our full range of Raspberry Pi cameras and accessories at Zbotic — including camera modules, PTZ cameras, and everything you need to get started.

Tags: CCTV, home security, motion detection, OpenCV, Python, Raspberry Pi, security camera
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
Raspberry Pi 5 Benchmarks: Rea...
blog raspberry pi 5 benchmarks real performance numbers vs pi 4 595022
blog raspberry pi cluster build a mini supercomputer at home 595029
Raspberry Pi Cluster: Build a ...

Related posts

Svg%3E
Read more

Raspberry Pi Benchmarks: Performance Testing All Models

April 1, 2026 0
Table of Contents Introduction and Use Cases Hardware Requirements Software Installation Configuration and Setup Testing and Validation Advanced Features Troubleshooting... Continue reading
Svg%3E
Read more

Raspberry Pi PoE: Power Over Ethernet Setup Guide

April 1, 2026 0
Table of Contents Introduction and Use Cases Hardware Requirements Software Installation Configuration and Setup Testing and Validation Advanced Features Troubleshooting... Continue reading
Svg%3E
Read more

Raspberry Pi GSM HAT: SMS and Cellular IoT

April 1, 2026 0
Table of Contents Introduction and Use Cases Hardware Requirements Software Installation Configuration and Setup Testing and Validation Advanced Features Troubleshooting... Continue reading
Svg%3E
Read more

Raspberry Pi RS485: Industrial Sensor Network

April 1, 2026 0
Table of Contents Introduction and Use Cases Hardware Requirements Software Installation Configuration and Setup Testing and Validation Advanced Features Troubleshooting... Continue reading
Svg%3E
Read more

Raspberry Pi CAN Bus: Vehicle OBD2 Data Reader

April 1, 2026 0
Table of Contents Introduction and Use Cases Hardware Requirements Software Installation Configuration and Setup Testing and Validation Advanced Features Troubleshooting... Continue reading

Add comment Cancel reply

Your email address will not be published. Required fields are marked

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now