Python-OpenCV 处理视频(五): 运动方向判断
在檢測(cè)出運(yùn)動(dòng)的物體之后,我還需要知道運(yùn)動(dòng)的方向,使用了上一節(jié)中的辦法檢測(cè)運(yùn)動(dòng)我發(fā)現(xiàn)很難去計(jì)算運(yùn)動(dòng)方向,開(kāi)始考慮通過(guò)計(jì)算輪廓的中點(diǎn)的變化來(lái)實(shí)現(xiàn),但是因?yàn)槊看螜z測(cè)出得輪廓的數(shù)量不穩(wěn)定,所以這個(gè)辦法會(huì)讓誤差不可控。
這時(shí)我發(fā)現(xiàn)了goodFeaturesToTrack函數(shù),簡(jiǎn)直是救了我,goodFeaturesToTrack函數(shù)可以獲取圖像中的最大特征值的角點(diǎn),以下是我的思路:
-
對(duì)兩幀圖像做一個(gè)absdiff得到新圖像。
-
對(duì)新圖像做灰度和二值化處理。
-
使用goodFeaturesToTrack函數(shù)得到最大特征值的角點(diǎn)。
-
計(jì)算角點(diǎn)的平均點(diǎn),扔進(jìn)隊(duì)列。
-
維護(hù)一個(gè)長(zhǎng)度為10的隊(duì)列,隊(duì)列滿時(shí)計(jì)算隊(duì)列中數(shù)據(jù)的增減情況,來(lái)確定運(yùn)動(dòng)方向。
以下是代碼示例:
#!usr/bin/env python #coding=utf-8import cv2 import numpy as np import Queuecamera = cv2.VideoCapture(0) width = int(camera.get(3)) height = int(camera.get(4))firstFrame = None lastDec = None firstThresh = Nonefeature_params = dict( maxCorners = 100,qualityLevel = 0.3,minDistance = 7,blockSize = 7 )# Parameters for lucas kanade optical flow lk_params = dict( winSize = (15,15),maxLevel = 2,criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))color = np.random.randint(0,255,(100,3)) num = 0q_x = Queue.Queue(maxsize = 10) q_y = Queue.Queue(maxsize = 10)while 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]# 下面的是幾種不同的二值化的方法,感覺(jué)對(duì)我來(lái)說(shuō)效果都差不多# 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)p0 = cv2.goodFeaturesToTrack(thresh, mask = None, **feature_params)if p0 is not None:x_sum = 0y_sum = 0for i, old in enumerate(p0):x, y = old.ravel()x_sum += xy_sum += yx_avg = x_sum / len(p0)y_avg = y_sum / len(p0)if q_x.full():# print list(q_x.queue)qx_list = list(q_x.queue)key = 0diffx_sum = 0for item_x in qx_list:key +=1if key < 10:diff_x = item_x - qx_list[key]diffx_sum += diff_x# print diff_xif diffx_sum < 0 and x_avg < 500:# print "some coming form left"cv2.putText(frame, "some coming form left", (100,100), 0, 0.5, (0,0,255),2)else:print "right"print x_avgq_x.get()q_x.put(x_avg)cv2.putText(frame, str(x_avg), (300,100), 0, 0.5, (0,0,255),2)frame = cv2.circle(frame,(int(x_avg),int(y_avg)),5,color[i].tolist(),-1)cv2.imshow("Security Feed", frame)firstFrame = gray.copy()camera.release() cv2.destroyAllWindows()總的來(lái)講作為一個(gè)圖像處理的小白,不斷地折騰和嘗試,終于搞出了自己想要的東西,OpenCV絕對(duì)是喜歡折騰的人必要掌握的一個(gè)庫(kù)了,以后肯定還會(huì)繼續(xù)研究這塊東西。
總結(jié)
以上是生活随笔為你收集整理的Python-OpenCV 处理视频(五): 运动方向判断的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python-OpenCV 处理视频(四
- 下一篇: Python-OpenCV 处理图像(六