在图像处理和计算机视觉应用中,鼠标交互是一个非常常见的功能。我们可以利用鼠标事件来绘制矩形、圆形、线条等,或者选择图像的感兴趣区域(ROI)。在 OpenCV 中,我们可以通过设置鼠标回调函数来处理这些交互。
1. OpenCV 鼠标事件概述
OpenCV 提供了 函数,用于设置鼠标事件的回调函数。通过不同的鼠标事件,您可以处理鼠标按下、松开和移动等行为。常见的鼠标事件包括:
setMouseCallback()
:鼠标左键按下。
EVENT_LBUTTONDOWN
:鼠标左键释放。
EVENT_LBUTTONUP
:鼠标移动。
EVENT_MOUSEMOVE
:鼠标右键按下。
EVENT_RBUTTONDOWN
这些事件通过回调函数传递给我们,我们可以在回调函数中根据事件类型做出不同的响应。
2. 鼠标绘制示例
下面是一个完整的 OpenCV 示例,演示如何使用鼠标绘制矩形。用户按下鼠标左键开始绘制,松开鼠标左键结束绘制。在鼠标移动时,会实时更新矩形的大小。
示例代码
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
Point sp(-1, -1); // 起始点
Point ep(-1, -1); // 结束点
Mat temp; // 用于保存图像副本
// 鼠标回调函数
static void on_draw(int event, int x, int y, int flags, void* userdata) {
Mat image = *((Mat*)userdata);
if (event == EVENT_LBUTTONDOWN) { // 按下鼠标左键
sp.x = x; // 记录起始点的横坐标
sp.y = y; // 记录起始点的纵坐标
std::cout << "Start point: " << sp << std::endl;
}
else if (event == EVENT_LBUTTONUP) { // 松开鼠标左键
ep.x = x; // 记录结束点的横坐标
ep.y = y; // 记录结束点的纵坐标
int dx = ep.x - sp.x; // 计算矩形的宽度
int dy = ep.y - sp.y; // 计算矩形的高度
if (dx > 0 && dy > 0) {
Rect box(sp.x, sp.y, dx, dy); // 计算矩形区域
rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0); // 绘制矩形
imshow("Mouse Drawing", image); // 显示图像
imshow("ROI Area", image(box)); // 显示选定的ROI区域
}
}
else if (event == EVENT_MOUSEMOVE) { // 鼠标移动时
if (sp.x > 0 && sp.y > 0) { // 确保已经按下鼠标
ep.x = x; // 更新结束点的横坐标
ep.y = y; // 更新结束点的纵坐标
int dx = ep.x - sp.x; // 计算矩形的宽度
int dy = ep.y - sp.y; // 计算矩形的高度
if (dx > 0 && dy > 0) {
temp.copyTo(image); // 将原图恢复
Rect box(sp.x, sp.y, dx, dy); // 计算矩形区域
rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0); // 绘制矩形
imshow("Mouse Drawing", image); // 显示图像
}
}
}
}
// 鼠标绘制演示
void mouse_drawing_demo(Mat& image) {
namedWindow("Mouse Drawing", WINDOW_AUTOSIZE); // 创建窗口
setMouseCallback("Mouse Drawing", on_draw, (void*)(&image)); // 设置鼠标回调
imshow("Mouse Drawing", image); // 显示图像
temp = image.clone(); // 备份原图
}
int main() {
// 读取图像
Mat image = imread("your_image_path_here.jpg"); // 使用您自己的图像路径
if (image.empty()) {
std::cout << "无法加载图像!" << std::endl;
return -1;
}
mouse_drawing_demo(image); // 开启鼠标绘制功能
waitKey(0); // 等待用户按键
destroyAllWindows(); // 关闭窗口
return 0;
}

3. 代码详解
3.1 读取图像并创建窗口
Mat image = imread("your_image_path_here.jpg"); // 读取图像
if (image.empty()) {
std::cout << "无法加载图像!" << std::endl;
return -1;
}
用于读取图像文件。若文件路径正确且图像加载成功,
imread() 将返回
image.empty()。
false
3.2 设置鼠标回调函数
setMouseCallback("Mouse Drawing", on_draw, (void*)(&image));
设置一个回调函数,当用户在窗口中执行鼠标操作时,OpenCV 将调用这个回调函数。在本例中,回调函数是
setMouseCallback()。
on_draw
3.3 鼠标回调函数的处理
回调函数 根据不同的鼠标事件进行处理:
on_draw
:当左键按下时,记录起始点的坐标。
EVENT_LBUTTONDOWN
:当左键松开时,记录结束点的坐标,并绘制矩形。
EVENT_LBUTTONUP
:当鼠标移动时,实时更新矩形的大小。
EVENT_MOUSEMOVE
在绘制矩形时,我们使用 函数来绘制一个矩形,
rectangle() 表示矩形的颜色是红色。
Scalar(0, 0, 255)
3.4 显示图像
imshow("Mouse Drawing", image);
imshow("ROI Area", image(box)); // 显示矩形区域
用来显示当前图像。在矩形绘制过程中,矩形区域会被实时显示,并且用户可以看到矩形随鼠标移动而动态变化。
imshow()
3.5 恢复图像并绘制矩形
temp.copyTo(image); // 恢复图像
rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);
用来将原图恢复,以便用户在绘制矩形时不会影响其他区域。
copyTo()
4. 总结
通过鼠标事件,我们可以实现与图像的交互操作,例如绘制矩形、选择感兴趣区域(ROI)等。这种功能在许多图像处理应用中都非常有用,如手动标注数据、裁剪图像等。OpenCV 提供了简单易用的 和鼠标事件处理机制,让我们能够快速实现鼠标交互。
setMouseCallback()



![在苹果iPhone手机上编写ios越狱插件deb[超简单] - 鹿快](https://img.lukuai.com/blogimg/20251123/23f740f048644a198a64e73eeaa43e60.jpg)













暂无评论内容