opencv之鼠标事件

在实际的图像处理当中,很多时候需要我们人为的选择感兴趣的区域(ROI),比如在图像中框出目标物体等。其实之前有不少地方都有用到这种鼠标事件的响应功能,感觉挺有用的,虽然不是自动选择物体,现在单独拿出来总结一下。

为了可以响应鼠标事件,首先必须创建一个回调函数,该函数使得点击鼠标时,在opencv中注册回调函数,就可以可以调用该回调函数了。回调函数的格式为:

void CvMouseCallback( int event, int x, int y, int flags, void *param);

参数意义:

第一个参数event的值为:

这里写图片描述

第二、三个参数x、y是事件发生时 鼠标位置的x,y坐标值(图像的像素坐标,与窗口大小无关)。

第四个参数flags,每一位指定了在事件发生时的不同状态:

这里写图片描述

最后一个参数是一个void指针,可以用来以任何结构方式传递额外的参数信息。

在opencv中注册回调函数:

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

第一个参数:指定回调函数需要注册到的窗口,即事件发生的窗口;
第二个参数:回调函数;
第三个参数:用来传递额外的信息给前面提到的void *param参数。

下面给出书上的利用鼠标画矩形的源码:

#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;
            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);//这时就把已经确定的矩阵写到image图像里
            }
            break;
        }
}

reference:学习opencv中文版

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值