OpenCV是一个著名的计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
程序的大致效果就是:显示一张较大的图像,鼠标在图像上移动的时候会实时的显示一个"十"字的交叉线,然后在图像上点两个点得到的矩形框就是感兴趣区域。
一、介绍一下OpenCV中如何设置鼠标事件的回调函数
1)设置鼠标回调函数
void SetMouseCallback(const string & winname,MouseCallback onMouse,void* userdata=0)
参数说明:
winname: 窗口的名字
onMouse: 鼠标事件发生的时候,调用的函数的函数指针
userdata: 在鼠标事件发生的时候,传给调用函数的参数
2)对第二个参数MouseCallback onMouse的详细说明:
它表示鼠标事件发生的时候,被调用的函数的函数指针,其函数原型为:
void my_mouse(int event, int x, int y, int flags, void* param);
- event是鼠标事件类型,OpenCV中定义的常见事件有(枚举类型变量):
CV_EVENT_MOUSEMOVE =0,CV_EVENT_LBUTTONDOWN =1,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
- x, y表示鼠标在图像坐标系中的位置
- flags是CV_EVENT_FLAG的组合,用来表示鼠标拖拽的事件,其状态有:
EVENT_FLAG_LBUTTON //左键拖拽EVENT_FLAG_RBUTTON //右键拖拽EVENT_FLAG_MBUTTON //中键拖拽EVENT_FLAG_CTRLKEY //按住Ctrl不放EVENT_FLAG_SHIFTKEY //按住Shift不放EVENT_FLAG_ALTKEY //按住Alt不放
- params用来接收函数被调用时,用户传给它的数据(注意是一个void*类型)
二、上代码
#include #include #include using namespace cv;using namespace std;#define WIN_NAME "Pano"#define PANO_IMAGE_PATH "/home/llf/Pictures/cat.jpg"#define ROI_SAVE_PATH "/home/llf/Pictures/res_roi.jpg"Mat pano, pano_raw, pano_dst;vector two_points;/* * 鼠标事件回调*/void my_mouse_call_back(int event, int x, int y, int flags, void* param) { switch (event) { case CV_EVENT_MOUSEMOVE: pano = pano_raw.clone(); line(pano, Point(x, 0), Point(x, pano.rows), Scalar(0, 255, 0), 5); line(pano, Point(0, y), Point(pano.cols, y), Scalar(0, 255, 0), 5); break; case CV_EVENT_LBUTTONDOWN: if(two_points.size() < 2) { Point p(x, y); two_points.push_back(p); line(pano_raw, Point(x, 0), Point(x, pano_raw.rows), Scalar(0, 255, 0), 10); line(pano_raw, Point(0, y), Point(pano_raw.cols, y), Scalar(0, 255, 0), 10); } break; case CV_EVENT_RBUTTONDOWN: { Mat roi = pano_dst(Rect(two_points[0], two_points[1])); namedWindow("roi", WINDOW_NORMAL); imshow("roi", roi); waitKey(0); imwrite(ROI_SAVE_PATH, roi); destroyWindow("roi"); } break; default: break; }}int main(int argc, char **argv) { pano = imread(PANO_IMAGE_PATH, IMREAD_COLOR); pano_dst = (pano_raw = pano.clone()).clone(); namedWindow(WIN_NAME, WINDOW_NORMAL); setMouseCallback(WIN_NAME, my_mouse_call_back, NULL); int key = -1; while(27 != key) { imshow(WIN_NAME, pano); key = waitKey(20); } return 0;}
效果:鼠标挪到哪里,十字架的中心就挪到哪里
如果对我的推|文有兴趣,欢迎转|载分|享。也可以推|荐给朋友关|注哦。只推干货,宁缺毋滥。