【人脸检测】第十一篇 鼠标绘图
注:转载至https://blog.****.net/morewindows/article/details/8426283
【人脸检测】第十一篇 鼠标绘图
前面介绍了图像处理中的Canny边缘检测、轮廓检测、直方图以及直方图均衡化。本篇介绍个互动性强一点内容——用鼠标绘图。在OpenCV中进行鼠标绘图也是非常简易的,主要使用到cvSetMouseCallback函数,下请看介绍。
一.关键函数
1.1 cvSetMouseCallback
函数功能:设置处理鼠标消息的回调函数
函数原型:
/* assign callback for mouse events */
CVAPI(void) cvSetMouseCallback(
const char* window_name,
CvMouseCallback on_mouse,
void* param CV_DEFAULT(NULL)
);
函数说明:
第一个参数表示窗口名称。
第二个参数表示鼠标消息的消息处理函数。
第三个参数表示用户定义传入鼠标指定消息处理函数的参数。
1.2 CvMouseCallback
函数功能:鼠标消息的回调函数
函数原型:
typedef void (CV_CDECL *CvMouseCallback )(int event, int x, int y, int flags, void* param);
函数说明:
第一个参数表示鼠标消息类型,取值如下:
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()中将接收到的参数。
二.示例程序代码
代码示范如下,按下‘r’键可以重新绘图,按下‘s’键则保存图片到磁盘中。
- // 鼠标绘图
- //By MoreWindows (http://blog.****.net/MoreWindows)
- #include <opencv2/opencv.hpp>
- using namespace std;
- #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
- const char *pstrWindowsMouseDrawTitle = "鼠标绘图(http://blog.****.net/MoreWindows)";
- // 鼠标消息的回调函数
- 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)); //可以用cvSet()将图像填充成白色
- 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;
- }
运行效果如下图所示:
画一些复杂的图画也可以。
瓶花:
玫瑰:
米老鼠:
呵呵,由于程序只能画黑白图像,要能支持彩色画笔估计画图效果会好的多。