Python-OpenCV 超簡單實用運動偵測算法

一、概念

運動偵測,英文翻譯為“Motion detection technology”,一般也叫移動檢測,常用於無人值守監控錄像和自動報警。通過攝像頭按照不同幀率採集得到的圖像會被CPU按照一定算法進行計算和比較,當畫面有變化時,如有人走過,鏡頭被移動,計算比較結果得出的數字會超過閾值並指示系統能自動作出相應的處理。


—–百度百科

差分算法

差分檢測根據當前圖像與參考圖像的差別分析來判斷序列圖像中是否有運動的物體。在環境亮度變化不大的情況下,如果對應像素灰度值的差異小於某個閾值,則認為畫面靜止無運動變化,如果圖像區域某處的灰度變化大於某個閾值,則認為這是由於圖像中運動 的物體所引起的,然後求出運動目標在圖像中的位置。

基於相鄰幀差的算法:

將前後兩幀圖像對應像素點的灰度值相減;
基於背景圖像與當前幀差的算法:
將當前幀和背景幀對應像素的灰度值相減;

一、幀差法

1. 幀差法原理

移動偵測即是根據視頻每幀或者幾幀之間像素的差異,對差異值設置閾值,篩選大於閾值的像素點,做掩模圖即可選出視頻中存在變化的楨。幀差法較為簡單的視頻中物體移動偵測,幀差法分為:單幀差、兩楨差、和三楨差。隨著幀數的增加是防止檢測結果的重影。

2. 算法思路

步驟:

  1. 讀取視頻
  2. 選取兩幀
  3. 灰度化
  4. 濾波
  5. 幀間做差
  6. 二值化
  7. 形態學操作

opencv中的absdiff可以用來求兩幅灰度圖像的差值圖像.

3. 代碼

# encoding=utf-8

import datetime
import imutils
import time
import cv2

min_area = 500
camera = cv2.VideoCapture(0)
# 等待攝像頭準備好
time.sleep(0.25)

# 初始化視頻流的第一幀
firstFrame = None

# 遍歷視頻的每一幀
while True:
# 獲取幀並初始化occupied/unoccupied文本

(grabbed, frame) = camera.read()
text = "Unoccupied"

# 調整該幀的大小,轉換為灰階圖像並且對其進行高斯模糊
frame = imutils.resize(frame, width=500)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)

# 初始化第1幀
if firstFrame is None:
firstFrame = gray
continue

# 差分
frameDelta = cv2.absdiff(firstFrame, gray)
thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]

# 形態學操作 膨脹
thresh = cv2.dilate(thresh, None, iterations=2)
thresh, contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 遍歷輪廓
for c in contours:
# if the contour is too small, ignore it
print('area = %f ' % cv2.contourArea(c))
if cv2.contourArea(c) < min_area:
continue

# compute the bounding box for the contour, draw it on the frame,
# and update the text
# 計算輪廓的邊界框,在當前幀中畫出該框
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
text = "Occupied"

# draw the text and timestamp on the frame
# 幀上寫文字以及時間戳
cv2.putText(frame, "Room Status: {}".format(text), (10, 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.putText(frame, datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"),
(10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1)

# 顯示幀

cv2.imshow("Security Feed", frame)
cv2.imshow("Thresh", thresh)
cv2.imshow("Frame Delta", frameDelta)
key = cv2.waitKey(1)

# q鍵跳出循環
if key == ord("q"):
break

# 清理資源
camera.release()
cv2.destroyAllWindows()

運行效果:

Python-OpenCV 超簡單實用運動偵測算法

Python-OpenCV 超簡單實用運動偵測算法


分享到:


相關文章: