opencv python 多帧降噪算法_OpenCV-Python中用于视频跟踪的Meanshift和Camshift算法介绍...
學習目標
在本章中,
- 我們將學習用于跟蹤視頻中對象的Meanshift和Camshift算法。
Meanshift
Meanshift背后的直覺很簡單,假設你有點的集合。(它可以是像素分布,例如直方圖反投影)。你會得到一個小窗口(可能是一個圓形),并且必須將該窗口移到最大像素密度(或最大點數)的區域。如下圖所示:
初始窗口以藍色圓圈顯示,名稱為“C1”。其原始中心以藍色矩形標記,名稱為“C1o”。但是,如果找到該窗口內點的質心,則會得到點“C1r”(標記為藍色小圓圈),它是窗口的真實質心。當然,它們不匹配。因此,移動窗口,使新窗口的圓與上一個質心匹配。再次找到新的質心。很可能不會匹配。因此,再次移動它,并繼續迭代,以使窗口的中心及其質心落在同一位置(或在很小的期望誤差內)。因此,最終您獲得的是一個具有最大像素分布的窗口。它帶有一個綠色圓圈,名為“C2”。正如您在圖像中看到的,它具有最大的點數。整個過程在下面的靜態圖像上演示:
因此,我們通常會傳遞直方圖反投影圖像和初始目標位置。當對象移動時,顯然該移動會反映在直方圖反投影圖像中。結果,meanshift算法將窗口移動到最大密度的新位置。
OpenCV中的Meanshift
要在OpenCV中使用meanshift,首先我們需要設置目標,找到其直方圖,以便我們可以將目標反投影到每幀上以計算均值偏移。我們還需要提供窗口的初始位置。對于直方圖,此處僅考慮色相。另外,為避免由于光線不足而產生錯誤的值,可以使用cv.inRange()函數丟棄光線不足的值。
import numpy as npimport cv2 as cvimport argparseparser = argparse.ArgumentParser(description='This sample demonstrates the meanshift algorithm. The example file can be downloaded from: https://www.bogotobogo.com/python/OpenCV_Python/images/mean_shift_tracking/slow_traffic_small.mp4')parser.add_argument('image', type=str, help='path to image file')args = parser.parse_args()cap = cv.VideoCapture(args.image)# 視頻的第一幀ret,frame = cap.read()# 設置窗口的初始位置x, y, w, h = 300, 200, 100, 50 # simply hardcoded the valuestrack_window = (x, y, w, h)# 設置初始ROI來追蹤roi = frame[y:y+h, x:x+w]hsv_roi = cv.cvtColor(roi, cv.COLOR_BGR2HSV)mask = cv.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))roi_hist = cv.calcHist([hsv_roi],[0],mask,[180],[0,180])cv.normalize(roi_hist,roi_hist,0,255,cv.NORM_MINMAX)# 設置終止條件,可以是10次迭代,也可以至少移動1 ptterm_crit = ( cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1 )while(1): ret, frame = cap.read() if ret == True: hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV) dst = cv.calcBackProject([hsv],[0],roi_hist,[0,180],1) # 應用meanshift來獲取新位置 ret, track_window = cv.meanShift(dst, track_window, term_crit) # 在圖像上繪制 x,y,w,h = track_window img2 = cv.rectangle(frame, (x,y), (x+w,y+h), 255,2) cv.imshow('img2',img2) k = cv.waitKey(30) & 0xff if k == 27: break else: break我使用的視頻中的三幀如下:
Camshift
您是否密切關注了最后結果?這兒存在一個問題。無論汽車離相機很近或非常近,我們的窗口始終具有相同的大小。這是不好的。我們需要根據目標的大小和旋轉來調整窗口大小。該解決方案再次來自“ OpenCV Labs”,它被稱為Gary布拉德斯基(Gary Bradsky)在其1998年的論文“用于感知用戶界面中的計算機視覺面部跟蹤”中發表的CAMshift(連續自適應均值偏移)[26]。它首先應用Meanshift。一旦Meanshift收斂,它將更新窗口的大小為s = 2 times sqrt{frac{M_{00}}{256}}。它還可以計算出最合適的橢圓的方向。再次將均值偏移應用于新的縮放搜索窗口和先前的窗口位置。該過程一直持續到達到要求的精度為止。
OpenCV中的Camshift
它與meanshift相似,但是返回一個旋轉的矩形(即我們的結果)和box參數(用于在下一次迭代中作為搜索窗口傳遞)。請參見下面的代碼:
import numpy as npimport cv2 as cvimport argparseparser = argparse.ArgumentParser(description='This sample demonstrates the camshift algorithm. The example file can be downloaded from: https://www.bogotobogo.com/python/OpenCV_Python/images/mean_shift_tracking/slow_traffic_small.mp4')parser.add_argument('image', type=str, help='path to image file')args = parser.parse_args()cap = cv.VideoCapture(args.image)# 獲取視頻第一幀ret,frame = cap.read()# 設置初始窗口x, y, w, h = 300, 200, 100, 50 # simply hardcoded the valuestrack_window = (x, y, w, h)# 設置追蹤的ROI窗口roi = frame[y:y+h, x:x+w]hsv_roi = cv.cvtColor(roi, cv.COLOR_BGR2HSV)mask = cv.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))roi_hist = cv.calcHist([hsv_roi],[0],mask,[180],[0,180])cv.normalize(roi_hist,roi_hist,0,255,cv.NORM_MINMAX)# 設置終止條件,可以是10次迭代,有可以至少移動1個像素term_crit = ( cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1 )while(1): ret, frame = cap.read() if ret == True: hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV) dst = cv.calcBackProject([hsv],[0],roi_hist,[0,180],1) # 應用camshift 到新位置 ret, track_window = cv.CamShift(dst, track_window, term_crit) # 在圖像上畫出來 pts = cv.boxPoints(ret) pts = np.int0(pts) img2 = cv.polylines(frame,[pts],True, 255,2) cv.imshow('img2',img2) k = cv.waitKey(30) & 0xff if k == 27: break else: break三幀的結果如下
附加資源
Exercises
總結
以上是生活随笔為你收集整理的opencv python 多帧降噪算法_OpenCV-Python中用于视频跟踪的Meanshift和Camshift算法介绍...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: rostcm6情感分析案例分析_卷积情感
- 下一篇: python内置类型_Python内置对