mosse

article/2025/9/29 21:58:35

MOSSE

MOSSE(Minimum Output Sum of Squared Error) 是2010年 的CVPR,它的全名叫做Visual Object Tracking using Adaptive Correlation Filters。 MOSSE 是第一篇将correlation filter(CF) 引入object tracking 的论文,它也是CSK和KCF/DCF等算法的基础。

CF(相关滤波)

相关一般分为自相关和互相关,这里我们一般指的是互相关,假设我们有两个信号f和g

f∗表示f的共轭,互相关的直接解释就是衡量两个信号在某个时刻τ时的相似程度。
假设f和g的形状一样,那么一定是f和g对齐的时候二者的相似程度最大,此时达到最大的输出响应,如下图所示:

卷积计算和相关计算的关系

  • Two-dimensional correlation is equivalent to two-dimensional convolution with the filter matrix rotated 180 degrees.

论文解读


将CF应用在tracking方面最基本的思想就是,设计一个滤波模板,使得该模板与跟踪目标的ROI做卷积运算,得到最大的输出响应。


  • g表示输出响应
  • f表示输入原始图片的灰度图像
  • h表示滤波模板
    为了简化计算,将时域的卷积转化为频域的点乘积。
    时域公式表示:频域公式表示:所以目标H的计算为:在跟踪的光照等其他因素的影响下,为了提高滤波模板的鲁棒性,在文章中作者对GroundTruth进行随机仿射变换得到一系列的训练样本fi,gi是由高斯函数产生的并且其峰值位置是在fi的中心,我们同时考虑m帧作为参考,这就是MOSSE模型的思想,最终该模型的目标函数表示为:将目标函数最小化,对上式在频域进行求导(复数域不同于实数域),得到:在跟踪过程中,我们只需要将以上模板与当前帧与滤波模板做相关操作,在输出响应中找到最大值的位置,该位置就是目标在当前帧中的位置。本文的参数更新的策略为:其中,η是一个超参数,为经验值。

缺点:

  • 输入的特征为单通道灰度图像,特征表达能力有限
  • 没有尺度更新,对于尺度变化的跟踪目标不敏感

代码解析

这里面主要做的就是 ,初始帧的输入与输出来求出Ai与Bi,从而求出初始的模板Hi,下面将初始的Hi与当前帧所在的上个位置进行卷积,频域也就是进行相乘。然后找到最大值的位置也就是当前目标的中心,由于宽高不变,所以在此基础上更新宽高就可以了,实现目标跟踪。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import numpy as np
import cv2
import os
from utils import linear_mapping, pre_process, random_warp"""
This module implements the basic correlation filter based tracking algorithm -- MOSSEDate: 2018-05-28"""class mosse:def __init__(self, args, img_path):# get arguments..self.args = argsself.img_path = img_path# get the img lists...self.frame_lists = self._get_img_lists(self.img_path)self.frame_lists.sort()# start to do the object tracking...def start_tracking(self):# get the image of the first frame... (read as gray scale image...)init_img = cv2.imread(self.frame_lists[0])init_frame = cv2.cvtColor(init_img, cv2.COLOR_BGR2GRAY)init_frame = init_frame.astype(np.float32)# get the init ground truth.. [x, y, width, height]init_gt = cv2.selectROI('demo', init_img, False, False)init_gt = np.array(init_gt).astype(np.int64)# start to draw the gaussian response...response_map = self._get_gauss_response(init_frame, init_gt)# start to create the training set ...# get the goal..print(init_gt)g = response_map[init_gt[1]:init_gt[1]+init_gt[3], init_gt[0]:init_gt[0]+init_gt[2]]print(g)fi = init_frame[init_gt[1]:init_gt[1]+init_gt[3], init_gt[0]:init_gt[0]+init_gt[2]]G = np.fft.fft2(g)# start to do the pre-training...Ai, Bi = self._pre_training(fi, G)# start the tracking...for idx in range(len(self.frame_lists)):current_frame = cv2.imread(self.frame_lists[idx])frame_gray = cv2.cvtColor(current_frame, cv2.COLOR_BGR2GRAY)frame_gray = frame_gray.astype(np.float32)if idx == 0:Ai = self.args.lr * AiBi = self.args.lr * Bipos = init_gt.copy()clip_pos = np.array([pos[0], pos[1], pos[0]+pos[2], pos[1]+pos[3]]).astype(np.int64)else:Hi = Ai / Bifi = frame_gray[clip_pos[1]:clip_pos[3], clip_pos[0]:clip_pos[2]]fi = pre_process(cv2.resize(fi, (init_gt[2], init_gt[3])))Gi = Hi * np.fft.fft2(fi)gi = linear_mapping(np.fft.ifft2(Gi))# find the max pos...max_value = np.max(gi)max_pos = np.where(gi == max_value)dy = int(np.mean(max_pos[0]) - gi.shape[0] / 2)dx = int(np.mean(max_pos[1]) - gi.shape[1] / 2)# update the position...pos[0] = pos[0] + dxpos[1] = pos[1] + dy# trying to get the clipped position [xmin, ymin, xmax, ymax]clip_pos[0] = np.clip(pos[0], 0, current_frame.shape[1])clip_pos[1] = np.clip(pos[1], 0, current_frame.shape[0])clip_pos[2] = np.clip(pos[0]+pos[2], 0, current_frame.shape[1])clip_pos[3] = np.clip(pos[1]+pos[3], 0, current_frame.shape[0])clip_pos = clip_pos.astype(np.int64)# get the current fi..fi = frame_gray[clip_pos[1]:clip_pos[3], clip_pos[0]:clip_pos[2]]fi = pre_process(cv2.resize(fi, (init_gt[2], init_gt[3])))# online update...Ai = self.args.lr * (G * np.conjugate(np.fft.fft2(fi))) + (1 - self.args.lr) * AiBi = self.args.lr * (np.fft.fft2(fi) * np.conjugate(np.fft.fft2(fi))) + (1 - self.args.lr) * Bi# visualize the tracking process...cv2.rectangle(current_frame, (pos[0], pos[1]), (pos[0]+pos[2], pos[1]+pos[3]), (255, 0, 0), 2)cv2.imshow('demo', current_frame)cv2.waitKey(100)# if record... save the frames..if self.args.record:frame_path = 'record_frames/' + self.img_path.split('/')[1] + '/'if not os.path.exists(frame_path):os.mkdir(frame_path)cv2.imwrite(frame_path + str(idx).zfill(5) + '.png', current_frame)# pre train the filter on the first frame...def _pre_training(self, init_frame, G):height, width = G.shapefi = cv2.resize(init_frame, (width, height))# pre-process img..fi = pre_process(fi)Ai = G * np.conjugate(np.fft.fft2(fi))Bi = np.fft.fft2(init_frame) * np.conjugate(np.fft.fft2(init_frame))for _ in range(self.args.num_pretrain):if self.args.rotate:fi = pre_process(random_warp(init_frame))else:fi = pre_process(init_frame)Ai = Ai + G * np.conjugate(np.fft.fft2(fi))Bi = Bi + np.fft.fft2(fi) * np.conjugate(np.fft.fft2(fi))return Ai, Bi# get the ground-truth gaussian reponse...def _get_gauss_response(self, img, gt):# get the shape of the image..height, width = img.shape# get the mesh grid...xx, yy = np.meshgrid(np.arange(width), np.arange(height))# get the center of the object...center_x = gt[0] + 0.5 * gt[2]center_y = gt[1] + 0.5 * gt[3]# cal the distance...dist = (np.square(xx - center_x) + np.square(yy - center_y)) / (2 * self.args.sigma)# get the response map...response = np.exp(-dist)# normalize...response = linear_mapping(response)return response# it will extract the image list def _get_img_lists(self, img_path):frame_list = []for frame in os.listdir(img_path):if os.path.splitext(frame)[1] == '.jpg':frame_list.append(os.path.join(img_path, frame)) return frame_list# it will get the first ground truth of the video..def _get_init_ground_truth(self, img_path):gt_path = os.path.join(img_path, 'groundtruth.txt')with open(gt_path, 'r') as f:# just read the first frame...line = f.readline()gt_pos = line.split(',')return [float(element) for element in gt_pos]

