Phát hiện chuyển động (motion detection) là một kỹ thuật quan trọng trong xử lý video, được ứng dụng rộng rãi từ hệ thống giám sát an ninh, xe tự lái đến các thiết bị IoT. Ý tưởng cơ bản là theo dõi sự thay đổi giữa các khung hình (frames) liên tiếp để xác định xem có vật thể di chuyển hay không. Đây là bước nền tảng để phát triển các bài toán phức tạp hơn như theo dõi đối tượng (object tracking) hay nhận diện hành vi.
Nếu bạn đã từng tìm hiểu về Phân tích dữ liệu điểm danh sinh viên theo thời gian hoặc Tạo phân tích dữ liệu cho đồ án quản lý sinh viên, thì xử lý video để phát hiện chuyển động cũng mang lại giá trị tương tự: biến dữ liệu thô thành thông tin hành động. Bài viết này sẽ hướng dẫn bạn cách thực hiện từng bước bằng Python và OpenCV, từ đọc video, xử lý ảnh đến đánh dấu vùng chuyển động.
Tập dữ liệu sử dụng
Để thực hành, chúng ta sẽ sử dụng video mẫu từ OpenCV hoặc tải video giám sát có sẵn trên Kaggle:
👉 OpenCV Sample Videos
Bạn có thể tải về file traffic.mp4 hoặc sử dụng webcam để thử nghiệm trên video trực tiếp.
Đọc và hiển thị video
Trước tiên, bạn cần nạp video từ file hoặc từ webcam. OpenCV cung cấp hàm cv2.VideoCapture() để đọc luồng video. Việc hiển thị từng khung hình giúp bạn kiểm tra dữ liệu có nạp đúng không và quan sát từng bước xử lý. Trong thực tế, hệ thống giám sát sử dụng kỹ thuật này để xử lý từng frame trong thời gian thực.
Ngoài ra, việc giải phóng bộ nhớ và đóng cửa sổ hiển thị sau khi kết thúc là quan trọng để tránh treo chương trình, nhất là khi làm việc với video dài hoặc camera trực tiếp.
import cv2
# Đọc video từ file
cap = cv2.VideoCapture('traffic.mp4')
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
cv2.imshow('Video', frame)
# Nhấn 'q' để thoát
if cv2.waitKey(30) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Chuyển đổi sang ảnh xám và làm mờ
Mỗi khung hình (frame) của video là một ảnh màu. Tuy nhiên, để đơn giản hóa và tăng tốc xử lý, chúng ta thường chuyển nó sang ảnh thang độ xám (grayscale). Điều này giúp thuật toán tập trung vào độ sáng thay vì màu sắc. Tiếp đó, làm mờ ảnh bằng Gaussian Blur giúp giảm nhiễu và loại bỏ các thay đổi nhỏ không đáng kể như ánh sáng chập chờn hoặc chuyển động lá cây.
Hai bước này đóng vai trò quan trọng để hệ thống phát hiện chuyển động ổn định hơn, tránh báo động giả từ những thay đổi nhỏ.
# Đọc frame đầu để làm reference ret, first_frame = cap.read() gray_first = cv2.cvtColor(first_frame, cv2.COLOR_BGR2GRAY) gray_first = cv2.GaussianBlur(gray_first, (21, 21), 0)
Phát hiện chuyển động bằng phương pháp Background Subtraction
Để phát hiện chuyển động, chúng ta so sánh frame hiện tại với một “background” chuẩn (ở đây là frame đầu tiên). Khi sự khác biệt về pixel vượt qua một ngưỡng nhất định, nó được coi là chuyển động. Phương pháp này đơn giản nhưng rất hiệu quả với các video giám sát tĩnh, nơi background ít thay đổi.
Kỹ thuật threshold hóa nhị phân giúp xác định vùng chuyển động, còn morphological operations (dilate) giúp kết nối các vùng nhỏ thành vùng lớn hơn, dễ dàng vẽ khung (bounding box) xung quanh.
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)
# Tính sự khác biệt tuyệt đối
frame_delta = cv2.absdiff(gray_first, gray)
thresh = cv2.threshold(frame_delta, 25, 255, cv2.THRESH_BINARY)[1]
# Giãn ảnh để kết nối vùng trắng gần nhau
thresh = cv2.dilate(thresh, None, iterations=2)
# Tìm contours
contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
if cv2.contourArea(contour) < 500:
continue # Bỏ qua vùng nhỏ
(x, y, w, h) = cv2.boundingRect(contour)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow('Motion Detection', frame)
if cv2.waitKey(30) & 0xFF == ord('q'):
break
Nâng cao – dùng MOG2 để xử lý background động
Phương pháp so sánh với frame đầu tiên có hạn chế nếu background thay đổi dần (ví dụ ánh sáng thay đổi theo thời gian). Để xử lý điều này, OpenCV cung cấp thuật toán BackgroundSubtractorMOG2 giúp xây dựng background động và phát hiện chuyển động tốt hơn.
MOG2 thích hợp cho các ứng dụng giám sát thực tế, nơi môi trường có sự thay đổi nhẹ.
fgbg = cv2.createBackgroundSubtractorMOG2()
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
fgmask = fgbg.apply(frame)
cv2.imshow('Foreground Mask', fgmask)
cv2.imshow('Original Frame', frame)
if cv2.waitKey(30) & 0xFF == ord('q'):
break
Kết luận
Bài viết này đã hướng dẫn bạn cách xử lý video để phát hiện chuyển động bằng Python và OpenCV. Bạn đã học cách đọc video, xử lý ảnh, phát hiện vùng chuyển động và vẽ khung bao quanh đối tượng di chuyển. Đây là bước đầu tiên quan trọng để xây dựng các hệ thống giám sát thông minh, theo dõi đối tượng hoặc nhận diện hành vi.
Bạn có thể mở rộng bằng cách kết hợp nhận diện khuôn mặt, đếm số lượng đối tượng di chuyển hoặc triển khai trên camera IP để giám sát trực tiếp. Kỹ thuật này là nền tảng cho nhiều ứng dụng AI trong đời sống hàng ngày.

