OpenCV的KCF调用,网上已有好多,我接触KCF时,希望利用OpenCV搭建一个KCF示例程序,但从网上粘过来的代码运行时总是报错,“Ptr<Tracker> tracker = Tracker::create();" 这句在编译是出现Tracker中没有create成员”,当时很纳闷,具体的参考的代码如下:
#include <opencv2/core/utility.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <cstring>
using namespace std;
using namespace cv;
int main() {
// declares all required variables
//! [vars]
Rect2d roi;
Mat frame;
//! [vars]
// create a tracker object
Ptr<Tracker> tracker = Tracker::create("KCF"); //在我的OpenCV3.3.0中运行报错找不到成员函数
//! [create]
// set input video
//! [setvideo]
std::string video = "E:\\demo1.avi";
VideoCapture cap(video);
//! [setvideo]
// get bounding box
//! [getframe]
cap >> frame;
//! [getframe]
//! [selectroi]选择目标roi以GUI的形式
roi = selectROI("tracker", frame);
//! [selectroi]
//quit if ROI was not selected
if (roi.width == 0 || roi.height == 0)
return 0;
// initialize the tracker
//! [init]
tracker->init(frame, roi);
//! [init]
// perform the tracking process
printf("Start the tracking process\n");
for (;; ) {
// get frame from the video
cap >> frame;
// stop the program if no more images
if (frame.rows == 0 || frame.cols == 0)
break;
// update the tracking result
//! [update]
tracker->update(frame, roi);
//! [update]
//! [visualization]
// draw the tracked object
rectangle(frame, roi, Scalar(255, 0, 0), 2, 1);
// show image with the tracked object
imshow("tracker", frame);
//! [visualization]
//quit on ESC button
if (waitKey(1) == 27)
break;
}
return 0;
}
最后点开OpenCV库源码,发现现在已经没有tracker 这个类了,而是TrackerKCF类了,调用KCF算法的初始化应该使用:Ptr<TrackerKCF> tracker = TrackerKCF::create();
网上查了一下,Ptr是个Ptr模板类啥的没太明白,参考:
https://www.jianshu.com/p/0642948df118
https://www.cnblogs.com/liu-jun/archive/2013/03/24/2979648.html
反正大致就是这样搞是为了安全和泛型编程,以前调用fast角点检测也遇到这个Ptr ,好像比较新版的OpenCV好些地方都采样了这种方式。
因此高版本的OpenCV中调用KCF的完整代码如下:
#include <opencv2/core/utility.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <cstring>
using namespace std;
using namespace cv;
int main()
{
Rect2d roi;
Mat frame;
Ptr<TrackerKCF> tracker = TrackerKCF::create();//高版本一般是这样创建KCF的
string video = ".\KCFTestData\NBA.mov"; //视频流
// VideoCapture cap(0);//启用摄像头
VideoCapture cap(video);
if (!cap.isOpened())
{
return 0;
}
cout << "press c to leap current Image" << endl;
cout << "press q to slect current Image" << endl;
cout << "press empty key to start track RIO Object" << endl;
cap >> frame;
while (1)
{
char key = waitKey(1);
if (key == 'c') // 按c键跳帧
{
cap >> frame;
}
if (key == 'q') // 按q键退出跳帧
{
break;
}
imshow("first", frame);
}
cv::destroyWindow("first");
roi = selectROI("tracker", frame);
if (roi.width == 0 || roi.height == 0)
return 0;
tracker->init(frame, roi);
// perform the tracking process
printf("Start the tracking process\n");
for (;; )
{
// get frame from the video
cap >> frame;
// stop the program if no more images
if (frame.rows == 0 || frame.cols == 0) {
cv::destroyWindow("tracker");
break;
}
// update the tracking result
tracker->update(frame, roi);
// draw the tracked object
rectangle(frame, roi, Scalar(255, 0, 0), 2, 1);
// show image with the tracked object
imshow("tracker", frame);
//quit on ESC button
if (char(waitKey(1)) == 'q') {
cv::destroyWindow("tracker");
break;
}
}
return 0;
}
至此就完成了KCF的调用,最后说一句,在库配置正确的前提下,当运行OpenCV程序出错了,很大可能是你没有按照它约定的用法书写程序,此时你可以去看看OpenCV库的函数源码,一般浏览一下类下有没有这个成员函数和成员变量,函数的参数个数对吧等,这样也许就找到问题了。