【OpenCV-Python】教程:5-2 Meanshift-Camshift(Continuously Adaptive Meanshift)

OpenCV Python Meanshift & Camshift

【目标】

  • Meanshift
  • Camshift
  • 用Meanshift和Camshift跟踪目标

【理论】

Meanshift(均值漂移)

均值漂移从字面上感觉就是很简单。假设有一个点集(或者一个像素分布,类似于直方图反向投影),给定一个小的窗口,然后需要移动这个窗口来是的像素密度或者(像素个数)最大化。如下图:

【OpenCV-Python】教程:5-2 Meanshift-Camshift(Continuously Adaptive Meanshift)_第1张图片

初始的窗口为蓝色的圆 C1,圆心为 C1_o,然后在圆里面找到所有像素的重心在 C1_r,所以就移动圆心从 C1_oC1_r ,如此往复不停的去寻找点集的重心,直到移动的距离很小或者移动次数达到设定的阈值,就会停止移动,我们定义最终的窗口为 C2

【OpenCV-Python】教程:5-2 Meanshift-Camshift(Continuously Adaptive Meanshift)_第2张图片

所以,我们通常传递直方图反向投影和初始的目标框,当目标移动时,很明显,移动就会体现在直方图反向投影图像中,结果,均值漂移算法将移动窗口到最大密度的新位置。

Camshift (Continuously Adaptive Meanshift)

仔细观察最后的结果了吗?有一个问题,窗口始终保持了同样的大小,即使目标在变大或者变小,这是非常不好的。我们需要自适应窗口大小,才能让目标在变化的过程中,能够被移动到新的位置。再次强调,这个方案来自于 “OpenCV Labs”,被称为 CAMshift (Continuously Adaptive Meanshift) 。

首先应用 meanshift,一旦 meanshift 收敛,将更新窗口的尺寸 s = 2 × M 00 256 s=2×\sqrt{\frac{M_{00}}{256}} s=2×256M00 ; 同时会计算最佳椭圆拟合(还有方向);然后,用 meanshift 和新的窗口去搜索目标,该过程一直进行直到达到指定精度或者迭代次数;

【OpenCV-Python】教程:5-2 Meanshift-Camshift(Continuously Adaptive Meanshift)_第3张图片

【代码】

Meanshift

# meanshift
import numpy as np 
import cv2 

# 读入视频
videoname = "assets/slow_traffic_small.mp4"
cap = cv2.VideoCapture(videoname)
if cap.isOpened() == False:
    print("Error opening video stream or file")
    exit(-1)

ret, frame = cap.read()

# 初始化窗口
x, y, w, h = 300, 200, 100, 50 
track_window = (x, y, w, h)

# 计算直方图
roi = frame[y:y+h, x:x+w]
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_roi, np.array((0., 60., 32.)), np.array((180., 255., 255.)))
roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0, 180])
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)

# 设置终止条件,10次,精度为1个像素
term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)

while(True):
    ret, frame = cap.read()
    if ret == True:
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)

        # 执行均值漂移
        ret, track_window = cv2.meanShift(dst, track_window, term_crit)

        # 画结果
        x, y, w, h = track_window
        img2 = cv2.rectangle(frame, (x, y), (x + w, y + h), 255, 2)
        cv2.imshow('meanshift', img2)

      
        k = cv2.waitKey(50) & 0xff
        if k == 27:
            break
    else:
        break

cv2.destroyAllWindows()
cap.release()

Camshift

# CAMshift
import numpy as np
import cv2

# 读入视频
videoname = "assets/slow_traffic_small.mp4"
cap = cv2.VideoCapture(videoname)
if cap.isOpened() == False:
    print("Error opening video stream or file")
    exit(-1)

ret, frame = cap.read()

# 初始化窗口
x, y, w, h = 300, 200, 100, 50
track_window = (x, y, w, h)

# 计算直方图
roi = frame[y:y+h, x:x+w]
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_roi, np.array((0., 60., 32.)),
                   np.array((180., 255., 255.)))
roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0, 180])
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)

# 设置终止条件,10次,精度为1个像素
term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)

while (True):
    ret, frame = cap.read()
    if ret == True:
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)

        # 执行均值漂移
        ret, track_window = cv2.CamShift(dst, track_window, term_crit)

        # 画结果
        pts = cv2.boxPoints(ret)
        pts = np.int0(pts)
        img2 = cv2.polylines(frame, [pts], True, 255, 2)
        cv2.imshow('camshift', img2)

        k = cv2.waitKey(30) & 0xff
        if k == 27:
            break
    else:
        break

cv2.destroyAllWindows()
cap.release()

【接口】

  • meanshift
cv2.meanShift(	probImage, window, criteria	) ->	retval, window

在反向投影图像上找到目标

  • probImage: 目标直方图的反向投影
  • window: 初始化寻找窗口,返回里的结果是查找到的目标
  • criteria: 停止搜索的条件
  • camshift
cv2.CamShift(	probImage, window, criteria	) ->	retval, window

查找目标的中心,尺寸和方向

  • probImage: 目标直方图的反向投影
  • window: 初始化寻找窗口,返回里的结果是查找到的目标
  • criteria: 停止搜索的条件
  • calcBackProject

见 【OpenCV-Python】教程:3-10 直方图(4)直方图反向投影_黄金旺铺的博客-CSDN博客

【参考】

  1. Meanshift and Camshift
  2. “Computer Vision Face Tracking for Use in a Perceptual User Interface” in 1998 [34]
  3. French Wikipedia page on Camshift. (The two animations are taken from there)
  4. 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

你可能感兴趣的:(#,OpenCV-Python,教程,opencv,python,计算机视觉,meanshift,camshift)