1、修改窗口背景色或者光标形状

  在OpenCV1.0版本利用函数int cvNamedWindow( const char* name, int flags )初始化创建一个窗口后,窗口的背景色是灰色,光标形状是十字线,通过如下方法改变这些窗口属性:

 第一种方法是从源头直接修改。(1) 打开OpenCV安装目录下的_make文件夹,使用VC6.0打开opencv.dsw工程,打开文件”…\\highgui\\window_win32.cpp” 找到函数CV_IMPL int cvInitSystem( int, char** ),该函数就是被cvNamedWindow函数调用用来创建窗口的,在该函数中可以看到注册窗口的一些属性(包括窗口背景色是灰色,光标形状是十字线等),只要修改相应属性值即可改变窗口的属性(比如将窗口背景色的属性值改为WHITE_BRUSH就使得窗口背景色为白色,将光标形状属性ID改为IDC_ARROW就使得窗口的光标变成箭头形状)。

(2) 修改了相应属性值后,还需要在VC6.0中选择build | Batch build菜单项,在弹出的对话框中,选择需要重新编译的库,点击Rebuild。这样就生成了修改后的库文件和动态链接库文件。这种方法直接通过修改WNDCLASS参数来达到目的。

 第二种方法就是在当前工程中通过调用全局函数来修改。比如要修改窗口背景色可以采用以下示例代码:

  cvNamedWindow("Image",1);

    HDC dc;

    HBRUSH brush;

    HGDIOBJ oldgdi;

    RECT rc;

    dc = ::GetDC((HWND)cvGetWindowHandle("Image"));

    brush = ::CreateSolidBrush(RGB(0,0,0));

    oldgdi = ::SelectObject(dc,brush);

    ::GetClientRect((HWND)cvGetWindowHandle("Image"),&rc);

    ::FillRect(dc,&rc,brush);

    ::SelectObject(dc,oldgdi);

    ::DeleteObject(brush);

    ::ReleaseDC((HWND)cvGetWindowHandle("Image"),dc);

修改窗口光标可以利用以下一对函数:

mycursor = ::LoadCursor(NULL,IDC_ARROW);  ::SetCursor(mycursor);

2、窗口消息处理

  OpenCV1.0提供了鼠标、键盘、拖动条等常用的事件消息处理机制,对于鼠标和拖动条消息,用户可以自己编写回调函数来实现需要的功能。例如:对于鼠标的消息处理,用户在完成回调函数编写后只需调用OpenCV中的cvSetMouseCallback函数将处理鼠标消息的回调函数地址传给窗口过程函数即可。具体消息处理流程见如下示意图:

  仔细观察window_w32.cpp文件中的窗口回调函数WindowProc的定义会发现(如图4所示),该函数在调用HighGUIProc之前和之后还做了2个工作,那就是访问了由函数指针hg_on_preprocess和hg_on_postprocess指向的函数地址空间。如果将用户自定义的回调函数地址赋值给这两个指针同样可以完成窗口消息的处理,正好OpenCV1.0有两个函数可以达到如此目的,这两个函数分别如图2所示在头文件highgui.h中已经作了申明:

这两个函数的实现实例如图3所示:

例如用户想要创建右键式弹出菜单,那么对菜单的响应消息WM_COMMAND在OpenCV封装的HighGUIProc函数中并未处理,此时用户可以自己定义回调函数,然后通过函数cvSetPreprocessFuncWin32或者cvSetPostprocessFuncWin32将用户定义的函数地址赋值给函数指针hg_on_preprocess或者hg_on_postprocess。

最后基于VC6.0创建一个Win32 Console Application程序,实现如下功能:

(1) 创建一个窗口,修改初始化的光标形状并加载一幅图像;

(2) 在图像上通过鼠标绘制绿色矩形框,在鼠标左键按下并移动鼠标时光标形状改变;

(3) 鼠标右键按下创建一个弹出式菜单,并响应菜单条目消息。

实现示例代码如下:

