使用其他按键作为opencv的waitKey()函数参数
我正在做一个程序(使用python和opencv),在这个程序里,我用空格键
来切换到下一个画面,用Esc
键来退出程序。这两个键是我目前能用的。为了找到更多的键,我尝试了各种代码,但都没有成功,尤其是方向键。
我发现了这个链接,里面讲了关于waitkey
的内容,但我试了之后也没用。
所以我想问的是,除了esc
和空格键
之外,怎么才能在我的python-opencv程序中捕捉到其他键,以便触发某些功能呢?
12 个回答
已经发布的回答表明,waitKey
返回的一些奇怪值可能是由于不同平台之间的差异。下面,我想提出的是(至少在某些平台上)waitKey
的奇怪行为是由于键盘修饰键的影响。这个帖子看起来和Tomasz的回答相似,因为我最开始是把它写成一个编辑,但被拒绝了。
waitKey
返回的键码会根据启用的修饰键而变化。NumLock、CapsLock,以及Shift、Ctrl和Alt键都会通过启用某些位来修改waitKey
返回的键码。这些标志中最小的是Shift,值为0x10000。
下面是Tomasz发布的脚本的修改版本:
#!/usr/bin/env python
import cv2
import sys
cv2.imshow(sys.argv[1], cv2.imread(sys.argv[1]))
res = cv2.waitKey(0)
print 'You pressed %d (0x%x), 2LSB: %d (%s)' % (res, res, res % 2**16,
repr(chr(res%256)) if res%256 < 128 else '?')
这将产生以下结果:
按下字母q和NumLock:
你按下了1048689 (0x100071),2LSB: 113 ('q')
按下Escape键和CapsLock,但没有NumLock:
你按下了131099 (0x2001b),2LSB: 27 ('\x1b')
按下空格键和Shift以及NumLock:
你按下了1114144 (0x110020),2LSB: 32 (' ')
按下右箭头键和Ctrl,NumLock关闭:
你按下了327507 (0x4ff53),2LSB: 65363 ('S')
我希望这能帮助解释waitKey
的奇怪行为,以及如何获取实际按下的键,而不受NumLock和CapsLock状态的影响。从这里开始,做一些类似的事情相对简单:
ctrlPressed = 0 != res & (1 << 18)
...因为“控制键”标志是(将最低有效位算作位0)位18。Shift在位16,CapsLock的状态在位17,Alt在位19,NumLock在位20。正如Tomasz好心指出的,单独按下Shift也会返回一个值,LShift和RShift有不同的值(仍然包含刚才描述的所有这些修饰键)。我鼓励你在依赖这些值之前,先在你自己的平台上仔细检查所有这些修饰键和它们的值。:)
通过 waitKey
返回的按键代码似乎和平台有关。不过,看看这些按键返回的值可能会很有趣(顺便说一下,在我的平台上,Esc 并不是返回27...)
Abid的回答中列出的那些整数对普通人来说大多没什么用(除非你是个天才)。不过,如果你把它们转换成十六进制,或者看看最低有效字节,你可能会发现一些规律...
下面是我用来检查 waitKey
返回值的脚本:
#!/usr/bin/env python
import cv2
import sys
cv2.imshow(sys.argv[1], cv2.imread(sys.argv[1]))
res = cv2.waitKey(0)
print('You pressed %d (0x%x), LSB: %d (%s)' % (res, res, res % 256,
repr(chr(res%256)) if res%256 < 128 else '?'))
你可以把它当作一个简单的命令行图片查看器。
以下是我得到的一些结果:
按下字母 q:
你按下了 1048689 (0x100071),最低有效字节: 113 ('q')
按下 Esc 键(通常是 ASCII 27):
你按下了 1048603 (0x10001b),最低有效字节: 27 ('\x1b')
按下空格键:
你按下了 1048608 (0x100020),最低有效字节: 32 (' ')
这个列表可以继续,不过你可以看到,当你得到一些“奇怪”的结果时,应该怎么处理。
顺便说一下,如果你想把它放在一个循环里,你可以直接用 waitKey(0)
(一直等待),而不是忽略 -1
的返回值。
编辑:这些高位的内容比表面看起来的要复杂,具体请参考 Andrew C 的回答(提示:这和键盘的修饰键有关,比如各种“锁”,例如 NumLock)。
不过,我最近的经验显示,确实存在平台依赖性——例如在 Windows 上使用 Python 3.6 的 Anaconda 中的 OpenCV 4.1.0 并不会产生这些高位,对于某些(重要的)按键,它从 waitKey()
返回 0
(比如方向键、Home、End、PageDn、PageUp,甚至 Del 和 Ins)。至少 Backspace 返回 8
(但是... 为什么 Del 不返回呢?)。
所以,如果你想要一个跨平台的用户界面,你可能只能使用 W、A、S、D、字母、数字、Esc、Space 和 Backspace 这些键;)
你可以在Python中使用 ord()
函数来实现这个功能。
比如,如果你想模拟按下 'a' 键,可以这样做:
if cv2.waitKey(33) == ord('a'):
print "pressed a"
这里有一个示例代码:绘制直方图
更新:
要找到任何键的值,可以用一个简单的脚本打印出这个键的值,代码如下:
import cv2
img = cv2.imread('sof.jpg') # load a dummy image
while(1):
cv2.imshow('img',img)
k = cv2.waitKey(33)
if k==27: # Esc key to stop
break
elif k==-1: # normally -1 returned,so don't print it
continue
else:
print k # else print its value
运行这段代码后,我得到了以下值:
Upkey : 2490368
DownKey : 2621440
LeftKey : 2424832
RightKey: 2555904
Space : 32
Delete : 3014656
...... # Continue yourself :)