版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons)
meanshift、camshift、Kalman三种常用都尝试了,还是meanshift效果更理想,未移植的源码如下;
# 创建时间:2019年8月1日
# meanshift均值漂移目标跟踪
import numpy as np
import cv2
# meanshift兴趣区域跟踪
# 输入参数:img目标区域图像矩阵;frame:训练图像矩阵
# 输出参数:中心点坐标cx,xy;输出图像矩阵output_img
def meanshift(img, frame):
# 标记初始感兴趣区域
r, h, c, w = 140, 390, 190, 725
# r, h, c, w = 0, 720, 0, 1280
# 组成一个元组
track_window = (c, r, w, h)
# 提取感兴趣的区域并将其转换成HSV
roi = img[r:r+h, c:c+w]
hsv_roi = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 创建包含具有HSV的RIO所有像素的掩码
mask = cv2.inRange(hsv_roi, np.array((100., 30., 32.)), np.array((180., 120., 255.)))
# 计算感兴趣区域ROI的直方图并将其归一化
roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0,180])
cv2.normalize(roi_hist,roi_hist, 0, 255, cv2.NORM_MINMAX)
# 指定均值漂移终止一系列的计算行为
# 均值漂移迭代十次后或者中心移动至少一个像素时,终止
term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)
# 处理训练图像
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
# 计算中心点坐标
cx = int(x + w / 2)
cy = int(y + h / 2)
print('中心坐标:', cx, cy)
output_img = cv2.rectangle(frame, (x, y), (x+w, y+h), 255, 2)
return output_img, cx, cy
cap = cv2.VideoCapture('../video/test_rectangle_2.mp4')
# 目标兴趣区域
img = cv2.imread('pure_rectangle.jpg')
while cap.isOpened():
ret, frame = cap.read()
img2, x, y = meanshift(img, frame)
cv2.imshow('img2', img2)
k = cv2.waitKey(60) & 0xff
if k == 27:
break
cv2.destroyAllWindows()
cap.release()
效果: