相关滤波之开篇Mosse原理及代码详解

  • 相关滤波(Correlation Filter )介绍
  • 代码解读
  • 程序框图

本文主要介绍相关滤波算法开篇——mosse具体原理及其python代码实现流程

相关滤波(Correlation Filter )介绍

相关滤波(CF)源于信号处理领域,有这么一句话“两个信号越相似,其相关值越高。在跟踪,就是找到与跟踪目标响应最大的项” 贯穿了整个相关滤波算法的根本。

2010年CVPR,David S.Bolme在文章《visual object tracking using adaptive correlation filters》中首次将相关滤波用在了跟踪领域,在其文章的基础之上,很多改进的算法相继出现,跟踪的效果也越来越好。

两个信号之间的相关为,
(f⊗g)(τ)=∫∞−∞f∗(t)g(t+τ)dt(f\otimes g)(\tau)=\int_\infty^{-\infty}f^*(t)g(t+\tau)dt (f⊗g)(τ)=∫∞−∞​f∗(t)g(t+τ)dt(f⊗g)(n)=∑−∞∞f∗[m]g(m+n)(f\otimes g)(n)=\sum_{-\infty}^\infty f^*[m]g(m+n) (f⊗g)(n)=−∞∑∞​f∗[m]g(m+n) 其中f表示f的复共轭。correlation的直观解释就是衡量两个函数在某个时刻相似程度。
在图像中相关滤波意思就是输入图像(框选的目标)跟滤波器之间做一个相关操作,相关操作类似卷积操作(卷积需要反转,相关不用),相关操作如下图所示。

这里要注意输入图像f,滤波器h,及相应输出g的大小是完全一样的。


相关滤波意思就是现在在第一帧图像中框选了一个目标,然后对这个目标训练一个滤波器(大小相同)使得其输出响应g(大小相同)在中间值最大。其中输入图像给定,响应图也是可以直接生成的。一般都是用高斯函数,中间值最大,旁边逐渐降低。

然后滤波器的值推导过程类似于机器学习的线性回归
minH∗=∑i=1m∣H∗Fi−Gi∣2min_{H^*}=\sum _{i=1}^m|H^*F_i-G_i|^2 minH∗​=i=1∑m​∣H∗Fi​−Gi​∣2
就是要找一个滤波器H*使得其上式的结果最小,其实也就是找到一个滤波器,使得其响应在中间的值最大,这就是利用了相关滤波器的原理。
然后根据数学求导,各种计算规则(有兴趣的可以看下原来论文,步骤很详细,这里就不展示了),最终可以得到
Hwv=∑iFiwvGiwv∗∑iFiwvFiwv∗H_{wv}={\sum _i F_{iwv}G^*_{iwv}\over \sum _i F_{iwv}F^*_{iwv} }Hwv​=∑i​Fiwv​Fiwv∗​∑i​Fiwv​Giwv∗​​上面得到是H中每个元素的值,最后得到H为:
H=∑iFi⋅Gi∗∑iFi⋅Fi∗H={\sum _iF_i\cdot G^*_i \over \sum _iF_i\cdot F^*_i }H=∑i​Fi​⋅Fi∗​∑i​Fi​⋅Gi∗​​上式就是滤波器的模型公式。
其中的G为高斯函数矩阵的傅里叶变换,F为输入目标图矩阵的傅里叶变换,都是用的快速傅里叶变换(FFT),这块不懂的可以查看快速傅里叶变换

然后为了具有更好的鲁棒性,滤波器采用迭代的方法Ht=AtBtH_t={A_t\over B_t}Ht​=Bt​At​​At=ηFt⋅Gt∗+(1−η)At−1A_t=\eta F_t \cdot G^*_t +(1-\eta)A_{t-1}At​=ηFt​⋅Gt∗​+(1−η)At−1​Bt=ηFt⋅Ft∗+(1−η)Bt−1B_t=\eta F_t \cdot F^*_t +(1-\eta)B_{t-1}Bt​=ηFt​⋅Ft∗​+(1−η)Bt−1​更新参数为η,每一帧的滤波器都与上一帧的取值有关。
至此,第一帧图像目标框选之后就得到了一个设计好的滤波器,然后对第二帧图像提取目标区域对其与刚才的滤波器先进行傅里叶变换进行卷积之后逆向傅里叶变换找最大响应值,这个响应值的位置就是第二帧图像的待追踪目标的中心。

