web-dev-qa-db-fra.com

Utilisation d'autres touches pour la fonction waitKey () de opencv

Je travaille sur un programme (python, opencv) dans lequel j'utilise spacebar pour accéder à l'image suivante et Esc pour quitter le programme. Ce sont les deux seules clés que je travaille. J'ai essayé de trouver plus de clés, j'ai essayé divers codes mais je n'ai pas fonctionné. surtout les touches fléchées.

J'ai trouvé this à propos de waitkey, mais cela ne fonctionne pas.

Ma question est donc la suivante: comment puis-je récupérer d'autres clés que esc et spacebar pour déclencher certaines fonctions de mon programme python-opencv?

40
md1hunox

Vous pouvez utiliser la fonction ord() en Python pour cela.

Par exemple, si vous souhaitez déclencher une touche, procédez comme suit:

if cv2.waitKey(33) == ord('a'):
   print "pressed a"

Voir un exemple de code ici: Histogramme de dessin

METTRE À JOUR :

Pour trouver la valeur de clé pour n'importe quelle clé, imprimez la valeur de clé à l'aide d'un script simple, comme suit:

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

Avec ce code, j'ai les valeurs suivantes:

Upkey : 2490368
DownKey : 2621440
LeftKey : 2424832
RightKey: 2555904
Space : 32
Delete : 3014656
...... # Continue yourself :)
62
Abid Rahman K

Les codes clés retournés par waitKey semblent dépendre de la plate-forme. Cependant, il peut être très instructif de voir ce que les clés retournent (Et d'ailleurs, sur ma plate-forme, Esc ne retourne pas 27 ...)

Les nombres entiers que les listes de réponses d'Abid sont la plupart du temps inutiles pour l'esprit humain (Sauf si vous êtes un savant prodige ...). Cependant, si vous les examinez en hexadécimal, .__ ou si vous regardez le byte le moins significatif, vous remarquerez peut-être des motifs ...

Mon script pour examiner les valeurs de retour de waitKey est ci-dessous:

#!/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 '?')

Vous pouvez l'utiliser comme visionneuse d'images minimale en ligne de commande.

Quelques résultats que j'ai obtenus:

  • q lettre:

    Vous avez appuyé sur 1048689 (0x100071), LSL: 113 ("q")

  • Touche d'échappement (traditionnellement, ASCII 27):

    Vous avez appuyé sur 1048603 (0x10001b), LSB: 27 ('\ x1b')

  • Espace:

    Vous avez appuyé sur 1048608 (0x100020), LSB: 32 ('')

Cette liste pourrait continuer, quelle que soit la façon dont vous voyez le chemin à parcourir, lorsque vous obtenez des résultats «étranges».

En passant, si vous voulez le mettre en boucle, vous pouvez simplement waitKey(0) (attendre indéfiniment), au lieu d’ignorer la valeur de retour -1.

15
Tomasz Gandor

Les réponses déjà publiées suggèrent que certaines des valeurs inhabituelles obtenues par waitKey sont dues à des différences de plate-forme. Ci-dessous, je propose que (du moins sur certaines plates-formes) le comportement apparemment étrange de waitKey est dû aux modificateurs de clavier. Ce message est similaire à la réponse de Tomasz, car j’avais initialement écrit ceci en tant que montage, qui a été rejeté.


Les codes clés retournés par waitKey changent en fonction des modificateurs activés. NumLock, CapsLock et les touches Maj, Ctrl et Alt modifient tous le code clé renvoyé par waitKey en activant certains bits au-dessus des deux octets les moins significatifs. Le plus petit de ces drapeaux est Shift à 0x10000.

Une version modifiée du script publié par Tomasz est donnée ci-dessous:

#!/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 '?')

Ce qui donne les résultats suivants:

  • q lettre avec verrouillage numérique:

    Vous avez appuyé sur 1048689 (0x100071), 2LSB: 113 ("q")

  • Touche d'échappement avec CapsLock mais pas NumLock:

    Vous avez appuyé sur 131099 (0x2001b), 2LSB: 27 ('\ x1b')

  • Espace avec Shift et NumLock:

    Vous avez appuyé sur 1114144 (0x110020), 2LSB: 32 ('')

  • Touche flèche droite avec contrôle, Verrouillage numérique désactivé:

    Vous avez appuyé sur 327507 (0x4ff53), 2LSB: 65363 ("S")

J'espère que cela aide à expliquer le comportement inhabituel de waitKey et comment obtenir la touche réelle enfoncée quel que soit l'état de NumLock et de CapLock. À partir de là, il est relativement simple de faire quelque chose comme:

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

... puisque l'indicateur de "clé de contrôle" est le bit 19. Shift est au bit 17, l'état de CapsLock au bit 18, Alt au bit 20 et NumLock au bit 21.

12
Andrew C.

Si vous souhaitez suspendre le programme pour prendre des captures d'écran de la progression

(montré dans disons cv2.imshow)

cv2.waitKey (0) continuerait après avoir appuyé sur le bouton "Scr" (ou sa combinaison), mais vous pouvez essayer ceci 

cv2.waitKey(0)
input('')

cv2.waitkey (0) pour donner au programme assez de temps pour traiter tout ce que vous voulez voir dans imshow et input ('')

faire attendre que vous appuyiez sur Entrée dans la fenêtre de la console

cela fonctionne sur python 3

1
GodIsAnAstronaut

Quant à moi, le code ci-dessous ne fonctionne pas, lorsqu’elle est exécutée, l’image passera rapidement à la suivante sans votre presse:

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

Mais cela fonctionne:

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)

Sortie comme ci-dessous:

 enter image description here

1
Jayhello

Avec Ubuntu et C++, j'ai eu des problèmes avec la distribution Character/Integer. J'avais besoin d'utiliser cv::waitKey()%256 pour obtenir la valeur ASCII correcte.

1
00zetti

Pour C++:

En cas d'utilisation de caractères/chiffres au clavier, une solution plus simple serait:

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;
}
1
Poka Yoke