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

相关文章

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

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

Java 方法重载Overload常见误区及注意事项

《Java方法重载Overload常见误区及注意事项》Java方法重载允许同一类中同名方法通过参数类型、数量、顺序差异实现功能扩展,提升代码灵活性,核心条件为参数列表不同,不涉及返回类型、访问修饰符... 目录Java 方法重载(Overload)详解一、方法重载的核心条件二、构成方法重载的具体情况三、不构

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I

Python中反转字符串的常见方法小结

《Python中反转字符串的常见方法小结》在Python中,字符串对象没有内置的反转方法,然而,在实际开发中,我们经常会遇到需要反转字符串的场景,比如处理回文字符串、文本加密等,因此,掌握如何在Pyt... 目录python中反转字符串的方法技术背景实现步骤1. 使用切片2. 使用 reversed() 函

Python中将嵌套列表扁平化的多种实现方法

《Python中将嵌套列表扁平化的多种实现方法》在Python编程中,我们常常会遇到需要将嵌套列表(即列表中包含列表)转换为一个一维的扁平列表的需求,本文将给大家介绍了多种实现这一目标的方法,需要的朋... 目录python中将嵌套列表扁平化的方法技术背景实现步骤1. 使用嵌套列表推导式2. 使用itert

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

在Linux中改变echo输出颜色的实现方法

《在Linux中改变echo输出颜色的实现方法》在Linux系统的命令行环境下,为了使输出信息更加清晰、突出,便于用户快速识别和区分不同类型的信息,常常需要改变echo命令的输出颜色,所以本文给大家介... 目python录在linux中改变echo输出颜色的方法技术背景实现步骤使用ANSI转义码使用tpu

Conda与Python venv虚拟环境的区别与使用方法详解

《Conda与Pythonvenv虚拟环境的区别与使用方法详解》随着Python社区的成长,虚拟环境的概念和技术也在不断发展,:本文主要介绍Conda与Pythonvenv虚拟环境的区别与使用... 目录前言一、Conda 与 python venv 的核心区别1. Conda 的特点2. Python v

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文