6.OpenCV鼠标事件

1.简介

鼠标事件使用传统的回调函数机制来完成。我们事先写好一个回调程序,在OpenCV发生任何鼠标事件时,都会调用这个程序。

2.鼠标事件回调函数原型

void mouse_callback(
                int event,
                int x,
                int y,
                int flags,
                void* parmas);
  • event: 鼠标事件类型
事件数值
cv::EVENT_MOUSEMOVE0
cv::EVENT_LBUTTONDOWN1
cv::EVENT_RBUTTONDOWN2
cv::EVENT_MBUTTONDOWN3
cv::EVENT_LBUTTONUP4
cv::EVENT_RBUTTONUP5
cv::EVENT_MBUTTONUP6
cv::EVENT_LBUTTONBLCLK7
cv::EVENT_RBUTTONBLCLK8
cv::EVENT_MBUTTONBLCLK9
  • x: 鼠标事件发生时的x坐标。这里的坐标是图像上的像素坐标
  • y: 鼠标事件发生时的y坐标。
  • flags: 标志位,每一个位表示不同的条件,具体条件如下
标志数值
cv::EVENT_FLAG_LBUTTON1
cv::EVENT_FLAG_RBUTTON2
cv::EVENT_FLAG_MBUTTON4
cv::EVENT_FLAG_CTRLKEY8
cv::EVENT_FLAG_SHIFTKEY16
cv::EVENT_FLAG_ALTKEY32
  • params: 用于传递额外的信息给鼠标事件

3.鼠标注册函数

void cv::setMouseCallback(
            const string&      windowName,
            cv::MouseCallback  on_mouse,
            void*              param = NULL
);
  • windowName: 回调函数作用的窗口名称
  • on_mouse: 要注册的回调函数
  • param: 给回调函数传递的参数

4.简单绘图例子

#include <QCoreApplication>
#include "opencv2/opencv.hpp"

void my_mouse_callback(int event, int x, int y, int flags, void* param); //自己定义的鼠标事件回调函数

cv::Rect box;
bool drawing_box = false;

void draw_box(cv::Mat& img, cv::Rect box)
{
    cv::rectangle(img, box.tl(), box.br(), cv::Scalar(0x00, 0x00, 0xFF));//BGR画红色的框
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    box = cv::Rect(-1, -1, 0, 0);
    cv::Mat img(200, 200, CV_8UC3), temp;
    img.copyTo(temp); //使用copyTo复制一个img类

    img = cv::Scalar::all(0); //给img所有像素初始化为黑色
    cv::namedWindow("DBox_test"); //创建一个显示窗口

    //注册自己的鼠标回调
    cv::setMouseCallback("DBox_test", my_mouse_callback, (void*)&img);

    for (;;) {
        img.copyTo(temp);
        if(drawing_box)
            draw_box(temp, box);
        cv::imshow("DBox_test", temp);

        if(cv::waitKey(15) == 27)
            break;
    }
    return a.exec();
}

void my_mouse_callback(int event, int x, int y, int flags, void* param)
{
    cv::Mat& image = *(cv::Mat*)param;

    switch (event) {
    case cv::EVENT_MOUSEMOVE:
        //在绘画状态中,鼠标移动时,记录当前xy轴,绘制矩形
        if(drawing_box) {
            box.width = x - box.x;
            box.height = y - box.y;
        }
        break;
    case cv::EVENT_LBUTTONDOWN:
        drawing_box = true; //鼠标左键按下,开始绘制
        box = cv::Rect(x, y, 0, 0); //记录鼠标左键按下时的x,y轴,作为矩形起点
        break;
    case cv::EVENT_LBUTTONUP:
        drawing_box = false; //鼠标左键松开,绘制完成
        if(box.width < 0) {
            box.x += box.width; //鼠标向左边运行,x轴负增长,所以这里取反
            box.width *= -1;
        }
        if(box.height < 0) {
            box.y += box.height; //鼠标向上方运行,y轴负增长,取反
            box.height *= -1;
        }
        draw_box(image, box);
        break;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值