opencv之滑鼠響應函式
阿新 • • 發佈:2021-06-28
目錄
背景
- 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的.