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. 阿里云中Centos下配置防火墙

    一.检查iptables服务状态 [root@woxplife ~]# service iptables status iptables: Firewall is not running. 说明ipt ...

  2. mysql 去除空格

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

  3. windows server 2012 r2 iis8.5 部署asp.net mvc4/5程序小结

    windows server 2012 r2 iis8.5 部署asp.net mvc4/5程序小结 原文链接:http://www.xuanhun521.com/Blog/66d491f8-b479 ...

  4. Deployment Pipeline using Docker, Jenkins, Java

    Deployment Pipeline using Docker, Jenkins, Java and Couchbase http://blog.couchbase.com/2016/septemb ...

  5. paip.输出内容替换在Apache 过滤器filter的设置

    paip.输出内容替换在Apache 过滤器filter的设置 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog ...

  6. Leetcode 219 Contains Duplicate II STL

    找出是否存在nums[i]==nums[j],使得 j - i <=k 这是map的一个应用 class Solution { public: bool containsNearbyDuplic ...

  7. JAVA数组所占内存大小的对比

    1.两个数据模型 第一个是基本类型数组,第二个使用的是Float对象数组 public class SummaryModel{ private float[] summaryData; public ...

  8. UIScrollView offset in UINavigationController

    转:UIScrollView offset in UINavigationController 通过设置viewCtronller的 self.automaticallyAdjustsScrollVi ...

  9. libuv在cocos2d-x中的使用

    libuv经过Node.js的实践和应用,已经证明非常之成熟,本来之前项目用的是这个:clsocket https://github.com/DFHack/clsocket  当初选它的主要原因是它支 ...

  10. 一个优秀windows C++程序员的知识体系

    思考一个优秀windows C++ 程序员该有哪些知识,可最终发现什么知识都不能少, 看下图: 除了上面知识,程序员还要不断学习, 保持对新知识的热情. 转自http://www.cppblog.co ...