cc(9条消息) 基于MeanShift的目标跟踪算法及实现_taotao1233的博客-CSDN博客_meanshift目标跟踪算法https://blog.csdn.net/jinshengtao/article/details/30258833https://blog.csdn.net/jinshengtao/article/details/30258833(9条消息) MeanShift(均值漂移)MATLAB程序详解_战死为止的博客-CSDN博客_均值漂移matlab代码https://blog.csdn.net/qq_34122861/article/details/89556503 本人写程序和open-cv都是新人,看了上面的文章后发现没有python版本的,就按照一摸一样的思路仿写了python的代码,但是是打开笔记本自带摄像头进行MeanShift目标跟踪。希望给萌新一些参考,由于我也是新手,这是我写的第一个比较长的代码,所以会有很多冗余甚至错误,欢迎大家指正。如果看不懂可以参考上面的博客。
代码import math import numpy as np import cv2 def get_tr(img): # 定义需要返回的参数 mouse_params = {'x': None, 'width': None, 'height': None, 'y': None, 'temp': None} cv2.namedWindow('image') # 鼠标框选 *** 作函数 cv2.setMouseCallback('image', on_mouse, mouse_params) cv2.imshow('image', img) cv2.waitKey(0) return [mouse_params['x'], mouse_params['y'], mouse_params['width'], mouse_params['height']], mouse_params['temp'] def on_mouse(event, x, y, flags, param): global img, point1 img2 = img.copy() if event == cv2.EVENT_LBUTTONDOWN: # 左键点击 point1 = (x, y) cv2.circle(img2, point1, 10, (0, 255, 0), 5) cv2.imshow('image', img2) elif event == cv2.EVENT_MOUSEMOVE and (flags & cv2.EVENT_FLAG_LBUTTON): # 按住左键拖曳 cv2.rectangle(img2, point1, (x, y), (255, 0, 0), 5) cv2.imshow('image', img2) elif event == cv2.EVENT_LBUTTONUP: # 左键释放 point2 = (x, y) cv2.rectangle(img2, point1, point2, (0, 0, 255), 5) cv2.imshow('image', img2) # 返回框选矩形左上角点的坐标、矩形宽度、高度以及矩形包含的图像 param['x'] = min(point1[0], point2[0]) param['y'] = min(point1[1], point2[1]) param['width'] = abs(point1[0] - point2[0]) param['height'] = abs(point1[1] - point2[1]) param['temp'] = img[param['y']:param['y']+param['height'], param['x']:param['x']+param['width']] def main(): global img cap = cv2.VideoCapture(0) # 获取视频第一帧 ret, frame = cap.read() img = frame # 框选目标并返回相应信息:rect为四个信息,temp为框选出来的图像 rect, temp = get_tr(img) (a, b, c) = temp.shape y = [a/2, b/2] # 计算目标图像的权值矩阵 m_wei = np.zeros((a,b)) for i in range(a): for j in range(b): z = (i-y[0])**2 + (j-y[1])**2 m_wei[i, j] = 1 - z/(y[0]**2 + y[1]**2) # 计算目标权值直方图 C = 1/sum(sum(m_wei)) hist1 = np.zeros(16**3) for i in range(a): for j in range(b): q_b = math.floor(float(temp[i, j, 0]) / 16) q_g = math.floor(float(temp[i, j, 1]) / 16) q_r = math.floor(float(temp[i, j, 2]) / 16) q_temp1 = q_r*256 + q_g*16 + q_b hist1[int(q_temp1)] = hist1[int(q_temp1)] + m_wei[i, j] hist1 = hist1*C # 接着读取视频并进行目标跟踪 while(1): ret, frame = cap.read() if ret == True: Img = frame num = 0 Y = [1, 1] # mean shift迭代 while (np.sqrt(Y[0]**2+Y[1]**2) > 0.5) & (num < 20): num = num+1 # 计算候选区域直方图 temp2 = Img[int(rect[1]):int(rect[1]+rect[3]), int(rect[0]):int(rect[0]+rect[2])] hist2 = np.zeros(16**3) q_temp2 = np.zeros((a, b)) for i in range(a): for j in range(b): q_b = math.floor(float(temp2[i, j, 0]) / 16) q_g = math.floor(float(temp2[i, j, 1]) / 16) q_r = math.floor(float(temp2[i, j, 2]) / 16) q_temp2[i, j] = q_r * 256 + q_g * 16 + q_b hist2[int(q_temp2[i, j])] = hist2[int(q_temp2[i, j])] + m_wei[i, j] hist2 = hist2*C w = np.zeros(16**3) for i in range(16**3): if hist2[i] != 0: w[i] = math.sqrt(hist1[i]/hist2[i]) else: w[i] = 0 sum_w = 0 sum_xw = [0, 0] for i in range(a): for j in range(b): sum_w = sum_w + w[int(q_temp2[i, j])] sum_xw = sum_xw + w[int(q_temp2[i, j])]*np.array([i-y[0], j - y[1]]) Y = sum_xw/sum_w # 位置更新 rect[0] = rect[0] + Y[1] rect[1] = rect[1] + Y[0] v0 = int(rect[0]) v1 = int(rect[1]) v2 = int(rect[2]) v3 = int(rect[3]) pt1 = (v0, v1) pt2 = (v0+v2, v1+v3) # 画矩形 IMG = cv2.rectangle(Img, pt1, pt2, (0, 0, 255), 2) cv2.imshow('IMG', IMG) k = cv2.waitKey(60) & 0xff if k == 27: break else: break if __name__ == '__main__': main()结果
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)