雕刻时光

just do it……nothing impossible
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

鼠标在窗口中画矩形——鼠标事件

Posted on 2014-01-21 11:07  huhuuu  阅读(1029)  评论(0编辑  收藏  举报

  鼠标事件采用回调函数的形式,即需要鼠标处理点击移动事件的话,首先必须创建一个回调函数。

  如下形式:

void my_mouse_callback( //回调函数的声明,而回调函数也是需要这种参数格式
    int event,int x,int y,int flags,void * param
    );

  第一个参数是表示鼠标的事件类型,如左键按下去,左键回上来,鼠标移动等。

  有如下类型:

  

  x,y表示现在鼠标所处的位置,

  flags表示鼠标事件标志:

  

  最后一个额外的指针,可以传递你所需要的数据指针,这里用来传递image的指针。

  

  下面是注册回调函数到opencv中,注册函数是:

  

CVAPI(void) cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse,
                                void* param CV_DEFAULT(NULL));

  第一个参数是窗口名称,

  第二个参数是回调函数名称,

  第三个参数是上面讲过可以额外传递数据的指针。

 

鼠标画矩阵的源码:

#include<iostream>
using namespace std;

#include "stdafx.h"
#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;

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(){
    box = cvRect(-1,-1,0,0);
    IplImage * image = cvCreateImage(
        cvSize(500,500),
        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);//这里是在鼠标移动的时候矩阵,能够随鼠标的移动而移动
                                        //注意到这里有两个图像,现在是先把临时的矩阵(大小)还在变化的矩阵写在temp图像上
        cvShowImage("Box Example",temp);//显示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; //drawing_box=true 表示鼠标按下去了
                    box = cvRect(x,y,0,0);
                }
            break;

            case CV_EVENT_LBUTTONUP:
                {
                    drawing_box = false; //表示数遍按抬起来后的
                    draw_box(image,box);//这时就把已经确定的矩阵写到image图像里
                }
                break;
        }

}

参考:学习opencv