首页 > 代码库 > [OpenCV]3 关于HighGUI

[OpenCV]3 关于HighGUI


通过HighGUI(high-level graphical user interface)可以实现打开窗口、显示图像、读出和写入图像文件,处理鼠标、光标、键盘事件。而HighGUI主要分成“视频输入/输出”、“图像输入/输出”和“GUI工具”,分别在cacap*、grfmt*和window*源文件中实现。

<span style="font-family:Microsoft YaHei;font-size:18px;">int cvNamedWindow  
( const char* name,  
  int flags=CV_WINDOW_AUTOSIZE  
);  
</span>

第一个参赛用来表示新窗口的名称,这个名称显示在窗口的顶部,同时用作HighGUI中其他函数调用窗口的句柄。第二参赛是个标志,用来表示是否需要使窗口大小自动适应读入的图像大小。释放可以用cvReleaseImage()和cvDestroyWindow()来实现。

       载入图像可以用cvLoadImage(),当打开一副图像时,该函数并不分析文件扩展名,而是通过分析图像文件的前几个字节来确定图像的编码格式。注意:当cvLoadImage()读入失败时,并不会产生一个运行时错误,而是返回一个空指针。与cvLoadImage()对应的函数是cvSaveImage(),其实现了保存图像功能。

<span style="font-family:Microsoft YaHei;font-size:18px;">IplImage* cvLoadImage  
( const char* filename,  
  int              iscolor=CV_LOAD_IMAGE_COLOR  
);  
  
int cvSaveImage  
(  
 const char*   filename,  
 const CvArr* image  
);  
</span>

代码中的CvArr是C语言的风格,功能与面向对象语言中基类类似的结构。同样的显示图像可以用cvShowImage()。我比较喜欢读代码所以在此贴一段标准的实例吧。

<span style="font-family:Microsoft YaHei;font-size:18px;">int main(int argc,char** argv)  
{  
    // Create a named window with the name of the file.  
    cvNamedWindow(argv[1],1]);  
  
    // Load the image from the given file name.  
    IplImage* img=cvLoadImage(argv[1]);  
  
    // Show the image the user hits the "Esc" key.  
    while(1)  
    {  
        if(cvWaitKey(100)==27)  
             break;  
     }  
     // Clean up and don't be piggies  
     cvDestoryWindow(argv[1]);  
     cvReleaseImage(&img);  
} 
</span>

 

      在cvLoadImage()中当然你也可以直接输入Linux地址。

<span style="font-family:Microsoft YaHei;font-size:18px;">void cvMoveWindow  
( const char* name,  
  int  x,  
  int  y  
);  
</span>

cvMoveWindow()将窗口移动到其左上角为x,y的位置。下面介绍要给很重要的函数。

<span style="font-family:Microsoft YaHei;font-size:18px;">while(1)  
{  
    if(cvWaitKey(1000)==27)  
        break;  
}  
</span>

在这个程序中,则是告诉OpenCV等待用户触发事件100ms,如果在100ms内没有用户触发则继续循环;如果用户触发且按键ASCII码为27(ESC),则退出循环。

在鼠标事件中,和键盘当然最大的不同就是,鼠标响应事件采用回掉函数的方式来处理。因此为了可以响应鼠标点击事件,首先必须创建一个回掉函数。在创建这个函数之后需要在OpenCV中注册这个函数,以便特定窗口被触发鼠标事件后,OpenCV可以正确的调用这个函数。

<span style="font-family:Microsoft YaHei;font-size:18px;">void CvMouseCallback  
(  
   int event,  
   int x,  
   int y,  
   int flags,  
   void* param  
);  
</span>

event必须是以下表中的一个值。第二个以及第三个参数被设置成事件发生时鼠标位置的x,y坐标值。注意:这些坐标代表窗口中图像的像素坐标,与窗口的大小没有关系。第四个参数flags,每一位指定了在事件发生时的不同状态。例如CV_EVENT_FLAGS_SHIFTKEY的值为16(flags的第五位为1),如果想知道shift是否被触发,可以用flags与位掩码(1<<4)求与。最后一个参数是一个void指针,可以用来以任何结构方式传递额外的参数信息。

事件名称数值
CV_EVENT_MOUSEMOVE0
CV_EVENT_LBUTTONDOWN1
CV_EVENT_RBUTTONDOWN2
CV_EVENT_MBUTTONDOWN3
CV_EVENT_LBUTTONUP4
CV_EVENT_RBUTTONUP5
CV_EVENT_MBUTTONUP6
CV_EVENT_LBUTTONDBLCLK7
CV_EVENT_RBUTTONDBLCLK8
CV_EVENT_MBUTTONDBLCLK9

实现注册的函数是cvSetMouseCallback(),该函数需要3个参数。第一个参数指定了回掉函数需要注册到的窗口,第二个参数为回掉函数,最后一个参数用来传递额外的信息给前面提到的void* param参数。

<span style="font-family:Microsoft YaHei;font-size:18px;">void cvSetMouseCallback  
(  
    const char* window_name,  
    CvMouseCallback  on_mouse,  
    void* param=NULL  
);  
</span>

以下是一个完整的实例。

<span style="font-family:Microsoft YaHei;font-size:18px;">#include<cv.h>  
#include<highgui.h>  
  
void my_mouse_callback(int event, int x, int y, int flags, void* param);  
  
CvRect box;  
bool drawing_box = false;  
  
// A litte subroutine to draw a box onto an image  
void draw_box(IplImage* img, CvRect rect)  
{  
    cvRectangle(img,   
        cvPoint(box.x, box.y),   
        cvPoint(box.x + box.width, box.y + box.height),  
        cvScalar(0xff, 0x00, 0x00));  
}  
  
int main(int argc, char* argv[])  
{  
    box = cvRect(-1, -1, 0, 0);  
    IplImage* image = cvCreateImage(  
        cvSize(200, 200),  
        IPL_DEPTH_8U,  
        3);  
    cvZero(image);  
    IplImage* temp = cvCloneImage(image);  
    cvNamedWindow("Box Example");  
  
    cvSetMouseCallback("Box Example",  
        my_mouse_callback,  
        (void*)image);  
  
    while (1)  
    {  
        cvCopyImage(image, temp);  
        if (drawing_box)  
            draw_box(temp, box);  
        cvShowImage("Box Example", temp);  
  
        if (cvWaitKey(15) == 27)  
            break;  
    }  
  
    cvReleaseImage(&image);  
    cvReleaseImage(&temp);  
    cvDestroyWindow("Box Example");  
}  
  
void my_mouse_callback(int event, int x, int y, int flags, void* param)  
{  
    IplImage* image = (IplImage*)param;  
  
    switch (event)  
    {  
    case CV_EVENT_MOUSEMOVE:  
    {  
        if (drawing_box)  
        {  
            box.width = x - box.x;  
            box.height = y - box.y;  
        }  
    }  
        break;  
    case CV_EVENT_LBUTTONDOWN:  
    {  
        drawing_box = true;  
        box = cvRect(x, y, 0, 0);  
    }  
        break;  
    case CV_EVENT_LBUTTONUP:  
    {  
        drawing_box = false;  
        if (box.width < 0)  
        {  
            box.x += box.width;  
            box.width *= -1;  
        }  
        if (box.height<0)  
        {  
            box.y += box.height;  
            box.height *= -1;  
        }  
        draw_box(image, box);  
    }  
        break;  
    }  
}  </span>

[OpenCV]3 关于HighGUI