Python-OpenCV 处理视频(四): 运动检测
生活随笔
收集整理的這篇文章主要介紹了
Python-OpenCV 处理视频(四): 运动检测
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
0x00. 平均值法
通過計算兩幀圖像之間變化了的像素點占的百分比,來確定圖像中是否有動作產生。
這里主要用到 Absdiff 函數,比較兩幀圖像之間有差異的點,當然需要將圖像進行一些處理,例如平滑處理,灰度化處理,二值化處理,經過處理之后的二值圖像上的點將更有效。
代碼示例:
import cv2.cv as cvcapture=cv.CaptureFromCAM(0)frame1 = cv.QueryFrame(capture) frame1gray = cv.CreateMat(frame1.height, frame1.width, cv.CV_8U) cv.CvtColor(frame1, frame1gray, cv.CV_RGB2GRAY)res = cv.CreateMat(frame1.height, frame1.width, cv.CV_8U)frame2gray = cv.CreateMat(frame1.height, frame1.width, cv.CV_8U)w= frame2gray.width h= frame2gray.height nb_pixels = frame2gray.width * frame2gray.heightwhile True:frame2 = cv.QueryFrame(capture)cv.CvtColor(frame2, frame2gray, cv.CV_RGB2GRAY)cv.AbsDiff(frame1gray, frame2gray, res)cv.ShowImage("After AbsDiff", res)cv.Smooth(res, res, cv.CV_BLUR, 5,5)element = cv.CreateStructuringElementEx(5*2+1, 5*2+1, 5, 5, cv.CV_SHAPE_RECT)cv.MorphologyEx(res, res, None, None, cv.CV_MOP_OPEN)cv.MorphologyEx(res, res, None, None, cv.CV_MOP_CLOSE)cv.Threshold(res, res, 10, 255, cv.CV_THRESH_BINARY_INV)cv.ShowImage("Image", frame2)cv.ShowImage("Res", res)#-----------nb=0for y in range(h):for x in range(w):if res[y,x] == 0.0:nb += 1avg = (nb*100.0)/nb_pixels#print "Average: ",avg, "%\r",if avg >= 5:print "Something is moving !"#-----------cv.Copy(frame2gray, frame1gray)c=cv.WaitKey(1)if c==27: #Break if user enters 'Esc'.break0x01. 背景建模與前景檢測
背景建模也是檢測運動物體的一種辦法,下面是代碼示例:
import cv2.cv as cvcapture = cv.CaptureFromCAM(0) width = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH)) height = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT))gray = cv.CreateImage((width,height), cv.IPL_DEPTH_8U, 1)background = cv.CreateMat(height, width, cv.CV_32F) backImage = cv.CreateImage((width,height), cv.IPL_DEPTH_8U, 1) foreground = cv.CreateImage((width,height), cv.IPL_DEPTH_8U, 1) output = cv.CreateImage((width,height), 8, 1)begin = True threshold = 10while True:frame = cv.QueryFrame( capture )cv.CvtColor(frame, gray, cv.CV_BGR2GRAY)if begin:cv.Convert(gray, background) #Convert gray into background formatbegin = Falsecv.Convert(background, backImage) #convert existing background to backImagecv.AbsDiff(backImage, gray, foreground) #Absdiff to get differencescv.Threshold(foreground, output, threshold, 255, cv.CV_THRESH_BINARY_INV)cv.Acc(foreground, background,output) #Accumulate to backgroundcv.ShowImage("Output", output)cv.ShowImage("Gray", gray)c=cv.WaitKey(1)if c==27: #Break if user enters 'Esc'.break0x02. 我的方法
上面的幾種辦法我都試了下,基本上能識別出運動的物體,但是發現總是有點瑕疵,所以又比對了幾種別人的方案,然后合成了一個自己的方案:
具體處理思路:
-
對兩幀圖像做一個absdiff得到新圖像。
-
對新圖像做灰度和二值化處理。
-
使用findContours函數獲取二值化處理之后的圖片中的輪廓。
-
使用contourArea()過濾掉自己不想要的面積范圍的輪廓。
這個辦法基本上能夠檢測出物體的圖像中物體的移動,而且我覺得通過設定contourArea()函數的過濾范圍,可以檢測距離攝像頭不同距離范圍的運動物體。
以下是代碼示例:
#!usr/bin/env python #coding=utf-8import cv2 import numpy as npcamera = cv2.VideoCapture(0) width = int(camera.get(3)) height = int(camera.get(4))firstFrame = Nonewhile True:(grabbed, frame) = camera.read()gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)gray = cv2.GaussianBlur(gray, (21, 21), 0)if firstFrame is None:firstFrame = graycontinueframeDelta = cv2.absdiff(firstFrame, gray)thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]# thresh = cv2.adaptiveThreshold(frameDelta,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\# cv2.THRESH_BINARY,11,2)# thresh = cv2.adaptiveThreshold(frameDelta,255,cv2.ADAPTIVE_THRESH_MEAN_C,\# cv2.THRESH_BINARY,11,2)thresh = cv2.dilate(thresh, None, iterations=2)(_, cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)for c in cnts:if cv2.contourArea(c) < 10000:continue(x, y, w, h) = cv2.boundingRect(c)cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)cv2.imshow("Security Feed", frame)firstFrame = gray.copy() camera.release() cv2.destroyAllWindows()總結
以上是生活随笔為你收集整理的Python-OpenCV 处理视频(四): 运动检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python-OpenCV 处理视频(三
- 下一篇: Python-OpenCV 处理视频(五