每一步目标图像在傅里叶变换前还要进行一些预处理
(1)FFT卷积算法需要将图像和滤波器映射到拓扑结构上,边界采用循环图像的方式填充,即将图像的左边缘连接到右侧边缘,将顶部连接到底部。
(2)采用点乘余弦窗处理,使图像边缘慢慢变成零。
在代码中都有所体现

接下来讲代码,附上GitHub链接
是python代码(因为对python比较熟悉)
项目根目录下主要有
datasets文件夹(用于存放跟踪图片集)
examples文件夹(用于存放gif动图,可不用)
demo.py (主程序,用于初始化参数,及运行各个函数)
mosse.py(跟踪算法的实现)
utils.py(一些图像处理操作)

代码解读

接下来分别介绍下各个具体模块的代码首先是主程序demo.py

from mosse import mosse
import argparseparse = argparse.ArgumentParser()
parse.add_argument('--lr', type=float, default=0.125, help='the learning rate')
parse.add_argument('--sigma', type=float, default=100, help='the sigma')
parse.add_argument('--num_pretrain', type=int, default=128, help='the number of pretrain')
parse.add_argument('--rotate', action='store_true', help='if rotate image during pre-training.')
parse.add_argument('--record', action='store_true', help='record the frames')if __name__ == '__main__':args = parse.parse_args()img_path = 'datasets/surfer/'tracker = mosse(args, img_path)tracker.start_tracking()

其中下半部分为主程序,进行参数的赋值,图像路径的赋值,跟踪器的设计,开始跟踪
上半部分为参数的赋值,为python自带模块argparse 的使用。

其次是
mosse.py
这里定义了一个mosse类 用于mosse算法的实现
主要就是一个方法

    def start_tracking(self):# 得到图像的第一帧init_img = cv2.imread(self.frame_lists[0])init_frame = cv2.cvtColor(init_img, cv2.COLOR_BGR2GRAY)init_frame = init_frame.astype(np.float32)# 在第一帧中框选中需要的目标区域init_gt = cv2.selectROI('demo', init_img, False, False)init_gt = np.array(init_gt).astype(np.int64)# 得到当前的高斯响应response_map = self._get_gauss_response(init_frame, init_gt)# 得到目标图像大小的高斯响应图g = response_map[init_gt[1]:init_gt[1]+init_gt[3], init_gt[0]:init_gt[0]+init_gt[2]]#原始图像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)# 预处理Ai, Bi = self._pre_training(fi, G)# 开始跟踪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))# 找到最大的响应点,这就是第二帧的目标位置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)# 更新位置信息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#可视化跟踪序列图像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)

整个流程基本与mosse算法原理一致,对照着原理,把这个推导一遍,会更加好理解这个算法基本原理

utils.py里面主要就是对图像进行一些预处理比如图像线性映射,进行点乘余弦窗处理,使图像边缘慢慢变成零,图像反转操作等。

程序框图

以上就是整个mosse算法的原理及代码流程,最后附上一张流程框图,结合去看,会理解的更加深入。

先写到这里,第一次写博客,很多不是很完善,之后慢慢改。。

