首页 > 其他分享 >08 回调函数+键盘响应操作

08 回调函数+键盘响应操作

时间:2023-01-12 16:34:11浏览次数:67  
标签:include 函数 08 键盘 响应 using 回调 waitKey

08 回调函数+键盘响应操作

opencv知识点:

  • 回调函数 - callback
  • 键盘响应 - waitKey()

本课所解决的问题:

  • 什么是回调函数(callback)?
  • 在opencv中如何进行键盘响应?
  • 如何利用键盘响应对图像进行操作?
  • 处理视频的时候waitKey的参数应为多少?

1.回顾createTrackbar

在前面的课中,调用createTrackbar时,我们把函数on_lighton_contrast作为参数传入了,这种特别的方式,它被称为callback。回调函数(callback)在很多的UI和界面编程中非常常用 ,它最早在Windows叫做消息机制。

这里我们详细讲解一下回调函数,来加深对这种方式的理解

什么是回调函数

作者:no.body
链接:回调函数(callback)是什么?
来源:知乎

我们绕点远路来回答这个问题。

编程分为两类:系统编程(system programming)和应用编程(application programming)

  • 所谓系统编程,简单来说,就是编写
  • 而应用编程就是利用写好的各种库来编写具某种功用的程序,也就是应用

系统程序员会给自己写的库留下一些接口,即API(应用编程接口),以供应用程序员使用。
所以在抽象层的图示里,库位于应用的底下。

当程序跑起来时,一般情况下,应用程序(application program)会时常通过API调用库里所预先备好的函数。
但是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。

这个被传入的、后又被调用的函数就称为回调函数(callback function)

打个比方,有一家旅馆提供叫醒服务,但是要求旅客自己决定叫醒的方法。可以是打客房电话,也可以是派服务员去敲门,睡得死怕耽误事的,还可以要求往自己头上浇盆水。

  • 这里,“叫醒”这个行为是旅馆提供的,相当于库函数
  • 但是叫醒的方式是由旅客决定并告诉旅馆的,也就是回调函数
  • 而旅客告诉旅馆怎么叫醒自己的动作,也就是把回调函数传入库函数的动作,称为登记回调函数

如下图所示(图片来源:维基百科):

849bf81c44014dca97ea42dec743a696

回调机制的优势

从上面的例子可以看出,回调机制提供了非常大的灵活性。

请注意,从现在开始,我们把图中的库函数改称为中间函数了。
这是因为回调并不仅仅用在应用和库之间,任何时候,只要想获得类似于上面情况的灵活性,都可以利用回调。

这种灵活性是怎么实现的呢?

乍看起来,回调似乎只是函数间的调用,但仔细一琢磨,可以发现两者之间的一个关键的不同:

在回调中,我们利用某种方式,把回调函数像参数一样传入中间函数。

可以这么理解,在传入一个回调函数之前,中间函数是不完整的。

换句话说,程序可以在运行时,通过登记不同的回调函数,来决定、改变中间函数的行为。

2.键盘响应

接下来是本课的内容,键盘响应。

opencv中,利用waitKey(),可以实现键盘事件的响应

本函数没用显示图片,点击的图片是main函数中显示的图片
注意:无论是main函数的,还是key_demo函数的,都可以触发键盘事件

//函数定义
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.cpp

#include "opencv2/opencv.hpp"
#include "quickopencv.h"
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
	Mat src = imread("C:/Users/LZQ/Desktop/lena.png"); //  B, G, R
	if (src.empty()) {
		printf("could not load image....\n");
		return -1;
	}

	imshow("输入窗口", src);

	QuickDemo qd;

	qd.key_demo(src);
	waitKey(0);
	destroyAllWindows();
	return 0;
}

quickdemo.cpp

#include "quickopencv.h"
#include <opencv2/dnn.hpp>

using namespace cv;
using namespace std;

void QuickDemo::key_demo(Mat& image) {

	while (true) {

		char c = waitKey(1000);

		//int c = waitKey(1000);
		std::cout << c << std::endl;
	}
}

quickopencv.h

#pragma once
#include <opencv2/opencv.hpp>
using namespace cv;

class QuickDemo {            //快速的演示文件 class类
public:

	void key_demo(Mat& image);//08

};

我们点击图像,按键盘就会打印对应的键

0c3f391d63cddcb508e65d5f662e0a9

2ca7a63a6fe2c281eb7b708ca27e2de

3.利用键盘进行图像操作

我们利用键盘响应,来实现对图像的操作

程序

main.cpp

#include "opencv2/opencv.hpp"
#include "quickopencv.h"
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
	Mat src = imread("C:/Users/LZQ/Desktop/lena.png"); //  B, G, R
	if (src.empty()) {
		printf("could not load image....\n");
		return -1;
	}

	imshow("输入窗口", src);

	QuickDemo qd;


	qd.key_demo(src);
	waitKey(0);
	destroyAllWindows();
	return 0;
}

quickdemo.cpp

#include "quickopencv.h"
#include <opencv2/dnn.hpp>

using namespace cv;
using namespace std;
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) { // Key #1
			std::cout << "you enter key # 1 " << std::endl;
			cvtColor(image, dst, COLOR_BGR2GRAY);
		}
		if (c == 50) { // Key #2
			std::cout << "you enter key # 2 " << std::endl;
			cvtColor(image, dst, COLOR_BGR2HSV);
		}
		if (c == 51) { // Key #3
			std::cout << "you enter key # 3 " << std::endl;
			dst = Scalar(50, 50, 50);
			add(image, dst, dst);
		}
		imshow("键盘响应", dst);
	}
}

quickopencv.h

#pragma once

#include <opencv2/opencv.hpp>

using namespace cv;

class QuickDemo {            //快速的演示文件 class类
public:

	void key_demo(Mat& image);//08

};

结果:

初始为黑色

a195afdb3560cc5d7aa9c864318cfed

按下1,变为灰度图像

25e80812934b691fabfc086b0d006b0

按下2,变为HSV图像

e8f175b042585119390ed4b75a50a82

按下3,亮度+50

ab12b1b6ecc203f68cc58e290eec792

4.视频处理的waitKey参数

waitKey()

标签:include,函数,08,键盘,响应,using,回调,waitKey
From: https://www.cnblogs.com/L707/p/17047021.html

相关文章