在Opencv当中的highgui模块中有大量可以用来处理图像的函数,他们可以使程序对鼠标或者键盘事件做出相应,也可以在图像上绘制形状或者写入文本。
这里主要说一下鼠标事件。
功能
通过编程,你可以让鼠标在置于图像窗口上时运行特定的指令。要实现这个功能,需要定义一个合适的回调函数。回调函数不会被显式地调用,而是会在响应特定事件(这里是指鼠标与图像窗口交互的事件)的时候被程序调用。为了能够被程序识别,回调函数需要有特殊的签名,并且必须注册。对于鼠标事件处理函数,回调函数必须具有这种签名:
函数
回调函数:
void onMouse(int Event,int x,int y,int flags,void* param )
Event是整数,表示出发会点函数的鼠标事件的类型。
X 和 Y为事件发生时鼠标的坐标,用像素坐标表示。
flags表示事件发生的时候按下鼠标的那个键。
param是指向任意对象的指针,作为附件的参数发送给函数。
处理鼠标动作函数:
void setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0)
winname:窗口的名字
onMouse:鼠标响应函数,回调函数。指定窗口里每次鼠标时间发生的时候,被调用的函数指针。 这个函数的原型应该为void on_Mouse(int event, int x, int y, int flags, void* param);
userdate:传给回调函数的参数。
鼠标事件
EVENT_MOUSEMOVE 滑动
EVENT_LBUTTONDOWN 左键点击
EVENT_RBUTTONDOWN 右键点击
EVENT_MBUTTONDOWN 中键点击
EVENT_LBUTTONUP 左键放开
EVENT_RBUTTONUP 右键放开
EVENT_MBUTTONUP 中键放开
EVENT_LBUTTONDBLCLK 左键双击
EVENT_RBUTTONDBLCLK 右键双击
EVENT_MBUTTONDBLCLK 中键双击
例子
检测鼠标的左键按下后,会显示点击图片中的具体坐标,并且显示是什么东西。
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace std;
void onMouse(int event, int x, int y, int flags, void* param) {
cv::Mat *im = reinterpret_cast<cv::Mat*>(param);
switch (event) { // dispatch the event
case cv::EVENT_LBUTTONDOWN: // 鼠标左键按下
if (50 < x && x < 250)
{
if (50 < y && y < 250)
{
cout << "你选择的是苹果" << "," << "点击的位置是 ("
<< x << "," << y << ")" << endl;
}
else if (350 < y && y < 550)
{
cout << "你选择的是杯子" << "," << "点击的位置是 ("
<< x << "," << y << ")" << endl;
}
}
else if (350 < x && x < 550)
{
if (50 < y && y < 250)
{
cout << "你选择的是书本" << "," << "点击的位置是 ("
<< x << "," << y << ")" << endl;
}
else if (350 < y && y < 550)
{
cout << "你选择的是钢笔" << "," << "点击的位置是 ("
<< x << "," << y << ")" << endl;
}
}
break;
}
}
int main() {
cv::Mat image; // 新建一个空图
// 读取图像并转化为灰度图
image = cv::imread("test.png", cv::IMREAD_GRAYSCALE);
if (image.empty()) {
//如果读取失败的话
cout << "Error reading image..." << endl;
return 0;
}
//输出图像的长和宽
cout << "This image is " << image.rows << " x "
<< image.cols << endl;
//输出图像的通道数
cout << "This image has "
<< image.channels() << " channel(s)" << endl;
// 创建一个窗口,窗口名称为"Original Image"
cv::namedWindow("Original Image"); // 命名
cv::imshow("Original Image", image); // 显示原始图像
// set the mouse callback for this image
cv::setMouseCallback("Original Image", onMouse, reinterpret_cast<void*>(&image));
cv::waitKey(0); // 按任何键结束
return 0;
}
使用的 test.png 如图所示。