`
touchmm
  • 浏览: 1038334 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

运动目标跟踪与检测的源代码(CAMSHIFT 算法)

阅读更多

采用 CAMSHIFT 算法快速跟踪和检测运动目标的 C/C++ 源代码,OPENCV BETA 4.0 版本在其 SAMPLE 中给出了这个例子。算法的简单描述如下(英文):

This application demonstrates a fast, simple color tracking algorithm that can be used to track faces, hands . The CAMSHIFT algorithm is a modification of the Meanshift algorithm which is a robust statistical method of finding the mode (top) of a probability distribution. Both CAMSHIFT and Meanshift algorithms exist in the library. While it is a very fast and simple method of tracking, because CAMSHIFT tracks the center and size of the probability distribution of an object, it is only as good as the probability distribution that you produce for the object. Typically the probability distribution is derived from color via a histogram, although it could be produced from correlation, recognition scores or bolstered by frame differencing or motion detection schemes, or joint probabilities of different colors/motions etc.

In this application, we use only the most simplistic approach: A 1-D Hue histogram is sampled from the object in an HSV color space version of the image. To produce the probability image to track, histogram "back projection" (we replace image pixels by their histogram hue value) is used.

算法的详细情况,请看论文:

http://www.assuredigit.com/incoming/camshift.pdf

关于OPENCV B4.0 库的使用方法以及相关问题,请查阅下面的相关文章:

http://forum.assuredigit.com/display_topic_threads.asp?ForumID=11&TopicID=3471

运行文件下载:

http://www.assuredigit.com/product_tech/Demo_Download_files/camshiftdemo.exe

该运行文件在VC6.0环境下编译通过,是一个 stand-alone 运行程序,不需要OPENCV的DLL库支持。在运行之前,请先连接好USB接口的摄像头。然后可以用鼠标选定欲跟踪目标。

=====

#ifdef _CH_
#pragma package <opencv>
#endif

#ifndef _EiC
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <ctype.h>
#endif

IplImage *image = 0, *hsv = 0, *hue = 0, *mask = 0, *backproject = 0, *histimg = 0;
CvHistogram *hist = 0;

int backproject_mode = 0;
int select_object = 0;
int track_object = 0;
int show_hist = 1;
CvPoint origin;
CvRect selection;
CvRect track_window;
CvBox2D track_box; // tracking 返回的区域 box,带角度
CvConnectedComp track_comp;
int hdims = 48; // 划分HIST的个数,越高越精确
float hranges_arr[] = {0,180};
float* hranges = hranges_arr;
int vmin = 10, vmax = 256, smin = 30;

void on_mouse( int event, int x, int y, int flags )
{
if( !image )
return;

if( image->origin )
y = image->height - y;

if( select_object )
{
selection.x = MIN(x,origin.x);
selection.y = MIN(y,origin.y);
selection.width = selection.x + CV_IABS(x - origin.x);
selection.height = selection.y + CV_IABS(y - origin.y);

selection.x = MAX( selection.x, 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;
selection.height -= selection.y;

}

switch( event )
{
case CV_EVENT_LBUTTONDOWN:
origin = cvPoint(x,y);
selection = cvRect(x,y,0,0);
select_object = 1;
break;
case CV_EVENT_LBUTTONUP:
select_object = 0;
if( selection.width > 0 && selection.height > 0 )
track_object = -1;
#ifdef _DEBUG
printf("\n # 鼠标的选择区域:");
printf("\n X = %d, Y = %d, Width = %d, Height = %d",
selection.x, selection.y, selection.width, selection.height);
#endif
break;
}
}


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;

#ifdef _DEBUG
printf("\n # Convert HSV to RGB:");
printf("\n HUE = %f", hue);
printf("\n R = %d, G = %d, B = %d", rgb[0],rgb[1],rgb[2]);
#endif

return cvScalar(rgb[2], rgb[1], rgb[0],0);
}

int main( int argc, char** argv )
{
CvCapture* capture = 0;
IplImage* frame = 0;

if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 );
else if( argc == 2 )
capture = cvCaptureFromAVI( argv[1] );

if( !capture )
{
fprintf(stderr,"Could not initialize capturing...\n");
return -1;
}

printf( "Hot keys: \n"
"\tESC - quit the program\n"
"\tc - stop the tracking\n"
"\tb - switch to/from backprojection view\n"
"\th - show/hide object histogram\n"
"To initialize tracking, select the object with mouse\n" );

//cvNamedWindow( "Histogram", 1 );
cvNamedWindow( "CamShiftDemo", 1 );
cvSetMouseCallback( "CamShiftDemo", on_mouse ); // on_mouse 自定义事件
cvCreateTrackbar( "Vmin", "CamShiftDemo", &vmin, 256, 0 );
cvCreateTrackbar( "Vmax", "CamShiftDemo", &vmax, 256, 0 );
cvCreateTrackbar( "Smin", "CamShiftDemo", &smin, 256, 0 );

for(;;)
{
int i, bin_w, c;

frame = cvQueryFrame( capture );
if( !frame )
break;

if( !image )
{
/* allocate all the buffers */
image = cvCreateImage( cvGetSize(frame), 8, 3 );
image->origin = frame->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 );
hist = cvCreateHist( 1, &hdims, CV_HIST_ARRAY, &hranges, 1 ); // 计算直方图
histimg = cvCreateImage( cvSize(320,200), 8, 3 );
cvZero( histimg );
}

cvCopy( frame, image, 0 );
cvCvtColor( image, hsv, CV_BGR2HSV ); // 彩色空间转换 BGR to HSV

if( track_object )
{
int _vmin = vmin, _vmax = vmax;

cvInRangeS( hsv, cvScalar(0,smin,MIN(_vmin,_vmax),0),
cvScalar(180,256,MAX(_vmin,_vmax),0), mask ); // 得到二值的MASK
cvSplit( hsv, hue, 0, 0, 0 ); // 只提取 HUE 分量

if( track_object < 0 )
{
float max_val = 0.f;
cvSetImageROI( hue, selection ); // 得到选择区域 for ROI
cvSetImageROI( mask, selection ); // 得到选择区域 for mask
cvCalcHist( &hue, hist, 0, mask ); // 计算直方图
cvGetMinMaxHistValue( hist, 0, &max_val, 0, 0 ); // 只找最大值
cvConvertScale( hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0 ); // 缩放 bin 到区间 [0,255]
cvResetImageROI( hue ); // remove ROI
cvResetImageROI( mask );
track_window = selection;
track_object = 1;

cvZero( histimg );
bin_w = histimg->width / hdims; // hdims: 条的个数,则 bin_w 为条的宽度

// 画直方图
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 ); // 使用 back project 方法
cvAnd( backproject, mask, backproject, 0 );

// calling CAMSHIFT 算法模块
cvCamShift( backproject, track_window,
cvTermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ),
&track_comp, &track_box );
track_window = track_comp.rect;

if( backproject_mode )
cvCvtColor( backproject, image, CV_GRAY2BGR ); // 使用backproject灰度图像
if( image->origin )
track_box.angle = -track_box.angle;
cvEllipseBox( image, track_box, CV_RGB(255,0,0), 3, CV_AA, 0 );
}

if( select_object && selection.width > 0 && selection.height > 0 )
{
cvSetImageROI( image, selection );
cvXorS( image, cvScalarAll(255), image, 0 );
cvResetImageROI( image );
}

cvShowImage( "CamShiftDemo", image );
cvShowImage( "Histogram", histimg );

c = cvWaitKey(10);
if( c == 27 )
break; // exit from for-loop
switch( c )
{
case 'b':
backproject_mode ^= 1;
break;
case 'c':
track_object = 0;
cvZero( histimg );
break;
case 'h':
show_hist ^= 1;
if( !show_hist )
cvDestroyWindow( "Histogram" );
else
cvNamedWindow( "Histogram", 1 );
break;
default:
;
}
}

cvReleaseCapture( &capture );
cvDestroyWindow("CamShiftDemo");

return 0;
}

#ifdef _EiC
main(1,"camshiftdemo.c");
#endif

分享到:
评论

相关推荐

    运动目标跟踪程序-MATLAB源代码.rar_matlab目标跟踪_实现目标跟踪_跟踪_运动目标跟踪_运动跟踪

    对于初学者,理解并实现这些源代码可以帮助深入理解运动目标跟踪的基本原理和MATLAB编程。同时,通过调试和优化代码,可以提升解决实际问题的能力,为今后的项目开发打下坚实基础。 总之,这个MATLAB运动目标跟踪...

    改进的camShift目标跟踪算法MFC实现源代码

    "改进的camShift目标跟踪算法MFC实现源代码"是一个基于Microsoft Foundation Classes (MFC)框架的项目,旨在利用优化的背景差分法和帧差法进行运动目标检测,并采用改进的camShift算法实现精准的跟踪。此外,该项目...

    opencv运动目标检测与跟踪源代码运动目标的检测与跟踪 ,有详细源代码。2.rar

    本压缩包“opencv运动目标检测与跟踪源代码运动目标的检测与跟踪,有详细源代码。2.rar”显然包含了一些关于运动目标检测和跟踪的源代码示例,可以帮助开发者深入了解和实践相关技术。 1. 运动目标检测:运动目标...

    opencv运动目标检测与跟踪源代码运动目标的检测与跟踪 ,有详细源代码。1.rar

    在提供的压缩包中,"a.txt"可能包含了OpenCV实现运动目标检测与跟踪的具体源代码。这些代码通常会涉及上述提到的算法,如背景减除、光流计算、跟踪算法等。通过阅读和理解代码,可以学习如何在实际项目中应用这些...

    opencv运动目标检测与跟踪源代码运动目标的检测与跟踪 ,有详细源代码。.rar

    这个压缩包“opencv运动目标检测与跟踪源代码运动目标的检测与跟踪 ,有详细源代码”显然包含了一些示例代码,帮助开发者理解和实现这些功能。 运动目标检测是计算机视觉中的一个核心任务,其目的是在连续的视频帧...

    Camshift算法的源代码

    - 虽然Camshift在处理颜色变化上有优势,但它可能对光照、遮挡和快速运动目标敏感。 - 可以结合其他技术,如卡尔曼滤波器或光流法,提高跟踪的鲁棒性。 - 参数选择也非常重要,合适的窗口大小和颜色空间选择能...

    Camshift Kalman目标跟踪算法

    "camshiftKalman跟踪算法"的实现通常包含C++源代码,可能包括处理视频帧、计算颜色直方图、执行Camshift算法、设置和更新Kalman滤波器状态等功能模块。这些源代码文件可能命名为不同的部分,如图像处理函数、追踪...

    CamShift算法代码

    - **源代码编译**:使用提供的CamShift和MeanShift代码,编译并运行,观察目标跟踪效果。 - **调试与优化**:根据实际需求,调整代码参数,如窗口大小、颜色空间、迭代次数等,以提高跟踪性能。 5. **代码学习与...

    全自动CAMSHIFT算法,meanshift算法的一种

    - HumanMotion.cpp:这是一个包含人体运动相关算法实现的源代码文件。 - ShadowTrack.cpp:此文件可能包含了具体的阴影追踪算法实现,可能与CAMSHIFT或Meanshift追踪技术有关。 - Vector3f.cpp:这个文件可能实现了...

    OPENCV目标跟踪_opencv运动目标检测功能源代码,在vs2010环境中运行_运动目标检测_VC++

    然后,你可以导入提供的源代码,这些代码可能包含了初始化相机、捕获视频帧、应用目标跟踪或运动目标检测算法、并在界面上显示结果的逻辑。 具体到这个项目,你可能会遇到以下步骤: 1. **初始化和捕获视频**:...

    人体运动目标跟踪源代码

    【标题】"人体运动目标跟踪源代码"涉及的是计算机视觉领域的一个重要技术——人体运动跟踪。这项技术在视频监控、虚拟现实、体育分析、人机交互等多个领域有着广泛的应用。OpenCV(开源计算机视觉库)是实现这一功能...

    camshift自动跟踪代码

    在实际应用中,CamShift自动跟踪代码可以广泛应用于各种场景,如监控系统中的目标追踪、体育赛事中的运动员跟踪、无人驾驶车辆的障碍物检测等。用户可以根据自己的需求调整代码,比如改变颜色空间的选择(如RGB、HSV...

    使用Camshift算法做目标跟踪,当目标目标被屏蔽后,用Bp神经网络+卡尔曼联合预测.zip

    然而,当目标被其他物体暂时遮挡时,传统的Camshift算法可能会丢失跟踪,因为遮挡导致的目标色彩信息的缺失。为了解决这个问题,本项目引入了预测机制。 **BP神经网络** 反向传播(Backpropagation, BP)神经网络是一...

    使用Camshift 算法做目标跟踪,当目标被遮挡后,用Bp神经网络+Kalman联合预测 .zip

    1. **初始化**:首先,使用Camshift算法在第一帧中检测到目标并确定其初始模板。 2. **跟踪**:在后续帧中,Camshift会根据上一帧的目标位置和颜色直方图进行追踪。如果目标未被遮挡,这个过程将持续有效。 3. **...

    opencv运动目标检测功能源代码,在vs2010环境中运行.zip

    7. **目标跟踪**:一旦检测到运动目标,可以使用OpenCV中的各种跟踪算法,如卡尔曼滤波器、光流法或CamShift等,对目标进行连续帧间的跟踪。 8. **显示结果**:最后,将原始图像和检测到的运动目标(通常是用彩色...

    实现多人脸跟踪的源代码

    然后,对每个检测到的人脸,独立应用CAMshift算法进行跟踪。为了处理人脸间的重叠和遮挡,可以采用一种称为“互斥区域”的策略,即当一个人脸的预测区域与其他人脸的跟踪结果有重叠时,优先保留跟踪时间更长或置信度...

    CamShift算法解析

    这个文件可能是一个包含了源代码、资源文件和编译设置的项目,可以帮助开发者理解如何在实际C++项目中集成和使用CamShift算法。 通过阅读和分析这些源代码,开发者可以深入理解CamShift的实现细节,例如如何建立...

    camshift跟踪

    这个文件很可能是项目中的源代码文件,可能包含了CamShift算法的实现,包括初始化、图像处理、颜色直方图的计算、Mean Shift迭代以及目标框的更新等关键步骤。通常,这样的项目会包含一个主程序,调用OpenCV的相关...

Global site tag (gtag.js) - Google Analytics