鼠标操作[OpenCV 笔记10]

void setMouseCallback(const string& winname, MouseCallback onMouse, void* userdata=0)

winname

窗口名字

onMouse

指定窗口每次鼠标事件发生的时候,被调用的函数指针。函数的原型应为void Foo(int event, int x, int y, int flags, void* param)。

  • event: 变量EVENT_XXX,例如
    • EVNET_MOUSEMOVE: 鼠标移动消息
    • EVENT_LBUTTONDOWN: 鼠标左键按下消息
  • x, y: 鼠标指针在图像坐标系中的坐标值(不是窗口坐标系)
  • flags: EVENT_FLAG的组合
  • param: 用户定义的传到SetMouseCallback函数调用的参数

userdata

用户定义的传递到回调函数的参数

示例

用鼠标在画框中华矩形,MouseEvent.cxx:

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

#define WINDOW_NAME "Painting Window"

// global function declaration
void on_MouseHandle( int event, int x, int y, int flags, void* param );
void DrawRectangle( cv::Mat& img, cv::Rect box );
void ShowHelpText();

// global variables
cv::Rect g_rectangle;
bool g_bDrawingBox = false; // draw or not
cv::RNG g_rng(12345);

// main
int main( int argc, char** argv )
{
    // initialize parameters
    g_rectangle = cv::Rect( -1, -1, 0, 0 );
    cv::Mat srcImage( 600, 800, CV_8UC3 ), tempImage;
    srcImage.copyTo( tempImage );
    
    g_rectangle = cv::Rect( -1, -1, 0, 0 );
    srcImage = cv::Scalar::all(0);
    
    // create window
    cv::namedWindow(WINDOW_NAME);
    
    // set call back function
    cvSetMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);
    
    while(1)
    {
        srcImage.copyTo(tempImage);
        
        // show rectangle while the mouse moves
        if (g_bDrawingBox)
            DrawRectangle(tempImage, g_rectangle);
        
        cv::imshow(WINDOW_NAME, tempImage);
        
        if (cvWaitKey(10)==27) {
            cv::imwrite("result.jpg", tempImage);
            break; // Press ECS to exit.
        }
    }
    return 0;
}

// mouse call back function
void on_MouseHandle( int event, int x, int y, int flags, void* param )
{
    cv::Mat& image = *(cv::Mat*) param;
    switch (event) {
        case cv::EVENT_MOUSEMOVE:
            // if mouse moved and drawing flag is true, update the rectangle size
            if (g_bDrawingBox) {
                g_rectangle.width = x-g_rectangle.x;
                g_rectangle.height = y-g_rectangle.y;
            }
            break;
        case cv::EVENT_LBUTTONDOWN:
            // if left button was clicked, prepare to draw rectangle
            //  (set the flag as true and mark the start position)
            {
                g_bDrawingBox = true;
                g_rectangle = cv::Rect( x, y, 0, 0 );  // mark the start point
            }
            break;
        case cv::EVENT_LBUTTONUP:
        {
            g_bDrawingBox = 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;
            }
            // draw
            DrawRectangle(image, g_rectangle);
        }
            break;
    }
}

// user defined function to draw rectangle
void DrawRectangle( cv::Mat& img, cv::Rect box )
{
    // random color
    cv::rectangle(img, box.tl(), box.br(), cv::Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));
}

结果图

原文地址:https://www.cnblogs.com/Xiaoyan-Li/p/5677289.html