0

我有一个机器学习项目,它正在为 linux 中的速度梦想游戏设计自主驱动程序。在这种情况下,我必须找到一种方法让键盘输出像这样实际的一维数组。

 up - down - right - left - upleft - upright - downleft - downright - do nothing
[0     0       0       0       0         0          0           0          1]

我将此代码用作截屏和处理的起始代码:

import time
import cv2
import mss
import numpy as np

def process_img(original_img):
    processed_img = cv2.cvtColor(original_img, cv2.COLOR_BGR2GRAY)
    processed_img = cv2.Canny(processed_img, threshold1=200, threshold2=300)
    return processed_img

with mss.mss() as sct:
    # Part of the screen to capture
    monitor = {"top": 0, "left": 70, "width": 640, "height": 480}

    while True:
        last_time = time.time()
        # Get raw pixels from the screen, save it to a Numpy array
        screen = np.array(sct.grab(monitor))
        new_screen = process_img(original_img=screen)

        # Display the picture
        cv2.imshow("Window", new_screen)

        print("Loop took {} seconds".format(time.time() - last_time))

        # Press "q" to quit
        k = cv2.waitKey(12)
        if k > 0:
            print(k)
        if k & 0xFF == ord("q"):
            cv2.destroyAllWindows()
            break

我知道使用功能可以捕获键码cv2.waitkey()。所以我可以想出一种方法来捕捉是否按下了向上 - 向下 - 向左或向右。但是有什么方法可以让我用 cv2.waitkey 捕捉像up-left, up-right, ... 这样的组合键。

在循环中捕捉按键cv2.waitkey对我来说非常重要,因为它在准确度方面对我的神经网络的性能有很大的改进。

4

2 回答 2

1

我认为cv2.waitKey不能同时捕捉多个按键。捕获两个组合键的简单方法,您可以记录最后捕获的键并将其与当前捕获键进行比较,检查这两个键是否满足您想要的组合键。

import cv2

cap = cv2.VideoCapture(0)
k = last_key = -1
up_left_is_pressed = up_right_is_pressed = False

while True:
    ok, image = cap.read()

    if not ok:
        break

    last_key = k # last catched key
    k = cv2.waitKey(1) # current catched key

    if k == -1:
        up_left_is_pressed = up_right_is_pressed = False

    if (k == ord('a') and last_key == ord('w')) or ((k == ord('w') and last_key == ord('a'))):
        up_left_is_pressed = True
        cv2.putText(image, "up left press", (25, 25), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
    elif (k == ord('d') and last_key == ord('w')) or ((k == ord('w') and last_key == ord('d'))):
        up_right_is_pressed = True
        cv2.putText(image, "up right press", (25, 25), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
    else:
        cv2.putText(image, "no key combination pressed", (25, 25), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0))

    cv2.imshow("hi", image)
    if k == 27:
        break
cap.release()
cv2.destroyAllWindows()
于 2019-10-16T08:50:08.073 回答
0

当您切换到另一个程序并按住键时,听起来“cv2.waitkey”不是一个好选择。我找到了这个示例并制作了一个示例代码来捕获在 windows 中完美运行并且在linux中还不错的按键。

import time
import cv2
import mss
import numpy as np
from pynput.keyboard import Key, Listener

def up():
    print("Go up")


def down():
    print("Go down")


def left():
    print("Go left")


def right():
    print("Go right")


def up_left():
    print("Go up_left")


def up_right():
    print("Go up_right")


def down_left():
    print("Go down_left")


def down_right():
    print("Go down_right")


def do_nothing():
    print("Do Nothing")


# Create a mapping of keys to function (use frozenset as sets are not hashable - so they can't be used as keys)

combination_to_function = {
    frozenset([Key.up]): up,  # No `()` after function_1 because
    # we want to pass the function, not the value of the function
    frozenset([Key.down, ]): down,
    frozenset([Key.left, ]): left,
    frozenset([Key.right, ]): right,
    frozenset([Key.up, Key.left]): up_left,
    frozenset([Key.up, Key.right]): up_right,
    frozenset([Key.down, Key.left]): down_left,
    frozenset([Key.down, Key.right]): down_right,
}

# Currently pressed keys
current_keys = set()


def on_press(key):
    # When a key is pressed, add it to the set we are keeping track of and check if this set is in the dictionary
    current_keys.add(key)
    if frozenset(current_keys) in combination_to_function:
        # If the current set of keys are in the mapping, execute the function
        combination_to_function[frozenset(current_keys)]()


def on_release(key):
    # When a key is released, remove it from the set of keys we are keeping track of
    if key in current_keys:
        current_keys.remove(key)


def process_img(original_img):
    processed_img = cv2.cvtColor(original_img, cv2.COLOR_BGR2GRAY)
    processed_img = cv2.Canny(processed_img, threshold1=200, threshold2=300)
    return processed_img


with mss.mss() as sct:
    # Part of the screen to capture
    monitor = {"top": 0, "left": 70, "width": 640, "height": 480}

    while True:
        listener = Listener(on_press=on_press, on_release=on_release)
        listener.start()
        last_time = time.time()
        # key_catcher = MockButton()
        # Get raw pixels from the screen, save it to a Numpy array
        screen = np.array(sct.grab(monitor))
        new_screen = process_img(original_img=screen)

        # Display the picture
        cv2.imshow("Window", new_screen)

        # print("Loop took {} seconds".format(time.time() - last_time))
        # Press "q" to quit

        k = cv2.waitKey(10)

        if k & 0xFF == ord("q"):
            cv2.destroyAllWindows()
            break

        listener.stop()
于 2019-10-19T13:58:20.743 回答