天天看點

python做視覺_機器視覺——python實作追蹤物體軌迹

import numpy as np

import argparse

import time

import cv2

# construct the argument parse and parse the arguments

ap = argparse.ArgumentParser()

ap.add_argument("-v", "--video",

help = "path to the (optional) video file")

args = vars(ap.parse_args())

# define the upper and lower boundaries for a color

# to be considered "blue"

blueLower = np.array([100,67,0],dtype="uint8")

blueUpper = np.array([255,128,50],dtype="uint8")

# load the video

if not args.get("video"):

camera = cv2.VideoCapture(0)

else:

camera = cv2.VideoCapture(args["video"])

我們将使用NumPy進行數值處理,使用argparse解析指令行參數,使用cv2進行OpenCV綁定。time包是可選的。

我們隻需要一個指令行參數,--video,也就是我們視訊的路徑。

我們将在視訊中追蹤的對象是藍色物體。由于除了該物體外,藍色在視訊中的任何其他位置都不常見,是以我們希望跟蹤藍色陰影。為了完成這種顔色跟蹤,我們定義了藍色陰影的下限和上限。請記住,OpenCV表示RGB顔色空間中的像素,但順序相反。

在這種情況下,如果大于R=0,G=67,B=100且小于R=50,G=128,B=255,則将顔色定義為“藍色”。

最後,我們打開視訊檔案并使用cv2.VideoCapture函數擷取對它的引用。我們将此引用指派給變量camera。

# keep looping

while True:

# grab the current frame

(grabbed,frame) = camera.read()

# check to see if we have reached the end of the video

if args.get("video") and not grabbed:

break

# determine which pixels fall within the blue boundaries

# and then blur the binary image

blue = cv2.inRange(frame,blueLower,blueUpper)

blue = cv2.GaussianBlur(blue,(3,3),0)

現在我們有了對視訊的引用,便可以開始處理幀。

我們開始循環周遊幀,一次一個。調用read()方法的調用抓取視訊中的下一幀,傳回具有兩個值的元組。第一個是grabbed,是一個布爾值,表示是否從視訊檔案中成功讀取了幀。第二個frame,是幀本身。

然後,我們檢查frame是否成功讀取。如果未讀取架構,則表示已到達視訊的末尾,我們break掉while循環。

為了在frame中找到藍色陰影,我們必須使用cv2.inRange函數。該函數有三個參數。第一個是我們想要檢查的frame。第二個是RGB像素的lower threshold,第三個是上限門檻值(upper threshold)。調用此函數的結果是門檻值圖像,像素落在上下範圍内設定為白色,像素不屬于此範圍 設為黑色。

最後,我們對門檻值圖像進行高斯模糊處理,以使查找輪廓更準确。

# find contours in the image

(_,cnts,_) = cv2.findContours(blue.copy(),cv2.RETR_EXTERNAL,

cv2.CHAIN_APPROX_SIMPLE)

# check to see if any contours were found

if len(cnts) > 0:

# sort the contours and find the largest one --

# we will assume this contour coorespondes to the

# area of my phone

cnt = sorted(cnts,key=cv2.contourArea,reverse=True)[0]

# compute the (rotated) bounding box around then

# contour and then draw it

rect = np.int32(cv2.boxPoints(cv2.minAreaRect(cnt)))

cv2.drawContours(frame,[rect],-1,(0,255,0),2)

# show the frame and the binary image

cv2.imshow("Traccking",frame)

cv2.imshow("Binary",blue)

# if your machine is fast, it may display the frames in

# what appears to be 'fast forward' since more than 32

# frames per second are being displayed -- a simple hack

# is just to sleep for a tiny bit in between frames;

# however, if your computer is slow, you probably want to

# comment out this line

time.sleep(0.025)

# if the 'q' key is pressed, stop the loop

if cv2.waitKey(1) & 0xFF == ord("q"):

break

# cleanup the camera and close any open windows

camera.release()

cv2.destroyAllWindows()

現在我們有了門檻值圖像,那麼我們需要找到圖像中最大的輪廓,假設最大輪廓對應于我們想要跟蹤的藍色物體輪廓。

我們調用cv2.findContours會在門檻值圖像中找到輪廓。我們使用copy()方法克隆門檻值圖像,因為cv2.findContour函數對傳入的NumPy數組具有破壞性。

然後檢查以確定實際發現輪廓。如果輪廓清單的長度為零,則沒有找到藍色區域。如果輪廓清單的長度大于零,那麼我們需要找到最大的輪廓。這裡,輪廓按相反的順序排序(最大的第一個),使用cv2.contourArea函數來 計算輪廓的面積。具有較大區域的輪廓存儲在清單的前面。在這種情況下,抓住具有最大面積的輪廓,再次假設該輪廓對應于藍色物體的輪廓。

現在我們有了藍色的輪廓,但我們需要在它周圍繪制一個邊界框。

調用cv2.minAreaRect計算輪廓周圍的最小邊界框。然後,cv2.boxPoints将邊界框重新定義為點清單。

注意

:在OpenCV 2.4.X中,我們将使用cv2.BoxPoints函數來計算輪廓的旋轉邊界框。但是,在OpenCV 3.0+中,此函數已移至cv2.boxPoints。兩個函數執行相同的任務,隻是略有不同的命名空間。

最後,我們使用cv2.drawContours函數繪制邊界框。

具有檢測到的藍色物體的frame顯示在第一個imshow,并且門檻值圖像(落入藍色像素的下/上範圍的像素)顯示在第二個imshow。

上面,time.sleep(0.025)可選的。在許多較新型号的機器上,系統可能足夠快以處理>32幀/秒。如果是這種情況,找到可接受的睡眠時間将減慢處理速度并将其降低到更正常的速度。

執行我們的腳本

python track.py

結果:

python做視覺_機器視覺——python實作追蹤物體軌迹

或者指定視訊路徑

python track.py --video "video\2018-11-27 18-38-15-927.mp4"

也是可以的。

部落格位址(有完整代碼):https://0leo0.github.io/2018/case_study_03.html

關注不迷路哦!!