72

我正在开发一个程序(python,opencv),在该程序中我使用spacebar转到下一帧并Esc退出程序。这是我唯一可以使用的两个键。我试图找出更多的键,为它们尝试了各种代码,但没有用。尤其是方向键。

我发现了这个waitkey,但它不起作用。

所以我的问题是,我如何捕捉其他键escspacebar触发我的 python-opencv 程序中的某些功能?

4

12 回答 12

117

您可以为此使用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 :)
于 2013-01-24T04:44:17.857 回答
25

返回的键码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()、、、、、、甚至和)。至少返回(但是......为什么不呢?)。HomeEndPageDnPageUpDelInsBackspace8Del

因此,对于跨平台 UI,您可能仅限于W, A, S, D, 字母, 数字, Esc,SpaceBackspace;)

于 2013-12-13T22:23:56.727 回答
15

已经发布的答案表明,获得的一些异常值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')

我希望这有助于解释waitKeyNumLock 和 CapLock 的异常行为以及如何按下实际键。从这里做类似的事情相对简单:

ctrlPressed = 0 != res & (1 << 18)

...因为“控制键”标志是第 19 位。移位在第 17 位,CapsLock 的状态在第 18 位,Alt 在第 20 位,NumLock 在第 21 位。

于 2015-11-05T21:25:10.120 回答
4

对我来说,下面的代码不起作用,当它运行时,图像会在没有你按下的情况下快速跳转到下一个:

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)

输出如下:

在此处输入图像描述

于 2018-08-03T03:46:09.440 回答
2

对于 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;
}
于 2015-06-25T10:46:41.050 回答
2

在 Ubuntu 和 C++ 中,我遇到了字符/整数转换的问题。我需要用来cv::waitKey()%256获取正确的 ASCII 值。

于 2016-10-17T11:41:50.613 回答
1

适用于 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
于 2020-04-28T08:28:33.030 回答
1

如果要暂停程序以截取进度

(假设在 cv2.imshow 中显示)

cv2.waitKey(0)按下“Scr”按钮(或其组合)后会继续,但你可以试试这个

cv2.waitKey(0)
input('')

cv2.waitkey(0) 给程序足够的时间来处理你想在 imshow 和 input('') 中看到的所有内容

让它等待您在控制台窗口中按 Enter

这适用于python 3

于 2018-04-24T16:06:58.847 回答
1

有趣的是,没有人在另一个 Stack Overflow 线程cv2.waitKeyEx()的这个答案中提到过。OpenCV 的文档内容cv2.waitKeyEx()如下:

类似于 waitKey,但返回完整的密钥代码。

笔记

关键代码是特定于实现的,取决于使用的后端:QT/GTK/Win32/etc

因此,跨平台实现可能需要一些注意。然而,对我来说,这是迄今为止让箭头键等在 Windows 上工作的最简单和最直接的解决方案。

于 2021-03-10T22:18:57.317 回答
0

这会将组合键直接打印到图像上:

z 按下 ctrl + z 按下

第一个窗口显示'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'
于 2020-04-13T13:24:58.130 回答
0

我也觉得这很令人困惑。我正在运行 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 
于 2019-05-22T18:26:52.833 回答
-1

这对我来说最有效:

http://www.asciitable.com/

有时,最好的答案是简单的答案;+)

于 2019-05-07T03:45:59.410 回答