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...\n");
        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;
}

时间: 2024-10-08 12:21:13

Opencv CamShift+Kalman目标跟踪的相关文章

目标跟踪学习笔记_1(opencv中meanshift和camshift例子的应用)

在这一节中,主要讲目标跟踪的一个重要的算法Camshift,因为它是连续自使用的meanShift,所以这2个函数opencv中都有,且都很重要.为了让大家先达到一个感性认识.这节主要是看懂和运行opencv中给的sample并稍加修改. Camshift函数的原型为:RotatedRect CamShift(InputArray probImage, Rect& window, TermCriteria criteria). 其中probImage为输入图像直方图的反向投影图,window为要

目标跟踪之粒子滤波---Opencv实现粒子滤波算法

目标跟踪学习笔记_2(particle filter初探1) 目标跟踪学习笔记_3(particle filter初探2) 前面2篇博客已经提到当粒子数增加时会内存报错,后面又仔细查了下程序,是代码方面的问题.所以本次的代码与前几次改变比较小.当然这些code基本也是参考网上的.代码写得很不规范,时间不够,等以后有机会将其优化并整理成类的形式.)              Opencv实现粒子滤波算法            摘要 本文通过opencv实现了一种目标跟踪算法——粒子滤波算法,算法的

目标跟踪--CamShift

转载请注明出处! !! http://blog.csdn.net/zhonghuan1992 目标跟踪--CamShift CamShift全称是ContinuouslyAdaptive Mean Shift,即连续自适应的MeanShift算法.而MeanShift算法,首先得对MeanShift算法有个初步的了解,可以參考这里.而CamShift是在MeanShift的基础上,依据上一帧的结果.来调整下一帧的中心位置和窗体大小,所以.当跟踪的目标在视频中发生变化时,可以对这个变化有一定的调整

目标跟踪之camshift---opencv中meanshift和camshift例子的应用

在这一节中,主要讲目标跟踪的一个重要的算法Camshift,因为它是连续自使用的meanShift,所以这2个函数opencv中都有,且都很重要.为了让大家先达到一个感性认识.这节主要是看懂和运行opencv中给的sample并稍加修改. Camshift函数的原型为:RotatedRect CamShift(InputArray probImage, Rect& window, TermCriteria criteria). 其中probImage为输入图像直方图的反向投影图,window为要

OpenCv目标跟踪_cvGoodFeaturesToTrack()寻找角点

在OpenCv中提供了两种实现目标跟踪的关键算法,LK算法和HS算法,也就是通常所说的稀疏光流和稠密光流. 寻找角点 角点,其实也就是一幅图像中,容易被跟踪的特征点,通常来说,这个点在两个正交方向上都有明显的倒数,该点在图像中我们认为是独一无二的. 从直观上讲,角点是一类有足够信息并且能够从当前帧和下一帧都能提取出来的点. 关于角点的定义,是由Harris提出的,其基础是图像灰度强度的二阶导数矩阵 .该定义的角点位于图像二阶导数的自相关矩阵中有两个最大特征值的地方,这本质上表示以此点为中心周围存

opencv学习之基于背景提取等目标跟踪算法#20190704

/* *********************************************************************************************************************** 任务目标: 基于背景提取的目标跟踪算法实践及代码分析. ***************************************************************************************************

目标跟踪

目标跟踪过程分为2部分,即目标特征提取和目标跟踪算法. 其中目标特征提取又包括以下几种: 1. 各种色彩空间直方图,利用色彩空间的直方图分布作为目标跟踪的特征,可以减少物体远近距离的影响,因为其颜色分布大致相同. 2.轮廓特征,提取目标的轮廓特征,可以加快算法的速度,且可以在目标有小部分影响的情况下同样有效果. 3. 纹理特征,如果被跟踪目标是有纹理的,则根据其纹理特征来跟踪效果会有所改善. 目标跟踪算法目前大概分为以下4种: 1. 基于meanshift算法,即利用meanshift算法可以快

目标跟踪学习笔记1

首先提供几篇关于粒子滤波算法的博客:http://www.cnblogs.com/yangyangcv/archive/2010/05/23/1742263.html 这篇博客比较通俗易懂,简单的介绍了粒子滤波的基本工作思想和步骤.http://www.cnblogs.com/lwbaptx/archive/2011/10/20/2218419.html这篇博客用的是opencv1.0,实现的功能是用粒子滤波跟踪鼠标轨迹,有视频演示,效果还不错.http://blog.csdn.net/yang

(转) 深度学习在目标跟踪中的应用

深度学习在目标跟踪中的应用 原创 2016-09-05 徐霞清 深度学习大讲堂 点击上方“深度学习大讲堂”可订阅哦!深度学习大讲堂是高质量原创内容的平台,邀请学术界.工业界一线专家撰稿,致力于推送人工智能与深度学习最新技术.产品和活动信息! 开始本文之前,我们首先看上方给出的3张图片,它们分别是同一个视频的第1,40,80帧.在第1帧给出一个跑步者的边框(bounding-box)之后,后续的第40帧,80帧,bounding-box依然准确圈出了同一个跑步者.以上展示的其实就是目标跟踪(vis