之前的单目标跟踪算法已经调试成功,在这基础上想把之前的单目标跟踪改进成多目标算法。在这中间碰了些许此壁,最后成功了。首选我列举出来找到的主要三种“说法”:
- 利用MultiTracker来写,但是用这个写的时候我遇到了一个问题。就是这个方式必须要打开两个window,在一个window中实现截取,在另一个window中显示。当时因为我执着于在当前的框架上添加的原因,最后这个办法没有采用。(最后利用下面的方法调试成功了以后还没有回过来重新测试这个方法,这个工作留到下次再做,今天先趁热写个博客。)
相关博客请参见以下地址:
opencv tracking(3) 多目标跟踪示例
opencv学习笔记四十五:扩展模块的单目标、多目标跟踪
再利用这个方法来进行改进自己的程序的时候,如果不利用两个窗口的话会出现只能跟踪一个目标的情况。(其实在学习后一个方法的时候,找到了可能导致这个的一个原因,下次再尝试。)
- 还没有开始研究的看到的算法,就是sort和deep sort算法。
前面那些单目标跟踪的算法是只针对单目标的算法,就算是实现成了多目标,但是究其原理还是通过对单目标的跟踪来实现的,但是sort和deep sort看样子是专门的多目标跟踪算法。有空去好好学习了以后来补充。附上目前找到的链接:
https://www.cnblogs.com/kekeoutlook/p/11179522.html
https://blog.youkuaiyun.com/weixin_38106878/article/details/100009101
https://blog.youkuaiyun.com/zgcr654321/article/details/90446526
https://zhuanlan.zhihu.com/p/97449724?from_voters_page=true
- 第二个方法是利用Ptr来管理MultiTracker实现
参考博客:
[OpenCV实战]16 使用OpenCV实现多目标跟踪
在这个方法中有一个很明显的区别就是他利用Ptr模板类来管理MultiTracker类。其他很多方面都是类似的,比如单目标跟踪用的是selectROI()函数,但是这里用的是selectROIs(),还有单目标用init这里不用init()方法,而是用add()方法代替了,其他的update()等方法都是大同小异的。详情见代码,跟之前的单目标的对比就知道啦。
在这中间学到了一个个人感觉很有用、很值得深究的东西,就是Ptr模板类。初步了解,他是一个智能指针,智能指针有shared_ptr,unique_ptr,weak_ptr,scoped_ptrd等,Ptr看了一眼源代码貌似是shared_ptr的子类。智能指针的一种通用实现技术是使用引用计数(reference count)。直白的说就是在OpenCV中会利用Ptr模板类来实现对一些类的资源管理,比如释放之类的。链接如下:
https://www.jianshu.com/p/0642948df118
在写这个程序的时候遇到了一个问题,就是我再选择跟踪算法的时候,比如
Ptr<Tracker> tracker; tracker = TrackerKCF::create();
然后要将他添加到多目标跟踪里面的时候需要用以下代码:
multiTracker->add(tracker, frame, Rect2d(rois[i]));
在这个add()方法中第一个传入的参数就是tracker,此时我最初的实现方法是,程序刚开始时候提示用户输入,并利用上一个代码对应的进行create(),但是这样以来,他总是会跟踪失败。(也就是跟我的单目标跟踪实例里面的一样)
我看人家博客里面并不是这么实现的,他是写了个方法进行选择跟踪算法,然后只在调用add的时候才去调用那个方法。(给人的直观感觉就像是我第一个实现方法他实现的太早了,也就是饭出锅的太早了,add()的时候都凉透了,必须在add()时候才出锅,那样才热乎)在这里可把我整懵逼了,因为没想到会因为这个报错,看了一下午都不知道为什么,差点心态大蹦,明明两个程序一模一样,但是一个却可以另一个却不行。后来忘了在这个博客
https://blog.youkuaiyun.com/lingyunxianhe/article/details/80380970
写道Ptr是个模板类,然后附了个链接,点进去才开始怀疑应该是在这里除了问题,有可能是因为他自动管理的时候释放了还是怎么样,还不太清楚。应该是为了泛型编程和安全考虑的吧。
本人参考的文章作者的观点是:CSRT精度最高,KCF速度精度综合最好,MOSSE速度最快。
我也会进行一个测试,并附上感受的。
附上我的代码:#include <iostream> #include <opencv2/opencv.hpp> #include <opencv2/tracking.hpp> #include <opencv2/core/ocl.hpp> using namespace cv; using namespace std; vector<string> trackerTypes = { "BOOSTING", "MIL", "KCF", "TLD", "MEDIANFLOW", "MOSSE", "CSRT" }; /** * @brief Create a Tracker By Name object 根据设定的类型初始化跟踪器 * * @param trackerType * @return Ptr<Tracker> */ Ptr<Tracker> createTrackerByName(string trackerType) { Ptr<Tracker> tracker; if (trackerType == trackerTypes