Using other keys for the waitKey() function of opencv

前端 未结 11 698
天涯浪人
天涯浪人 2020-11-29 19:16

I\'m working on a program (python ,opencv) in which I use the spacebar to go to the next frame, and Esc to exit the program. These are the only two

相关标签:
11条回答
  • 2020-11-29 19:24

    The answers which have already been posted suggest that some of the unusual values obtained by waitKey are due to platform differences. Below, I propose that (at least on some platforms) the apparently odd behaviour of waitKey is due to keyboard modifiers. This post looks similar to Tomasz's answer because I initially wrote this as an edit, which was rejected.


    The keycodes returned by waitKey change depending on which modifiers are enabled. NumLock, CapsLock, and the Shift, Ctrl, and Alt keys all modify the keycode returned by waitKey by enabling certain bits above the two Least Significant Bytes. The smallest of these flags is Shift at 0x10000.

    A modified version of the script Tomasz posted is given below:

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

    Which give the following results:

    • q letter with NumLock:

      You pressed 1048689 (0x100071), 2LSB: 113 ('q')

    • Escape key with CapsLock but not NumLock:

      You pressed 131099 (0x2001b), 2LSB: 27 ('\x1b')

    • Space with Shift and NumLock:

      You pressed 1114144 (0x110020), 2LSB: 32 (' ')

    • Right Arrow Key with Control, NumLock off:

      You pressed 327507 (0x4ff53), 2LSB: 65363 ('S')

    I hope that helps to explain the unusual behaviour of waitKey and how to get the actual key pressed regardless of the state of NumLock and CapLock. From here it's relatively simple to do something like:

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

    ...as the "control key" flag is bit 19. Shift is at bit 17, the state of CapsLock at bit 18, Alt is at bit 20, and NumLock is at bit 21.

    0 讨论(0)
  • 2020-11-29 19:29

    You can use ord() function in Python for that.

    For example, if you want to trigger 'a' key press, do as follows :

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

    See a sample code here: Drawing Histogram

    UPDATE :

    To find the key value for any key is to print the key value using a simple script as follows :

    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
    

    With this code, I got following values :

    Upkey : 2490368
    DownKey : 2621440
    LeftKey : 2424832
    RightKey: 2555904
    Space : 32
    Delete : 3014656
    ...... # Continue yourself :)
    
    0 讨论(0)
  • 2020-11-29 19:31

    The keycodes returned by waitKey seem platform dependent. However, it may be very educative, to see what the keys return (and by the way, on my platform, Esc does not return 27...)

    The integers thay Abid's answer lists are mosty useless to the human mind (unless you're a prodigy savant...). However, if you examine them in hex, or take a look at the Least Significant Byte, you may notice patterns...

    My script for examining the return values from waitKey is below:

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

    You can use it as a minimal, command-line image viewer.

    Some results, which I got:

    • q letter:

      You pressed 1048689 (0x100071), LSB: 113 ('q')

    • Escape key (traditionally, ASCII 27):

      You pressed 1048603 (0x10001b), LSB: 27 ('\x1b')

    • Space:

      You pressed 1048608 (0x100020), LSB: 32 (' ')

    This list could go on, however you see the way to go, when you get 'strange' results.

    BTW, if you want to put it in a loop, you can just waitKey(0) (wait forever), instead of ignoring the -1 return value.

    EDIT: There's more to these high bits than meets the eye - please see Andrew C's answer (hint: it has to do with keyboard modifiers like all the "Locks" e.g. NumLock).

    My recent experience shows however, that there is a platform dependence - e.g. OpenCV 4.1.0 from Anaconda on Python 3.6 on Windows doesn't produce these bits, and for some (important) keys is returns 0 from waitKey() (arrows, Home, End, PageDn, PageUp, even Del and Ins). At least Backspace returns 8 (but... why not Del?).

    So, for a cross platform UI you're probably restricted to W, A, S, D, letters, digits, Esc, Space and Backspace ;)

    0 讨论(0)
  • 2020-11-29 19:33

    With Ubuntu and C++ I had problems with the Character/Integer cast. I needed to use cv::waitKey()%256 to obtain the correct ASCII value.

    0 讨论(0)
  • 2020-11-29 19:34

    This prints the key combination directly to the image:

    The first window shows 'z' pressed, the second shows 'ctrl' + 'z' pressed. When a key combination is used, a question mark appear.

    Don't mess up with the question mark code, which is 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'
    
    0 讨论(0)
  • 2020-11-29 19:37

    I too found this perplexing. I'm running Ubuntu 18 and found the following: If the cv.imshow window has focus, you'll get one set of values in the terminal - like the ASCII values discussed above.

    If the Terminal has focus, you'll see different values. IE- you'll see "a" when you press the a key (instead of ASCII value 97) and "^]" instead of "27" when you press Escape.

    I didn't see the 6 digit numbers mentioned above in either case and I used similar code. It seems the value for waitKey is the polling period in mS. The dots illustrate this.

    Run this snippet and press keys while focus is on the test image, then click on the terminal window and press the same keys.

        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 
    
    0 讨论(0)
提交回复
热议问题