我正在开发一个程序(python,opencv),在该程序中我使用spacebar
转到下一帧并Esc
退出程序。这是我唯一可以使用的两个键。我试图找出更多的键,为它们尝试了各种代码,但没有用。尤其是方向键。
我发现了这个waitkey
,但它不起作用。
所以我的问题是,我如何捕捉其他键esc
并spacebar
触发我的 python-opencv 程序中的某些功能?
您可以为此使用ord()
Python 中的函数。
例如,如果要触发“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 :)
返回的键码waitKey
似乎取决于平台。但是,看看键返回什么可能很有教育意义(顺便说一下,在我的平台上,Esc不会返回 27...)
阿比德的答案列表中的整数对人类的大脑来说几乎没有用处(除非你是一个神童……)。但是,如果您以十六进制检查它们,或者查看最低有效字节,您可能会注意到模式......
我用于检查返回值的脚本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), LSB: 113 ('q')
转义键(传统上为 ASCII 27):
你按下 1048603 (0x10001b), LSB: 27 ('\x1b')
空间:
你按了 1048608 (0x100020), LSB: 32 (' ')
当你得到“奇怪”的结果时,这个列表可以继续下去,但是你会看到要走的路。
顺便说一句,如果你想把它放在一个循环中,你可以waitKey(0)
(永远等待),而不是忽略-1
返回值。
编辑:这些高位比眼睛看到的要多 - 请参阅 Andrew C 的回答(提示:它与键盘修饰符有关,如所有“锁”,例如 NumLock)。
然而,我最近的经验表明,存在平台依赖性 - 例如,Windows 上 Python 3.6 上的 Anaconda 的 OpenCV 4.1.0 不会产生这些位,并且对于某些(重要的)键是从(0
箭头waitKey()
、、、、、、甚至和)。至少返回(但是......为什么不呢?)。HomeEndPageDnPageUpDelInsBackspace8
Del
因此,对于跨平台 UI,您可能仅限于W, A, S, D, 字母, 数字, Esc,Space和Backspace;)
已经发布的答案表明,获得的一些异常值waitKey
是由于平台差异造成的。下面,我建议(至少在某些平台上)明显奇怪的行为waitKey
是由于键盘修饰符造成的。这篇文章看起来与 Tomasz 的答案相似,因为我最初将其写为编辑,但被拒绝了。
更改返回的键码waitKey
取决于启用的修饰符。NumLock、CapsLock 以及 Shift、Ctrl 和 Alt 键都waitKey
通过启用两个最低有效字节上方的某些位来修改返回的键码。这些标志中最小的是 Shift at 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 '?')
这给出了以下结果:
带 NumLock 的 q 字母:
你按下了 1048689 (0x100071), 2LSB: 113 ('q')
带 CapsLock 但不带 NumLock 的 Escape 键:
你按了 131099 (0x2001b), 2LSB: 27 ('\x1b')
带 Shift 和 NumLock 的空格:
你按了 1114144 (0x110020), 2LSB: 32 (' ')
带控制的右箭头键,NumLock 关闭:
你按下了 327507 (0x4ff53), 2LSB: 65363 ('S')
我希望这有助于解释waitKey
NumLock 和 CapLock 的异常行为以及如何按下实际键。从这里做类似的事情相对简单:
ctrlPressed = 0 != res & (1 << 18)
...因为“控制键”标志是第 19 位。移位在第 17 位,CapsLock 的状态在第 18 位,Alt 在第 20 位,NumLock 在第 21 位。
对我来说,下面的代码不起作用,当它运行时,图像会在没有你按下的情况下快速跳转到下一个:
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
但这有效:
def test_wait_key():
lst_img_path = [
'/home/xy/yy_face_head/face_det_test/111.png',
'/home/xy/yy_face_head/face_det_test/222.png'
#.....more path ...
]
for f_path in lst_img_path:
img = cv2.imread(f_path)
cv2.imshow('tmp', img)
c = cv2.waitKey(0) % 256
if c == ord('a'):
print "pressed a"
else:
print 'you press %s' % chr(c)
输出如下:
对于 C++:
如果使用键盘字符/数字,更简单的解决方案是:
int key = cvWaitKey();
switch(key)
{
case ((int)('a')):
// do something if button 'a' is pressed
break;
case ((int)('h')):
// do something if button 'h' is pressed
break;
}
在 Ubuntu 和 C++ 中,我遇到了字符/整数转换的问题。我需要用来cv::waitKey()%256
获取正确的 ASCII 值。
适用于 Ubuntu18、python3、opencv 3.2.0 的答案与上述类似。但随着线路的变化cv2.waitKey(0)
。这意味着程序会一直等到按下按钮。
使用此代码,我找到了箭头按钮的键值:向上箭头 (82)、向下箭头 (84)、向左箭头 (81) 和 Enter(10) 等。
import cv2
img = cv2.imread('sof.jpg') # load a dummy image
while(1):
cv2.imshow('img',img)
k = cv2.waitKey(0)
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
(假设在 cv2.imshow 中显示)
cv2.waitKey(0)
按下“Scr”按钮(或其组合)后会继续,但你可以试试这个
cv2.waitKey(0)
input('')
cv2.waitkey(0) 给程序足够的时间来处理你想在 imshow 和 input('') 中看到的所有内容
让它等待您在控制台窗口中按 Enter
这适用于python 3
这会将组合键直接打印到图像上:
第一个窗口显示'z'
已按下,第二个窗口显示已'ctrl' + 'z'
按下。使用组合键时,会出现一个问号。
不要弄乱问号代码,即63
.
import numpy as np
import cv2
im = np.zeros((100, 300), np.uint8)
cv2.imshow('Keypressed', im)
while True:
key = cv2.waitKey(0)
im_c = im.copy()
cv2.putText(
im_c,
f'{chr(key)} -> {key}',
(10, 60),
cv2.FONT_HERSHEY_SIMPLEX,
1,
(255,255,255),
2)
cv2.imshow('Keypressed', im_c)
if key == 27: break # 'ESC'
我也觉得这很令人困惑。我正在运行 Ubuntu 18 并发现以下内容:如果 cv.imshow 窗口具有焦点,您将在终端中获得一组值 - 就像上面讨论的 ASCII 值一样。
如果终端有焦点,您将看到不同的值。IE-当你按下 a 键时你会看到“a”(而不是 ASCII 值 97),当你按下 Escape 时你会看到“^]”而不是“27”。
在这两种情况下,我都没有看到上面提到的 6 位数字,我使用了类似的代码。waitKey 的值似乎是以毫秒为单位的轮询周期。这些点说明了这一点。
运行此代码段并在焦点位于测试图像上时按下键,然后单击终端窗口并按下相同的键。
import cv2
img = cv2.imread('test.jpg')
cv2.imshow('Your test image', img)
while(1):
k = cv2.waitKey(300)
if k == 27:
break
elif k==-1:
print "."
continue
else:
print k