1.简介
鼠标事件使用传统的回调函数机制来完成。我们事先写好一个回调程序,在OpenCV发生任何鼠标事件时,都会调用这个程序。
2.鼠标事件回调函数原型
void mouse_callback(
int event,
int x,
int y,
int flags,
void* parmas);
事件 | 数值 |
---|
cv::EVENT_MOUSEMOVE | 0 |
cv::EVENT_LBUTTONDOWN | 1 |
cv::EVENT_RBUTTONDOWN | 2 |
cv::EVENT_MBUTTONDOWN | 3 |
cv::EVENT_LBUTTONUP | 4 |
cv::EVENT_RBUTTONUP | 5 |
cv::EVENT_MBUTTONUP | 6 |
cv::EVENT_LBUTTONBLCLK | 7 |
cv::EVENT_RBUTTONBLCLK | 8 |
cv::EVENT_MBUTTONBLCLK | 9 |
- x: 鼠标事件发生时的x坐标。这里的坐标是图像上的像素坐标
- y: 鼠标事件发生时的y坐标。
- flags: 标志位,每一个位表示不同的条件,具体条件如下
标志 | 数值 |
---|
cv::EVENT_FLAG_LBUTTON | 1 |
cv::EVENT_FLAG_RBUTTON | 2 |
cv::EVENT_FLAG_MBUTTON | 4 |
cv::EVENT_FLAG_CTRLKEY | 8 |
cv::EVENT_FLAG_SHIFTKEY | 16 |
cv::EVENT_FLAG_ALTKEY | 32 |
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;
}
}