MFC与opencv的cvSetMouseCallback用起来感觉很不兼容。

大部分时候,用cvSetMouseCallback也许只是为了获取一个矩形框,或者绘制一个点,或者其它什么简易的图形,通过调用该函数来得到鼠标交互的参数信息。

然而,这么一个简单的要求,在MFC框架中并不是很方便调用。

通过阅读 opencv 官方提供的samples源码,其中在grabcut上面有个GCApplication类,用来控制或者获取绘制信息,我觉得很方便,将其精简一下,如下:

#define GC_BGD 0
#define GC_FGD 1
#define GC_PR_BGD 2
#define GC_PR_FGD 3 const Scalar GREEN = Scalar(0,255,0); class GCApp
{
public:
enum{ NOT_SET = 0, IN_PROCESS = 1, SET = 2 }; public:
void mouseClick( int event, int x, int y, int flags, void* param );
void setImageAndWinName( const Mat& _image, const string& _winName);
void reset();
void showImage() const; public:
Rect rect;
uchar rectState;
const Mat* image;
Mat mask;
const string* winName;
}; void GCApp::reset()
{
if( !mask.empty() )
mask.setTo(Scalar::all(GC_BGD));
rectState = NOT_SET;
} void GCApp::setImageAndWinName( const Mat& _image, const string& _winName )
{
if( _image.empty() || _winName.empty() )
return;
image = &_image;
winName = &_winName;
mask.create( image->size(), CV_8UC1);
reset();
} void GCApp::showImage() const
{
if( image->empty() || winName->empty() )
return; Mat res;
image->copyTo( res ); if( rectState == IN_PROCESS || rectState == SET )
rectangle( res, Point( rect.x, rect.y ), Point(rect.x + rect.width, rect.y + rect.height ), GREEN, 2); imshow( *winName, res );
} void GCApp::mouseClick( int event, int x, int y, int flags, void* )
{
switch( event )
{
case CV_EVENT_LBUTTONDOWN: // set rect or GC_BGD(GC_FGD) labels
{
if( rectState == NOT_SET )
{
rectState = IN_PROCESS;
rect = Rect( x, y, 1, 1 );
}
showImage();
}
break;
case CV_EVENT_MOUSEMOVE:
if( rectState == IN_PROCESS )
{
rect = Rect( Point(rect.x, rect.y), Point(x,y) );
showImage();
}
break;
case CV_EVENT_LBUTTONUP:
if( rectState == IN_PROCESS )
{
rect = Rect( Point(rect.x, rect.y), Point(x,y) );
rectState = SET;
showImage();
}
break;
} }

由于cvSetMouseCallback需要回调on_mouse函数,声明一个on_mouse函数,注意,得是 static void

GCApp gcapp;
static void on_mouse( int event, int x, int y, int flags, void* param )
{
gcapp.mouseClick( event, x, y, flags, param );
}

然后,在需要的地方,加上如下的代码,即完成了对鼠标绘制信息的获取,在这里,是针对矩形绘制的获取:

        const string winName = "DrawRegion";
cvNamedWindow( winName.c_str(), CV_WINDOW_AUTOSIZE );
cvSetMouseCallback( winName.c_str(), on_mouse, 0 );
gcapp.setImageAndWinName( img, winName );
gcapp.showImage();
for (;;)
{
int c = cvWaitKey(0);
////// ESC 键 结束
if (char(c) == '\x1b' && gcapp.rectState == gcapp.SET)
{
break;
}
}
Rect rect = gcapp.rect;

