opencv库中键盘等待以及类似松手检测的操作

提起opencv中有关按键的函数,首先想到的肯定是cv2.waitKey()和cv2.waitKeyEx()。

先说说这俩有什么区别waitKey只支持返回部分按键对应的ASCII码,而waitKeyEx则支持返回全部按键的码。其实就是全和不全的区别,一般来说我们有waitKey就够用了。如果在使用waitkey()是按下了不支持的按键,cv2.waitKey()函数返回值应该是0。具体的可以去查opencv的官方文档。

OpenCV: High-level GUI

opencv库中键盘等待以及类似松手检测的操作_第1张图片

 cv.waitKey()的返回值是一个数,如果在等待时间内有键盘按键按下,返回值就是这个按键对应的ASCII码;如果超出了等待时间或者用鼠标点击的方式关闭,返回值就是-1。

还需要掌握的就是ord()这个函数,这是python的一个内置函数。作用就是返回一个字符对应的ASCII码,只能是一个字符,不能是字符串。例如:

num = ord('a')
print(num)

这里num这个变量的值就是a对应的ASCII码,也就是97。

在下面这段代码中,我是想通过键盘来控制小车前进或转向的速度,变量speed与turn分别是电机前进和转向PWM脉冲宽度调制信号的占空比,至于怎么处理这个PWM信号我们有电机驱动器会出手。这里仅是用WS键控制前进后退的速度AD键控制左转右转的角度。至于PWM的实现就是调用树莓派的GPIO来实现,不是本篇博客所重点分享的内容。

import cv2.cv2 as cv

img = cv.imread('xxx.jpg')
cv.imshow('t', img)
speed = 5       # 初始速度
turn = 0        # 初始转向
while True:
    rate = cv.waitKey()
    print(rate)
    if rate == ord('w'):
        speed = speed + 1
        print('前进速度加一,当前前进速度是::{:.0f}'.format(speed))
        while rate == ord('w'):     # 防止长按此键,起和松手检测一样的作用
            rate = cv.waitKey()
    elif rate == ord('s'):
        speed = speed - 1
        print('前进速度减一当前前进速度是::{:.0f}'.format(speed))
        while rate == ord('s'):
            rate = cv.waitKey()
    elif rate == ord('a'):
        turn = turn - 1
        print('左转加一,当前转向速度是::{:.0f}'.format(turn))
        while rate == ord('a'):
            rate = cv.waitKey()
    elif rate == ord('d'):
        turn = turn - 1
        print('右转加一,当前转向速度是::{:.0f}'.format(turn))
        while rate == ord('d'):
            rate = cv.waitKey()

    elif rate == ord('t'):
        exit()

注意运行这段代码,在按下键盘按键之前 ,我们需要把鼠标的焦点放在cv库显示的图片上。

但是这么写是能实现松手检测,即防止长按某键而导致pwm输出占空比一直增加或减少。但是也会存在一个问题就是按下一次wasd键之后,需要按另一个与刚刚不同的按键来跳出松手检测的while循环才能进行第二次wasd操作。由于本人水平有限,且我的实际需求是要结合opencv库,所以在仅使用opencv-python这一个库的时候只能想到这样的解决方案,虽然用起来有点别扭吧,但好歹实现的需求哈哈哈哈。

这里提供一些改进思路,比如可以结合time库,也可以使用keyboard库,或者参考ros中键盘控制小车的解决思路。后期改进后我会继续向大家分享。

未经作者允许禁止转载,如需转载请注明出处并联系作者。

你可能感兴趣的:(python,opencv)