利用OpenCV实现——目标跟踪方法(一)

目标跟踪一直是热门话题,对于实时帧跟踪首先要判断有无运动目标。

最简单的目标跟踪是首先处理视频(摄像头)帧,然后灰度化,二值化,包括滤波处理(Gaussian),模糊处理(blur),二值化处理等等得到前景和背景分离的动态目标。

有一个简单示例见链接链接,得到目标的相关信息。

本文介绍第一种目标跟踪方法!

可以处理视频文件 或者 摄像头实时采集 的背景分割图像。具体系列前景背景分离方法将在后文中详述。

本文方法核心是模板匹配

先上代码:

/*
 * Developer : Prakriti Chintalapoodi - c.prakriti@gmail.com 
*/

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

#define MAX_FEATURES 400

using namespace cv;
using namespace std;

#define NUM_FRAMES_TO_PROCESS  600

// Global Variables
Mat frame1, img_object;
Point pt1, pt2;
bool roi_capture = false;
bool got_roi = false;

// Function Headers
void mouse_click(int event, int x, int y, int flags, void *param);
void findObject(Mat& frame, Mat& img_object);

int main(int argc, char* argv[])
{
    /*
	if (argc != 2)
    {
        cout << "Usage: ./ObjectTracker <Input Video file>" << endl;
        return -1;
    }
	*/
    VideoCapture inputVideo("./test_videos//football.avi");
    if (!inputVideo.isOpened())
    {
        cout << "Error opening Input Video " << argv[1] << endl;
        return -1;
    }

    double fps = inputVideo.get(CV_CAP_PROP_FPS);
    int delay = 1000/fps;    // time in ms between successive frames = 1000/fps
    cout << "FPS = " << fps << endl;
    cout << "Number of frames = " << static_cast<int>(inputVideo.get(CV_CAP_PROP_FRAME_COUNT)) << endl;

    inputVideo >> frame1;     // read first frame only
    if(!frame1.empty())
    {
        // Collect the ROI of the object, store it in img_object
        cout << "Click and drag to select the object to detect" << endl;
        namedWindow("Frame 1: Capture ROI", 1);
        moveWindow("Frame 1: Capture ROI", 600, 300);
        imshow("Frame 1: Capture ROI", frame1);
        setMouseCallback("Frame 1: Capture ROI", mouse_click, 0);

        waitKey(0);

        // close the window after ROI is saved
        destroyWindow("Frame 1: Capture ROI");
        destroyWindow("ROI");
    }

    Mat frame;
    bool stop(false);
    int frameNum = 0;

    // Set position in video back to beginning
    inputVideo.set(CV_CAP_PROP_POS_FRAMES, 0);

    // Process every frame of video only when object ROI has been selected
    if (!img_object.empty())
    {
        namedWindow("Input Video");
        moveWindow("Input Video", 600, 300);

        while(!stop)
        {
            inputVideo >> frame;            // read current frame
            if( frame.empty()) break;       // check if at end
            frameNum++;
            imshow("Input Video", frame);

            // Find the object in current frame, draw a rectangle around it
            findObject(frame, img_object);

            if (inputVideo.get(CV_CAP_PROP_POS_FRAMES) == NUM_FRAMES_TO_PROCESS)
            {
                cout << "\nDone" << endl;
                break;
            }
            // introduce delay or press key to stop
            if (waitKey(delay) >= 0)
                stop = true;
        }
    }

    waitKey(0);
    return 0;
}


// Records mouseclick events to get x-y coordinates of ROI
// Store coordinates in global variables pt1, pt2.
void mouse_click(int event, int x, int y, int flags, void *param)
{
    switch(event)
    {
    case CV_EVENT_LBUTTONDOWN:
    {
        cout << "Mouse Left Button Pressed" << endl;
        if (!roi_capture)
        {
            pt1.x = x;
            pt1.y = y;
        }
        else
        {
            cout << "ROI already acquired" << endl;
        }
        break;
    }
    case CV_EVENT_LBUTTONUP:
    {
        if (!got_roi)
        {
            cout << "Mouse Left Button released" << endl;
            pt2.x = x;
            pt2.y = y;

            Mat roi(frame1, Rect(pt1, pt2));
            roi.copyTo(img_object);
            cout << "ROI acquired" << endl;
            namedWindow("ROI", 1);
            moveWindow("ROI", 1000, 300);
            imshow("ROI", roi);
            got_roi = true;
            cout << "Press any key to close ROI windows and start detecting object in video" << endl;
        }
        else
        {
            cout << "ROI already acquired" << endl;
        }
        break;
    }
    }
}

// Function to perform template matching and track the object in the video
void findObject(Mat& frame, Mat& img_object)
{
    // Source image to display
    Mat img_display;
    frame.copyTo(img_display);

    // Create the result matrix
    Mat result;
    int result_cols =  frame.cols - img_object.cols + 1;
    int result_rows = frame.rows - img_object.rows + 1;
    result.create(result_cols, result_rows, CV_32FC1);

    // Do the Template Matching and Normalize
    // Matching method choices are:
    // CV_TM_SQDIFF, CV_TM_SQDIFF_NORMED, CV_TM_CCORR, CV_TM_CCORR_NORMED, CV_TM_CCOEFF, CV_TM_CCOEFF_NORMED
    int match_method = CV_TM_SQDIFF_NORMED;
    matchTemplate( frame, img_object, result, match_method );
    normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );

    // Localizing the best match with minMaxLoc
    double minVal; double maxVal;
    Point minLoc; Point maxLoc; Point matchLoc;
    minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());

    /// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better
    if( match_method  == TM_SQDIFF || match_method == TM_SQDIFF_NORMED )
    { matchLoc = minLoc; }
    else
    { matchLoc = maxLoc; }

    // Draw a rectangle around the found object
    rectangle(img_display, matchLoc, Point(matchLoc.x + img_object.cols , matchLoc.y + img_object.rows), Scalar(255,0,0), 2, 8, 0 );
    namedWindow("Object Tracking", 1);
    moveWindow("Object Tracking", 1000, 300);
    imshow("Object Tracking", img_display);
}

源代码测试下载链接 如下

  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值