如何优雅的在MFC中使用cvSetMouseCallback?的更多相关文章

  1. MFC中使用FLASH

    一.准备工作 第一步:下载并安装Adobe Flash Player. 从官方网站(http://get.adobe.com/cn/flashplayer/)上下载最新的Flash Player(大约 ...

  2. MFC中换行实现

    在mfc中编辑框允许输入多行时,换行符被表示为<归位><换行>即"\r\n",用ascii码表示为13 10 如果为编辑框中想要输入换行,就请将编辑框的属性 ...

  3. MFC中的各种DC区别

    转载自:xntop的<区别MFC中的CClientDC.CWindowDC.CPaintDC.CMetaFileDC> CClientDC及其子类 1. CClientDC类只能在客户区绘 ...

  4. VC++ MFC中如何将应用程序的配置信息保存到注册表中(二)

    在上一篇中介绍了几个写入注册表数据和读取注册表数据的接口,并介绍了使用方法. 这一片教你如何使得你的应用程序在下次打开时保持上一次关闭前的状态. 在上一篇添加的代码的基础上,要添加WM_CLOSE消息 ...

  5. MFC中对话框类(Dialog)的应用

    转载http://hi.baidu.com/jackywdx/item/feee8041d2c2e12310ee1e85 Windows应用程序通常是通过对话框接收用户输入.向用户输出信息,本节介绍应 ...

  6. MFC中添加消息响应函数

    转自:http://blog.csdn.net/eddy_liu/article/details/8474677 目前,用MFC设计的Windows应用程序几乎都采用文档/视图结构.这种程序框架与简单 ...

  7. MFC中使用Duilib--2

    在上一篇文章"MFC中使用Duilib--1"中, 没有用到资源文件,即xml,本篇讲怎样加载文件. 1.  在exe输出目录下,创建一个skin目录,里面放入需要用到的图片文件, ...

  8. MFC中,如何自定义用户消息

    1.用处 在多个类之间传递消息.当需要响应用户操作,本类却无法实现时,可以向系统发出消息.然后让系统中的需要的位置实现它. 2.方法 2.1定义这个消息,并让拥有者发送这个这个消息,传递一个整型参数 ...

  9. 互斥对象 Mutex 和MFC中的CMutex

    互斥(Mutex)是一种用途非常广泛的内核对象.能够保证多个线程对同一共享资源的互斥访问.同临界区有些类似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共 ...

随机推荐

  1. Webalizer解析nginx基本配置

    先前使用了nginx做tomcat程序负载,后来需要解析日志.查看访问量.后来网上查了下,就使用了这个参考地址: http://daliang1215.iteye.com/blog/618829 .安 ...

  2. SQLSERVER复制的要点

    SQLSERVER复制的要点 在论坛里经常有人问:SQLSERVER复制出问题了!!SQLSERVER复制不运行了!!SQLSERVER复制遇到阻塞了!! 然后最后来一句:“怎麽办?????????? ...

  3. 用SQL语句断开某个数据库的所有活动连接

    每次一执行完一个数据库脚本,想要做一些别的操作的时候(比如还原数据库),老是有数据库活动连接,烦不胜烦(如下图所示). 下面给出一种删除数据库活动连接的方式.将下面代码段中的“--修改一下”处的数据库 ...

  4. MVP

    引自: http://www.cnblogs.com/Leo_wl/archive/2013/05/03/3056299.html http://www.codeproject.com/Article ...

  5. VS2010 调试不会命中当前断点

    方法1.直接把整个文件格式化了一次,断点就可以用了Ctrl + A全选菜单:编辑-〉高级-〉设置选定内容的格式 (Ctrl+K, Ctrl+F)通过比较文件发现是由于制表符Tab(0x09)引起的,原 ...

  6. [JS8] 显示从(0,0)到(0,0)的坐标

    <html> <head> <title>JS Unleashed</title> </head> <body> <SCR ...

  7. 无线客户端框架设计(5):调用MobileAPI的设计(iOS篇)

    这一节讲如何发起网络请求. iOS用于调用MobileAPI的第三方组件很多,我们这里采用的是以下组件: 1)ASIHTTPRequest,用于请求MobileAPI:http://allseeing ...

  8. 标签简化Spring-MVC配置

    新填入@RequestMapping标签 和@org.springframework.stereotype.Controller标签 这样做就是通过标签来简化之前,对HandlerMapping的配置 ...

  9. jquery的height()和javascript的height总结,js获取屏幕高度

    jquery的height()和javascript的height总结,js获取屏幕高度 2014年9月18日 15048次浏览 引子 今天是九一八事变八十三周年,大家勿忘国耻!加油学习!经济和技术等 ...

  10. R 报错:package ‘***’ is not available (for R version ****) 的解决方案

    R 安装sparklyr,ggplot2等包出现如下warning package '****' is not available (for R version 3.0.2) 系统环境 ubuntu1 ...