直接上代码,在上一篇的基础上,编了个KCF 跟踪测试程序
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <math.h>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
//#include "kcftracker.hpp"
#include <opencv2/tracking.hpp>
using namespace std;
using namespace cv;
cv::Mat org, dst, img, tmp;
float xMin = 0.0;
float yMin = 0.0;
float width = 0.0;
float height = 0.0;
bool CHOSE = false;
bool STATE_1 = false;
bool STATE_2 = false;
bool STATE_3 = false;
void on_mouse(int event, int x, int y, int flags, void *ustc)//event
{
static Point pre_pt(-1, -1);
static Point cur_pt(-1, -1);
char temp[16];
if (event == CV_EVENT_LBUTTONDOWN)
{
// 使用四个顶点计算出目标框
org.copyTo(img);
sprintf_s(temp, "(%d,%d)", x, y);
pre_pt = Point(x, y);
xMin = x;
yMin = y;
putText(img, temp, pre_pt, FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0, 255), 1, 8);
circle(img, pre_pt, 2, Scalar(255, 0, 0, 0), CV_FILLED, CV_AA, 0);
imshow("img", img);
}
else if (event == CV_EVENT_MOUSEMOVE && !(flags & CV_EVENT_FLAG_LBUTTON))
{
img.copyTo(tmp);
sprintf_s(temp, "(%d,%d)", x, y);
cur_pt = Point(x, y);
putText(tmp, temp, cur_pt, FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0, 255));
imshow("img", tmp);
STATE_2 = true;
}
else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))
{
img.copyTo(tmp);
sprintf_s(temp, "(%d,%d)", x, y);
cur_pt = Point(x, y);
putText(tmp, temp, cur_pt, FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0, 255));
rectangle(tmp, pre_pt, cur_pt, Scalar(0, 255, 0, 0), 5, 8, 0);
imshow("img", tmp);
}
else if (event == CV_EVENT_LBUTTONUP)//
{
org.copyTo(img);
sprintf_s(temp, "(%d,%d)", x, y);
cur_pt = Point(x, y);
putText(img, temp, cur_pt, FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0, 255));
circle(img, pre_pt, 2, Scalar(255, 0, 0, 0), CV_FILLED, CV_AA, 0);
rectangle(img, pre_pt, cur_pt, Scalar(0, 255, 0, 0), 1, 8, 0);//
imshow("img", img);
img.copyTo(tmp);
//
width = abs(pre_pt.x - cur_pt.x);
height = abs(pre_pt.y - cur_pt.y);
if (width == 0 || height == 0)
{
printf("width == 0 || height == 0");
return;
}
CHOSE = true;
dst = org(Rect(min(cur_pt.x, pre_pt.x), min(cur_pt.y, pre_pt.y), width, height));
// namedWindow("dst");
// imshow("dst",dst);
// waitKey(0);
STATE_3 = STATE_1 = STATE_2 = false;
}
}
#define HEIGHT 0.97
#define THETA 60
#define FOCUS 1100
#define PI 3.141592653
void adjustPosition(float x, float y, float &actual_x, float &actual_y) {
float move_pixel_x = x - (xMin + width / 2);
float move_pixel_y = y - (yMin + height / 2);
float S = HEIGHT / cos(THETA*PI / 180);
float DX = (S*move_pixel_x) / FOCUS;
float DY = (S*move_pixel_y) / FOCUS;
actual_x = DX;
actual_y = DY / cos(THETA*PI / 180);
}
int main()
{
// save_dir的路径,用于读取图像
string save_dir = "d:\1.jpg";
VideoCapture cap(0);
if (!cap.isOpened())
{
return -1;
}
// 当前帧
Mat frame;
Mat last_gray;
Mat first;
Mat cur_gray;
bool HOG = true;// 是否使用hog特征
bool FIXEDWINDOW = false;// 是否使用修正窗口
bool MULTISCALE = true;// 是否使用多尺度
bool SILENT = false;// 是否不做显示
bool LAB = false;// 是否使用LAB颜色
float sum_error_ncc = 0.0;
int err_num = 0;
float mean_error_ncc = 0.0;
bool LOST = false;
// 创建KCF跟踪器
// KCFTracker tracker(HOG, FIXEDWINDOW, MULTISCALE, LAB);
// KCFTracker tracker_redetect(HOG, FIXEDWINDOW, MULTISCALE, LAB);
// create the tracker
Ptr<Tracker> tracker = Tracker::create("KCF");
Rect2d result;// 跟踪结果目标框
bool stop = false;
bool FIRST = true;
int nFramesNochose = 0;
int nFrames = 0;// 帧号计数
while (!stop)
{
cap >> frame;//获取图像
org = frame;//?
org.copyTo(img);
org.copyTo(tmp);
if (!CHOSE) {
namedWindow("img");
imshow("img", frame);
setMouseCallback("img", on_mouse, 0);
}
if (CHOSE && FIRST)
{
result.x = xMin;
result.y = yMin;
result.width = width;
result.height = height;
printf("Initial Box : %f, %f, %f, %f\n", xMin, yMin, width, height);
// 使用第一帧和目标框来初始化跟踪器
tracker->init( frame, result);
cvtColor(frame, last_gray, CV_RGB2GRAY);
rectangle(frame, result, Scalar(0, 255, 255), 5, 8);
FIRST = false;
}
else if (CHOSE && !FIRST)
{
//double start = clock();
cvtColor(frame, last_gray, CV_RGB2GRAY);
// 更新当前帧的结果
tracker->update(frame,result);
sum_error_ncc += mean_error_ncc;
err_num++;
//double finish = clock();
//
//printf("TIME : %f ms!\n", (finish - start) * 1000 / CLOCKS_PER_SEC);
Scalar color;
if (mean_error_ncc<0.1)
color = Scalar(0, 255, 0, 0);
else
color = Scalar(0, 0, 255, 0);
rectangle(frame, result, color, 5, 8);
float actual_x = 0.0;
float actual_y = 0.0;
char buff[50] = { '\0' };
adjustPosition((result.x + result.width / 2), (result.y + result.height / 2), actual_x, actual_y);
sprintf_s(buff, "adjust (x : %.5f, y : %.5f)", actual_x, actual_y);
putText(frame, buff, Point(result.x, result.y - 20), FONT_HERSHEY_SIMPLEX, 0.5, color);
}
if (CHOSE && !FIRST) {
cvDestroyWindow("img");
namedWindow("tracking");//
imshow("tracking", frame);
}
else
imshow("img", frame);
if (waitKey(1) == 27)
break;
if (CHOSE)
nFrames++;
}
return 0;
}