前面一直使用camshift做跟踪,但是camshift实际使用的效果并不怎么好。随着对OpenCV稍微了解了一点点之后,看到这篇博客[同时看到这篇博客自适应三特征融合之Camshift目标跟踪——颜色、纹理、边缘方向]。在评论中提到现在较好的跟踪算法有KCF、TLD、MIL等。于是乎,原来死活找不到的跟踪算法,突然井喷式的冒出来,以前完全不懂视觉相关的知识,结果找算法都找不到,但是经过了这个层次之后,慢慢就接触到更高级的东西。虽然还有很多不懂的东西,但是起码视觉跟踪方面也算是翻开了新篇章。
简单的说,对象跟踪就是在视频的连续帧中定位对象。如果我们知道了物体在当前帧之前的运动模型(运动模型指对象在当前帧之前的帧的位置和速度),就可以根据当前的运动模型预测新位置,并且你将非常对象的新位置(卡尔曼滤波)。当然我们可以有更多对象运动的信息,比如对象在先前帧的外观。换句话说 ,我们可以构建一个外观模型来编码对象的外观。该外观模型可以用于在由运动模型预测的位置的小邻域中搜索,以更精确地预测对象的位置。
运动模型预测对象的大致位置,外观模型微调这个估计以基于外观提供更准确的估计。如果对象很简单,没有改变它的外观很多,我们可以使用一个简单的模板作为外观模型,并寻找那个模板。然而,现实生活中,对象的外观可能会发生巨大变化。为了解决这个问题,在许多现代跟踪器中,该外观模型是以在线方式训练的分类器。
分类器的工作是将图像的矩形区域分类为对象或背景。分类器接受图像补丁作为输入,并返回0和1之间的分数,以指示图像补丁包含对象的概率。当绝对确定图像补丁是背景时,分数为0;当绝对确定补丁是对象时,分数为1.
在机器学习中,我们使用在线这个词来指代在运行时在运行中训练的算法。离线分类器可能需要数千个实例来训练分类器,但是在运行时通常使用非常少的实例训练在线分类器。
分类器通过馈送正(对象)和负(背景)示例来训练。如果你想建立一个分类器来检测猫,你训练它与成千上万包含猫的图像和数千不包含猫的图像。这样分类器学习区分什么是猫和什么不是猫。在建立在线分类器,我们没有成千上万的正和负的例子。
博主:也就是我们可以给机器喂图片,让他建立一个模型,用这个模型去判别猫,但是我们可能无法知道机器判别这个物体是否是猫的标准。
优点:无。 这个算法是十年前并且可以运用,但我找不到一个很好的理由使用它,特别是当其他高级跟踪器(MIL,KCF)基于类似的原理可用。
缺点:跟踪性能平庸。
MIL跟踪器
此跟踪器在概念上类似于上述的BOOSTING跟踪器。 最大的区别在于,代替仅考虑对象的当前位置作为积极示例,它在当前位置周围的小邻域中查找以生成若干潜在的正例子。 你可能认为这是一个坏主意,因为在大多数这些“积极”的例子中,对象不是中心。
在MIL中,你没有指定正和负例子,但是有正和负“包”。 正包中的图像集合并不都是积极的例子。 相反,只有一个图像在积极的包里需要一个积极的例子。在我们的示例中,正包包含以对象的当前位置为中心的补丁,以及在其周围的小邻域中的补丁。 即使被跟踪对象的当前位置不准确,当来自当前位置的邻域的样本被放入正包中时,很有可能这个包包含至少一个图像,其中对象被良好地置于居中。
优点:性能相当不错。 它不像BOOSTING跟踪器那样漂移,它在部分遮挡下合理地工作。如果你使用OpenCV 3.0,这可能是你可用的最好的跟踪。 但是如果你使用更高版本,考虑KCF。
缺点:跟踪失败报告不可靠。不能从完全闭塞恢复。
优点:准确度和速度都比MIL更好,它报告跟踪失败比BOOSTING和MIL更好。* 如果您使用OpenCV 3.1和更高版本,我建议对于大多数应用程序使用这个。*
博主:看到这句话,估计要开始研究KCF算法了。哈哈!
缺点:不能从完全闭塞恢复。 未在OpenCV 3.0中实现。
Bug警告:在OpenCV 3.1(仅限Python)中有一个错误,因为返回了不正确的边界框。 参见错误报告。
优点:在多个帧的遮挡下工作最好。 此外,跟踪最佳的规模变化。
缺点:很多误报,使它几乎不可用。
在我的测试中,我发现这个跟踪器在运动是可预测和小规模的时候效果最好。 与其他跟踪器不同,即使跟踪明显失败,该跟踪器知道跟踪失败的时间。
优点:优秀的跟踪失败报告。 当运动是可预测的并且没有遮挡时工作得很好。
缺点:在大规模运动下失败。
Bug警告:不幸的是,在写这篇文章的时候,在使用Goturn时有一个错误在OpenCV 3.2实现使程序崩溃。
OpenCV 3.0提供4种跟踪器的实现:BOOSTING,MIL,TLD,MEDIANFLOW。
OpenCV 3.1提供5种跟踪器的实现:BOOSTING,MIL,KCF,TLD,MEDIANFLOW
OpenCV 3.2提供6种跟踪器的实现:BOOSTING,MIL,KCF,TLD,MEDIANFLOW,GOTURN
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Ptr tracker = Tracker::create("MIL");
VideoCapture video("videos/chaplin.mp4");
if(!video.isOpened())
{
cout << "could not read video file" << endl;
return 1;
}
Mat frame;
video.read(frame);
Rect2d bbox(287, 23, 86, 320);
tracker->init(frame, bbox);
while(video.read(frame))
{
tracker->update(frame, bbox);
rectangle(frame, bbox, Scalar(255, 0, 0), 2, 1);
imshow("Tracking", frame);
int k = waitKey(1);
if(k==27) break;
}
}
对于vs2013配置opencv3.2的过程,其实网上有很多文章讲解。但是我在编译和配置的过程中,遇到了许多问题。不只是在一片博客中找到答案,而是在多篇博客中找到答案,所以博主还是决定总结一下!这样以后再次遇到这些问题,就不会重复性的劳动了!
注意:网上有许多关于VS2015下配置opencv3.2的方法,使用的是opencv-3.2.0-vc14.exe
,也就是直接是windows版本的安装文件,但是必须是在VS2015以上编译版本才可以使用这种方法,在VS2013的编译环境中使用,我们需要下载opencv3.2的源码,在cmake的帮助下自行编译。博主使用的是VS2013,开始用的opencv3.3.1的版本,编译一直失败,后来查询了一下,可能是版本太高的问题。所以把版本降到opencv3.2。之后,就发现了一大堆的好的教程,我按照别人的教程,编译了一下午,终于配置成功。特此记录一下。
这里提供一下官网的opencv3.2.0的下载地址。
同时,因为要学习使用kcf算法,必须要添加opencv_contrib库。这里注意:opencv_contrib的版本要和下载的opencv的版本匹配。博主最开始使用的是最新版本的opencv_contrib版本,结果在cmake的时候出现了错误,后来才改正过来,感觉把opencv3.2在VS2013下编译的一些坑都踩了。
这里提供一下官网的opencv_contrib3.2.0的下载地址
最后,需要使用cmake来对opencv3.2.0的源码进行编译,所以我们需要下载一个windows版本的cmake。博主使用的cmake版本是cmake-3.6.0-win64-x64.zip。
这里提供一下官网的cmake版本下载地址
博主下载的cmake版本是免安装版本,解压之后,在cmake-3.6.0-win64-x64\bin
下直接双击cmake-gui.exe
即可打开cmake。然后进行cmake,注意就是指定opencv3.2.0的源码目录和build
目录,然后点击configure
,指定如下:
因为博主的windows是64位的,所以选择的VS版本是Visual Studio 12 2013 Win64,而且因为是编译windows平台的opencv库,所以不需要指定编译器,这也是桌面版的优势,以后要在ubuntu下交叉编译opencv3.2.0版本,估计又是一堆坑。
配置成功,如下图所示:
但是配置过程并不是那么顺利的,cmake需要下载各种包来进行安装,尤其是这个ippicv_windows_20151201.zip
,因为这个压缩包移植有错误,所以配置过程一直失败,好在这是个大家都会遇到的问题,大家参考这个网址下载ippicv_windows_20151201.zip
即可。然后把opencv-3.2.0\3rdparty\ippicv\downloads\windows-04e81ce5d0e329c3fbc606ae32cad44d\ippicv_windows_20151201.zip替换掉,然后继续configure
即可通过。
按照上面的方法,直接配置即可通过,但是博主要添加额外的模块opencv_contrib3.2.0,在OPENCV_EXTRA_MODUALS_PATH
选项中添加对应的opencv_contrib3.2.0的modules目录。如下图:
然后,通过CMAKE_INSTALL_PREFIX
设置编译的库的输出目录,比如博主的目录为F:\code\opencv-3.2.0\output
最后,点击add Entry,添加CMAKE_DEBUG_POSTFIX
选项,设置为d
,用于区分debug和release版本,否则编译安装时debug版本会被release版本覆盖。
设置好后,再次点击configure,然后generate。然后就是很长时间的一段编译才成功。
但是,之后,运行程序的时候,会找不到dll文件,比如找不到opencv_core320.dll
等,原因可能是没有在配置选项中勾选BUILD_opencv_world
如果没有勾选BUILD_opencv_world
,将只会生成opencv_world320.dll
。如果没有勾选BUILD_opencv_world
,会生成
opencv_core320.dll
opencv_flann320.dll
opencv_highgui320.dll
opencv_imgcodecs320.dll
…
等一系列的dll及相对应的lib,所以注意不要勾选BUILD_opencv_world
。
在编译成功库之后,在F:\code\opencv-3.2.0\build目录(博主编译库放置的目录)下打开opencv.sln。具体过程参考opencv3.2+opencv_contrib+cmake。
注意:这opencv3.2+opencv_contrib+cmake。这篇博文中提到了我们要设置环境变量的路径。博主因为之前安装的opencv2.4.9版本,设置过环境变量,结果运行opencv3.0的程序出现找不到opencv_flann320.dll
的错误,后来把原来的环境变量删除,然后重新添加了环境变量才成功。
当然,更详细参考【OpenCV3】OpenCV3.2.0在VS2013环境下Cmake编译与快速配置
在运行时出现Win64机器上VS报错“fatal error LNK1112: 模块计算机类型“x64”与目标计算机类型“X86”冲突”的问题,解决方法如下:
Win64机器上VS报错“fatal error LNK1112: 模块计算机类型“x64”与目标计算机类型“X86”冲突”
VS2013下配置opecv3.2.0的过程不算复杂,但是也有许多的坑,对于【OpenCV3】OpenCV3.2.0在VS2013环境下Cmake编译与快速配置中.props类型的文件的配置过程参考VS2013怎么配置opencv才能不用每次都重新配置一遍?。
注意:vs2013中的属性管理器在 菜单栏的视图->其他窗口->属性管理器中
近两年跟踪速度较快的算法小结(转)
对象跟踪小白?本文带你玩转OpenCV(C ++ / Python)
OpenCV编译
【OpenCV3】OpenCV3.2.0在VS2013环境下Cmake编译与快速配置
VS2013怎么配置opencv才能不用每次都重新配置一遍?
追踪算法KCF体验
为什么我的VS2013里找不到属性管理器
opencv3.2.0下载地址
opencv_contrib3.2.0下载地址
cmake版本下载地址
ippicv_windows_20151201.zip下载地址