オフィスや自宅の見守り用途として、WebカメラやUSBカメラを使った「動体検知システム」が注目されています。PythonのOpenCVを使えば、監視映像に動きがあった場合に自動で録画や通知を行う仕組みを自作できます。
この記事では、OpenCVを活用して動きのあったフレームを検出・表示・記録する基本構成を紹介します。
前提ライブラリのインストール
pip install opencv-python
動体検知の基本原理
フレーム間の差分をとり、変化が大きいエリアを「動き」と判断します。以下のような処理を組み合わせます。
- グレースケール化
- ぼかし(ノイズ軽減)
- フレーム間の差分
- 閾値処理と輪郭抽出
基本スクリプト:動きのあるエリアを矩形で表示
import cv2
cap = cv2.VideoCapture(0)
ret, frame1 = cap.read()
ret, frame2 = cap.read()
while cap.isOpened():
# フレームの差分を計算
diff = cv2.absdiff(frame1, frame2)
gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5, 5), 0)
_, thresh = cv2.threshold(blur, 25, 255, cv2.THRESH_BINARY)
dilated = cv2.dilate(thresh, None, iterations=2)
# 輪郭を取得して矩形で囲む
contours, _ = cv2.findContours(dilated, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
if cv2.contourArea(contour) < 1000:
continue
(x, y, w, h) = cv2.boundingRect(contour)
cv2.rectangle(frame1, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("Motion Detection", frame1)
frame1 = frame2
ret, frame2 = cap.read()
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
動きを検知したら画像を保存する
import datetime
if cv2.contourArea(contour) > 1000:
now = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
cv2.imwrite(f"motion_{now}.jpg", frame1)
不審な動きがあったときだけキャプチャを残す設計にすれば、ストレージも節約できます。
応用アイデア
- 動体検知時にSlackやLINEへ通知
- 特定の時間帯だけ監視を有効化
- 録画(VideoWriter)との連携
- 検知ログをCSV形式で記録
注意点と改善のヒント
- 小さなノイズや光の変化に反応しすぎないよう、輪郭サイズに閾値を設ける
- 静止フレームと比較する場合は「背景差分」手法も検討
- 動きのない時間は一定間隔でフレーム更新し、変化をリセットする
まとめ
PythonとOpenCVを使えば、Webカメラを活用した簡易的な動体検知システムが構築できます。防犯用途に限らず、業務現場での出入り監視や見守りサービスなど、幅広い応用が可能です。
今回の構成をベースに、録画・通知・ログ管理などを加えることで、本格的な監視カメラシステムへの発展も見込めます。ぜひ自分用または業務用に応用してみてください。