背景
- setMouseCallback()函数
void setMouseCallback(const string& winname, //图像视窗名称
MouseCallback onMouse, //鼠标响应函数,监视到鼠标操作后调用并处理相应动作
void* userdata = 0 //鼠标响应处理函数的ID,识别号
);
- OnMouseAction()响应函数
void OnMouseAction(int event,int x,int y,int flags,void *user_data)
{
// 自定义
}
- x, y
x - x coordinate of the mouse event
y - y coordinate of the mouse event
- Event
#define CV_EVENT_MOUSEMOVE 0 //滑动
#define CV_EVENT_LBUTTONDOWN 1 //左键点击
#define CV_EVENT_RBUTTONDOWN 2 //右键点击
#define CV_EVENT_MBUTTONDOWN 3 //中键点击
#define CV_EVENT_LBUTTONUP 4 //左键放开
#define CV_EVENT_RBUTTONUP 5 //右键放开
#define CV_EVENT_MBUTTONUP 6 //中键放开
#define CV_EVENT_LBUTTONDBLCLK 7 //左键双击
#define CV_EVENT_RBUTTONDBLCLK 8 //右键双击
#define CV_EVENT_MBUTTONDBLCLK 9 //中键双击
- flags
#define CV_EVENT_FLAG_LBUTTON 1 //左鍵拖曳
#define CV_EVENT_FLAG_RBUTTON 2 //右鍵拖曳
#define CV_EVENT_FLAG_MBUTTON 4 //中鍵拖曳
#define CV_EVENT_FLAG_CTRLKEY 8 //(8~15)按Ctrl不放事件
#define CV_EVENT_FLAG_SHIFTKEY 16 //(16~31)按Shift不放事件
#define CV_EVENT_FLAG_ALTKEY 32 //(32~39)按Alt不放事件
- userdata
Any pointer passes to the "**setMouseCallback"** function as the 3rd parameter (see below)
示例1
捕捉光标在图像中的移动实践, 并返回光标在图像中的坐标, 同时捕捉鼠标的左键, 中建和右键的响应实践.
#include <opencv2/opencv.hpp>
void CallBackFunc(int event, int x, int y, int flags, void* userdata)
{
if ( event == CV_EVENT_LBUTTONDOWN )
{
std::cout << "Left button of the mouse is clicked - position (" << x << ", " << y << ")" << std::endl;
}
else if ( event == CV_EVENT_RBUTTONDOWN )
{
std::cout << "Right button of the mouse is clicked - position (" << x << ", " << y << ")" << std::endl;
}
else if ( event == CV_EVENT_MBUTTONDOWN )
{
std::cout << "Middle button of the mouse is clicked - position (" << x << ", " << y << ")" << std::endl;
}
else if ( event == CV_EVENT_MOUSEMOVE )
{
std::cout << "Mouse move over the window - position (" << x << ", " << y << ")" << std::endl;
}
}
int main()
{
// Read image from file
cv::Mat img(480, 640, CV_8S, cv::Scalar(0));
//if fail to read the image
if ( img.empty() )
{
std::cout << "Error loading the image" << std::endl;
return -1;
}
cv::namedWindow("ImageDisplay", 1);
cv::imshow("ImageDisplay", img);
cv::setMouseCallback("ImageDisplay", CallBackFunc, NULL);
cv::waitKey(0);
return 0;
}
示例2
捕捉按下ctrl按键, 同时点击鼠标左键.....
#include <opencv2/opencv.hpp>
void CallBackFunc(int event, int x, int y, int flags, void* userdata)
{
if ( flags == (CV_EVENT_FLAG_CTRLKEY + CV_EVENT_FLAG_LBUTTON) )
{
std::cout << "Left mouse button is clicked while pressing CTRL key - position (" << x << ", " << y << ")" << std::endl;
}
else if ( flags == (CV_EVENT_FLAG_RBUTTON + CV_EVENT_FLAG_SHIFTKEY) )
{
std::cout << "Right mouse button is clicked while pressing SHIFT key - position (" << x << ", " << y << ")" << std::endl;
}
else if ( event == CV_EVENT_MOUSEMOVE && flags == CV_EVENT_FLAG_ALTKEY)
{
std::cout << "Mouse is moved over the window while pressing ALT key - position (" << x << ", " << y << ")" << std::endl;
}
}
int main(int argc, char** argv)
{
// Read image from file
cv::Mat img(480, 640, CV_8S, cv::Scalar(0));
//if fail to read the image
if ( img.empty() )
{
std::cout << "Error loading the image" << std::endl;
return -1;
}
cv::namedWindow("My Window", 1);
cv::setMouseCallback("My Window", CallBackFunc, NULL);
cv::imshow("My Window", img);
cv::waitKey(0);
return 0;
}
示例3
捕捉鼠标左键点击时间, 同时返回该光标的像素强度.
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace std;
using namespace cv;
void mouseEvent(int evt, int x, int y, int flags, void* param)
{
Mat* rgb = (Mat*) param;
if (evt == CV_EVENT_LBUTTONDOWN)
{
printf("%d %d: %d, %d, %d\n",
x, y,
(int)(*rgb).at<Vec3b>(y, x)[0],
(int)(*rgb).at<Vec3b>(y, x)[1],
(int)(*rgb).at<Vec3b>(y, x)[2]);
}
}
int main(int argc, char** argv)
{
// Read image from file
Mat img = imread("lena.JPG");
//if fail to read the image
if ( img.empty() )
{
cout << "Error loading the image" << endl;
return -1;
}
//Create a window
namedWindow("My Window", 1);
//set the callback function for any mouse event
setMouseCallback("My Window", mouseEvent, &img);
//show the image
imshow("My Window", img);
// Wait until user press some key
waitKey(0);
return 0;
}
示例4
捕捉鼠标左键点击时间, 同时捕捉鼠标拖动框选时间,
void onMouseAction(int event, int x, int y, int flag, void* g)
{
CalibEva* pthis = (CalibEva*)g;
cv::Point& begin_point = pthis->begin_point_;
cv::Point& end_point = pthis->end_point_;
bool& is_mouse_move = pthis->is_mouse_move_;
if (event == CV_EVENT_LBUTTONDOWN)
{
// INFO << "CV_EVENT_LBUTTONDOWN" << REND;
begin_point = cv::Point(x, y);
}
else if (event == CV_EVENT_LBUTTONUP)
{
// INFO << "CV_EVENT_LBUTTONUP" << REND;
end_point = cv::Point(x, y);
}
else if (event == CV_EVENT_MOUSEMOVE && (flag & CV_EVENT_FLAG_LBUTTON))
{
// INFO << "CV_EVENT_MOUSEMOVE" << REND;
is_mouse_move = true;
}
}
- 点击时间
// pick one corner point
cv::namedWindow("input_image", cv::WINDOW_NORMAL);
INFO << "Please pick the board corner in input image window!" << REND;
cv::imshow("input_image", input_image);
cv::setMouseCallback("input_image", onMouseAction, this);
cv::waitKey(0);
image_corner_point = end_point_;
- 拖动事件
cv::namedWindow("edge_cloud", cv::WINDOW_NORMAL);
INFO << "Please pick the " << select_line_num << " rectangle in edge cloud windows!" << REND;
cv::imshow("edge_cloud", edge_image);
cv::setMouseCallback("edge_cloud", onMouseAction, this);
cv::waitKey(0);
cv::rectangle(edge_image, cv::Rect(begin_point_, end_point_), cv::Scalar(255));
备注: 将类的this指针传递给callback函数, 其中用到的成员数据需要为public的, 有个判断是否有拖动的flag的.