前面介绍了图像处理中的Canny边缘检测、轮廓检测、直方图以及直方图均衡化。本篇介绍个互动性强一点内容——用鼠标绘图。在OpenCV中进行鼠标绘图也是非常简易的,主要使用到cvSetMouseCallback函数,下请看介绍。
函数功能:设置处理鼠标消息的回调函数
函数原型:
/* assign callback for mouse events */
CVAPI(void) cvSetMouseCallback(
const char* window_name,
CvMouseCallback on_mouse,
void* param CV_DEFAULT(NULL)
);
函数说明:
第一个参数表示窗口名称。
第二个参数表示鼠标消息的消息处理函数。
第三个参数表示用户定义传入鼠标指定消息处理函数的参数。
函数功能:鼠标消息的回调函数
函数原型:
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.csdn.net/MoreWindows)
#include
using namespace std;
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
const char *pstrWindowsMouseDrawTitle = "鼠标绘图(http://blog.csdn.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;
}
运行效果如下图所示:
画一些复杂的图画也可以。
瓶花:
玫瑰:
米老鼠:
呵呵,由于程序只能画黑白图像,要能支持彩色画笔估计画图效果会好的多。
如果我们要写自己写的好OpenCV分享给其它人使用应该怎么做了?请看《【OpenCV入门指南】第十二篇分享OpenCV程序》
《OpenCV入门指南》系列文章地址:http://blog.csdn.net/morewindows/article/category/863841
转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/8426283
欢迎关注微博:http://weibo.com/MoreWindows