Detecting Motion with Python: A Practical Guide
Introduction
In the world of computer vision, motion detection is a critical task for various applications, ranging from security surveillance to wildlife monitoring. By leveraging Python and some key libraries, you can efficiently detect and manage motion in a series of images. In this blog post, we'll explore a practical implementation of motion detection using Python. We'll delve into the core concepts and walk through the interesting parts of a script that accomplishes this task.
The Concept of Motion Detection
Motion detection in images involves comparing a current image frame to a reference background frame. The goal is to identify significant changes that indicate motion. This process can be broken down into several steps:
- Capturing Images: Retrieve images from a camera or an online source.
- Storing Images: Save the captured images for processing and future reference.
- Updating the Background: Periodically update the background frame to accommodate changes in the scene.
- Detecting Motion: Compare the current frame with the background frame to detect significant changes.
- Managing Storage: Clean up stored images to save space and maintain only relevant data.
Key Functions in the Script
Let's dissect the key functions and their roles in the motion detection script.
Image Retrieval
The get_image function retrieves an image from a specified URL. This image will be used for motion detection.
import requests
import numpy as np
def get_image(url):
response = requests.get(url, stream=True)
if response.status_code == 200:
return np.asarray(bytearray(response.content), dtype="uint8")
return None
Image Saving
The save_image function saves the retrieved image to a specified directory. It ensures the directory exists before saving.
import os
import cv2
def save_image(img, directory, filename):
if not os.path.exists(directory):
os.makedirs(directory)
cv2.imwrite(os.path.join(directory, filename), img)
Directory Cleanup
To manage storage, the script includes functions to clean up old images. The clean_images_directory function keeps only the most recent files, while the clean_motion_directory function removes images with high similarity.
def clean_images_directory(directory, keep_files):
files = os.listdir(directory)
files.sort()
files_to_remove = files[:-keep_files]
for file in files_to_remove:
if '.jpg' in file:
os.remove(os.path.join(directory, file))
def clean_motion_directory(directory, similarity_threshold=0.95):
from skimage.metrics import structural_similarity as ssim
files = [f for f in os.listdir(directory) if f.endswith('.jpg')]
files.sort()
to_remove = []
for i in range(len(files) - 1):
img1 = cv2.imread(os.path.join(directory, files[i]), cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread(os.path.join(directory, files[i+1]), cv2.IMREAD_GRAYSCALE)
similarity = ssim(img1, img2)
if similarity > similarity_threshold:
to_remove.append(files[i])
for file in to_remove:
os.remove(os.path.join(directory, file))
print(f"Cleaned motion directory: {len(to_remove)} similar images removed.")
Motion Detection
The detect_significant_motion function compares the current frame with the background frame. It identifies significant motion by checking if any contour in the difference image is large enough.
def detect_significant_motion(current_image, background, min_area=500, threshold=25):
gray_current = cv2.cvtColor(current_image, cv2.COLOR_BGR2GRAY)
gray_background = cv2.cvtColor(background, cv2.COLOR_BGR2GRAY)
frame_delta = cv2.absdiff(gray_background, gray_current)
thresh = cv2.threshold(frame_delta, threshold, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.dilate(thresh, None, iterations=2)
contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
if cv2.contourArea(contour) > min_area:
return True
return False
Main Loop
The main loop of the script orchestrates the entire process, including capturing images, updating the background, detecting motion, and managing storage.
import time
from datetime import datetime
url = "http://192.168.0.66:8092/?action=snapshot"
interval = 5
background_update_interval = 60 # Update background every 60 seconds
motion_cooldown = 10 # Cooldown period after motion detection (in seconds)
background = None
last_background_update = 0
last_motion_detection = 0
last_clean_time = time.time()
while True:
current_time = datetime.now().strftime("%Y%m%d_%H%M%S")
img_data = get_image(url)
if img_data is not None:
current_image = cv2.imdecode(img_data, cv2.IMREAD_COLOR)
save_image(current_image, "images", f"image_{current_time}.jpg")
clean_images_directory("images", 10)
if background is None or time.time() - last_background_update > background_update_interval:
background = current_image.copy()
last_background_update = time.time()
print("Background updated.")
if time.time() - last_motion_detection > motion_cooldown:
if detect_significant_motion(current_image, background):
save_image(current_image, "motion", f"motion_{current_time}.jpg")
print(f"Motion detected! Image saved: motion_{current_time}.jpg")
last_motion_detection = time.time()
else:
print("No significant motion detected.")
else:
print("In cooldown period after last motion detection.")
if time.time() - last_clean_time > 300:
clean_motion_directory("motion")
last_clean_time = time.time()
time.sleep(interval)
Conclusion
This script demonstrates a practical approach to motion detection using Python. By systematically capturing, processing, and managing images, it effectively identifies significant motion in a scene. Key concepts such as image comparison, background updating, and storage management are crucial for building robust motion detection systems. This example serves as a foundation that can be expanded and customized for various applications, providing a versatile tool in the realm of computer vision.
Meta Title and Description
Meta Title: Implementing Motion Detection with Python: A Practical Guide
Meta Description: Learn how to implement motion detection using Python. This guide covers key concepts, including image retrieval, processing, and storage management, with practical code examples.
Tags
- Python
- Computer Vision
- Motion Detection
- Image Processing
- OpenCV
- Tutorial
- Code Example
- Machine Learning