先上代码,再讲解
// 手写板.cpp: 实现移动鼠标的手写板
//
#include "stdafx.h"
#include
#include
#include
using namespace cv;
using namespace std;
int red, green, blue;
Mat imagen;
Mat screenBuffer;
int drawing;//用来标记是否正在动并且已经按下了
int r, last_x, last_y;//r表示每个点绘图时的半径,last_x,last_y记录上一个点的坐标
void draw(int x,int y)
{
circle(imagen, Point(x, y), r, Scalar(blue, green, red),-1, LINE_AA,0);
imagen.copyTo(screenBuffer);
imshow("手写板", screenBuffer);
}
void drawCursor(int x,int y)
{
imagen.copyTo(screenBuffer);
circle(screenBuffer, Point(x, y), r, Scalar(red, green, blue), 1, LINE_AA, 0);
}
void on_mouse(int event,int x,int y,int flags,void *param)
{
last_x = x; last_y = y; //用来记录上一个点
drawCursor(x, y);
//选择鼠标事件
if (event == CV_EVENT_LBUTTONDOWN)
{
drawing = 1;
drawCursor(x, y);
}
else if (event == CV_EVENT_LBUTTONUP)
{
drawing = 0;
}
else if(event==CV_EVENT_MOUSEMOVE && flags && CV_EVENT_FLAG_LBUTTON)
{
if (drawing == 1)
draw(x, y);
}
}
int main(int argc, char** argv)
{
printf(" 手写板\n"
"快捷键: \n"
"\tq - 退出程序\n"
"\tr - 重置白版\n"
"\t+ - 笔迹增粗 ++\n"
"\t- - 笔迹减细 --\n"
"\ts - 保存输入为 out.pbm\n" //输入可以作为样本再次部署进去
"\tc - 输入分类识别, 结果在console显示\n"
"\tESC - 退出程序\n");
drawing = 0;
r = 3;
red = green = blue = 0;
last_x = last_y = 0;
//创建图像
imagen.create(Size(128, 128), CV_8UC3);
imagen.setTo(Scalar(255,255, 255)); //把整幅图像改为白板图像 setTo函数设置矩阵的值为一样的值
screenBuffer=imagen.clone();
namedWindow("手写板",0);
resizeWindow("手写板", 512, 512);
cout << screenBuffer.rows << " " << screenBuffer.cols << endl;
setMouseCallback("手写板", on_mouse); //设置回调函数
for (;;)
{
int c;//因为waiteKey()只能返回整数
imshow("手写板", screenBuffer);
c = waitKey(10);
if ((char)c == 'r')
{
imagen.setTo(Scalar(255, 255, 255));
drawCursor(last_x, last_y);
}
else if ((char)c == '+')
{
r++;
drawCursor(last_x, last_y);
}
else if ((char)c == '-' && r>1)
{
r--;
drawCursor(last_x, last_y);
}
else if ((char)c == 'q')
{
break;
}
else if ((char)c == 's')
{
imwrite("out.pbm", imagen);
}
else if ((char)c == 'r')
{
;
}
}
destroyWindow("手写板");//销毁窗口
return 0;
}
实验情况如下: