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

2024-02-24 09:20

本文主要是介绍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 }

转载于:https://www.cnblogs.com/moondark/archive/2012/07/08/2582013.html

这篇关于CV编程常用的获取鼠标圈定区域的方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/741649

相关文章

nginx负载均衡及详细配置方法

《nginx负载均衡及详细配置方法》Nginx作为一种高效的Web服务器和反向代理服务器,广泛应用于网站的负载均衡中,:本文主要介绍nginx负载均衡及详细配置,需要的朋友可以参考下... 目录一、 nginx负载均衡策略1.1 基本负载均衡策略1.2 第三方策略1.3 策略对比二、 nginx配置2.1

Java调用Python的四种方法小结

《Java调用Python的四种方法小结》在现代开发中,结合不同编程语言的优势往往能达到事半功倍的效果,本文将详细介绍四种在Java中调用Python的方法,并推荐一种最常用且实用的方法,希望对大家有... 目录一、在Java类中直接执行python语句二、在Java中直接调用Python脚本三、使用Run

Java根据IP地址实现归属地获取

《Java根据IP地址实现归属地获取》Ip2region是一个离线IP地址定位库和IP定位数据管理框架,这篇文章主要为大家详细介绍了Java如何使用Ip2region实现根据IP地址获取归属地,感兴趣... 目录一、使用Ip2region离线获取1、Ip2region简介2、导包3、下编程载xdb文件4、J

Android 12解决push framework.jar无法开机的方法小结

《Android12解决pushframework.jar无法开机的方法小结》:本文主要介绍在Android12中解决pushframework.jar无法开机的方法,包括编译指令、框架层和s... 目录1. android 编译指令1.1 framework层的编译指令1.2 替换framework.ja

在.NET平台使用C#为PDF添加各种类型的表单域的方法

《在.NET平台使用C#为PDF添加各种类型的表单域的方法》在日常办公系统开发中,涉及PDF处理相关的开发时,生成可填写的PDF表单是一种常见需求,与静态PDF不同,带有**表单域的文档支持用户直接在... 目录引言使用 PdfTextBoxField 添加文本输入域使用 PdfComboBoxField

SQLyog中DELIMITER执行存储过程时出现前置缩进问题的解决方法

《SQLyog中DELIMITER执行存储过程时出现前置缩进问题的解决方法》在SQLyog中执行存储过程时出现的前置缩进问题,实际上反映了SQLyog对SQL语句解析的一个特殊行为,本文给大家介绍了详... 目录问题根源正确写法示例永久解决方案为什么命令行不受影响?最佳实践建议问题根源SQLyog的语句分

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

判断PyTorch是GPU版还是CPU版的方法小结

《判断PyTorch是GPU版还是CPU版的方法小结》PyTorch作为当前最流行的深度学习框架之一,支持在CPU和GPU(NVIDIACUDA)上运行,所以对于深度学习开发者来说,正确识别PyTor... 目录前言为什么需要区分GPU和CPU版本?性能差异硬件要求如何检查PyTorch版本?方法1:使用命