03.02 OpenCV-Python中用於視頻跟蹤的Meanshift和Camshift算法介紹

學習目標

在本章中,

  • 我們將學習用於跟蹤視頻中對象的Meanshift和Camshift算法。

Meanshift

Meanshift背後的直覺很簡單,假設你有點的集合。(它可以是像素分佈,例如直方圖反投影)。你會得到一個小窗口(可能是一個圓形),並且必須將該窗口移到最大像素密度(或最大點數)的區域。如下圖所示:

OpenCV-Python中用於視頻跟蹤的Meanshift和Camshift算法介紹

初始窗口以藍色圓圈顯示,名稱為“C1”。其原始中心以藍色矩形標記,名稱為“C1o”。但是,如果找到該窗口內點的質心,則會得到點“C1r”(標記為藍色小圓圈),它是窗口的真實質心。當然,它們不匹配。因此,移動窗口,使新窗口的圓與上一個質心匹配。再次找到新的質心。很可能不會匹配。因此,再次移動它,並繼續迭代,以使窗口的中心及其質心落在同一位置(或在很小的期望誤差內)。因此,最終您獲得的是一個具有最大像素分佈的窗口。它帶有一個綠色圓圈,名為“C2”。正如您在圖像中看到的,它具有最大的點數。整個過程在下面的靜態圖像上演示:

OpenCV-Python中用於視頻跟蹤的Meanshift和Camshift算法介紹

因此,我們通常會傳遞直方圖反投影圖像和初始目標位置。當對象移動時,顯然該移動會反映在直方圖反投影圖像中。結果,meanshift算法將窗口移動到最大密度的新位置。

OpenCV中的Meanshift

要在OpenCV中使用meanshift,首先我們需要設置目標,找到其直方圖,以便我們可以將目標反投影到每幀上以計算均值偏移。我們還需要提供窗口的初始位置。對於直方圖,此處僅考慮色相。另外,為避免由於光線不足而產生錯誤的值,可以使用cv.inRange()函數丟棄光線不足的值。

<code>import numpy as np
import cv2 as cv
import argparse
parser = 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 values
track_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 pt
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)
# 應用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/<code>

我使用的視頻中的三幀如下:

OpenCV-Python中用於視頻跟蹤的Meanshift和Camshift算法介紹

Camshift

您是否密切關注了最後結果?這兒存在一個問題。無論汽車離相機很近或非常近,我們的窗口始終具有相同的大小。這是不好的。我們需要根據目標的大小和旋轉來調整窗口大小。該解決方案再次來自“ OpenCV Labs”,它被稱為Gary布拉德斯基(Gary Bradsky)在其1998年的論文“用於感知用戶界面中的計算機視覺面部跟蹤”中發表的CAMshift(連續自適應均值偏移)[26]。它首先應用Meanshift。一旦Meanshift收斂,它將更新窗口的大小為s = 2 times sqrt{frac{M_{00}}{256}}。它還可以計算出最合適的橢圓的方向。再次將均值偏移應用於新的縮放搜索窗口和先前的窗口位置。該過程一直持續到達到要求的精度為止。

OpenCV-Python中用於視頻跟蹤的Meanshift和Camshift算法介紹

OpenCV中的Camshift

它與meanshift相似,但是返回一個旋轉的矩形(即我們的結果)和box參數(用於在下一次迭代中作為搜索窗口傳遞)。請參見下面的代碼:

<code>import numpy as np
import cv2 as cv
import argparse
parser = 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 values
track_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/<code>

三幀的結果如下

OpenCV-Python中用於視頻跟蹤的Meanshift和Camshift算法介紹

附加資源


  1. French Wikipedia page on Camshift:http://fr.wikipedia.org/wiki/Camshift. (The two animations are taken from there)
  2. Bradski, G.R., "Real time face and object tracking as a component of a perceptual user interface," Applications of Computer Vision, 1998. WACV '98. Proceedings., Fourth IEEE Workshop on , vol., no., pp.214,219, 19-21 Oct 1998

Exercises


  1. OpenCV comes with a Python :https://github.com/opencv/opencv/blob/master/samples/python/camshift.py for an interactive demo of camshift. Use it, hack it, understand it.


分享到:


相關文章: