1. 程式人生 > 其它 >opencv之滑鼠響應函式

opencv之滑鼠響應函式

目錄

背景

  • 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的.

參考