参考链接:
http://simtalk.cn/2017/07/03/Object-Tracking/
https://github.com/TianhongDai/mosse-object-tracking


http://chatgpt.dhexx.cn/article/qPRAjBh8.shtml

相关文章

【目标跟踪】|MOSSE原理及对应代码解释 matlab C

1原理 https://www.bilibili.com/video/av74302620/?spm_id_from333.788.videocard.0 https://blog.csdn.net/fzp95/article/details/78385795?utm_mediumdistribute.pc_relevant.none-task-blog-baidujs_title-4&spm1001.2101.3001.4242 相关和卷积操作》 https://bl…

单目标跟踪MOSSE详细算法步骤+理论说明

单目标跟踪MOSSE详细算法步骤理论推导 算法概述详细步骤候选框处理初始滤波器生成滤波器更新 理论说明对数变换(log函数)窗函数的理解 更新中 为了理解傅里叶变换,花了一周时间,可惜还是没有搞很清楚原理,暂且将其看作是数学家从浩瀚的知识海…

MOSSE相关滤波目标跟踪论文

论文全名:Visual Object Tracking using Adaptive Correlation Filters 论文摘自CVPR 2010,由David S. Bolme、J.Ross Beveridge、Bruce A. Draper与Yui Man Lui撰写,简称MOSSE。 摘要 虽然不常用,但相关滤波器可以通过旋转&…

上海2022年平均工资为12184,涨幅只有6.9%

大家好!我是韩老师。 到了每年的7月份,就是上海调整社保和公积金基数的时候了。 今天,上海人社局发布了有关民生保障待遇及社会救助待遇调整,其中最重要的信息透露了上海市2022年度职工月平均工资,即上海市2023年度社保…

上海市人才引进落户条件有哪些

在沪工作稳定,专业(业绩)与岗位相符,一般应能在本单位工作五年以上,且符合下列条件之一: 1、具有博士研究生学历并取得相应学位或者具有高级专业技术职务任职资格并受聘相应职务的专业技术人员和管理人员。 2、获得省部级及以上政府奖励的人员。 3、国家重大科技专项项…

全国平均工资水平排序 北京上海西藏居前三名

全国工资排序 你的工资涨了吗?省统计局昨日发布的数据显示,今年三季度末,江苏省城镇单位在岗职工平均工资达到21999元,比上年同期增加3211元,增长17.1%。这意味着1-9月份平均每月同比增收356元左右。 金融业平均工资排…

你的工资是怎样被平均的?终于有人把平均数、中位数和众数讲明白了

