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

相关文章

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

MySQL字符串常用函数详解

《MySQL字符串常用函数详解》本文给大家介绍MySQL字符串常用函数,本文结合实例代码给大家介绍的非常详细,对大家学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql字符串常用函数一、获取二、大小写转换三、拼接四、截取五、比较、反转、替换六、去空白、填充MySQL字符串常用函数一、

Java中Arrays类和Collections类常用方法示例详解

《Java中Arrays类和Collections类常用方法示例详解》本文总结了Java中Arrays和Collections类的常用方法,涵盖数组填充、排序、搜索、复制、列表转换等操作,帮助开发者高... 目录Arrays.fill()相关用法Arrays.toString()Arrays.sort()A

Nginx安全防护的多种方法

《Nginx安全防护的多种方法》在生产环境中,需要隐藏Nginx的版本号,以避免泄漏Nginx的版本,使攻击者不能针对特定版本进行攻击,下面就来介绍一下Nginx安全防护的方法,感兴趣的可以了解一下... 目录核心安全配置1.编译安装 Nginx2.隐藏版本号3.限制危险请求方法4.请求限制(CC攻击防御)

python生成随机唯一id的几种实现方法

《python生成随机唯一id的几种实现方法》在Python中生成随机唯一ID有多种方法,根据不同的需求场景可以选择最适合的方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习... 目录方法 1:使用 UUID 模块(推荐)方法 2:使用 Secrets 模块(安全敏感场景)方法

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

JAVA中安装多个JDK的方法

《JAVA中安装多个JDK的方法》文章介绍了在Windows系统上安装多个JDK版本的方法,包括下载、安装路径修改、环境变量配置(JAVA_HOME和Path),并说明如何通过调整JAVA_HOME在... 首先去oracle官网下载好两个版本不同的jdk(需要登录Oracle账号,没有可以免费注册)下载完

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu