來源丨小白學視覺
跟蹤對象的基本思想是找到對象的輪廓,基於HSV顏色值。
輪廓:突出顯示對象的圖像片段。例如,如果將二進制閾值應用於具有(180,255)的圖像,則大於180的像素將以白色突出顯示,而其他則為黑色。白色部分稱為輪廓。
在繼續下面的操作之前,請在系統中安裝OpenCV。打開命令提示符並鍵入
pip install opencv-pythonimport cv2cam = cv2.VideoCapture(0) img = cam.read()[1] #_, img = cam.read()參數0-用於主相機,例如在筆記本電腦網絡攝像頭中被視為主相機。1-代表中學,依此類推。
![](https://imageproxy.pixnet.cc/imgproxy?url=https://drbanana.ml/img/68747470733a2f2f6d6d62697a2e717069632e636e2f737a5f6d6d62697a5f6a70672f34417153456e4e556572696369633279797a704667456e664d70323358684e6d52345a63523049427265546b49344e6962685045375a4d397a456963663069614c4172496769614847594d4941733943316963337078637831574937412f3634303f77785f666d743d6a706567.webp)
1、使用高斯濾波器對圖像進行歸一化。歸一化圖像可能會丟失許多小信息,但是我們需要歸一化/模糊圖像,以使我們的對象獲得均等的顏色分布。
#cv2.gaussianBlur(source_image,Kernal_size,Border_width)
Blur_img = cv2.GaussianBlur(img,(11,11),0)2、將圖像轉換為HSV顏色模型。
HSV = cv2.cvtColor(Blur_img, cv2.COLOR_BGR2HSV)![](https://imageproxy.pixnet.cc/imgproxy?url=https://drbanana.ml/img/68747470733a2f2f6d6d62697a2e717069632e636e2f737a5f6d6d62697a5f6a70672f34417153456e4e556572696369633279797a704667456e664d70323358684e6d523442386c4f5576766a586657514c70586c384e76337048644c76744a6b67754c734874774d344d636963427969636f4d587845717169616835412f3634303f77785f666d743d6a706567.webp)
Obj_low = np.array([0,0,0]) # In my case (H,S,V)Obj_high = np.array([179,157,79])在給定的HSV值範圍內應用二進制閾值,黑白Obj_low和Obj_high。
MASK = cv2.inRange(HSV, Obj_low, Obj_high)![](https://imageproxy.pixnet.cc/imgproxy?url=https://drbanana.ml/img/68747470733a2f2f6d6d62697a2e717069632e636e2f737a5f6d6d62697a5f6a70672f34417153456e4e556572696369633279797a704667456e664d70323358684e6d5234304855663042476962595263715a35486b6c567731475a7965736a3830455452316378636a5a4a4436377637696344514b393836626f50412f3634303f77785f666d743d6a706567.webp)
#MASK2 = cv2.inRange(HSV,Obj2_low,Obj2_high)
如果嘗試跟蹤兩個不同的對象,則需要創建2個不同的蒙版,並最終在兩個蒙版上使用「按位與」運算符。
#mask = cv2.bitwise_and(mask1,mask2)
侵蝕和膨脹:侵蝕和膨脹填充閾值圖像中的黑色和白色斑點。這樣可使圖像更清晰,平滑並突出主要對象。
MASK = cv2.erode(MASK1, None, iterations=2)MASK = cv2.dilate(MASK1, None, iterations =2)![](https://imageproxy.pixnet.cc/imgproxy?url=https://drbanana.ml/img/68747470733a2f2f6d6d62697a2e717069632e636e2f737a5f6d6d62697a5f6a70672f34417153456e4e556572696369633279797a704667456e664d70323358684e6d5234413569635879677364487038476c434358456255325a336c4f52566551376f4d5453547431567044316273596c7144473757555a776d512f3634303f77785f666d743d6a706567.webp)
輪廓:突出顯示對象的圖像片段。例如,如果將二進制閾值應用於具有(180,255)的圖像,則大於180的像素將以白色突出顯示,而其他則為黑色。白色部分稱為輪廓。
cnts = cv2.findContours(MASK1.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]if len(cnts)>0 : c = max(cnts, key = cv2.contourArea)在上面給定的圖像中,整個白色邊界區域是輪廓。輪廓可能不止一個,但主要對象的面積將最大。所以選擇輪廓最大。然後..
得到主要物體的輪廓後,在輪廓上畫一個圓。
((x,y), radius) = cv2.minEnclosingCircle(c)M = cv2.moments(c)center = (int(M[『m10』]/ M[『m00』]), int(M[『m01』]/ M[『m00』]) )cv2.circle(img, center, 5, (0,0,255), -1)cv2.circle(img, center, int(radius), (0,0,255), 2)對象跟蹤程序代碼
import cv2import numpy as npcam = cv2.VideoCapture(0)Obj_low = np.array([0,0,0])Obj_high = np.array([179,157,79])while True: img = cam.read()[1] img = cv2.resize(img, (800,600) ) blur_img = cv2.GaussianBlur(img,(21,21),0) HSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)MASK1 = cv2.inRange(HSV, Obj_low, Obj_high) MASK1 = cv2.erode(MASK1, None, iterations=2) MASK1 = cv2.dilate(MASK1, None, iterations =2) cnts = cv2.findContours(MASK1.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] center = None if len(cnts)>0 : c = max(cnts, key = cv2.contourArea) ((x,y), radius) = cv2.minEnclosingCircle(c) M = cv2.moments(c) center = (int(M['m10']/ M['m00']), int(M['m01']/ M['m00']) ) if radius>10: cv2.circle(img, center, 5, (0,0,255), -1) cv2.circle(img, center, int(radius), (0,0,255), 2) cv2.imshow("my window",img) k = cv2.waitKey(1) if k==27: breakcam.release()cv2.destroyAllWindows()
本文僅做學術分享,如有侵權,請聯繫刪文。