提起opencv中有关按键的函数,首先想到的肯定是cv2.waitKey()和cv2.waitKeyEx()。
先说说这俩有什么区别waitKey只支持返回部分按键对应的ASCII码,而waitKeyEx则支持返回全部按键的码。其实就是全和不全的区别,一般来说我们有waitKey就够用了。如果在使用waitkey()是按下了不支持的按键,cv2.waitKey()函数返回值应该是0。具体的可以去查opencv的官方文档。
OpenCV: High-level GUI
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中键盘控制小车的解决思路。后期改进后我会继续向大家分享。
未经作者允许禁止转载,如需转载请注明出处并联系作者。