有关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 = 0;
IplImage* img1 = 0;

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(0);
    }

    mycursor = ::LoadCursor(NULL,IDC_ARROW);
    precursor= ::LoadCursor(NULL,IDC_CROSS);

    cvNamedWindow("Image",1);
    cvShowImage("Image",img);
    img1 = cvCloneImage(img);
//    cvSetPreprocessFuncWin32(wndcallback);//用这个函数时要确保用户定义的回调函数wndcallback的最后一个//参数*was_processed=0,否则窗口过程函数HighGUIProc就不能被调用,此时窗口重绘消息WM_PAINT如果用户没//有处理就不能被处理。
    cvSetPostprocessFuncWin32(wndcallback);

    while(1)
    {
        int key = cvWaitKey(5000);
        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 0;
}

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, 0, 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(0,255,0), 3);
                cvShowImage("Image", img);
            }
            break;
        default:
            break;
        }
        if (!isChangCursor)
            ::SetCursor(mycursor);
    }

     return *was_processed;
}
时间: 2024-10-03 13:40:01

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

【探索OpenCV】OpenCV1.0在VC6.0中的配置

1.安装OpenCV1.0 下载链接: OpenCV2.4.3 链接:http://pan.baidu.com/s/1dD4NuTV 密码:mddd 2.配置环境 我的安装路径为C:\Program Files (x86)\OpenCV 首先,需要检查环境变量是否配置完成,将bin的路径C:\Program Files (x86)\OpenCV\bin添加到环境变量path中(重启电脑后生效) 3.配置VC6.0 菜单Tools->Options->Directories:先设置lib路径,选

Linux下配置OpenCV1.0环境

自己一直嚷嚷着打算学学图像识别,识别个简单的,车牌号,验证码之类的,之前查过资料,OpenCV可以实现.昨天花了一个下午终于配置好环境了,今天写下总结. OpenCV这一名称包含了Open和Computer Vision两者的意思.实际上,Open指Open Source(开源,即开放源代码),Computer Vision则指计算机视觉.更详细介绍,请参考:http://zh.wikipedia.org/wiki/OpenCV 配置环境系统信息:Linux [email protected]:

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

转自:http://www.x2009.net/articles/windows-command-line-prompt-start-path-space.html 当使用Windows 中的命令行提示符执行这段指令时(测试Start命令执行带空格的路径的程序或文件问题),第一行Start会成功执行,跳出记事本程序,而第二行,会 Start跳出一个新的命令提示符,标题上写着路径,但是不会执行任何命令,第三行Start命令行提示符会提示C:\Program文件不存在,提示无 法执行. start

Apache Storm 1.1.0 中文文档 | ApacheCN

前言  Apache Storm 是一个免费的,开源的,分布式的实时计算系统. 官方文档: http://storm.apache.org 中文文档: http://storm.apachecn.org ApacheCN 最近组织了翻译 Storm 1.1.0 中文文档 的活动,整体 翻译进度 为 96%. 感谢大家参与到该活动中来 感谢无私奉献的 贡献者,才有了这份 Storm 1.1.0 中文文档 感谢一路有你的陪伴,我们才可以做的更好,走的更快,走的更远,我们一直在努力 ... 网页地址:

Hadoop-2.2.0中文文档—— Common - CLI MiniCluster

目的 使用 CLI MiniCluster, 用户可以简单地只用一个命令就启动或关闭一个单一节点的Hadoop集群,不需要设置任何环境变量或管理配置文件. CLI MiniCluster 同时启动一个 YARN/MapReduce 和 HDFS 集群. 这对那些想要快速体验一个真实的Hadoop集群或是测试依赖明显的Hadoop函数的非Java程序 的用户很有用. Hadoop Tarball 你需要从发布页获取tar包.或者,你可以从源码中自己编译. $ mvn clean install -

.NET Framework 2.0中的数据访问新特性

1. 异步数据访问 ? 支持异步数据编程 ? SqlConnection – BeginOpen – EndOpen ? SqlCommand – BeginExecuteNonQuery – BeginExecuteReader – BeginExecuteXmlReader – EndExecuteNonQuery – EndExecuteReader – EndExecuteXmlReader 2. 多活动结果集(MARS) ? 在 SQL Server 2005 中支持多活动结果集 ?

HDFS中的命令行

HDFS中的命令行 本文介绍了HDFS以命令行执行的时候.几个经常使用的命令行的作用和怎样使用~ 1. fs fs是启动命令行动作,该命令用于提供一系列子命令. 使用形式为hadoop fs –cmd <args> 当中,cmd是子命令,args是详细的命令操作. 比如hadoop fs –help 或者说fs是其余子命令的父亲.其余都是在"-cmd"的模式下的! 2. –cat 输出 hadoop fs –cat URI 将路径指定的文件输出到屏幕 3. –copyFro

WPF 在事件中绑定命令(可以在模版中绑定命令)

其实这也不属于MVVMLight系列中的东东了,没兴趣的朋友可以跳过这篇文章,本文主要介绍如何在WPF中实现将命令绑定到事件中. 上一篇中我们介绍了MVVMLight中的命令的用法,那么仅仅知道命令是如何构建使用的还不够,很多情况下我们都需要在某个事件触发的时候才去触发命令,所以将命令绑定到事件上是非常有效的做法,下面我们来接着实现将命令绑定到事件中. WPF实现命令绑定到事件 使用 System.Windows.Interactivity.dll 中的 Interaction 可以帮助我们实现

Hadoop-2.2.0中文文档——MapReduce 下一代 -——集群配置

目的 这份文档描写叙述了怎样安装.配置和管理从几个节点到有数千个节点的Hadoop集群. 玩的话,你可能想先在单机上安装.(看单节点配置). 准备 从Apache镜像上下载一个Hadoop的稳定版本号. 安装 安装一个Hadoop集群,一般包含分发软件到全部集群中的机器上或者是安装RPMs. 一般地,集群中的一台机器被唯一地设计成NameNode,还有一台机器被设置成ResourceManager.这是master(主). 集群中剩下的机器作为DataNode 和 NodeManager.这些是