OpenCV的鼠标操作——用鼠标画矩形(代码解读)
来源:互联网 发布:mac最好的视频播放器 编辑:程序博客网 时间:2024/06/05 02:29
起因
知乎上被邀请回答一个问题,关于OpenCV的鼠标操作的问题。我发现回答下来写了不少东西,可以整理为一篇文章发出来,顺便说下不少人关心的如何用操作鼠标,比如如何用鼠标在图像上画一个矩形或者说选择一个矩形的ROI。
知乎上的问题问的是下面这段代码是什么意思。
正好,这段代码我是看过的,而且就在最近两周。所以正好可以说道一下。
介绍
这一段代码我最初是在contrib模块里面tracking模块的samples里面看到的,出自roiSelector.hpp。这个文件的作用就是用鼠标在图片中选择一个矩形区域。感兴趣的读者可以到这里知道源代码。为了照顾一部分人,更加直白的说法是这段代码在下面这样的路径下:
opencv3.2\opencv_contrib-master\modules\tracking\samples
注意,这里是opencv contrib模块,不是官网下载的那个OpenCV.
显然,我们知道要用一个鼠标选择一个矩形区域,鼠标的运动可以细分为一下三个动作:
- 鼠标左键按下
- 鼠标非水平非垂直地滑动
- 鼠标左键抬起。
在roiSelector.hpp
的代码中,在处理EVENT_LBUTTONUP
(鼠标左键抬起事件)之前,还分别先对EVENT_LBUTTONDOWN
(鼠标左键按下事件)和EVENT_MOUSEMOVE
(鼠标移动事件)进行了处理。
为了说明题主给出的代码的具体含义,必须先明白前两个事件,也即鼠标左键按下和鼠标滑动,都是怎么处理的。为了方便说明,这里不讨论代码中从矩形中心开始画矩形的情况,我把这三个事件的代码简化如下,为了放方便说明,调整了顺序:
PS:加一句也许是废话的话,在OpenCV中,矩形的表示方式是(x,y,width,height),也即是矩形框左上角坐标,外加宽高。而OpenCV的图像坐标系也是以图像左上角为原点,越往右x越大,越往下y越大。
代码解读
代码经过了简化,但是应该已经足够说明问题。
简化后的代码如下:
switch (event) { // start to select the bounding box case cv::EVENT_LBUTTONDOWN: data->isDrawing = true; data->box = cv::Rect2d(x, y, 0, 0); break; // update the selected bounding box case cv::EVENT_MOUSEMOVE: if (data->isDrawing) { data->box.width = x - data->box.x; data->box.height = y - data->box.y; } break; // cleaning up the selected bounding box case cv::EVENT_LBUTTONUP: data->isDrawing = false; if (data->box.width < 0) { data->box.x += data->box.width; data->box.width *= -1; } if (data->box.height < 0) { data->box.y += data->box.height; data->box.height *= -1; } break; }
case 1
这里先说第一个case,也即第一个动作,鼠标左键按下事件:EVENT_LBUTTONDOWN。
// 若鼠标左键按下,则矩形初始化为以鼠标当时坐标为左上角坐标,宽高都为0的矩形。// 且开始画flag为真,左键不按下滑动鼠标则不会开始画。
case cv::EVENT_LBUTTONDOWN: data->isDrawing = true; data->box = cv::Rect2d(x, y, 0, 0); break;
case 2
第二个case,也即第二个动作,鼠标滑动事件:EVENT_MOUSEMOVE。
// 如果鼠标开始滑动,更新矩形的宽高。// 用滑动时鼠标所在的坐标x减去初始的x为矩形的宽度。// 坐标y减去矩形初始的y为矩形的宽。// 比如鼠标往左水平移动了5个像素,那么宽为5px。// 鼠标垂直向下移动了10个像素,那么矩形高为10px。
case cv::EVENT_MOUSEMOVE: if (data->isDrawing) { data->box.width = x - data->box.x; data->box.height = y - data->box.y; } break;
case 3
// cleaning up the selected bounding box// 无视上面这句英文。// 这里最后的一个动作,鼠标左键抬起(释放)。// 如果矩形宽小于0,结合前面说的OpenCV的坐标系方向,// 说明鼠标滑动的时候是从右往左滑动的,所以这个时候原本鼠标左键按下的起始点// 就不再是矩形的左上角的点,所以需要用原本的x减去矩形宽度// 才是现在的矩形的左上角的x坐标。由于此时宽度为负数,所以下面用加号表示相减。// 然后乘以-1使得宽度从负数变成正数。// 下面的高度为负同理。// 这里用两个if而不是if...else...的原因就是隐含如果宽高不为负,// 那么最后的宽高就是鼠标释放的时候坐标减去初始左上角坐标的得到的宽高。
case cv::EVENT_LBUTTONUP: data->isDrawing = false; if (data->box.width < 0) { data->box.x += data->box.width; data->box.width *= -1; } if (data->box.height < 0) { data->box.y += data->box.height; data->box.height *= -1; } break;}
公众号CVPy,分享OpenCV和Python的实战内容。。欢迎关注。
- OpenCV的鼠标操作——用鼠标画矩形(代码解读)
- opencv用鼠标画矩形
- 用鼠标画矩形的win32代码
- opencv鼠标操作及GUI矩形绘画
- matlab 用鼠标拖曳画矩形的代码
- OpenCV 接收鼠标消息——用鼠标画长方形
- OpenCV 接收鼠标消息——用鼠标画长方形
- OpenCV学习笔记-用鼠标在窗口中画矩形
- opencv-鼠标在窗口中画矩形
- OpenCV鼠标绘制矩形和截取图像的矩形区域
- opencv鼠标绘制矩形和截取图像的矩形区域
- opencv学习笔记——鼠标操作
- OpenCV鼠标画图例程,鼠标绘制矩形
- OpenCV鼠标画图例程,鼠标绘制矩形
- OpenCV鼠标画图例程,鼠标绘制矩形
- 基于opencv用鼠标在窗口中画矩形和线段的程序
- 基于opencv的鼠标操作
- Opencv鼠标描绘矩形框
- 安卓高手之路之ClassLoader(三)
- FTRL 算法
- 利用射线进行碰撞检测做射击效果
- 安卓高手之路之ClassLoader(四)
- 视觉里程计 特征点法
- OpenCV的鼠标操作——用鼠标画矩形(代码解读)
- 安卓高手之路之ClassLoader(总结篇)
- 向HDFS输出文件
- java.net.SocketException四大异常解决方案
- 安卓高手之路之(架构设计)
- 新浪微博视频下载教程
- jfinal 开发笔记
- 安卓高手之路之PackageManagerservice
- 十大必须掌握的机器学习算法,你都知道了吗?