Opencv CamShift+Kalman目标跟踪

时间:2022-09-14 14:20:49
#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 = , *hsv = , *hue = , *mask = , *backproject = , *histimg = ;
CvHistogram *hist = ; int select_object = ; //select_object = 0,還沒圈選物件 1,已圈選
int track_object = ; //1代表開始tracking, 0代表無追縱物件, -1代表初始化 先建model CvPoint origin; //取得滑鼠座標所在位置
CvRect selection; //取得選擇ROI的資訊
CvRect track_window;
CvConnectedComp track_comp; int hdims = ; //histo要分幾維
float hranges_arr[] = { , }; //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, ); //X Y OFFSET至少要大於0 如果滑鼠拖超過視窗外 則設為0
selection.y = MAX(selection.y, );
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, , ); //按鍵一押下去 初始化 先得到roi的初始點(但有可能是roi四個角的其中一個點)
select_object = ; //一旦押了滑鼠鍵 就等於開始選物件
break;
}
case CV_EVENT_LBUTTONUP:
{
select_object = ; //一旦放了滑鼠鍵 物件選完
if (selection.width > && selection.height > )
track_object = -; //有了roi了 可以開始進行tracking的工具了 break;
}
}
} //把原hue轉成RGB
CvScalar hsv2rgb(float hue)
{
int rgb[], p, sector;
static const int sector_data[][] =
{ { , , }, { , , }, { , , }, { , , }, { , , }, { , , } };
hue *= 0.033333333333333333333333333333333f;
sector = cvFloor(hue);
p = cvRound( * (hue - sector));
p ^= sector & ? : ; rgb[sector_data[sector][]] = ;
rgb[sector_data[sector][]] = ;
rgb[sector_data[sector][]] = p; return cvScalar(rgb[], rgb[], rgb[], );
} // 開始播放影像
void PlayVideo()
{
CvCapture* capture = ; //capture = cvCaptureFromAVI("1.avi");
capture = cvCreateCameraCapture();
if (!capture)
{
fprintf(stderr, "Could not initialize capturing...\n");
return;
} cvNamedWindow("Tracking Demo", );
cvNamedWindow("Histogram", );
cvNamedWindow("Back Project", ); cvSetMouseCallback("Tracking Demo", (CvMouseCallback)on_mouse); for (;;)
{
IplImage* frame = ;
int i, bin_w, c; frame = cvQueryFrame(capture);
if (!frame)
{ // 影片播放結束
g_bIsFinished = true;
break;
} if (!image)
{ image = cvCreateImage(cvGetSize(frame), , );
image->origin = frame->origin; //如果不加這一行的話 下面copy動作完之後,image->origin會從尾巴開始算 整張影像會倒過來 hsv = cvCreateImage(cvGetSize(frame), , );
hue = cvCreateImage(cvGetSize(frame), , );
mask = cvCreateImage(cvGetSize(frame), , ); backproject = cvCreateImage(cvGetSize(frame), , );
backproject->origin = frame->origin; hist = cvCreateHist(, &hdims, CV_HIST_ARRAY, &hranges, );
histimg = cvCreateImage(cvGetSize(frame), , );
cvZero(histimg);
} cvCopy(frame, image, );
cvCvtColor(image, hsv, CV_BGR2HSV); if (track_object)
{
cvInRangeS(hsv, cvScalar(, , , ), cvScalar(, , , ), mask);
cvSplit(hsv, hue, , , ); if (track_object < )
{
float max_val = .f;
cvSetImageROI(hue, selection);
cvSetImageROI(mask, selection);
cvCalcHist(&hue, hist, , mask);
cvGetMinMaxHistValue(hist, , &max_val, , );
cvConvertScale(hist->bins, hist->bins, max_val ? . / max_val : ., );
cvResetImageROI(hue);
cvResetImageROI(mask);
track_window = selection;
track_object = ; //此值等於1代表model建好 可以追縱了 //下面為 建立histogram image
cvZero(histimg);
bin_w = histimg->width / hdims;
for (i = ; i < hdims; i++)
{
int val = cvRound(cvGetReal1D(hist->bins, i)*histimg->height / );
CvScalar color = hsv2rgb(i*.f / hdims);
cvRectangle(histimg, cvPoint(i*bin_w, histimg->height),
cvPoint((i + )*bin_w, histimg->height - val),
color, -, , );
}
} cvCalcBackProject(&hue, backproject, hist);
cvAnd(backproject, mask, backproject, ); cvMeanShift(backproject, track_window,
cvTermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, , ),
&track_comp); track_window = track_comp.rect; CvScalar cc;
cc = cvScalar(, , ); cvRectangle(image, cvPoint(track_window.x, track_window.y),
cvPoint(track_window.x + track_window.width, track_window.y + track_window.height),
cc, , , );
} if (select_object && selection.width > && selection.height > )
{
cvSetImageROI(image, selection);
cvXorS(image, cvScalarAll(), image, );
cvResetImageROI(image);
} cvShowImage("Tracking Demo", image);
cvShowImage("Histogram", histimg);
cvShowImage("Back Project", backproject); c = cvWaitKey();
if (c == ) // ESC鍵,跳出程式
break; } cvReleaseCapture(&capture); cvDestroyWindow("Back Project");
cvDestroyWindow("Histogram");
cvDestroyWindow("Tracking Demo");
} int main()
{
while (g_bIsFinished)
{
g_bIsFinished = false;
PlayVideo();
} return ;
}

