#include1.目的#include using namespace std; using namespace cv; Mat img; void onMouse(int event, int x, int y, int flags, void* param) { if (event == EVENT_LBUTTONDOWN) { cout << "Mouse Down" << endl; circle(img, Point(x, y), 50, Scalar(0, 0, 0), 2, 8); } } int main() { //=================================================读图 //=================================================读取视频 //========================================================画线画矩形以及写字 //Mat img = Mat(300, 300, CV_8UC3, Scalar(0, 0, 0)); //line(img, Point(20, 20), Point(200, 200), Scalar(0, 255, 255),2,8); //circle(img, Point(150, 150), 100, Scalar(255, 0, 0), 2, 8); //rectangle(img, Point(20, 20), Point(200, 200), Scalar(255, 255, 255), 2, 8); //若线宽设置为 -1 ,则为填充 //putText(img, "Open CV", Point(150, 150), FONT_HERSHEY_COMPLEX, 0.5, Scalar(0, 255, 0), 1, 8); //namedWindow("img", WINDOW_NORMAL); //imshow("img", img); //waitKey(0); //destroyAllWindows(); //============================================================鼠标回调事件 img = Mat(500, 500, CV_8UC3, Scalar(255, 255, 255)); namedWindow("Mouse", WINDOW_NORMAL); setMouseCallback("Mouse",onMouse,&img); while (1) { imshow("Mouse", img); if (27 == waitKey(20)) { break; //20ms刷新一次显示,如果按下Esc则退出循环 } } destroyAllWindows(); }
读取一张图片,在该图片上截取一个ROI区域,将截取的图像在新窗口显示,并可以保存至工程目录下。
2.实现环境
C++、VS2019、opencv4.3.0
3.回调函数原理
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方法直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
4.实现代码如下:
#include#include using namespace cv; #define WINDOW "程序窗口" void on_MouseHandle(int event, int x, int y, int flags, void*param); void DrawRectangle(Mat& _img, Rect& _box); void shotScreen(Mat& _img); Rect g_rectangle;//截图位置信息 bool g_drawingBox = false;//绘图标识 Mat srcROI;//截图 int main() { g_rectangle = Rect(-1, -1, 0, 0); Mat srcImg, tempImg; srcImg = imread("../Leana.png");//读取图片 srcImg.copyTo(tempImg); namedWindow(WINDOW);//定义一个窗口 setMouseCallback(WINDOW, on_MouseHandle, (void*)&srcImg);//对WINDOW窗口进行鼠标检测 //不断更新 while (1) { srcImg.copyTo(tempImg); if (g_drawingBox) DrawRectangle(tempImg, g_rectangle);//画出矩形g_rectangle imshow(WINDOW, tempImg); if (waitKey(10) == 27)//按下esc结束 break; } return 0; } //event:鼠标事件标志(不需要自己传参) //x:鼠标在窗口中的x坐标 //y:鼠标在窗口中的y坐标 //flags:自定义的宏,做标记符,Ture时开始绘制矩形,false时不绘制 //* param:传入的图像 void on_MouseHandle(int event, int x, int y, int flags, void*param) { Mat& img = *(Mat*)param; switch (event)//检测鼠标事件 { case EVENT_MOUSEMOVE://鼠标移动事件 { if (g_drawingBox)//如果鼠标左键按下,则计算当前位置g_rectangle的宽高 { g_rectangle.width = x - g_rectangle.x; g_rectangle.height = y - g_rectangle.y; } } break; case EVENT_LBUTTONDOWN://鼠标左键按下事件 { g_drawingBox = true;//将绘图标识设为真,准备绘图 g_rectangle = Rect(x, y, 0, 0);//保存起点 } break; case EVENT_LBUTTONUP://鼠标左键抬起事件 { g_drawingBox = false;//将绘图标识设为假,停止绘图 //处理截图区域(因为向上截取则宽高为负,需要转换成正值) if (g_rectangle.width < 0) { g_rectangle.x += g_rectangle.width; g_rectangle.width *= (-1); } if (g_rectangle.height < 0) { g_rectangle.y += g_rectangle.height; g_rectangle.height *= (-1); } //若截图区域面积为0,则不进行截图 if (g_rectangle.width != 0 || g_rectangle.height != 0) { srcROI = img(g_rectangle); shotScreen(srcROI); } } break; } } void DrawRectangle(Mat& _img, Rect& _box) { rectangle(_img, _box.tl(), _box.br(), Scalar(0, 0, 255)); } //_img:截取的图片 void shotScreen(Mat& _img) { imshow("截图", _img); UINT ret = MessageBox(NULL, "是否保存当前截图", "提示", MB_YESNO); if (ret == IDYES) imwrite("../截图.png", _img); else destroyWindow("截图"); }


![Opencv鼠标回调函数[SetMouseCallBack] Opencv鼠标回调函数[SetMouseCallBack]](http://www.mshxw.com/aiimages/31/889511.png)
