使用已有的混合高斯前景檢測庫函數,實現一段視頻中的運動目標檢測
根據OpenCV官方提供的樣例代碼所寫
createBackgroundSubtractorMOG2()有3個參數,分別是歷史像素對背景像素計算值的影響時間,判斷是否為前景點的分割閾值,以及是否檢測倒影 仔細閱讀類內函數的話發現還能設置混合高斯的元數,像素更新率等其余參數
1.讀取文件,設置輸出視頻格式
import cv2 as cv
import numpy as np
cap = cv.VideoCapture('F:\大學\大三下\數字圖像處理\第3章作業 高斯建模與運動目標檢測\第3章作業 高斯建模與運動目標檢測\pets2006_0.avi')
fourcc = cv.VideoWriter_fourcc(*'MJPG')
fps = cap.get(cv.CAP_PROP_FPS)
print('該視頻的幀速率為:',fps)
size =(int(cap.get(cv.CAP_PROP_FRAME_WIDTH)),
int(cap.get(cv.CAP_PROP_FRAME_HEIGHT)))
print('該視頻每一幀的大小為:',size)
out1 = cv.VideoWriter('5_Gaussian_mask_normal.avi', fourcc, fps, size,0)
out2 = cv.VideoWriter('5_Gaussian_final_normal.avi', fourcc, fps, size)
#該視頻的幀速率為: 30.0
#該視頻每一幀的大小為: (320, 240)
調用背景檢測函數,並設置參數
檢測出前景區域的二值圖像之后,使用findContours()尋找邊緣 畫矩形可以選擇畫最小外接矩形,還是畫能覆蓋區域的最小的水平放置的矩形
#背景檢測框架
backSub = cv.createBackgroundSubtractorMOG2()
#設置混合高斯模型數
backSub.setNMixtures(5)
backSub.setShadowValue(0)
while cap.isOpened():
ret, frame = cap.read()
# if frame is read correctly ret is True
if not ret:
print("Can't receive frame any more. Exiting ...")
break
#每一幀背景檢測都會作為背景檢測的輸入
fgMask = backSub.apply(frame)
background = backSub.getBackgroundImage()
out1.write(fgMask)
#尋找檢測區域
#高斯平滑
blur = cv.GaussianBlur(fgMask,(5,5),0)
contours, hierarchy = cv.findContours(image = blur,mode = cv.RETR_CCOMP,method = cv.CHAIN_APPROX_SIMPLE)
image = frame;
# image = cv.drawContours(image,contours,-1,(255,0,0))
for i in range(0,len(contours)):
# #以下畫的是最小外接矩形,可以不是標准的水平放置的矩形框
# rect = cv.minAreaRect(contours[i])
# box = np.int0(cv.boxPoints(rect))
# s = np.square(box[1][0]-box[0][0])+np.square(box[1][1]-box[0][1])\
# +np.square(box[2][0]-box[1][0])+np.square(box[2][1]-box[1][1])
# if s > 500:
# cv.line(image,tuple(box[0]),tuple(box[1]),(255,0,0))
# cv.line(image,tuple(box[1]),tuple(box[2]),(255,0,0))
# cv.line(image,tuple(box[2]),tuple(box[3]),(255,0,0))
# cv.line(image,tuple(box[3]),tuple(box[0]),(255,0,0))
#以下畫的是標准水平放置的矩形框
x, y, w, h = cv.boundingRect(contours[i])
s = w*h
if s > 500:
cv.rectangle(image, (x,y), (x+w,y+h), (255,0,0))
out2.write(image)
if cv.waitKey(1) == ord('q'):
break
#Can't receive frame any more. Exiting ...
輸出背景圖像,並釋放資源
cv.imwrite('BackGround.png',background)
cap.release()
out1.release()
out2.release()
cv.destroyAllWindows()
背景檢測結果如下
運動目標檢測結果截圖