导读:我们在数据处理时,要小心各种陷阱!人们习惯使用统计数据来简化事物描述,但错误的统计方法不仅不能反映事实,还会让数据变得毫无意义。 作者:徐晟 来源:大数据DT(ID:…

计算机软件集成项目工程师上海,上海系统集成项目管理工程师积分政策,可以加多少分?...

系统集成项目管理工程师是计算机技术与软件专业技术资格(水平)考试中级资格里的一项考试,获得系统集成项目管理工程师证书在上海市办理居住证时可以获得100分的积分,具体依据如下: 系统集成项目管理工程师是计算机软件资格(水平)考试里中级的…

23省份2011年平均工资排行 北京最高甘肃垫底

2019独角兽企业重金招聘Python工程师标准>>> 23省份2011年平均工资排行 统计发现,目前全国已有北京等23个省区公布了2011年城镇单位在岗职工平均工资。数据显示,在这23省区中,北京职工月平均工资最高,为4672元/月&…

再见,工资!2020年6月程序员工资统计,平均14404元,网友:又跌了!

Python实战社群 Java实战社群 长按识别下方二维码,按需求添加 扫码关注添加客服 进Python社群▲ 扫码关注添加客服 进Java社群▲ 作者丨有数可据 来源丨 https://blog.csdn.net/juwikuang/article/details/106503404 见了鬼! 工资竟然又跌了 #平均工资 2…

上海落户说明

 当前位置:合肥家园网—楼市资讯—家园看房 上海最新户口政策 新闻来源:合肥家园网 2012-02-24 width"100" height"24" src"http://news.hfhome.cn/hits.aspx?NewsID77154" frameborder"0…

2020年6月程序员工资统计,平均14404元,网友:又跌了!

见了鬼! 工资竟然又跌了 #平均工资 2020年6月全国招收程序员313739人。2020年6月全国程序员平均工资14404元,工资中位数12500元,其中95%的人的工资介于5250元到35000元。 虽然收入又下降了,但是岗位比上个月多了起来,随…

上海市职称计算机证明补办,职称证书丢了还能补办吗?上海落户政策详解。

很多朋友们在准备积分申请的时候,由于时间过去太久,等找材料的时候发现,职称证书不见了,这可怎么办呢?别急,职称证书是可以补发的!只需要个人提供以下材料: 1、原《专业技术职务任职…

python一个月工资多少钱_python工资收入

13.9K / 月平均工资 数据统计来自近一年 13903 份样本,截至 2020-11-21 全国python一个月多少钱?平均工资 ¥13.9K/月 其中拿10K-15K工资的人占比最多,达 30.5% 其次拿15K-20K工资的占 20.3%,20K-30K占 19.3% 对比…

2021年全国平均工资出炉,你达标了吗?

我国人的收入是个谜,如果你去各大论坛,就会发现各个都是富人。比如“刚下飞机,人在漂亮国,年入刚过百万”。人均法拉利、劳斯莱斯,以至于中国的法拉利、劳斯莱斯、兰博基尼等豪车的拥有量已经超过了其全球销量。 那么大…

java开发深圳平均工资_深圳2017平均工资100173元!!这次你又又又拖后腿了吗!?...

原标题:深圳2017平均工资100173元!!这次你又又又拖后腿了吗!? 最近深圳的天气 我和烤肉之间真的只差一撮孜然 简直热到原地爆炸 虽然未来的几天即将开启雨雨雨的模式 但是依然湿热 不过大家也不要灰心 毕竟有位名人曾经…

海口java工资水平2017,2019年海口平均工资公布,海口平均工资水平最新数据

海口市平均工资是什么?2017年海口市的平均工资是多少,下面现代语文网小编就关于2017年海口市平均工资相关信息给大家整理下! 平均工资,是一项反映工资总体水平的指标,指企业、事业、机关单位的职工在一定时期内平均每人…

济宁java平均工资,2019年济宁平均工资公布,济宁平均工资水平最新数据

济宁市平均工资是什么?2017年济宁市的平均工资是多少,下面现代语文网小编就关于2017年济宁市平均工资相关信息给大家整理下! 平均工资,是一项反映工资总体水平的指标,指企业、事业、机关单位的职工在一定时期内平均每人…

kali免驱网卡ifconfig不显示?

一、问题现象 1. 插上 kali 免驱网卡后,ifconfig不显示 2. lsusb 显示有网卡的信息 联系了商家远程搞了一天,又是改 USB兼容性 ,又是安装各种包,最后重新装了kali系统还是没成功 二、后来我研究了一下解决了 1. 插上网卡&#x…

Linux下通过iwconfig命令连接无线

在无线抓取报文后,或者未启动图形化桌面,只有命令行的情况下,需要通过命令来配置无线上网。 1、启动无线接口 ifconfig -a ifconfig wlan0 up 2、扫描无线信号,找到要连接的无线 iwlist wlan 0 scanning 3、连接相应的无线ssid i…