OpenCV之鼠标操作

OpenCV之鼠标操作

opencv中的鼠标响应的函数是setMouseCallback(),可以实现画图的功能。

c++

void setMousecallback(
      const string& winname, 
      MouseCallback onMouse, 
      void* userdata=0
)
参数解释
winname窗口的名字
onMouse鼠标响应函数,回调函数。指定窗口里每次鼠标时间发生的时候,被调用的函数指针。
userdate传给回调函数的参数
函数的原型应该为
typedef void (CV_CDECL *CvMouseCallback )
      int event, 
      int x, 
      int flags, 
);

第一个参数表示鼠标消息类型,取值如下:

enum

{

CV_EVENT_MOUSEMOVE      =0,

CV_EVENT_LBUTTONDOWN    =1,

CV_EVENT_RBUTTONDOWN    =2,

CV_EVENT_MBUTTONDOWN    =3,

CV_EVENT_LBUTTONUP      =4,

CV_EVENT_RBUTTONUP      =5,

CV_EVENT_MBUTTONUP      =6,

CV_EVENT_LBUTTONDBLCLK  =7,

CV_EVENT_RBUTTONDBLCLK  =8,

CV_EVENT_MBUTTONDBLCLK  =9

};

第二,三个参数表示鼠标的坐标。

第四个参数表示附加事件,取值如下:

enum

{

CV_EVENT_FLAG_LBUTTON   =1,

CV_EVENT_FLAG_RBUTTON   =2,

CV_EVENT_FLAG_MBUTTON   =4,

CV_EVENT_FLAG_CTRLKEY   =8,

CV_EVENT_FLAG_SHIFTKEY  =16,

CV_EVENT_FLAG_ALTKEY    =32

};

第五个参数即设置cvSetMouseCallback()中将接收到的参数

code1

绘制长方形
#include <opencv2/opencv.hpp>
using namespace cv;

#define WINDOW_NAME "【程序窗口】" 

//      描述:全局函数的声明
void on_MouseHandle(int event, int x, int y, int flags, void* param);
void DrawRectangle(cv::Mat& img, cv::Rect box);

//描述:全局变量的声明
Rect g_rectangle;
bool g_bDrawingBox = false;//是否进行绘制
RNG g_rng(12345);

int main(int argc, char** argv)
{
    //改变console字体颜色
    system("color 9F");
    //准备参数
    g_rectangle = Rect(-1, -1, 0, 0);
    Mat srcImage(600, 800, CV_8UC3), tempImage;
    srcImage.copyTo(tempImage);
    g_rectangle = Rect(-1, -1, 0, 0);
    srcImage = Scalar::all(0);

    //设置鼠标操作回调函数
    namedWindow(WINDOW_NAME);
    setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);

    //程序主循环,当进行绘制的标识符为真时,进行绘制
    while (1)
    {
        //拷贝源图到临时变量
        srcImage.copyTo(tempImage);
        //当进行绘制的标识符为真,则进行绘制
        if (g_bDrawingBox) DrawRectangle(tempImage, g_rectangle);
        imshow(WINDOW_NAME, tempImage);
        if (waitKey(10) == 27) break;//按下ESC键,程序退出
    }
    return 0;
}


//      描述:鼠标回调函数,根据不同的鼠标事件进行不同的操作
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{

    Mat& image = *(cv::Mat*) param;
    switch (event)
    {
        //鼠标移动消息
    case EVENT_MOUSEMOVE:
    {
                            if (g_bDrawingBox)//如果是否进行绘制的标识符为真,则记录下长和宽到RECT型变量中
                            {
                                g_rectangle.width = x - g_rectangle.x;
                                g_rectangle.height = y - g_rectangle.y;
                            }
    }
        break;

        //左键按下消息
    case EVENT_LBUTTONDOWN:
    {
                              g_bDrawingBox = true;
                              g_rectangle = Rect(x, y, 0, 0);//记录起始点
    }
        break;

        //左键抬起消息
    case EVENT_LBUTTONUP:
    {
                            g_bDrawingBox = false;//置标识符为false
                            //对宽和高小于0的处理
                            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;
                            }
                            //调用函数进行绘制
                            DrawRectangle(image, g_rectangle);
    }
        break;

    }
}

//描述:自定义的矩形绘制函数
void DrawRectangle(cv::Mat& img, cv::Rect box)
{
    cv::rectangle(img, box.tl(), box.br(), cv::Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));//随机颜色
}

运行截图

这里写图片描述

code2

自由绘制
#include <opencv2/opencv.hpp>  
using namespace std; 
//隐藏命令行窗口 
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")  
const char *pstrWindowsMouseDrawTitle = "绘图";  
// 鼠标消息的回调函数  
void on_mouse(int event, int x, int y, int flags, void* param)  
{  
    static bool s_bMouseLButtonDown = false;  
    static CvPoint s_cvPrePoint = cvPoint(0, 0);  

    switch (event)  
    {  
    case CV_EVENT_LBUTTONDOWN:  
        s_bMouseLButtonDown = true;  
        s_cvPrePoint = cvPoint(x, y);  
        break;  

    case  CV_EVENT_LBUTTONUP:  
        s_bMouseLButtonDown = false;  
        break;  

    case CV_EVENT_MOUSEMOVE:  
        if (s_bMouseLButtonDown)  
        {  
            CvPoint cvCurrPoint = cvPoint(x, y);  
            cvLine((IplImage*)param, s_cvPrePoint, cvCurrPoint, CV_RGB(0, 0, 20), 3);  
            s_cvPrePoint = cvCurrPoint;  
            cvShowImage(pstrWindowsMouseDrawTitle, (IplImage*)param);  
        }  
        break;  
    }  
}  
int main()  
{     
    const int MAX_WIDTH = 500, MAX_HEIGHT = 400; 
    //保存绘制的图像 
    const char *pstrSaveImageName = "MouseDraw.jpg";  

    IplImage *pSrcImage =  cvCreateImage(cvSize(MAX_WIDTH, MAX_HEIGHT), IPL_DEPTH_8U, 3);  
    cvSet(pSrcImage, CV_RGB(255, 255, 255)); 
    cvNamedWindow(pstrWindowsMouseDrawTitle, CV_WINDOW_AUTOSIZE);  
    cvShowImage(pstrWindowsMouseDrawTitle, pSrcImage);  

    cvSetMouseCallback(pstrWindowsMouseDrawTitle, on_mouse, (void*)pSrcImage);  

    int c;  
    do{  
        c = cvWaitKey(0);  
        switch ((char)c)  
        {  
        case 'r':  
            cvSet(pSrcImage, CV_RGB(255, 255, 255));  
            cvShowImage(pstrWindowsMouseDrawTitle, pSrcImage);  
            break;  

        case 's':  
            cvSaveImage(pstrSaveImageName, pSrcImage);  
            break;  
        }  
    }while (c > 0 && c != 27);  

    cvDestroyWindow(pstrWindowsMouseDrawTitle);  
    cvReleaseImage(&pSrcImage);  
    return 0;  
} 

运行截图

这里写图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值