有关OpenCV1.0中GUI命令的几个函数学习总结
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命令的几个函数学习总结的更多相关文章
- Qt 5.0+ 中 connect 新语法与重载函数不兼容问题的解决方法,以及个人看法
Qt 5.0+ 版本提供了 connect 的新语法,相比之前的语法新语法可以提供编译期检查,使用也更方便.可是使用过程中发现一个小问题——当某个 signal 和成员函数是重载关系的时候,qmake ...
- OPencv1.0配置vs2010(介于OPencv的经典之作。都是OPencv1.0为基础的。)
首先下载OPencv1.0 我在之前的博客中写了下载的资源http://www.cnblogs.com/xiaochige/p/5990858.html 把OPencv1.0中bin文件夹下的所有内容 ...
- 浅析busybox-1.12.0中ash的脚本命令局限性
浅析busybox-1.12.0中ash的脚本命令局限性 LUTHER= 表示将LUTHER清空,将其变为null echo ${LUTHER:-111}如果执行该句之前LUTHER变量不存在,那么显 ...
- VS2010中使用命令行参数 分类: c/c++ 2014-07-11 22:24 634人阅读 评论(0) 收藏
在Linux下编程习惯了使用命令行参数,故使用VS2010时也尝试了一下. 新建项目,c++编写程序如下: #include<iostream> #include<fstream&g ...
- Linux下配置OpenCV1.0环境
自己一直嚷嚷着打算学学图像识别,识别个简单的,车牌号,验证码之类的,之前查过资料,OpenCV可以实现.昨天花了一个下午终于配置好环境了,今天写下总结. OpenCV这一名称包含了Open和Compu ...
- [转]Windows中的命令行提示符里的Start命令执行路径包含空格时的问题
转自:http://www.x2009.net/articles/windows-command-line-prompt-start-path-space.html 当使用Windows 中的命令行提 ...
- 转:Windows中的命令行提示符里的Start命令执行路径包含空格时的问题
转自:http://www.x2009.net/articles/windows-command-line-prompt-start-path-space.html 当使用Windows 中的命令行提 ...
- [C#] .NET4.0中使用4.5中的 async/await 功能实现异
好东西需要分享 原文出自:http://www.itnose.net/detail/6091186.html 在.NET Framework 4.5中添加了新的异步操作库,但是在.NET Framew ...
- 在 Typescript 2.0 中使用 @types 类型定义
在 Typescript 2.0 中使用 @type 类型定义 基于 Typescript 开发的时候,很麻烦的一个问题就是类型定义.导致在编译的时候,经常会看到一连串的找不到类型的提示.解决的方式经 ...
随机推荐
- 剑指offer系列44---只出现一次 的数字
[题目]一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. * [思路]异或性质:数异或自己即为0: * 一个数组中,从头到尾异或的结果为不重复数字异或结果. ...
- ARM地址映射
转自:http://blog.csdn.net/a3163504123/article/details/10958229 重映射之后,一般原来的地址依然有效.也就是说,可能两个地址,对应一个存储单元. ...
- 单元测试(junit使用)
1.测试的对象是一个类中的方法. 2.导入jar包. 3.单元测试方法时候,测试方法命名规则为 public void 方法名(){},注意:测试类不能命名为public class Test{},T ...
- git(5) windows下 pycharm + git(github) ,在本地方便管理
本篇博客讲解一下,windows下如何在pycharm下使用git(使用github设置和git一样),在本地进行commit,push,pull等操作 优点:简单,方便 pycharm版本:5.0. ...
- 在单线程中你最好使用ArrayList而不是Vector
<java核心技术卷一>571页上提到Vector类的所有方法都是同步的.可以由两个线程安全地访问同一个Vector对象.显然,如果可以确定我们不会在多个线程中对这个数组进行操作的话,我们 ...
- A^B问题
题目:输入包括两个正整数 A 和 B(1 <= A, B <= 10000),A 和 B 之前用空格隔开 ★数据输出 输出一行,若 A ^ B < 10000,则直接输出结果(不包含 ...
- java多线程之AtomicInteger
AtomicInteger原子操作实现同步 package Thread.Common; import java.util.Timer; import java.util.TimerTask; imp ...
- android之location 根据接口获取经纬度信息
http://maps.googleapis.com/maps/api/geocode/json?address=%E7%A6%8F%E5%BB%BA&sensor=falsehttp://m ...
- Eclipse中对Python代码自动格式化!
在Eclipse中使用PyDev发现无法进行代码格式化,使用通常的"Ctrl+Shift+F"快捷键,没有任何变化,难道不能对python代码格式化了吗? 通过下面设置,就可以每次 ...
- KVC , KVO , KVB
来源:http://www.cnblogs.com/jay-dong/archive/2012/12/13/2815778.html 熟悉oc语法的同学也许都会懂得这么一点:在oc中,类的成员变量或是 ...