OpenCV可以使用setMouseCallback设置鼠标事件的回调函数,从而然后根据需要进行处理。
setMouseCallback原型为:
void cv::setMouseCallback(const cv::String& windowName, MouseCallback onMouse, void* userData = 0);
其中,参数说明如下:
windowName:窗口名称
onMouse:回调函数的指针,用于处理鼠标事件
userData:用户数据指针,可以传递给回调函数
鼠标事件包括:
CV_EVENT_MOUSEMOVE:鼠标移动事件
CV_EVENT_LBUTTONDOWN:鼠标左键按下事件
CV_EVENT_LBUTTONUP:鼠标左键释放事件
CV_EVENT_RBUTTONDOWN:鼠标右键按下事件
CV_EVENT_RBUTTONUP:鼠标右键释放事件
CV_EVENT_MBUTTONDOWN:鼠标中键按下事件
CV_EVENT_MBUTTONUP:鼠标中键释放事件
回调函数的原型为:
void onMouse(int event, int x, int y, int flags, void* userdata);
其中,
event:鼠标事件类型
x、y:鼠标事件发生的位置
flags:鼠标事件的附加信息
userdata:用户数据指针
onMouse() 函数是一种回调函数,它将在用户与窗口交互时被调用。例如,当用户在窗口中单击鼠标时,这个函数将被调用。用户可以根据需要在这个函数中编写代码来响应鼠标事件。
void onMouse(int event, int x, int y, int flags, void* userdata);
event:表示鼠标事件的类型,可以是
CV_EVENT_MOUSEMOVE(鼠标移动)、CV_EVENT_LBUTTONUP(左键释放)、CV_EVENT_LBUTTONDOWN(左键按下)、CV_EVENT_RBUTTONUP(右键释放)、CV_EVENT_RBUTTONDOWN(右键按下)等。
x 和 y:表示鼠标事件在窗口中的坐标。
flags:表示鼠标的标志位,可以是
CV_EVENT_FLAG_LBUTTON(左键被按下)、CV_EVENT_FLAG_RBUTTON(右键被按下)、CV_EVENT_FLAG_MBUTTON(中键被按下)等。
userdata:表示用户自定义的数据,可以是任何类型的指针。
代码
ROI.cpp
#include <opencv2/opencv.hpp>
#include <stdio.h>
using namespace cv;
Mat src, temp;
void on_mouse(int event, int x, int y, int flags, void *userData)
{
static Point prePoint(0, 0);//初始坐标,设为static类型所以下次可以读取
static Point curPoint(0, 0);//实时坐标,设为static类型所以下次可以读取
src.copyTo(temp);//拷贝原图到缓存图像
if (event == CV_EVENT_LBUTTONDOWN)//左键按下,储存初始坐标
{
prePoint = Point(x, y);
}
if (event == CV_EVENT_MOUSEMOVE && !(flags & CV_EVENT_FLAG_LBUTTON))//鼠标移动时
{
}
else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))//鼠标按下左键并移动时,显示拖拽框
{
curPoint = Point(x, y);//储存当前鼠标坐标
rectangle(temp, prePoint, curPoint, Scalar(0, 255, 0), 2, 8, false);//实时绘制鼠标左键拖动时形成的矩形
imshow("img", temp);//显示绘制的图像
}
if (event == CV_EVENT_LBUTTONUP)//左键抬起
{
curPoint = Point(x, y);//储存当前鼠标坐标
//画坐标信息
char info[16] = {0};
sprintf(info,"(%d %d)",prePoint.x,prePoint.y);
putText(temp, info, prePoint, FONT_HERSHEY_SIMPLEX, 0.6, Scalar(0, 0, 255), 1, 8, false);//把表示鼠标左键按下时坐标的文字写到图像temp上
sprintf(info,"(%d %d)",curPoint.x,curPoint.y);
putText(temp, info, curPoint, FONT_HERSHEY_SIMPLEX, 0.6, Scalar(0, 0, 255), 1, 8, false);//把表示鼠标左键按下时坐标的文字写到图像temp上
//画拖拽框
rectangle(temp, prePoint, curPoint, Scalar(0, 255, 0), 2, 8, false);//根据初始点和结束点,将矩形画到temp上
//显示图片
imshow("img", temp);
//独立opencv窗口显示截取的图像
int width = abs(prePoint.x - curPoint.x);
int height = abs(prePoint.y - curPoint.y);
if (width == 0 || height == 0)//排除只点一下鼠标左键而没有进行拖曳操作的情况
{
;
}else{
Mat res = src(Rect(min(curPoint.x, prePoint.x), min(curPoint.y, prePoint.y), width, height));
destroyWindow("result");//避免上一次截取图像的显示对这一次截取图像的显示的影响
namedWindow("result");
imshow("result", res);
waitKey(0);
}
}
}
int main()
{
src = imread("D:\\z.jpg");
namedWindow("img");
imshow("img", src);
setMouseCallback("img", on_mouse, 0);//设置窗口鼠标事件回调函数
cv::waitKey(0);
return 0;
}
