鼠标截图
在图上做标记时,opencv主要用setMouseCallback()这个函数,下面来讲解:
一、setMouseCallback()
void setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0)
winname:窗口的名字;userdate:传给回调函数的参数;
onMouse:鼠标响应函数,回调函数。指定窗口里每次鼠标事件发生的时候,被调用的函数指针。 这个函数的原型为:
void on_Mouse(int event, int x, int y, int flags, void* param);
event是 CV_EVENT_*变量之一
x和y是鼠标指针在图像坐标系的坐标(不是窗口坐标系)
flags是CV_EVENT_FLAG的组合, param是用户定义的传递到setMouseCallback函数调用的参数。
//常用的event:
#define CV_EVENT_MOUSEMOVE//移动
#define CV_EVENT_LBUTTONDOWN //左键按下
#define CV_EVENT_RBUTTONDOWN //右键按下
#define CV_EVENT_LBUTTONUP //左键抬起
#define CV_EVENT_RBUTTONUP //右键抬起
例程:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv; //不需要每次都输入 cv::
Mat ROI; Point pt;//鼠标截取图像的一部分
bool flag = false;
Mat img = imread("121.jpg");
Mat img_copy = img.clone();//clone 是完全的深拷贝,在内存中申请新的空间,与A独立
void onMouse(int event, int x, int y, int flag, void*) {
switch (event)
{
case CV_EVENT_LBUTTONDOWN://左键按下
flag = true;
pt.x = x;
pt.y = y;
break;
case CV_EVENT_MOUSEMOVE://鼠标移动
if (flag) { //只有在点击鼠标左键的情况下移动鼠标才执行
img_copy.copyTo(img);
//以便永远只有一个矩形(否则许多矩形会重叠在一起),清除之前在img图像上,鼠标移动产生的矩形框,只保留最终的一个矩形框
rectangle(img, pt, Point(x, y), Scalar(255, 0, 0), 2, 8);//定义一个矩形框,pt表示起始点(按下左键时的鼠标左标);Point表示实时变化的坐标点;颜色;线宽;线型
}
break;
case CV_EVENT_LBUTTONUP://左键抬起
flag = false;
ROI = img_copy(Rect(pt.x, pt.y, x - pt.x, y - pt.y));//x,y,宽,高
imshow("ROI", ROI);
//imwrite("filename",ROI);
break;
default:
break;
}
}
void main(){
namedWindow("mouse", CV_WINDOW_AUTOSIZE);
setMouseCallback("mouse", onMouse, 0); //每次鼠标放在图中区域,就会触发onMouse函数
while (1) {
imshow("mouse", img);
if (27 == waitKey(20))//按ESC键退出(esc键对应的ascall码是27)
break;
}
}
结果: