同一窗口下基于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);}
原创粉丝点击