#include <stdio.h>
#include "cv.h"
#include "highgui.h"
#include "opencv_test.h" #define IDM_OTSU 0x0010
#define IDM_JOSE 0x0020 int wndcallback( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, int* was_processed); IplImage* img = ;
IplImage* img1 = ; CvPoint pt1;
CvPoint pt2;
POINT pt3;
HMENU mymenu;
HCURSOR mycursor;
HCURSOR precursor;
bool isChangCursor = false; int main()
{
img = cvLoadImage("lena.jpeg");
if (!img)
{
printf("can not load the image!");
exit();
} mycursor = ::LoadCursor(NULL,IDC_ARROW);
precursor= ::LoadCursor(NULL,IDC_CROSS); cvNamedWindow("Image",);
cvShowImage("Image",img);
img1 = cvCloneImage(img);
// cvSetPreprocessFuncWin32(wndcallback);//用这个函数时要确保用户定义的回调函数wndcallback的最后一个//参数*was_processed=0,否则窗口过程函数HighGUIProc就不能被调用,此时窗口重绘消息WM_PAINT如果用户没//有处理就不能被处理。
cvSetPostprocessFuncWin32(wndcallback); while()
{
int key = cvWaitKey();
if (key == ' ')
break;
} printf("menu is destroy : %d \n",::DestroyMenu(mymenu));
printf("cursor is destroy : %d \n",::DestroyCursor(mycursor));
printf("precursor is destroy : %d \n",::DestroyCursor(precursor));
cvReleaseImage(&img);
cvReleaseImage(&img1);
cvDestroyWindow("Image"); return ;
} int wndcallback( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ,int* was_processed)
{
if (hwnd == (HWND)cvGetWindowHandle("Image"))
{
switch (uMsg)
{
case WM_COMMAND:
if (LOWORD(wParam) == IDM_OTSU)
printf("otsu !\n");
else if (LOWORD(wParam) == IDM_JOSE)
printf("jose !\n");
break;
case WM_RBUTTONUP:
pt3.x = LOWORD(lParam);
pt3.y = HIWORD(lParam);
::ClientToScreen(hwnd,&pt3);
mymenu = ::CreatePopupMenu();
::AppendMenu(mymenu,MF_STRING,IDM_OTSU,"Otsu(&O)");
::AppendMenu(mymenu,MF_STRING,IDM_JOSE,"Jose(&J)");
::TrackPopupMenu(mymenu,TPM_LEFTALIGN | TPM_LEFTBUTTON, pt3.x, pt3.y, , hwnd, NULL); break;
case WM_LBUTTONDOWN:
pt1.x = LOWORD(lParam);
pt1.y = HIWORD(lParam);
break;
case WM_LBUTTONUP:
isChangCursor = false;
break;
case WM_MOUSEMOVE:
if (MK_LBUTTON == wParam)
{
isChangCursor = true;
::SetCursor(precursor); pt2.x = LOWORD(lParam);
pt2.y = HIWORD(lParam);
img = cvCloneImage(img1);
cvRectangle(img, pt1, pt2, cvScalar(,,), );
cvShowImage("Image", img);
}
break;
default:
break;
}
if (!isChangCursor)
::SetCursor(mycursor);
} return *was_processed;
}

