目标跟踪:KCF
环境:Ubuntu16.04
下载原版的KCFcpp.master,可以去github上下,然后更改源文件;也可以去我的资源里下:https://download.csdn.net/download/weixin_44264994/12228741
更改runtracker.cpp源文件:
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "kcftracker.hpp"
#include <dirent.h>
using namespace std;
using namespace cv;
// 当前帧
Mat frame;
//初始帧框选目标时候用来显示用的Mat对象
Mat backup;
// Tracker results 跟踪目标的结果框
Rect result;
//函数声明
void on_mouse(int event, int x, int y, int flags, void* );
//初始帧用来框选目标的两个点
cv::Point Point1;
cv::Point Point2;
//初始帧框选目标时判断是第几个点
int counter = 1;
int main(int argc, char* argv[]){
if (argc > 5) return -1;
bool HOG = true; // 是否使用hog特征
bool FIXEDWINDOW = false; // 是否使用修正窗口
bool MULTISCALE = true; // 是否使用多尺度
bool SILENT = true; // 是否不做显示
bool LAB = false; // 是否使用LAB颜色
//不同位置的参数代表的含义
for(int i = 0; i < argc; i++){
if ( strcmp (argv[i], "hog") == 0 )
HOG = true;
if ( strcmp (argv[i], "fixed_window") == 0 )
FIXEDWINDOW = true;
if ( strcmp (argv[i], "singlescale") == 0 )
MULTISCALE = false;
if ( strcmp (argv[i], "show") == 0 )
SILENT = false;
if ( strcmp (argv[i], "lab") == 0 ){
LAB = true;
HOG = true;
}
if ( strcmp (argv[i], "gray") == 0 )
HOG = false;
}
//使用setMouseCallback函数,首先要有一个窗口和名字
cv::namedWindow("Camera", cv::WINDOW_NORMAL);
//用来显示帧号的一些设置
int text_offset = 50;
cv::Point origin(text_offset, text_offset);
int fontFace = cv::FONT_HERSHEY_COMPLEX;
double fontScale = 0.7;
cv::Scalar color(255, 0, 0);
int thickness = 1;
cv::LineTypes lineType = cv::LINE_AA;
bool bottomLeftOrigin = false;
// Create KCFTracker object
KCFTracker tracker(HOG, FIXEDWINDOW, MULTISCALE, LAB);
// Write Results
ofstream resultsFile;
string resultsPath = "output.txt";
resultsFile.open(resultsPath);
// Frame counter
int nFrames = 0;
//open camera, 0表示使用的是笔记本电脑自带的摄像头,如果是外接的摄像头一般要改成1
VideoCapture cam(0);
if ( !cam.isOpened())
return -1;
while(true)
{
cam>> frame;
if(frame.empty())
break;
putText(frame, to_string(nFrames), origin, fontFace, fontScale, color, thickness, lineType, bottomLeftOrigin);
// First frame, 框选目标并初始化tracker
if (nFrames == 0) {
imshow("Camera", frame);
frame.copyTo(backup);
cv::setMouseCallback("Camera", on_mouse);
waitKey(0);
tracker.init(Rect(Point1.x, Point1.y, Point2.x - Point1.x, Point2.y - Point1.y), frame);
rectangle(frame, Point1, Point2, Scalar(0, 255, 255), 2, 8);
resultsFile << Point1.x << "," << Point1.y << "," << Point2.x - Point1.x << "," << Point2.y - Point1.y << endl;
}
// Update
else{
cout << "nFrames: " << nFrames << endl;
result = tracker.update(frame);
rectangle( frame, Point( result.x, result.y ), Point( result.x+result.width, result.y+result.height), Scalar( 0, 255, 255 ), 2, 8 );
resultsFile << result.x << "," << result.y << "," << result.width << "," << result.height << endl;
}
nFrames++;
imshow("Camera", frame);
if( waitKey(10)== ' ' )
break;
}
cam.release();
resultsFile.close();
return 0;
}
//每点击两个点之后,把两个点组成的矩形框的四个点的坐标显示出来
void on_mouse(int event, int x, int y, int flags, void*){
if (event == cv::EVENT_LBUTTONDOWN){
if (counter == 2){
Point2.x = x;
Point2.y = y;
cout << "leftTop, rightTop, leftBottom, rightBottom: "
<< Point1.x << "," << Point1.y << ","
<< Point2.x << "," << Point1.y << ","
<< Point1.x << "," << Point2.y << ","
<< Point2.x << "," << Point2.y << endl << endl;
cv::Point leftTopCorner;
cv::Point rightBottomCorner;
leftTopCorner.x = min(Point1.x, Point2.x);
leftTopCorner.y = min(Point1.y, Point2.y);
rightBottomCorner.x = max(Point1.x, Point2.x);
rightBottomCorner.y = max(Point1.y, Point2.y);
cv::rectangle(frame, leftTopCorner, rightBottomCorner, cv::Scalar(0, 255, 0), 1, cv::LINE_AA, 0);
Point1 = leftTopCorner;
Point2 = rightBottomCorner;
cv::imshow("Camera", frame);
backup.copyTo(frame);
counter =1;
return;
}
else if (counter == 1) {
Point1.x = x;
Point1.y = y;
cv::drawMarker(frame, Point1, cv::Scalar(0, 255, 0), cv::MARKER_CROSS, 10, 1, cv::LINE_AA);
cv::imshow("Camera", frame);
backup.copyTo(frame);
counter++;
cout << "You've selected one point, now select the second! " << endl;
}
}
}
生成:
cd build
cmake ..
make
然后运行./KCF就可以了,初始打开摄像头后手动选择跟踪目标,左上角和右下角两个坐标点,回车开始跟踪,空格退出
跟踪效果:
重定位不太行