// 鼠标事件绘制图像
// 按下鼠标左键,拖动鼠标,绘制矩形
// 鼠标响应事件 void setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0)
代码:
Point startP(-1, -1);
Point endP(-1, -1);
static void on_Mouse(int event, int x, int y, int flags, void* userdata)
{
int w, h;
Mat m = *((Mat*)userdata);
// 判断鼠标事件
if (event == EVENT_LBUTTONDOWN) // 鼠标左键按下
{
// 获取鼠标点坐标
startP.x = x; // 获取鼠标的坐标点
startP.y = y;
}
else if (event == EVENT_MOUSEMOVE) // 鼠标在移动
{
if (startP.x > 0 && startP.y > 0) // 起始坐标不为负值时进行操作
{
//
//获取鼠标坐标
endP.x = x;
endP.y = y;
w = endP.x - startP.x;
h = endP.y - startP.y;
//画矩形
//rectangle(m, Rect(startP, endP), Scalar(0, 255, 255), 1, 1, 0);
//imshow("鼠标绘制", m); // 响应一次,绘制一次
}
}
else if (event == EVENT_LBUTTONUP) // 鼠标抬起
{
// 获取鼠标坐标
endP.x = x;
endP.y = y;
w = endP.x - startP.x;
h = endP.y - startP.y;
//MessageBox(NULL, _T("鼠标左键抬起"), NULL, 0);
if (w>0&&h>0)
{
// 画矩形
rectangle(m, Rect(startP, endP), Scalar(255, 0, 0), 1, 1, 0);
imshow("鼠标绘制", m);
startP.x = -1; // 当次完事后重置,方便下次再次重画
startP.y = -1;
}
}
}
void CV120201012Dlg::mouseDraw_Demo()
{
// 创建一个窗口
namedWindow("鼠标绘制", WINDOW_AUTOSIZE);
//创建一幅图像
Mat img = Mat::zeros(Size(500,500),CV_8UC3);
if (img.empty())
{
MessageBox(_T("图像加载失败!"), _T("error"));
return;
}
// 调用鼠标响应事件函数
setMouseCallback("鼠标绘制",on_Mouse,(void*)(&img));
imshow("鼠标绘制",img);
waitKey(0); // 重点 !!!缺少会无法运行
}
结果图:
遇到的问题:
1、mouseDraw_Demo()函数结尾的 waitKey(0),一定不可以省略,不写就会出现 程序运行后,鼠标一动,就发生异常的问题。(但想不通具体是为什么,有知道原因的大神,请赐教~)
2、if (event == EVENT_LBUTTONDOWN) // 鼠标左键按下
else if (event == EVENT_MOUSEMOVE) // 鼠标在移动
这俩个判断事件应该为同级。之前设计代码的时候,想着,先按下鼠标左键,在鼠标左键按下的情况下在移动鼠标,所以设计成了
if (event == EVENT_LBUTTONDOWN) // 鼠标左键按下
{
else if (event == EVENT_MOUSEMOVE) // 鼠标在移动
}
导致不能响应鼠标移动事件。思考后发现原因是:
假设程序响应的当前事件是鼠标左键按下,则此时执行响应函数中的 event = EVENT_LBUTTONDOWN,所以导致 EVENT_MOUSEMOVE 不能被响应,只有当此次响应函数执行完毕, event 才会被重新赋值。所以 事件的响应判断应该为同级。
3、else if (event == EVENT_MOUSEMOVE) // 鼠标在移动
判断语句中的 //rectangle(m, Rect(startP, endP), Scalar(0, 0, 255), 1, 1, 0);
//imshow("鼠标绘制", m);
注释被打开,则会绘制每次鼠标移动的矩形轨迹,结果如下图