有关OpenCV1.0中GUI命令的几个函数学习总结的更多相关文章

  1. Qt 5.0+ 中 connect 新语法与重载函数不兼容问题的解决方法,以及个人看法

    Qt 5.0+ 版本提供了 connect 的新语法,相比之前的语法新语法可以提供编译期检查,使用也更方便.可是使用过程中发现一个小问题——当某个 signal 和成员函数是重载关系的时候,qmake ...

  2. OPencv1.0配置vs2010(介于OPencv的经典之作。都是OPencv1.0为基础的。)

    首先下载OPencv1.0 我在之前的博客中写了下载的资源http://www.cnblogs.com/xiaochige/p/5990858.html 把OPencv1.0中bin文件夹下的所有内容 ...

  3. 浅析busybox-1.12.0中ash的脚本命令局限性

    浅析busybox-1.12.0中ash的脚本命令局限性 LUTHER= 表示将LUTHER清空,将其变为null echo ${LUTHER:-111}如果执行该句之前LUTHER变量不存在,那么显 ...

  4. VS2010中使用命令行参数 分类: c/c++ 2014-07-11 22:24 634人阅读 评论(0) 收藏

    在Linux下编程习惯了使用命令行参数,故使用VS2010时也尝试了一下. 新建项目,c++编写程序如下: #include<iostream> #include<fstream&g ...

  5. Linux下配置OpenCV1.0环境

    自己一直嚷嚷着打算学学图像识别,识别个简单的,车牌号,验证码之类的,之前查过资料,OpenCV可以实现.昨天花了一个下午终于配置好环境了,今天写下总结. OpenCV这一名称包含了Open和Compu ...

  6. [转]Windows中的命令行提示符里的Start命令执行路径包含空格时的问题

    转自:http://www.x2009.net/articles/windows-command-line-prompt-start-path-space.html 当使用Windows 中的命令行提 ...

  7. 转:Windows中的命令行提示符里的Start命令执行路径包含空格时的问题

    转自:http://www.x2009.net/articles/windows-command-line-prompt-start-path-space.html 当使用Windows 中的命令行提 ...

  8. [C#] .NET4.0中使用4.5中的 async/await 功能实现异

    好东西需要分享 原文出自:http://www.itnose.net/detail/6091186.html 在.NET Framework 4.5中添加了新的异步操作库,但是在.NET Framew ...

  9. 在 Typescript 2.0 中使用 @types 类型定义

    在 Typescript 2.0 中使用 @type 类型定义 基于 Typescript 开发的时候,很麻烦的一个问题就是类型定义.导致在编译的时候,经常会看到一连串的找不到类型的提示.解决的方式经 ...

随机推荐

  1. js为DIV动态设置id属性

    <script> var objs=document.getElementById("iproduct").getElementsByTagName("div ...

  2. 嵌入式设计模式:有限状态自动机的C语言实现

    转自:http://www.cnblogs.com/autosar/archive/2012/06/22/2558604.html 状态机模式是一种行为模式,在<设计模式>这本书中对其有详 ...

  3. 简单实例讲解linux的module模块编译步骤

    注:原博文地址http://blog.sina.com.cn/s/blog_4ba5b45e0102v25h.html ---------------------------------------- ...

  4. 转-Android联网 — HttpURLConnection和HttpClient选择哪个好?

    http://www.ituring.com.cn/article/199619?utm_source=tuicool 在Android开发中,访问网络我们是选择HttpURLConnection还是 ...

  5. Hibernae 的延迟加载

    http://blog.csdn.net/xc635960736/article/details/7049863 Hibernae 的延迟加载   Hibernae 的延迟加载是一个非常常用的技术,实 ...

  6. JavaScript 类

    一.基础 //定义obj类 var obj = function(){ //声明v1成员 var v1 = ''; //声明get_v1方法,用this关键字定义 this.get_v1 = func ...

  7. 如何利用svn自动同步更新到网站服务器

    我们最终的目的是:当本地提交后,SVN服务器自动更新服务器端指定WEB目录内的文件 实现方法: 找到服务器端 SVN版本库所在的目录(目录名称是Repositories),这个目录是在安装Visual ...

  8. c#图片上绘制半透明矩形

    p.CreateGraphics().FillRectangle( ,Color.LightGreen)), iLeft, iTop, iRight - iLeft, iBottom - iTop); ...

  9. oracle常用的数据迁移方法

    源地址:http://wenku.baidu.com/link?url=lI6UYpvDs_y8ku6DytEZLl4GSJjQ0GAGPvv8txrbRoQKgqzTCMAfBZI5mn9t-KQk ...

  10. JAVA继承时this和super关键字

    JAVA继承时this和super关键字 本文主要讨论在方法前使用this或super关键字时,编译器在什么地方查找对应的函数. 在子类中指定this关键字.首先在本类中查找,如果本类中找不到,再在父 ...