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. HibernateTemplate和HibernateDaoSupport(spring注入问题)

    HibernateTemplate HibernateTemplate是spring提供的一个就hibernate访问持久层技术而言.支持Dao组件的一个工具.HibernateTemplate提供持 ...

  2. linux-6的yum软件仓库

    yum命令 命令 作用 yum repolist all  列出所有仓库 yum list all  列出仓库中的所有软件包 yum  info 软件包名称  查看软件包信息 yum install  ...

  3. 【概念笔记】JAVA基础 - part2

    IT`huhiu前言录 这是续JAVA基础 - part1 链接http://www.cnblogs.com/ithuhui/p/5922067.html的. 笔记慢慢在修改和补充 JAVA里面重要的 ...

  4. 利用Formdata实现form提交文件上传不跳转页面

    作者:幻月九十链接:https://www.zhihu.com/question/19631256/answer/119911045来源:知乎著作权归作者所有,转载请联系作者获得授权. $('form ...

  5. MongoDB基本概念

    MongoDB是一种强大灵活可扩展的数据存储方式,它扩展了关系数据库的众多功能.MongoDB的功能非常丰富,但是却非常容易上手和便于使用,今天来了解一下MongoDB的主要概念. 文档 文档是的核心 ...

  6. 用c#开发微信 (6) 微渠道 - 推广渠道管理系统 1 基础架构搭建

    我们可以使用微信的“生成带参数二维码接口”和 “用户管理接口”,来实现生成能标识不同推广渠道的二维码,记录分配给不同推广渠道二维码被扫描的信息.这样就可以统计和分析不同推广渠道的推广效果. 本系统使用 ...

  7. 基于阿里云容器服务用docker容器运行ASP.NET 5示例程序

    小试阿里云容器服务 之后,接下来有一个挡不住的小试冲动--用docker容器运行程序.首先想到的程序是 ASP.NET 5示例程序,于是参考msdn博客中的这篇博文 Running ASP.NET 5 ...

  8. mysql 去除空格

    update nm_user set nickname=TRIM(Replace(Replace(Replace(nickname,'\t',''),'\n',''),'\r',''))

  9. shellKali Linux Web 渗透测试— 初级教程(第三课)

    shellKali Linux Web 渗透测试— 初级教程(第三课) 文/玄魂 目录 shellKali Linux Web 渗透测试—初级教程(第三课) 课程目录 通过google hack寻找测 ...

  10. [stm32][ucos][ucgui] 2、LED闪烁、串口、滑块、文本编辑框简单例程

    上一篇:[stm32][ucos] 1.基于ucos操作系统的LED闪烁.串口通信简单例程 * 内容简述: 本例程操作系统采用ucos2.86a版本, 建立了7个任务            任务名   ...