个人资料,仅供学习使用
修改时间——2022年1月21日 20:41:13
学习课程:OpenCV4 C++ 快速入门视频30讲
视频老师:贾志刚
08 键盘响应操作
opencv知识点:
- callback - 回调函数
- waitKey - 键盘响应
本课所解决的问题:
- 什么是回调函数(callback)?
- 在opencv中如何进行键盘响应?
- 如何利用键盘响应对图像进行操作?
1.简述回调函数(callback)
我们前面createTrackbar中,我们把函数on_light
,on_contrast
作为参数传入了
这种特别的方式,它被称为callback
callback这种方式,在很多的UI和界面编程中非常常用
它最早在Windows叫做消息机制
为了方便之后的学习,我们来对callback进行一下简述
什么是回调函数?
作者:no.body
链接:回调函数(callback)是什么?
来源:知乎
我们绕点远路来回答这个问题。
编程分为两类:系统编程(system programming)和应用编程(application programming)。
- 所谓系统编程,简单来说,就是编写库
- 而应用编程就是利用写好的各种库来编写具某种功用的程序,也就是应用。
系统程序员会给自己写的库留下一些接口,即API(应用编程接口),以供应用程序员使用。
所以在抽象层的图示里,库位于应用的底下。
当程序跑起来时,一般情况下,应用程序(application program)会时常通过API调用库里所预先备好的函数。
但是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。
这个被传入的、后又被调用的函数就称为回调函数(callback function)。
打个比方,有一家旅馆提供叫醒服务,但是要求旅客自己决定叫醒的方法。可以是打客房电话,也可以是派服务员去敲门,睡得死怕耽误事的,还可以要求往自己头上浇盆水。
- 这里,“叫醒”这个行为是旅馆提供的,相当于库函数
- 但是叫醒的方式是由旅客决定并告诉旅馆的,也就是回调函数
- 而旅客告诉旅馆怎么叫醒自己的动作,也就是把回调函数传入库函数的动作,称为登记回调函数
如下图所示(图片来源:*):
回调机制的优势
从上面的例子可以看出,回调机制提供了非常大的灵活性。
请注意,从现在开始,我们把图中的库函数改称为中间函数了。
这是因为回调并不仅仅用在应用和库之间,任何时候,只要想获得类似于上面情况的灵活性,都可以利用回调。
这种灵活性是怎么实现的呢?
乍看起来,回调似乎只是函数间的调用,但仔细一琢磨,可以发现两者之间的一个关键的不同:
在回调中,我们利用某种方式,把回调函数像参数一样传入中间函数。
可以这么理解,在传入一个回调函数之前,中间函数是不完整的。换句话说,程序可以在运行时,通过登记不同的回调函数,来决定、改变中间函数的行为。
这就比简单的函数调用,要灵活太多了。
2.键盘响应
在opencv中,利用waitKey,可以实现键盘事件的响应
//函数定义
void key_demo(Mat& image);
//函数实现
void QuickDemo::key_demo(Mat& image) {
while (true) {
char c = waitKey(1000);
/*
用char存储,能存储一些字符,但像esc这些就无法存储
为了存储这些功能键,我们可以转为int存储方式,存储它们对应的ASCII码值
*/
//int c = waitKey(1000);
std::cout << c << std::endl;
}
/*
本函数没用显示图片,点击的图片是main函数中显示的图片
注意:无论是main函数的,还是key_demo函数的,都可以触发键盘事件
之后利用了这个函数实现键盘响应
*/
}
我们点击图像,按键盘就会打印对应的键
3.利用键盘进行图像操作
我们利用键盘响应,来实现对图像的操作
void QuickDemo::key_demo(Mat& image) {
Mat dst = Mat::zeros(image.size(), image.type());
while (true) {
int c = waitKey(100);
if (c == 27) {//退出
break;
}
if (c == 49) {//1 图像转为灰度
std::cout << "1" << std::endl;
cvtColor(image,dst,COLOR_BGR2GRAY);
}
if (c == 50) {//2 图像转为HSV
std::cout << "2" << std::endl;
cvtColor(image, dst, COLOR_BGR2HSV);
}
if (c == 51) {//3 图像亮度+50
std::cout << "3" << std::endl;
dst = Scalar(50, 50, 50);
add(image, dst, dst);
}
imshow("键盘响应", dst);
}
}
初始为黑色
按下1,变为灰度图像
按下2,变为HSV图像
按下3,亮度+50
本课所用API查阅
1.waitKey