OpenCV-鼠标响应

OpenCV-鼠标响应

1.环境配置

OpenCV版本:OpenCV4

编程语言:C/C++

2.鼠标响应

OpenCV4中提供了鼠标响应相关函数setMouseCallback()。函数原型如下:

 void cv::setMouseCallback(const String& winname,
                           MouseCallback onMouse,
                           void* userdata = 0)
 /*
  * winname:添加鼠标响应的窗口的名字
  * onMouse:鼠标响应的回调函数
  * userdata:传递给回调函数的可选参数
  */

该函数能够为指定的图像窗口创建鼠标响应。第二个参数是鼠标响应的回调函数,该函数在鼠标状态发生改变时被调用,是一个MouseCallback类型的函数。

MouseCallback类型的回调函数。函数原型如下:

 typedef void(*cv::MouseCallback)(int event,
                                  int x,
                                  int y,
                                  int flags,
                                  void* userdata)
 /*
  * event:鼠标响应事件标志,参数为EVENT_*形式
  * x:鼠标指针在图像坐标系中的x坐标
  * y:鼠标指针在图像坐标系中的y坐标
  * flags:鼠标响应标志,参数为EVENT_FLAG_*形式
  * userdata:传递给回调函数的可选参数
  */

MouseCallback类型的回调函数是一个无返回值的函数,函数名可以任意设置,有5个参数,在鼠标状态发生改变的时候被调用。

MouseCallback类型回调函数鼠标响应事件标志可选参数及含义

标志参数 简记 含义
EVENT_MOUSEMOVE 0 表示鼠标指针在窗口上移动
EVENT_LBUTTONDOWN 1 表示按下鼠标左键
EVENT_RBUTTONDOWN 2 表示按下鼠标右键
EVENT_MBUTTONDOWN 3 表示按下鼠标中键
EVENT_LBUTTONUP 4 表示释放鼠标左键
EVENT_RBUTTONIP 5 表示释放鼠标右键
EVENT_MBUTTONUP 6 表示释放鼠标中键
EVENT_LBUTTONDBLCLK 7 表示双击鼠标左键
EVENT_RBUTTONDBLCLK 8 表示双击鼠标右键
EVENT_MBUTTONDBLCLK 9 表示双击鼠标中键
EVENT_MOUSEWHEEL 10 正值表示向前滚动,负值表示向后滚动
EVENT_MOUSEHWHEEL 11 正值表示向左滚动,负值表示向右滚动

MouseCallback类型回调函数鼠标响应标志及含义

标志参数 简记 含义
EVENT_FLAG_LBUTTON 1 按住左键拖拽
EVENT_FLAG_RBUTTON 2 按住右键拖拽
EVENT_FLAG_MBUTTON 4 按住中键拖拽
EVENT_FLAG_CTRLKEY 8 按"Ctrl"键
EVENT_FLAG_SHIFTKEY 16 按"Shift"键
EVENT_FLAG_ALTKEY 32 按"Alt"键

鼠标响应就是当鼠标位于对应的图像窗口内时,时刻检测鼠标状态,当鼠标状态发生改变时,调用回调函数,并根据回调函数中的判断逻辑选择执行相应的操作。

3.示例程序

直接看例程会好理解一些。绘制鼠标移动轨迹的示例程序。在该程序中,如果鼠标右键被按下,就会提示“点击鼠标左键才可以绘制轨迹”,若单机左键,就会输出当前鼠标的坐标,并将该点坐标定义为某段轨迹的起始位置。之后按住左键移动鼠标,会进入到第三个逻辑判断,绘制鼠标的移动轨迹。

 #include 
 #include 
 ​
 using namespace std;
 using namespace cv;
 ​
 Mat img, imgPoint;
 Point prePoint;     // 前一刻鼠标的坐标,用于绘制直线
 // 鼠标响应回调函数
 void mouse(int event, int x, int y, int flags, void* userdata);
 ​
 int main(void)
 {
     img = imread("lena.png");   // 输入图片位置
     if (!img.data)
     {
         cout << "请确认输入图像名称是否正确!" << endl;
         return -1;
     }
 ​
     img.copyTo(imgPoint);
     imshow("图像窗口1", img);
     imshow("图像窗口2", imgPoint);
 ​
     // 鼠标响应函数
     setMouseCallback("图像窗口1", mouse, 0);
 ​
     waitKey(0);
 ​
     return 0;
 }
 ​
 // 鼠标响应回调函数
 void mouse(int event, int x, int y, int flags, void* userdata)
 {
     if (EVENT_RBUTTONDOWN == event)     // 单击右键
         cout << "点击鼠标左键才可以绘制轨迹" << endl;
     if (EVENT_LBUTTONDOWN == event)     // 单击左键
     {
         prePoint = Point(x, y);
         cout << "轨迹起始坐标" << prePoint << endl;
     }
     
     // 开始绘制鼠标移动的轨迹
     // 鼠标指针在窗口上移动 && 按住左键拖拽
     if (EVENT_MOUSEMOVE == event && (flags & EVENT_FLAG_LBUTTON)) 
     {
         // 通过改变图像像素显示鼠标移动轨迹
         imgPoint.at(y, x) = Vec3b(0, 0, 255);
         imgPoint.at(y, x - 1) = Vec3b(0, 0, 255);
         imgPoint.at(y, x + 1) = Vec3b(0, 0, 255);
         imgPoint.at(y + 1, x) = Vec3b(0, 0, 255);
         imgPoint.at(y - 1, x) = Vec3b(0, 0, 255);
         imshow("图像窗口2", imgPoint);
 ​
         // 通过绘制直线显示鼠标移动轨迹
         Point pt(x, y);     // 当前鼠标坐标
         line(img, prePoint, pt, Scalar(0, 0, 255), 2, 5, 0);
         prePoint = pt;
         imshow("图像窗口1", img);
     }
 }
 ​

你可能感兴趣的:(OpenCV,opencv,c++,linux)