C++CamShift跟踪——加载一段视频并跟踪指定区域

描述

有一段视频,通过离线的方式我知道要跟踪的部分在哪里。
可以离线将要跟踪的部分的像素位置,输入到代码中,则播放视频时能够一直跟踪这个物体

代码

// Tracks the selected object using CAMShift algorithm

#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <iostream>
#include <ctype.h>

using namespace cv;
using namespace std;

#define CV_TERMCRIT_EPS 2
#define CV_TERMCRIT_ITER 1  
#define CV_AA 16

Mat image;

bool selectObject = false;
int trackObject = 0;
Point origin;
Rect selection;
int vmin = 10, vmax = 256, smin = 30;

void setTrackArea()
{
    selectObject = true;
    selection = Rect(114, 270, 177, 187);

    // std::cout<<"fa:"<<selection.x<<std::endl;
    // std::cout<<"fa:"<<selection.y<<std::endl;
    // std::cout<<"fa:"<<selection.width<<std::endl;
    // std::cout<<"fa:"<<selection.height<<std::endl;
    trackObject = -1;
}

static void help()
{
    cout << "\nCAMShift based object tracking\n"
    "You select a colored object and the algorithm tracks it.\n"
    "This takes the input from the webcam\n"
    "Usage: \n"
    "$ ./main [camera number]\n";
    
    cout << "\n\nKeyboard input options: \n"
    "\tESC - quit the program\n"
    "\ts - stop the tracking\n"
    "\tp - pause video\n"
    "\nTo start tracking an ostdbject, select the rectangular region around it with the mouse\n\n";
}

int main( int argc, const char** argv )
{
    help();
    
    VideoCapture cap;
    Rect trackWindow;
    int hsize = 16;
    float hranges[] = {0,180};
    const float* phranges = hranges;
    
    int camNum = 0;

    
    cap.open("../1.mp4");
    
    if( !cap.isOpened() )
    {
        help();
        cout << "***Could not initialize capturing...***\n";
        cout << "Current parameter's value: " << camNum << endl;
        return -1;
    }
    
    namedWindow( "CamShift Object Tracker", 0 );
    
    setTrackArea();

    Mat frame, hsv, hue, mask, hist, histimg = Mat::zeros(200, 320, CV_8UC3), backproj;
    bool paused = false;
    
    for(;;)
    {
        if( !paused )
        {
            cap >> frame;
            // std::cout<<frame.cols<<std::endl;544
            // std::cout<<frame.rows<<std::endl;960
            if( frame.empty() )
                break;
        }
        
        frame.copyTo(image);
        
        if( !paused )
        {
            cvtColor(image, hsv, COLOR_BGR2HSV);
            
            if( trackObject )
            {
                int _vmin = vmin, _vmax = vmax;
                
                inRange(hsv, Scalar(0, smin, MIN(_vmin,_vmax)),
                        Scalar(180, 256, MAX(_vmin, _vmax)), mask);
                int ch[] = {0, 0};
                hue.create(hsv.size(), hsv.depth());
                mixChannels(&hsv, 1, &hue, 1, ch, 1);
                
                if( trackObject < 0 )
                {
                    Mat roi(hue, selection), maskroi(mask, selection);
                    calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges);
                    normalize(hist, hist, 0, 255, NORM_MINMAX);
                    
                    trackWindow = selection;
                    trackObject = 1;
                    
                    histimg = Scalar::all(0);
                    int binW = histimg.cols / hsize;
                    Mat buf(1, hsize, CV_8UC3);
                    for( int i = 0; i < hsize; i++ )
                        buf.at<Vec3b>(i) = Vec3b(saturate_cast<uchar>(i*180./hsize), 255, 255);
                    cvtColor(buf, buf, COLOR_HSV2BGR);
                    
                    for( int i = 0; i < hsize; i++ )
                    {
                        int val = saturate_cast<int>(hist.at<float>(i)*histimg.rows/255);
                        rectangle( histimg, Point(i*binW,histimg.rows),
                                  Point((i+1)*binW,histimg.rows - val),
                                  Scalar(buf.at<Vec3b>(i)), -1, 8 );
                    }
                }
                
                calcBackProject(&hue, 1, 0, hist, backproj, &phranges);
                backproj &= mask;
                RotatedRect trackBox = CamShift(backproj, trackWindow,
                                                TermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ));

                int r_;
                if( trackWindow.area() <= 1 )
                {
                    int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5)/6;
                    trackWindow = Rect(trackWindow.x - r, trackWindow.y - r,
                                       trackWindow.x + r, trackWindow.y + r) &
                    Rect(0, 0, cols, rows);
                    r_ = r;
                }
                cv::circle(image, cv::Point2d(trackWindow.x + int(trackWindow.width/2), trackWindow.y + int(trackWindow.height/2)), 1, cv::Scalar(0, 255, 255), 20, 8);

                ellipse( image, trackBox, Scalar(0,0,255), 3, CV_AA );
            }
        }
        else if( trackObject < 0 )
            paused = false;
        
        // std::cout<<selectObject<<std::endl;
        // std::cout<<selection.width<<std::endl;
        // std::cout<<selection.height<<std::endl;
        if( selectObject && selection.width > 0 && selection.height > 0 )
        {
            // Mat roi(image, selection);
            // bitwise_not(roi, roi);
                
                std::string imageName = "../data/template.jpeg"; // 改成你想要的图片
                cv::Mat roi;
                roi = imread( imageName, IMREAD_COLOR ); // Read the file
                bitwise_not(roi, roi);
               
        }
        
        imshow( "CamShift Object Tracker", image );
        
        char c = (char)waitKey(10);
        if( c == 27 )
            break;
        switch(c)
        {
            case 's':
                trackObject = 0;
                histimg = Scalar::all(0);
                break;

            case 'p':
                paused = !paused;
                break;
                
            default:
                ;
        }
    }
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值