• CV编程常用的获取鼠标圈定区域的方法


      在CV里面,很多时候需要自己手动截出一块区域,然后针对这块区域进行处理,OpenCV并没有提供直接可调用的函数,如果每次都要自己写的话,估计写获取鼠标圈定区域就需要花很有一段时间~

      近来是在做视频跟踪这一块,有的跟踪是基于检测的跟踪,则不需要手动圈定,但很多时候,为了能直接看到跟踪的效果,则采取手动圈定的方式,如下图所示:

      我在看粒子滤波源码的时候发现了其鼠标圈定函数写的已经比较好调用,后来再看到meanshift跟踪,发现所用获取鼠标圈定函数一样的,所以我将其收集下来,以备后用,唔,接下来就是贴代码,这上面有部分我自己的代码……

      若能看懂其鼠标圈定函数,则对自己以后写此函数很有裨益,注释就不写那么多了,整体也比较容易吧:

      1 #include <cv.h>
      2 #include <highgui.h>
      3 
    //-------------- 控制获取区域个数 4 const int MAX_OBJECTS = 1; 5
      //-------- 对参数封装 cvSetMouseCallback 所需参数
      6 typedef struct params {
      7   CvPoint loc1[MAX_OBJECTS];
      8   CvPoint loc2[MAX_OBJECTS];
      9   IplImage* objects[MAX_OBJECTS];
     10   char* win_name;
     11   IplImage* orig_img;
     12   IplImage* cur_img;
     13   int n;
     14 } params;
     15 
     16 int GetRegions( IplImage*, CvRect** );
     17 void mouse( int, int, int, int, void* );
     18 
     19 int main(void)
     20 {
     21     IplImage *frame, *frame_copy;
     22     CvCapture *video;
     23     CvScalar color;
     24     CvRect* regions;
     25 
     26     char *video_file = "E:\\Coding\\acivs\\1.AVI";
     27 
     28     video = cvCaptureFromFile( video_file );
     29     if(!video)
     30     {
     31         printf("Cannot open the video file!!!");
     32         return -1;
     33     }
     34 
     35     int frmNo = 0, nObjects = 0;
     36     while( frame = cvQueryFrame( video ) )
     37     {
     38         frame_copy = cvCloneImage( frame );
     39         if(frmNo == 0)
     40         {
     41             printf("Please select a region to track !");
     42             while( nObjects == 0 )
     43             {
     44                 nObjects = GetRegions( frame, &regions );
     45                 if( nObjects == 0 )
     46                     printf( "Please select a object\n" );
     47             }
     48         }
     49         else
     50         {
     51             printf("This is the %d st frame\n", frmNo);
     52 
     53         }
     54         frmNo++;
     55         cvReleaseImage(&frame_copy);
     56     }
     57 
     58     cvReleaseCapture( &video );
     59     return 0;
     60 }
     61 //-------- 获取的区域 regions
     62 int GetRegions( IplImage* frame, CvRect** regions )
     63 {
     64   char* win_name = "First frame";
     65   params p;
     66   CvRect* r;
     67   int i, x1, y1, x2, y2, w, h;
     68   
     69   /* use mouse callback to allow user to define object regions */
     70   p.win_name = win_name;
     71   p.orig_img = cvCloneImage( frame );
     72   p.cur_img = NULL;
     73   p.n = 0;
     74   cvNamedWindow( win_name, 1 );
     75   cvShowImage( win_name, frame );
     76   cvSetMouseCallback( win_name, &mouse, &p );
     77   cvWaitKey( 0 );
     78   cvDestroyWindow( win_name );
     79   cvReleaseImage( &(p.orig_img) );
     80   if( p.cur_img )
     81     cvReleaseImage( &(p.cur_img) );
     82 
     83   /* extract regions defined by user; store as an array of rectangles */
     84   if( p.n == 0 )
     85     {
     86       *regions = NULL;
     87       return 0;
     88     }
     89   r = (CvRect *)malloc( p.n * sizeof( CvRect ) );
     90   for( i = 0; i < p.n; i++ )
     91     {
     92       x1 = MIN( p.loc1[i].x, p.loc2[i].x );
     93       x2 = MAX( p.loc1[i].x, p.loc2[i].x );
     94       y1 = MIN( p.loc1[i].y, p.loc2[i].y );
     95       y2 = MAX( p.loc1[i].y, p.loc2[i].y );
     96       w = x2 - x1;
     97       h = y2 - y1;
     98 
     99       /* ensure odd width and height */
    100       w = ( w % 2 )? w : w+1;
    101       h = ( h % 2 )? h : h+1;
    102       r[i] = cvRect( x1, y1, w, h );
    103     }
    104   *regions = r;
    105   return p.n;
    106 }
    107 
    108 void mouse( int event, int x, int y, int flags, void* param )
    109 {
    110   params* p = (params*)param;
    111   CvPoint* loc;
    112   int n;
    113   IplImage* tmp;
    114   static int pressed = FALSE;
    115   
    116   /* on left button press, remember first corner of rectangle around object */
    117   if( event == CV_EVENT_LBUTTONDOWN )
    118     {
    119       n = p->n;
    120       if( n == MAX_OBJECTS )
    121     return;
    122       loc = p->loc1;
    123       loc[n].x = x;
    124       loc[n].y = y;
    125       pressed = TRUE;
    126     }
    127 
    128   /* on left button up, finalize the rectangle and draw it in black */
    129   else if( event == CV_EVENT_LBUTTONUP )
    130     {
    131       n = p->n;
    132       if( n == MAX_OBJECTS )
    133     return;
    134       loc = p->loc2;
    135       loc[n].x = x;
    136       loc[n].y = y;
    137       cvReleaseImage( &(p->cur_img) );
    138       p->cur_img = NULL;
    139       cvRectangle( p->orig_img, p->loc1[n], loc[n], CV_RGB(0,0,0), 1, 8, 0 );
    140       cvShowImage( p->win_name, p->orig_img );
    141       pressed = FALSE;
    142       p->n++;
    143     }
    144 
    145   /* on mouse move with left button down, draw rectangle as defined in white */
    146   else if( event == CV_EVENT_MOUSEMOVE  &&  flags & CV_EVENT_FLAG_LBUTTON )
    147     {
    148       n = p->n;
    149       if( n == MAX_OBJECTS )
    150     return;
    151       tmp = cvCloneImage( p->orig_img );
    152       loc = p->loc1;
    153       cvRectangle( tmp, loc[n], cvPoint(x, y), CV_RGB(255,255,255), 1, 8, 0 );
    154       cvShowImage( p->win_name, tmp );
    155       if( p->cur_img )
    156     cvReleaseImage( &(p->cur_img) );
    157       p->cur_img = tmp;
    158     }
    159 }
  • 相关阅读:
    5G 时代,云计算迎来新风口
    阿里云VS腾讯云 谁才是中国未来的云计算之王?
    IaaS,PaaS,SaaS 的区别
    财经天下周刊:中国云计算——马化腾的救命稻草 任正非的“下个荣耀”
    HDOJ-1671 Phone List
    【转】Java进阶之路
    Delphi XE2 之 FireMonkey 入门(30)
    Delphi XE2 之 FireMonkey 入门(29)
    Delphi XE2 之 FireMonkey 入门(28)
    Delphi XE2 之 FireMonkey 入门(27)
  • 原文地址:https://www.cnblogs.com/moondark/p/2582013.html
Copyright © 2020-2023  润新知