官网https://docs.opencv.org/3.4.1/db/df8/tutorial_py_meanshift.html
Meanshift均值漂移
Meanshift背后的原理很简单。
假设你有一堆点(就像直方图反向投影一样的像素分布)。给你一个小窗口(圆形的),你需要把窗口移动到最大像素灰度区域(或者是点数量最多的区域)。如下图所示
初始窗口是图中蓝色圆形框C1,它的初始圆心标记为蓝色矩形“C1_o”,而窗口中点的质心被标记为蓝色圆圈“C1_r”,显然两者并不重合。把圆形窗口的圆心C1_o移动到质心C1_r位置,此时(窗口内的点发生了变化)又会产生新的质心,很大可能现在圆心(原来的质心)和新的质心还是不匹配的。重复上面的操作,反复迭代,尝试把圆心和质心重合同一个位置(或者有一个小的期望误差)。最终你得到的就是包含像素分布最大的窗口,即图中的绿色圆圈,称为C2。你可以发现绿色圆圈中有最大点数量。整个过程如下图所示
通常我们要传入直方图反向投影得到的图像和目标的初始位置。显然,当对象移动时候,移动会反映到直方图反向投影图中。最终结果,meanshift 算法就把我们的窗口移动到图像中灰度值最大的新位置了。
Meanshift in OpenCV
要在opencv中使用meanshift,首先我们需要设置目标,计算它的直方图,这样我们就能把目标反向投影到每一帧中用于计算meanshift。另外我们还需要提供窗口的初始位置。对于直方图,我们只需要考虑Hue(色调)。 同时,为了避免亮度低导致出错,可以利用cv.inRange() 函数忽略低亮度值。
以下代码是官网例子
import cv2
import numpy as np
from matplotlib import pyplot as plt
cap = cv2.VideoCapture('slow.flv')
# take first frame of the video
ret,frame = cap.read()
# setup initial location of window,设置初试窗口位置和大小
r,h,c,w = 250,90,400,125 # simply hardcoded the values
track_window = (c,r,w,h) #x,y,w,h
# set up the ROI for tracking,设置追踪的区域
roi = frame[r:r+h, c:c+w]
# roi区域的hsv图像
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
# 取值hsv值在(0,60,32)到(180,255,255)之间的部分
mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
# 计算直方图,参数为 图片(可多),通道数,蒙板区域,直方图长度,范围
roi_hist &#