同一窗口下基于KCF 目标跟踪和基于模板匹配的目标跟踪效果比较
来源:互联网 发布:当前网络热门话题 编辑:程序博客网 时间:2024/05/22 09:37
参考图像跟踪(四)KCF算法
我们知道KCF 是一个效率和速度都比较好的一种跟踪算法。而模板匹配的目标跟踪是比较笨的一种方式,因此有必要放在一起比比看。代码已经在下面!
大家可以自己去比较!
当然基本条件是要有特殊库,要基于opencv 3.0以上的配置!
实现用鼠标选取一个跟踪区域,然后就有不同颜色的框来指示跟踪效果了。
总得来说,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;bool isKCF = false;void templatematchtracking(Mat frame, Mat &templ, Rect2d &rect);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; Rect2d rect = Rect2d(min(cur_pt.x, pre_pt.x), min(cur_pt.y, pre_pt.y), width, height); rect &= Rect2d(0, 0, org.cols, org.rows); dst = org(rect); // 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.141592653void 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 templRect,kcfRect;// 跟踪结果目标框 Mat templmat; 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) { templRect.x = xMin; templRect.y = yMin; templRect.width = width; templRect.height = height; templRect &= Rect2d(0, 0, org.cols, org.rows); kcfRect = templRect; printf("Initial Box : %f, %f, %f, %f\n", xMin, yMin, width, height); // 使用第一帧和目标框来初始化跟踪器 tracker->init(frame, kcfRect); cvtColor(frame, last_gray, CV_RGB2GRAY); rectangle(frame, kcfRect, Scalar(0, 255, 255), 5, 8); templmat = last_gray(templRect); FIRST = false; } else if (CHOSE && !FIRST) { //double start = clock(); cvtColor(frame, last_gray, CV_RGB2GRAY); //if (isKCF) { // 更新当前帧的结果 tracker->update(frame, kcfRect); } //else { templatematchtracking(frame, templmat, templRect); } sum_error_ncc += mean_error_ncc; err_num++; //double finish = clock(); ////////////////////////////////////////////////////////////////// //printf("TIME : %f ms!\n", (finish - start) * 1000 / CLOCKS_PER_SEC); Scalar color1,color; if (mean_error_ncc < 0.1) { color = Scalar(0, 255, 0, 0); color1 = Scalar(255, 0, 0,0); } else { color = Scalar(0, 0, 255, 0); color1 = Scalar(0, 255, 125, 0); } rectangle(frame, templRect, color, 3, 8); rectangle(frame, kcfRect, color1, 2, 8); float actual_x = 0.0; float actual_y = 0.0; char buff[50] = { '\0' }; adjustPosition((templRect.x + templRect.width / 2), (templRect.y + templRect.height / 2), actual_x, actual_y); sprintf_s(buff, "adjust (x : %.5f, y : %.5f)", actual_x, actual_y); putText(frame, buff, Point(templRect.x, templRect.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;}void templatematchtracking(Mat frame, Mat &templ, Rect2d &rect){ Mat grayFrame; cvtColor(frame, grayFrame, CV_RGB2GRAY);//由于模板匹配只支持单通道,因此需要转为灰度图像 //设置搜索窗口大小,按照移动的速度,设置为原来兴趣窗口的2倍大小,也可以使很大。 Rect2d findRect; findRect.width = min((int)rect.width * 2, frame.cols); findRect.height = min((int)rect.height * 2, frame.rows); findRect.x = rect.x + rect.width * 0.5 - findRect.width * 0.5; findRect.y = rect.y + rect.height * 0.5 - findRect.height * 0.5; findRect &= Rect2d(0, 0, frame.cols, frame.rows); Mat matchResult; matchTemplate(grayFrame(findRect), templ, matchResult, CV_TM_CCOEFF);//使用归一化相关系数匹配法,最强匹配法,值最大表示匹配最好 1表示最好。 double maxVal = 0; Point maxLoc; //筛选出最大匹配点 minMaxLoc(matchResult, 0, &maxVal, 0, &maxLoc); cout << "the maxVal =" << maxVal << endl; //找到下一次模板新的起始点 rect.x = maxLoc.x + findRect.x; rect.y = maxLoc.y + findRect.y; //更新模板,这样表示可能导致当初跟踪的目标会发生变化。 rect &= Rect2d(0, 0, frame.cols, frame.rows); templ = grayFrame(rect);}
阅读全文
0 0
- 同一窗口下基于KCF 目标跟踪和基于模板匹配的目标跟踪效果比较
- 基于模板匹配的运动目标跟踪
- [opencv]模板匹配算法(单图像模板匹配和基于模板匹配的目标跟踪)
- [opencv]模板匹配算法(单图像模板匹配和基于模板匹配的目标跟踪)
- 目标跟踪算法----KCF进阶(基于KCF改进的算法总结)
- 目标跟踪算法----KCF进阶(基于KCF改进的算法总结)
- 目标跟踪:模板匹配
- 目标跟踪:KCF
- 基于特征点匹配的自适应目标跟踪算法
- 最简单的目标跟踪-模板匹配跟踪
- KCF目标跟踪算法笔记
- KCF目标跟踪算法学习
- KCF目标跟踪算法介绍
- 基于核函数的目标跟踪算法(下)
- 基于meanshift的单目标跟踪方法
- 基于mean-shift的简单目标跟踪
- 基于SVM与Meanshift的目标跟踪
- 基于MeanShift的目标跟踪算法
- 开篇
- redis 集群搭建
- 关于 String对象 常量池 字符串常量
- C++ 动态捕获整型数列
- ubutu tomcat 启用80端口步骤
- 同一窗口下基于KCF 目标跟踪和基于模板匹配的目标跟踪效果比较
- 使用jQuery库出错:index.jsp:16 Uncaught ReferenceError: $ is not defined
- 函数中返回字符串的方法
- Linux:使用xargs为其他命令提供参数
- iOS OC内存分析优化~笔记
- Iput设备使用分析--2(应用层面)
- 189. Rotate Array
- C#基础-016 循环
- 邻接表的创建