相关滤波之开篇Mosse原理及代码详解相关推荐

  1. batchnorm原理及代码详解

    转载自:http://www.ishenping.com/ArtInfo/156473.html batchnorm原理及代码详解 原博文 原微信推文 见到原作者的这篇微信小文整理得很详尽.故在csd ...

  2. DeepLearning tutorial(1)Softmax回归原理简介+代码详解

    FROM: http://blog.csdn.net/u012162613/article/details/43157801 DeepLearning tutorial(1)Softmax回归原理简介 ...

  3. DeepLearning tutorial(3)MLP多层感知机原理简介+代码详解

    FROM:http://blog.csdn.net/u012162613/article/details/43221829 @author:wepon @blog:http://blog.csdn.n ...

  4. DeepLearning tutorial(4)CNN卷积神经网络原理简介+代码详解

    FROM: http://blog.csdn.net/u012162613/article/details/43225445 DeepLearning tutorial(4)CNN卷积神经网络原理简介 ...

  5. Pytorch|YOWO原理及代码详解(二)

    Pytorch|YOWO原理及代码详解(二) 本博客上接,Pytorch|YOWO原理及代码详解(一),阅前可看. 1.正式训练 if opt.evaluate:logging('evaluating ...

  6. 人脸识别SeetaFace2原理与代码详解

    人脸识别SeetaFace2原理与代码详解 前言 一.人脸识别步骤 二.SeetaFace2基本介绍 三.seetaFace2人脸注册.识别代码详解 3.1 人脸注册 3.1.1 人脸检测 3.1.2 ...

  7. Pytorch | yolov3原理及代码详解(二)

    阅前可看: Pytorch | yolov3原理及代码详解(一) https://blog.csdn.net/qq_24739717/article/details/92399359 分析代码: ht ...

  8. 曲率高斯滤波去噪python实现(附代码详解)

    曲率高斯滤波去噪python实现(附代码详解) 曲率滤波的理论基础可以参考下曲率滤波的理论基础和应用,这篇博客介绍的思想完美的避开了一大堆数学公式,简直是我的福音,但还是要细看的,不然很容易忽略重点, ...

  9. Pytorch | yolov3原理及代码详解(一)

    YOLO相关原理 : https://blog.csdn.net/leviopku/article/details/82660381 https://www.jianshu.com/p/d13ae10 ...

  10. 深入浅出吃透多线程、线程池核心原理及代码详解

    一.多线程详解 1.什么是线程 线程是一个操作系统概念.操作系统负责这个线程的创建.挂起.运行.阻塞和终结操作.而操作系统创建线程.切换线程状态.终结线程都要进行CPU调度--这是一个耗费时间和系统资 ...

最新文章

  1. Failed while installing Dynamic Web Module 2.5. Project facet jst.web.jstl has not been defined.
  2. 软件和硬件的关系以及软件调动硬件的工作原理
  3. POJ2301+水~~~~~~
  4. comsol稀物质传递_印刷指南丨印刷油墨传递的影响因素?
  5. docker 镜像加速
  6. pythonista3使用说明_Pythonista中文文档:sound
  7. 前端学习(2116):为什么组件data必须是函数
  8. 5g存储服务器是什么项目,5G时代对服务器有什么要求?
  9. 虚数填补了数学的那一个缺口?
  10. react native笔记-个人记录-初始化工程遇到的问题
  11. python进入内置函数文件_python基础知识-set、函数、内置函数、文件操作
  12. 三菱伺服自动调谐_自动化领域最值得关注的十大伺服电机
  13. python机器学习案例系列教程——模型评估总结
  14. 自动化测试工具-Airtest
  15. linux升级内核5.10 网卡无法启动,博通网卡在Linux 5.10内核下无法搜索到无线网络的解决...
  16. DVWA安装教程(懂你的不懂·详细)
  17. postgresql 日期相减
  18. Revit开发将WPF的Ower设置为Revit窗体
  19. 利用python提取基因cDNA长度,exon数量,pep长度和PI
  20. loadrunner 操作mysql_loadrunner学习笔记(从MYSQL中取数据)

热门文章

  1. 《HBase权威指南》读书笔记(一)
  2. 弗兰克赫兹实验matlab画图,物理实验论文
  3. (转载)十四步实现拥有强大AI的五子棋游戏
  4. R语言及其IDE(RStudio)下载安装流程
  5. c语言十七算法,算法精解十七(C语言版)
  6. mysql性能优化金字塔法则 下载_千金良方:MySQL性能优化金字塔法则 pdf版
  7. 软件测试mysql面试题及答案_软件测试技术之面试必问的25道数据库测试题
  8. Datalogic 得利捷最新推出Matrix 320 5MP:不仅限于内部物流追溯
  9. vs2015-devexpress 安装
  10. 酒吧、ktv、夜店收银系统分析