OpenCV之鼠标操作

来源:互联网 发布:金十数据dora是谁 编辑:程序博客网 时间:2024/05/16 01:22

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;  } 

运行截图

这里写图片描述

1 0
原创粉丝点击