OpenCV 鼠标响应
开发环境如下:
VS2022 + OpenCV 4.6.1
鼠标响应函数原型
- winname :添加鼠标响应窗口的名字
- onMouse :鼠标响应的回调函数
- userdata :传递给回调函数的可选参数
- event:鼠标响应事件标志,参数类型为 EVENT_* 形式
- x,y :鼠标在图像坐标系中的x,y坐标
- flags:鼠标响应标志
- userdata: 传递给回调函数的可选参数
setMouseCallback 函数为指定的窗口创建鼠标响应,就是只有在设置的窗口上进行操作,函数才会正常响应。MouseCallback函数的函数名可以任意设置,并且该函数只有在鼠标状态发生变化的时候才会调用。
EVENT 事件
cv::EVENT_FLAG_LBUTTON = 1,按住左键拖拽
cv::EVENT_FLAG_RBUTTON = 2,按住右键拖拽
cv::EVENT_FLAG_MBUTTON = 4,按住中键拖拽
cv::EVENT_FLAG_CTRLKEY = 8,按住“CTRL”
cv::EVENT_FLAG_SHIFTKEY = 16,按住“SHIFT”
cv::EVENT_FLAG_ALTKEY = 32,按住“ALT”
cv::EVENT_MOUSEMOVE = 0,鼠标在窗口上移动
cv::EVENT_LBUTTONDOWN = 1,按下鼠标i左键
cv::EVENT_RBUTTONDOWN = 2,按下鼠标右键
cv::EVENT_MBUTTONDOWN = 3,按下鼠标中键
cv::EVENT_LBUTTONUP = 4,释放鼠标左键
cv::EVENT_RBUTTONUP = 5,释放鼠标右键
cv::EVENT_MBUTTONUP = 6,释放鼠标中键
cv::EVENT_LBUTTONDBLCLK = 7,双击鼠标左键
cv::EVENT_RBUTTONDBLCLK = 8,双击鼠标右键
cv::EVENT_MBUTTONDBLCLK = 9,双击鼠标中键
cv::EVENT_MOUSEWHEEL = 10,正值表示向前滚动,负值表示向后滚动
cv::EVENT_MOUSEHWHEEL = 11,正值表示向左滚动,负值表示向右滚动
实际的说就是,鼠标响应就是当鼠标位于对应的图像窗口时,时刻检测鼠标状态,当鼠标状态发生改变时,调用回调函数,并且根据回调函数中的判断逻辑选择执行相应的操作。
示例测试代码
#include <opencv2\opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
//全局变量
Mat img, img_point, img_point_Roi;//图片
Point prePoint, lastPoint;//起始点 终止点
Rect img_Roi;//感兴趣区
String img_file_name = "D:/img_file/00.jpg";//图片文件路径
//函数声明
void mouse(int event, int x, int y, int flags, void*);//鼠标事件回调函数
int main()
{
img = imread(img_file_name);
if (img.empty())
{
cout << "error open image file" << endl;
return -1;
}
img.copyTo(img_point);.//深拷贝
imshow("img", img);
imshow("img_point", img_point);
setMouseCallback("img_point", mouse, 0);
waitKey(0);
return 0;
}
void mouse(int event, int x, int y, int flags, void*)//鼠标事件回调函数
{
if (event == EVENT_LBUTTONDOWN)//左键按下
{
cout << "left button put down" << endl;
prePoint = Point(x, y);
cout << "first point" << prePoint << endl;
}
if ((event == EVENT_MOUSEMOVE) && (flags & EVENT_FLAG_LBUTTON))//鼠标移动 并且 按住左键拖拽
{
//cout << "mouse moving" << endl;
//显示鼠标移动轨迹
img_point.at<Vec3b>(y, x) = Vec3b(0, 0, 255);
img_point.at<Vec3b>(y + 1, x) = Vec3b(0, 0, 255);
img_point.at<Vec3b>(y - 1, x) = Vec3b(0, 0, 255);
img_point.at<Vec3b>(y, x + 1) = Vec3b(0, 0, 255);
img_point.at<Vec3b>(y, x - 1) = Vec3b(0, 0, 255);
imshow("img_point", img_point);
}
if (event == EVENT_LBUTTONUP)//释放左键
{
cout << "left button put up" << endl;
lastPoint = Point(x, y);
cout << "last point" << lastPoint << endl;
img_Roi = Rect(prePoint, lastPoint);//感兴趣区域
img_point_Roi = img(img_Roi)//截图
rectangle(img_point, prePoint, lastPoint, Scalar(0, 0, 255), 1, 8, 0);//绘制矩形
imshow("img_point_Roi", img_point_Roi);
imshow("img_point", img_point);
}
}
效果
总结
OpenCV对于图像处理的方法还是很多的,自己在开始学之后也发现能够实现一个功能的方式有很多种,当然自己所做的这个功能还是比较简单的,也只是后面很多步骤的一个开始。