OpenCV 鼠标操作 SetMouseCallback

鼠标操作消息回调函数的函数为 SetMouseCallback。

原型:

void setMouseCallback(const string& winname, MouseCallback onMouse, void *userdata = 0);
  1. 第一个参数:窗口名字;
  2. 第二个参数:指定窗口里每次鼠标事件发生的时候,被调用的函数指针。原型:void Foo(int event, int x, int y, int flags, void *param)
  3. 第三个参数:用户定义的传递到回调函数的参数,默认值 0。
#include <opencv2/opencv.hpp>

using namespace cv;

#define WINDOW_NAME "【程序窗口】"


/********全局函数声明**********/
void on_MouseHandle(int event, int x, int y, int flags, void* param);
void DrawRectange(Mat& img, Rect box);
//void ShowHelpText();  

/********全局变量声明*********/
Rect g_rectangle;
bool g_bDrawingBox = false; // 是否进行绘制
RNG g_rng(12345);


int main(int argc, char ** argv)
{
    g_rectangle = Rect(-1, -1, 0, 0);
    Mat srcImage(600, 800, CV_8UC3), tempImage;
    srcImage.copyTo(tempImage);

    //g_rectangle = Rect(-1, -1, 0, 0);
    srcImage = Scalar::all(0);

    // 设置鼠标操作回调函数
    namedWindow(WINDOW_NAME);
    setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);

    // 程序主循环, 当绘制标识符位真时,进行绘制
    while (1)
    {
        srcImage.copyTo(tempImage);
        if (g_bDrawingBox) {
            DrawRectange(tempImage, g_rectangle); // 绘制
        }
        imshow(WINDOW_NAME, tempImage);

        if (waitKey(10) == 27) {
            break; // ESC 键按下,退出程序
        }
    }

    return 0;
}

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

    switch (event)
    {
        // 鼠标移动消息
    case EVENT_MOUSEMOVE:
        // 如果绘制标识为真,记录下长和宽到 RECT 中
        if (g_bDrawingBox) {
            g_rectangle.width = x - g_rectangle.x;
            g_rectangle.height = y - g_rectangle.y;
        }
        break;
        // 左键按下
    case EVENT_LBUTTONDOWN:
        g_bDrawingBox = true;
        g_rectangle = Rect(x, y, 0, 0);// 记录起始点
        break;
        // 左键抬起
    case EVENT_LBUTTONUP:
        g_bDrawingBox = false; // 置标识位 false
        // 对宽和高小于 0 的处理
        if (g_rectangle.width < 0) {
            g_rectangle.x += g_rectangle.width;
            g_rectangle.width *= -1;
        }
        if (g_rectangle.height < 0) {
            g_rectangle.y += g_rectangle.height;
            g_rectangle.height *= -1;
        }
        DrawRectange(image, g_rectangle);
        break;
    default:
        break;
    }
}

// 自定义矩形绘制函数
void DrawRectange(Mat& img, Rect box)
{
    rectangle(img, box.tl(), box.br(), Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255))); // 随机颜色
}




参考:

《OpenCV3 编程入门》 毛星云 P78

posted @   double64  阅读(340)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示