Opencv CamShift+Kalman目标跟踪Opencv CamShift+Kalman目标跟踪

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

  1. Python Opencv-contrib Camshift&amp&semi;kalman卡尔曼滤波&amp&semi;CSRT算法 目标跟踪实现

    本次课题实现目标跟踪一共用到了三个算法,分别是Camshift.Kalman.CSRT,基于Python语言的Tkinter模块实现GUI与接口设计,项目一共包含三个文件: main.py: # co ...

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

    目标跟踪学习笔记_2(particle filter初探1) 目标跟踪学习笔记_3(particle filter初探2) 前面2篇博客已经提到当粒子数增加时会内存报错,后面又仔细查了下程序,是代码方 ...

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

    在这一节中,主要讲目标跟踪的一个重要的算法Camshift,因为它是连续自使用的meanShift,所以这2个函数opencv中都有,且都很重要.为了让大家先达到一个感性认识.这节主要是看懂和运行op ...

  4. 目标跟踪--CamShift

    转载请注明出处! !! http://blog.csdn.net/zhonghuan1992 目标跟踪--CamShift CamShift全称是ContinuouslyAdaptive Mean S ...

  5. Video Target Tracking Based on Online Learning—深度学习在目标跟踪中的应用

    摘要 近年来,深度学习方法在物体跟踪领域有不少成功应用,并逐渐在性能上超越传统方法.本文先对现有基于深度学习的目标跟踪算法进行了分类梳理,后续会分篇对各个算法进行详细描述. 看上方给出的3张图片,它们 ...

  6. TLD目标跟踪算法

    1. 简介 TLD目标跟踪算法是Tracking-Learning-Detection算法的简称.这个视频跟踪算法框架由英国萨里大学的一个捷克籍博士生Zdenek Kalal提出.TLD将传统的视频跟 ...

  7. 目标跟踪之Lukas-Kanade光流法

    转载自:http://blog.csdn.net/u014568921/article/details/46638557 光流是图像亮度的运动信息描述.光流法计算最初是由Horn和Schunck于19 ...

  8. Video Target Tracking Based on Online Learning—TLD单目标跟踪算法详解

    视频目标跟踪问题分析         视频跟踪技术的主要目的是从复杂多变的的背景环境中准确提取相关的目标特征,准确地识别出跟踪目标,并且对目标的位置和姿态等信息精确地定位,为后续目标物体行为分析提供足 ...

  9. 目标跟踪之Lukas-Kanade光流法(转)

    光流是图像亮度的运动信息描述.光流法计算最初是由Horn和Schunck于1981年提出的,创造性地将二维速度场与灰度相联系,引入光流约束方程,得到光流计算的基本算法.光流计算基于物体移动的光学特性提 ...

随机推荐

  1. Android 捕获异常并在应用崩溃后重启应用

    问题概述: 在Android应用开发中,偶尔会因为测试的不充分导致一些异常没有被捕获,这时应用会出现异常并强制关闭,这样会导致很不好的用户体验,为了解决这个问题,我们需要捕获相关的异常并做处理. 首先 ...

  2. ubuntu14&period;04美化

    首先我美化grub启动菜单背景和开关机背景,还有自动换壁纸.其它的美化日后再写博文. Grub启动菜单背景更换: 这个很简单,比以前的ubuntu和grub版本简单多了,直接将图片文件放到/boot/ ...

  3. 第27章 项目8:使用XML-RPC进行文件共享

    1.问题 创建一个简单的P2P文件共享程序. P2P文件共享程序是在不同计算机上的程序交换文件.P2P交互内,任何节点(peer)都可以是链接到其他节点.在这样一个由节点组成的虚拟网络中,是没有*节 ...

  4. java执行windows 的cmd 命令

    //获取运行时 Runtime rt = Runtime.getRuntime(); //获取进程 Process p = rt.exec(String[] cmdarray);     或者   P ...

  5. onclick传对象

    用onclick传对象的时候,用jquery无法进行操作 onclick=(this) 接收到参数后只需要转化一下 console.log($(obj).html());

  6. 如何在线显示php源代码

    通过php提供的函数highlight_file和highlight_string实现

  7. Abandoned country&lpar;最小生成树&plus;树形DP&rpar;

    #include<bits/stdc++.h> using namespace std; struct node{ int u, v, w, nex; bool gone; node(){ ...

  8. Vivado安装教程

    Vivado的各个版本的安流程其实都差不多,本教程用Vivado2016.4为例进行安装,同样适用于之前和之后的各个版本. 下载好安装包后打开,双击xsetup.exe运行安装程序 弹出的窗口,提示现 ...

  9. 32位 64位 获得进程peb的方法

    基于上一篇文章,大概了解了peb的获取方法,但是那个方法只能获得当前进程的PEB,不能获得其他的进程的PEB.根据那个思想,获得其他进程PEB则需要注入,得到进程信息,然后进程间通信,将信息返回来,经 ...

  10. jave获取音频时长

    本文转载自:http://blog.csdn.net/ntotl/article/details/50419983 下载 jave-1.0.2.jar File source =new File('d ...