首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Camshift算法原理及其Opencv实现(2)

Camshift算法原理及其Opencv实现(2)

  • int main( int argc, char** argv )  
  • {  
  •     CvCapture* capture = 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 )  
  •         //打开avi
  •         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, 0 );  
  •     //设置鼠标回调函数
  •     cvCreateTrackbar( "Vmin", "CamShiftDemo", &vmin, 256, 0 );  
  •     cvCreateTrackbar( "Vmax", "CamShiftDemo", &vmax, 256, 0 );  
  •     cvCreateTrackbar( "Smin", "CamShiftDemo", &smin, 256, 0 );  
  •     //设置滑动条

  •     for(;;)  
  •     //进入视频帧处理主循环
  •     {  
  •         IplImage* frame = 0;  
  •         int i, bin_w, c;  

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

  •         if( !image )  
  •         //image为0,表明刚开始还未对image操作过,先建立一些缓冲区
  •         {  
  •             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 );  
  •         //把图像从RGB表色系转为HSV表色系

  •         if( track_object )  
  •         //track_object非零,表示有需要跟踪的物体
  •         {  
  •             int _vmin = vmin, _vmax = vmax;  

  •             cvInRangeS( hsv, cvScalar(0,smin,MIN(_vmin,_vmax),0),  
  •                         cvScalar(180,256,MAX(_vmin,_vmax),0), mask );  
  •             //制作掩膜板,只处理像素值为H:0~180,S:smin~256,V:vmin~vmax之间的部分
  •             cvSplit( hsv, hue, 0, 0, 0 );  
  •             //分离H分量

  •             if( track_object < 0 )  
  •             //如果需要跟踪的物体还没有进行属性提取,则进行选取框类的图像属性提取
  •             {  
  •                 float max_val = 0.f;  
  •                 cvSetImageROI( hue, selection );  
  •                 //设置原选择框为ROI
  •                 cvSetImageROI( mask, selection );  
  •                 //设置掩膜板选择框为ROI
  •                 cvCalcHist( &hue, hist, 0, mask );  
  •                 //得到选择框内且满足掩膜板内的直方图
  •                 cvGetMinMaxHistValue( hist, 0, &max_val, 0, 0 );  
  •                 cvConvertScale( hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0 );  
  •                 // 对直方图的数值转为0~255
  •                 cvResetImageROI( hue );  
  •                 //去除ROI
  •                 cvResetImageROI( mask );  
  •                 //去除ROI
  •                 track_window = selection;  
  •                 track_object = 1;  
  •                 //置track_object为1,表明属性提取完成
  •                 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 );  
  •             //计算hue的反向投影图
  •             cvAnd( backproject, mask, backproject, 0 );  
  •             //得到掩膜内的反向投影
  •             cvCamShift( backproject, track_window,  
  •                         cvTermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ),  
  •                         &track_comp, &track_box );  
  •             //使用MeanShift算法对backproject中的内容进行搜索,返回跟踪结果
  •             track_window = track_comp.rect;  
  •             //得到跟踪结果的矩形框

  •             if( backproject_mode )  
  •                 cvCvtColor( backproject, image, CV_GRAY2BGR );  

  •             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( (char) c == 27 )  
  •             break;  
  •         switch( (char) 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
继承事业,薪火相传
返回列表