C++ opencv 键盘响应事件

1.回调函数讲解

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

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

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

        

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

当程序跑起来时,一般情况下,应用程序(application program)会时常通过API调用库里所预先备好的函数。


但是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。

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

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

这里,“叫醒”这个行为是旅馆提供的,相当于库函数


但是叫醒的方式是由旅客决定并告诉旅馆的,也就是回调函数


而旅客告诉旅馆怎么叫醒自己的动作,也就是把回调函数传入库函数的动作,称为登记回调函数


如下图所示(图片来源:维基百科):
在这里插入图片描述


回调机制的优势


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

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

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

乍看起来,回调似乎只是函数间的调用,但仔细一琢磨,可以发现两者之间的一个关键的不同:
在回调中,我们利用某种方式,把回调函数像参数一样传入中间函数。
可以这么理解,在传入一个回调函数之前,中间函数是不完整的。

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

这就比简单的函数调用,要灵活太多了。
 

2.键盘响应

1.api

waitKey(delay )

在一个给定的时间内(单位ms)等待用户按键触发;如果用户没有按下键,则继续等待(循环)。有按键按下,返回按键的ASCII值。无按键按下,返回-1。

延时delay = 0 函数则延时无限长,必须有键按下才继续执行。
延时delay > 0 函数返回值为按下的键的ASCII码值,超时则返回-1。
waitKey(0),表示程序会无限制的等待用户的按键事件;
waitKey(1),表示程序每1ms检测一次按键,检测到返回按键值,检测不到返回-1;
waitKey(100),表示程序每100ms检测一次按键,检测到返回按键值,检测不到返回-1;
 

由于返回ascill值,用此方法,音视频控制wait一般是1

key = waitKey(1);
          
            if (key == 'q')
            {
            destroyAllWindows();
            }

2.实例代码


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    //w.show();

    namedWindow("windows", WINDOW_NORMAL);
    resizeWindow("windows", 500, 500);


    Mat srcImage = imread("C:\\Users\\29492\\Desktop\\Qt +opencv\\project\\light contrast regulate\\car7.png");
//默认BGR

    if (srcImage.empty())
    {
        printf("could not load image……\n");
    }


    imshow("windows", srcImage);

    std::cout <<srcImage << std::endl;

    Mat dst = Mat::zeros(srcImage.size(), srcImage.type());
    while(1)
    {
        key = waitKey(1);
        
            if (key == 'q')
            {
            destroyAllWindows();
            break;
            }

            if (key == 'w')
            {
            cvtColor(srcImage,dst,COLOR_BGR2GRAY);
            std::cout << "1" << std::endl;
            imshow("windows", dst);

            }

            if (key == 'e')
            {
            cvtColor(srcImage, dst, COLOR_BGR2HSV);
            std::cout << "2" << std::endl;
            imshow("windows", dst);

            }

            if (key == 'r')
            {
                dst = Scalar(50, 50, 50);
                add(srcImage, dst, dst);
                std::cout << "3" << std::endl;
                imshow("windows", dst);

            }

    }

    return a.exec();
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

打酱油的;

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值