zoukankan      html  css  js  c++  java
  • Opencv CamShift+Kalman目标跟踪

    #include "stdio.h"
    #include "string.h"
    #include "iostream"
    
    #include "opencv/cv.h"
    #include "opencv/cxcore.h"
    #include "opencv/cvaux.h"
    #include "opencv/highgui.h"
    #include "opencv/ml.h"
    #include "opencv2/core/core.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/video/video.hpp"
    #include "opencv2/videostab/videostab.hpp"
    #include "opencv2/stitching/stitcher.hpp"
    
    #include "opencv2/contrib/contrib.hpp"
    #include "opencv2/objdetect/objdetect.hpp"
    
    
    #pragma comment(lib,"opencv_calib3d2410d.lib")
    #pragma comment(lib,"opencv_contrib2410d.lib")
    #pragma comment(lib,"opencv_core2410d.lib")
    #pragma comment(lib,"opencv_features2d2410d.lib")
    #pragma comment(lib,"opencv_highgui2410d.lib")
    #pragma comment(lib,"opencv_imgproc2410d.lib")
    #pragma comment(lib,"opencv_objdetect2410d.lib")
    #pragma comment(lib,"opencv_video2410d.lib")
    #pragma comment(lib,"opencv_flann2410d.lib")
    #pragma comment(lib,"opencv_gpu2410d.lib")
    #pragma comment(lib,"opencv_legacy2410d.lib")
    #pragma comment(lib,"opencv_ml2410d.lib")
    #pragma comment(lib,"opencv_nonfree2410d.lib")
    #pragma comment(lib,"opencv_ocl2410d.lib")
    #pragma comment(lib,"opencv_photo2410d.lib")
    #pragma comment(lib,"opencv_stitching2410d.lib")
    #pragma comment(lib,"opencv_superres2410d.lib")
    #pragma comment(lib,"opencv_ts2410d.lib")
    #pragma comment(lib,"opencv_stitching2410d.lib")
    
    
    IplImage *image = 0, *hsv = 0, *hue = 0, *mask = 0, *backproject = 0, *histimg = 0;
    CvHistogram *hist = 0;
    
    int select_object = 0;     //select_object = 0,還沒圈選物件  1,已圈選
    int track_object = 0;      //1代表開始tracking, 0代表無追縱物件, -1代表初始化 先建model
    
    CvPoint origin;            //取得滑鼠座標所在位置
    CvRect selection;          //取得選擇ROI的資訊
    CvRect track_window;
    CvConnectedComp track_comp;
    
    int hdims = 30;                        //histo要分幾維
    float hranges_arr[] = { 0, 180 };         //hue只有0~180而已
    float* hranges = hranges_arr;
    
    bool g_bIsFinished = true;
    
    
    // OpenCV 滑鼠觸發後的回呼函式
    void on_mouse(int event, int x, int y, int flags, void* param)  //x-軸  往右為正  最左為0,   y-軸  往下為正  最上為0
    {
        if (!image)  //至少要有image才能點滑鼠指標  才能產生下面的ROI 不然跳出
            return;
    
        if (image->origin)                //如果image->origin為1代表該圖以左下為原點 0則是以左上為原點  
            y = image->height - y;         //1則把y值倒置 從下往上是正值  變成左下為0  match原圖座標軸
    
        if (select_object)                //一開始select_object為0  所以進不來  但是只要一押了滑鼠鍵  就進得來了  代表開始選roi
        {
            selection.x = MIN(x, origin.x);         //滑鼠按下去後  左上角的值隨時在變  所以一直update  取最左的x
            selection.y = MIN(y, origin.y);
            selection.width = selection.x + CV_IABS(x - origin.x);    //OFFSET加X Y的長度,不能超過整個視窗大小
            selection.height = selection.y + CV_IABS(y - origin.y);   //CV_IAB取絕對值  代表  整個視窗佔整個window的位置
    
            selection.x = MAX(selection.x, 0);       //X Y OFFSET至少要大於0  如果滑鼠拖超過視窗外  則設為0
            selection.y = MAX(selection.y, 0);
            selection.width = MIN(selection.width, image->width);       //如果寬或長大過視窗  則先取視窗長度
            selection.height = MIN(selection.height, image->height);    //最大也不會超過視窗大小
    
            selection.width -= selection.x;     //上面所取的視窗長度扣掉OFFSET  不怕滑鼠拖移到視窗外
            selection.height -= selection.y;
        }
    
        switch (event)
        {
        case CV_EVENT_LBUTTONDOWN:
        {
                                     origin = cvPoint(x, y);
                                     selection = cvRect(x, y, 0, 0);     //按鍵一押下去  初始化  先得到roi的初始點(但有可能是roi四個角的其中一個點)
                                     select_object = 1;               //一旦押了滑鼠鍵  就等於開始選物件
                                     break;
        }
        case CV_EVENT_LBUTTONUP:
        {
                                   select_object = 0;              //一旦放了滑鼠鍵  物件選完
                                   if (selection.width > 0 && selection.height > 0)
                                       track_object = -1;          //有了roi了  可以開始進行tracking的工具了
    
                                   break;
        }
        }
    }
    
    
    //把原hue轉成RGB
    CvScalar hsv2rgb(float hue)
    {
        int rgb[3], p, sector;
        static const int sector_data[][3] =
        { { 0, 2, 1 }, { 1, 2, 0 }, { 1, 0, 2 }, { 2, 0, 1 }, { 2, 1, 0 }, { 0, 1, 2 } };
        hue *= 0.033333333333333333333333333333333f;
        sector = cvFloor(hue);
        p = cvRound(255 * (hue - sector));
        p ^= sector & 1 ? 255 : 0;
    
        rgb[sector_data[sector][0]] = 255;
        rgb[sector_data[sector][1]] = 0;
        rgb[sector_data[sector][2]] = p;
    
        return cvScalar(rgb[2], rgb[1], rgb[0], 0);
    }
    
    // 開始播放影像
    void PlayVideo()
    {
        CvCapture* capture = 0;
    
        //capture = cvCaptureFromAVI("1.avi");
        capture = cvCreateCameraCapture(0);
        if (!capture)
        {
            fprintf(stderr, "Could not initialize capturing...
    ");
            return;
        }
    
        cvNamedWindow("Tracking Demo", 1);
        cvNamedWindow("Histogram", 1);
        cvNamedWindow("Back Project", 1);
    
        cvSetMouseCallback("Tracking Demo", (CvMouseCallback)on_mouse);
    
        for (;;)
        {
            IplImage* frame = 0;
            int i, bin_w, c;
    
            frame = cvQueryFrame(capture);
            if (!frame)
            {  // 影片播放結束
                g_bIsFinished = true;
                break;
            }
    
            if (!image)
            {
            
                image = cvCreateImage(cvGetSize(frame), 8, 3);
                image->origin = frame->origin; //如果不加這一行的話  下面copy動作完之後,image->origin會從尾巴開始算  整張影像會倒過來
    
                hsv = cvCreateImage(cvGetSize(frame), 8, 3);
                hue = cvCreateImage(cvGetSize(frame), 8, 1);
                mask = cvCreateImage(cvGetSize(frame), 8, 1);
    
                backproject = cvCreateImage(cvGetSize(frame), 8, 1);
                backproject->origin = frame->origin;
    
                hist = cvCreateHist(1, &hdims, CV_HIST_ARRAY, &hranges, 1);
                histimg = cvCreateImage(cvGetSize(frame), 8, 3);
                cvZero(histimg);
            }
    
            cvCopy(frame, image, 0);
            cvCvtColor(image, hsv, CV_BGR2HSV);
    
            if (track_object)
            {
                cvInRangeS(hsv, cvScalar(0, 0, 0, 0), cvScalar(180, 255, 255, 0), mask);
                cvSplit(hsv, hue, 0, 0, 0);
    
                if (track_object < 0)
                {
                    float max_val = 0.f;
                    cvSetImageROI(hue, selection);
                    cvSetImageROI(mask, selection);
                    cvCalcHist(&hue, hist, 0, mask);
                    cvGetMinMaxHistValue(hist, 0, &max_val, 0, 0);
                    cvConvertScale(hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0);
                    cvResetImageROI(hue);
                    cvResetImageROI(mask);
                    track_window = selection;
                    track_object = 1;    //此值等於1代表model建好  可以追縱了
    
                    //下面為   建立histogram image
                    cvZero(histimg);
                    bin_w = histimg->width / hdims;
                    for (i = 0; i < hdims; i++)
                    {
                        int val = cvRound(cvGetReal1D(hist->bins, i)*histimg->height / 255);
                        CvScalar color = hsv2rgb(i*180.f / hdims);
                        cvRectangle(histimg, cvPoint(i*bin_w, histimg->height),
                            cvPoint((i + 1)*bin_w, histimg->height - val),
                            color, -1, 8, 0);
                    }
                }
    
                cvCalcBackProject(&hue, backproject, hist);
                cvAnd(backproject, mask, backproject, 0);
    
                cvMeanShift(backproject, track_window,
                    cvTermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1),
                    &track_comp);
    
                track_window = track_comp.rect;
    
                CvScalar cc;
                cc = cvScalar(255, 0, 0);
    
                cvRectangle(image, cvPoint(track_window.x, track_window.y),
                    cvPoint(track_window.x + track_window.width, track_window.y + track_window.height),
                    cc, 2, 8, 0);
            }
    
            if (select_object && selection.width > 0 && selection.height > 0)
            {
                cvSetImageROI(image, selection);
                cvXorS(image, cvScalarAll(255), image, 0);
                cvResetImageROI(image);
            }
    
            cvShowImage("Tracking Demo", image);
            cvShowImage("Histogram", histimg);
            cvShowImage("Back Project", backproject);
    
            c = cvWaitKey(150);
            if (c == 27)   // ESC鍵,跳出程式
                break;
    
        }
    
        cvReleaseCapture(&capture);
    
        cvDestroyWindow("Back Project");
        cvDestroyWindow("Histogram");
        cvDestroyWindow("Tracking Demo");
    }
    
    int main()
    {
        while (g_bIsFinished)
        {
            g_bIsFinished = false;
            PlayVideo();
        }
    
        return 0;
    }

  • 相关阅读:
    Hanoi塔
    采药
    进制转换(大数)
    Load Balancing with NGINX 负载均衡算法
    upstream模块实现反向代理的功能
    epoll
    在nginx启动后,如果我们要操作nginx,要怎么做呢 别增加无谓的上下文切换 异步非阻塞的方式来处理请求 worker的个数为cpu的核数 红黑树
    粘性会话 session affinity sticky session requests from the same client to be passed to the same server in a group of servers
    负载均衡 4层协议 7层协议
    A Secure Cookie Protocol 安全cookie协议 配置服务器Cookie
  • 原文地址:https://www.cnblogs.com/mypsq/p/5089163.html
Copyright © 2011-2022 走看看