实现内容:
用USB摄像头通过旭日x3派的手势识别模块采集人体姿态,并按照协议在PC机上代替拳皇游戏中按键的输入,以实现在游戏中简单锻炼身体,并放松心情的目的.

准备工作

注: 需要提前准备好python环境

  • 1 下载 Mame


    点击 立即下载后,任选一下载地址即可,下载完成后需要解压,即可看到启动程序.

  • 2 安装拳皇及配置相关设置
    下载部分:
    搞定了模拟器,还需要有游戏的roms才能运行,大家可以自行在网上找各种资源,这里提供的是拳皇

下载之后,将下载的zip文件直接放到刚才解压出来文件夹下面的roms下面。

接下来,在你刚才解压出来的文件夹目录下,在地址栏输入cmd,回车。

在弹出的命令行里 输入:

mame -keyboardprovider win32 sfiii3nr1

即可启动游戏
配置设置:按键后 选择 Input(this machine) 进行部分按键更改 更改时 注意鼠标双击需要更改的按键或者按Enter键选择需要更改的按键 ,然后在键盘上输入更改的按键, 注意有一秒左右的延时 不要重复键入

更改按键可参照以下 按键说明(将左边的对应更改为右边的即可):

‘COIN_P1’: ‘5’,
‘COIN_P2’: ‘6’,
‘P1_START’: ‘1’,
‘P2_START’: ‘2’,
‘P1_JPUNCH’: ‘L-CTRL’,
‘P2_JPUNCH’: ‘A’,
‘P1_RIGHT’: ‘RIGHT’,
‘P2_RIGHT’: ‘G’,
‘P1_LEFT’: ‘L’,
‘P2_LEFT’: ‘D’,
‘P1_DOWN’: ‘DOWN’,
‘P2_DOWN’: ‘F’,
‘P1_UP’: ‘UP’,
‘P2_UP’: ‘R’,
‘P1_SKICK’: ‘L-SHIFT’,
‘P2_SKICK’: ‘W’,

更改完成后按Esc退出即可
补充: 将游戏页面最小化 Ctrl+Esc 即可

  • 3 windows 电脑端启动信号接收程序
import os
import re
import socket
import argparse
import time
from threading import Thread try: import win32api import win32con
except ModuleNotFoundError: os.system('pip3 install pywin32') import win32api import win32con key2code = {'0': 48, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53, '6': 54, '7': 55, '8': 56, '9': 57, 'a': 65, 'b': 66, 'c': 67, 'd': 68, 'e': 69, 'f': 70, 'g': 71, 'h': 72, 'i': 73, 'j': 74, 'k': 75, 'l': 76, 'm': 77, 'n': 78, 'r': 82, 'o': 79, 'p': 80, 'q': 81, 's': 83, 't': 84, 'u': 85, 'v': 86, 'w': 87, 'x': 88, 'y': 89, 'z': 90, '/0': 96, '/1': 97, '/2': 98, '/3': 99, '/4': 100, '/5': 101, '/6': 102, '/7': 103, '/8': 104, '/9': 105, '*': 106, '+': 107, 'enter': 108, '-': 109, '.': 110, '/': 111, 'f1': 112, 'f2': 113, 'f3': 114, 'f4': 115, 'f5': 116, 'f6': 117, 'f7': 118, 'f8': 119, 'f9': 120, 'f10': 121, 'f11': 122, 'f12': 123, 'backspace': 8, 'tab': 9, 'clear': 12, 'l-shift': 16, 'r-shift': 16, 'l-ctrl': 17, 'r-ctrl': 17, 'alt': 18, 'capslock': 20, 'esc': 27, 'space': 32, 'pageup': 33, 'pagedown': 34, 'end': 35, 'home': 36, 'left': 37, 'up': 38, 'right': 39, 'down': 40, 'insert': 45, 'delete': 46, 'help': 47, 'numlock': 144}
key2scan = {'numlock': [0x45, 0xc5], '/': [0xe035, 0xe0b5], '*': [0x09, 0x89], '-': [0x0c, 0x8c], '7': [0x08, 0x88], '8': [0x09, 0x89], '9': [0x0a, 0x8a], '4': [0x05, 0x85], '5': [0x06, 0x86], '6': [0x07, 0x87], '1': [0x02, 0x82], 'end': [0xe04f, 0xe0cf], '2': [0x03, 0x83], '3': [0x04, 0x84], 'pgdn': [0x51, 0xd1], '0': [0x0b, 0x8b], 'ins': [0x52, 0xd2], '.': [0x34, 0xb4], 'del': [0x53, 0xd3], '+': [0x0d, 0x8d], 'enter': [0x1c, 0x9c], 'insert': [0xe052, 0xe0d2], 'page up': [0xe049, 0xe0c9], 'delete': [0xe053, 0xe0d3], 'page down': [0xe051, 0xe0d1], 'left': [0xe046, 0xe0c6], 'right': [0xe04d, 0xe0cd], 'up': [0xe048, 0xe0c8], 'down': [0xe050, 0xe0d0], 'esc': [0x01, 0x81], 'f1': [0x3b, 0xbb], 'f2': [0x3c, 0xbc], 'f3': [0x3d, 0xbd], 'f4': [0x3e, 0xbe], 'f5': [0x3f, 0xbf], 'f6': [0x40, 0xc0], 'f7': [0x41, 0xc1], 'f8': [0x42, 0xc2], 'f9': [0x43, 0xc3], 'f10': [0x44, 0xc4], 'f11': [0x57, 0xd7], 'f12': [0x58, 0xd8], '~': [0x29, 0xa9], '·': [0x29, 0xa9], '<tab>': [0x0f, 0x8f], '!': [0x02, 0x82], 'q': [0x10, 0x90], '@': [0x03, 0x83], 'w': [0x11, 0x91], '#': [0x04, 0x84], 'e': [0x12, 0x12], '$': [0x05, 0x85], 'r': [0x13, 0x93], '%': [0x06, 0x86], 't': [0x14, 0x94], '^': [0x07, 0x87], 'y': [0x15, 0x95], '&': [0x08, 0x88], 'u': [0x16, 0x96], 'i': [0x17, 0x97], '(': [0x0a, 0x8a], 'o': [0x18, 0x98], ')': [0x0b, 0x8b], 'p': [0x19, 0x99], '_': [0x0c, 0x8c], '{': [0x1a, 0x9a], '[': [0x1a, 0x9a], '=': [0x0d, 0x8d], '}': [0x1b, 0x9b], ']': [0x1b, 0x9b], '|': [0x2b, 0xab], '\\': [0x2b, 0xab], 'backspace': [0x0e, 0x8e], 'capslock': [0x3a, 0xba], 'l-shift': [0x2a, 0xaa], 'a': [0x1e, 0x9e], 'z': [0x2c, 0xac], 's': [0x1f, 0x9f], 'x': [0x2d, 0xad], 'd': [0x20, 0xa0], 'c': [0x2e, 0xae], 'f': [0x21, 0xa1], 'v': [0x2f, 0xaf], 'g': [0x22, 0xa2], 'b': [0x30, 0xb0], 'h': [0x23, 0xa3], 'n': [0x31, 0xb1], 'j': [0x24, 0xa4], 'm': [0x32, 0xb2], 'k': [0x25, 0xa5], '<': [0x33, 0xb3], ',': [0x33, 0xb3], 'l': [0x26, 0xa6], '>': [0x34, 0xb4], ':': [0x27, 0xa7], ';': [0x27, 0xa7], '?': [0x35, 0xb5], '': [0x35, 0xb5], '"': [0x28, 0xa8], '\'': [0x28, 0xa8], 'r-shift': [0x36, 0xb6], 'l-ctrl': [0x1d, 0x9d], 'l-alt': [0x38, 0xb8], 'space': [0x39, 0xb9], 'r-alt': [0xe038, 0xe0b8], 'r-ctrl': [0xe01d, 0xe09d], } class SocketKeyBoard(object): def __init__(self, ip, port=8000): self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) print("socket bind " + ip + ":" + str(port)) self.socket.bind((ip, port)) self.socket.listen(128) self.client_socket, self.client_addr = None, None self.auto_thread = Thread(target=self.auto_run, args=()) self.auto_thread.start() self.hold_key_list = {} def auto_run(self): while True: time.sleep(0.01) remove_key_list = [] for key in self.hold_key_list.keys(): if self.hold_key_list[key] < time.time(): self.press_key(key, win32con.KEYEVENTF_KEYUP) remove_key_list.append(key) for key in remove_key_list: self.hold_key_list.pop(key) @staticmethod def press_key(key, code=0): if code == 0: print("press", key, time.time()) else: print("release", key, time.time()) if key in key2code.keys(): if key2scan[key][0] & 0xff00 == 0xe000: win32api.keybd_event(key2code[key], key2scan[key][0] & 0x00ff, win32con.KEYEVENTF_EXTENDEDKEY | code, 0) else: win32api.keybd_event(key2code[key], key2scan[key][0], 0 | code, 0) else: print("get unexpected key: ", key) def run(self): total_len = 0 while True: if self.client_socket: rev_info = self.client_socket.recv(1024) if not rev_info: self.client_socket = None continue key_list = re.findall("\"(.*?)\"", rev_info.decode()) key_list = [key.strip().lower() for key in key_list] for key in key_list: total_len += 1 if 'hold' in key: key_temp = key.split(':')[0] keep_time = float(re.findall("hold(.*?)s", key.split(':')[1])[0]) self.hold_key_list[key_temp] = time.time() + keep_time key = key_temp self.press_key(key) time.sleep(0.01) for key in key_list: if ':hold' in key: continue if key in key2code.keys(): self.press_key(key, win32con.KEYEVENTF_KEYUP) else: print("wait for connecting ...") self.client_socket, self.client_addr = self.socket.accept() print("connect success from: ", self.client_addr) def parse_args(): description = "start web socket keyboard application" parser = argparse.ArgumentParser(description=description) parser.add_argument('--ip', help="the local ip number") parser.add_argument('--port', help='set listen port ', default=8000) args_ = parser.parse_args() return args_ if __name__ == "__main__": args = parse_args() socket_keyboard = SocketKeyBoard(ip=args.ip, port=args.port) socket_keyboard.run()

先将代码在PC机 上保存为 .py 文件,然后找到文件目录,并键入cmd

输入如下命令

python3 your_python_file --ip your_ip


注意:(1)用python3输入后没有上图所示输出,可用python 代替继续尝试
( 2) IP为自己PC机 的IP 地址 可以在cmd 命令提示符里面 键入 ipconfig 查询

  • 4 旭日x3派可以运行人体检测代码
    参考 旭日X3 派官网box应用算法中的手势识别手势识别

  • 5 最后将下面的python代码保存进自己的旭日x3派中

import rclpy
import time
import socket
import math
import json
import argparse
from rclpy.node import Node
from ai_msgs.msg import PerceptionTargets
from threading import Thread
from collections import Counter #Action to key mapping
ACTION2KEY = { 'COIN_P1': '5', 'COIN_P2': '6', 'P1_START': '1', 'P2_START': '2', 'P1_JPUNCH': 'L-CTRL', 'P2_JPUNCH': 'A', 'P1_RIGHT': 'RIGHT', 'P2_RIGHT': 'G', 'P1_LEFT': 'L', 'P2_LEFT': 'D', 'P1_DOWN': 'DOWN', 'P2_DOWN': 'F', 'P1_UP': 'UP', 'P2_UP': 'R', 'P1_SKICK': 'L-SHIFT', 'P2_SKICK': 'W',
}
"""
hand gesture:
0: Background,  // 无手势
1: FingerHeart,  // 比心
2: ThumbUp,  // 大拇指向上
3: Victory, // V手势
4: Mute,  // 嘘
10: Palm,  // 手掌
11: Okay,  //  OK手势
12: ThumbRight,  //  大拇指向右
13: ThumbLeft,  //  大拇指向左
14: Awesome,  //  666手势
"""
GESTURE_VICTORY = 3
GESTURE_OKAY = 11
GESTURE_AWESOME = 14 class PlayerState(object): """ Player status There are two players by default. left_arm_line: state of left arm right_arm_line: state of right arm up_or_down: control up and down or squat jump kick: kick left_gesture: left hand gesture right_gesture: right hand gesture time_stamp: timestamp """ def __init__(self, right_arm_line=False, left_arm_line=False, move_direction=0, kick=False, right_gesture=0, left_gesture=0): self.left_arm_line = left_arm_line self.right_arm_line = right_arm_line self.move_direction = move_direction self.kick = kick self.left_gesture = left_gesture self.right_gesture = right_gesture self.time_stamp = time.time() def __str__(self): return "\rarm " + str(self.left_arm_line) + " " + str(self.right_arm_line) + " move " + str( self.move_direction) + " kick " + str(self.kick) + " gesture " + str(self.left_gesture) + " " + str( self.right_gesture) + " " + str(self.time_stamp) class Player(object): """ This class defines players. state_list The list stores a series of action states of players, which are obtained by matching the results of key point detection with the corresponding actions. Method def get_ Action() filters the player's state_list to get the final action. Filtering is to ensure the stability of output action. """ def __init__(self, name): self.state_list = [] self.id = 0 self.name = name def get_action(self): action_num = {} buffer_time_step = 0.5 if len(self.state_list) < 15: return [], {} while self.state_list and time.time() - self.state_list[0].time_stamp > buffer_time_step: self.state_list.pop(0) if not self.state_list: return [], {} action_list = [] select_tile = len(self.state_list) // int(buffer_time_step / 0.2) right_arm_list = [state.right_arm_line for state in self.state_list] left_arm_list = [state.left_arm_line for state in self.state_list] if right_arm_list[-select_tile:].count(True) - select_tile // 5 > right_arm_list[ -select_tile * 2:-select_tile].count( True) or left_arm_list[-select_tile:].count(True) - select_tile // 5 > left_arm_list[ -select_tile * 2:-select_tile].count( True): action_list.append(self.name + '_JPUNCH') action_num[self.name + '_JPUNCH'] = max(right_arm_list.count(True), left_arm_list.count(True)) left_gesture_list = [state.left_gesture for state in self.state_list] right_gesture_list = [state.right_gesture for state in self.state_list] if left_gesture_list.count(GESTURE_VICTORY) > (len(left_gesture_list) / 3 + 1) or right_gesture_list.count( GESTURE_VICTORY) > (len(right_gesture_list) / 3 + 1): action_list.append('COIN_' + self.name) action_num['COIN_' + self.name] = max(left_gesture_list.count(GESTURE_VICTORY), right_gesture_list.count( GESTURE_VICTORY)) elif left_gesture_list.count(GESTURE_OKAY) > (len(left_gesture_list) / 3 + 1) or right_gesture_list.count( GESTURE_OKAY) > (len(right_gesture_list) / 3 + 1): action_list.append(self.name + '_START') action_num[self.name + '_START'] = max(left_gesture_list.count(GESTURE_OKAY), right_gesture_list.count( GESTURE_OKAY)) move_direction_list = [state.move_direction for state in self.state_list] if move_direction_list.count(1) > len(move_direction_list) / 2: action_list.append(self.name + '_DOWN') action_num[self.name + '_DOWN'] = move_direction_list.count(1) elif move_direction_list.count(2) > len(move_direction_list) / 2: action_list.append(self.name + '_UP') action_num[self.name + '_UP'] = move_direction_list.count(2) elif move_direction_list.count(3) > len(move_direction_list) / 2: action_list.append(self.name + '_RIGHT') action_num[self.name + '_RIGHT'] = move_direction_list.count(3) elif move_direction_list.count(4) > len(move_direction_list) / 2: action_list.append(self.name + '_LEFT') action_num[self.name + '_LEFT'] = move_direction_list.count(4) kick_list = [state.kick for state in self.state_list] if kick_list.count(True) > (len(kick_list) / 10 + 1): action_list.append(self.name + '_SKICK') action_num[self.name + '_SKICK'] = kick_list.count(True) return action_list, action_num class Game(object): """ Instantiate players. Give each player a unique ID. To solve the track of key point detection_ For the problem that the player cannot match after the ID changes, maintain a queue to store the ID. """ def __init__(self): self.players = [Player("P1"), Player("P2")] self.show_id_list = [] self.action_buffer = set() self.action_nums = {} def push_state(self, hand_match_dict, body_parser_dict): for track_id in body_parser_dict.keys(): right_arm, left_arm, move_direction, kick = self.stat_detection(body_parser_dict[track_id]) self.show_id_list.append(track_id) while len(self.show_id_list) > 100: self.show_id_list.pop(0) match_idx = -1 for player_idx in range(2): if self.players[player_idx].id == track_id: match_idx = player_idx if match_idx == -1: p0_sum = self.show_id_list.count(self.players[0].id) p1_sum = self.show_id_list.count(self.players[1].id) if p0_sum < 10: self.players[0].id = track_id match_idx = 0 elif p1_sum < 10: self.players[1].id = track_id match_idx = 1 if match_idx != -1: right_gesture_id = 0 left_gesture_id = 0 if (track_id, 'left') in hand_match_dict: left_gesture_id = hand_match_dict[(track_id, 'left')] if (track_id, 'right') in hand_match_dict: right_gesture_id = hand_match_dict[(track_id, 'right')] self.players[match_idx].state_list.append( PlayerState(right_arm, left_arm, move_direction, kick, left_gesture_id, right_gesture_id)) return self @staticmethod def stat_detection(points): def is_line(a, b, c): pow_len_a_b = (math.pow(a.x - b.x, 2) + math.pow(a.y - b.y, 2)) pow_len_b_c = (math.pow(b.x - c.x, 2) + math.pow(b.y - c.y, 2)) pow_len_a_c = (math.pow(a.x - c.x, 2) + math.pow(a.y - c.y, 2)) cosC = -(pow_len_a_b + pow_len_b_c - pow_len_a_c) / (2 * math.sqrt(pow_len_a_b) * math.sqrt(pow_len_b_c)) return cosC > 0.8 def is_y_similar(a, b, c): x_a_c = abs(a.x - c.x) if x_a_c < 0.1: print("x is too small") return False y_a_c = abs(a.y - c.y) x_y_ratio = y_a_c / x_a_c return x_y_ratio < 0.4 def arm_status(): is_right_line = is_line(points[10], points[8], points[6]) is_right_y_similar = is_y_similar(points[10], points[8], points[6]) is_left_line = is_line(points[9], points[7], points[5]) is_left_y_similar = is_y_similar(points[9], points[7], points[5]) return is_right_line and is_right_y_similar, is_left_line and is_left_y_similar def move_direction(): """ 0: stand 1: down 2: up 3: left 4: right :return: """ # down if abs(points[16].y - points[14].y) < abs(points[14].y - points[12].y) / 2 or abs( points[15].y - points[13].y) < abs(points[13].y - points[11].y) / 2: return 1 # up if points[8].y < points[0].y or points[7].y < points[0].y: return 2 middle_x = (points[5].x + points[6].x + points[12].x + points[11].x) / 4 middle_y = (points[5].y + points[6].y + points[12].y + points[11].y) / 4 # right if points[10].x < middle_x and points[9].x < middle_x and points[9].y > middle_y: return 3 # left if points[10].x > middle_x and points[9].x > middle_x and points[10].y > middle_y: return 4 return 0 def kick(): return (abs(points[16].y - points[13].y) < abs(points[15].y - points[14].y) and points[14].y < points[12].y) or abs(points[15].y - points[14].y) < abs( points[15].y - points[13].y) and points[13].y < points[11].y right_arm_line_, left_arm_line_ = arm_status() move_direction_ = move_direction() kick_ = kick() return right_arm_line_, left_arm_line_, move_direction_, kick_ def refresh_action(self): for player in self.players: action_list, action_num = player.get_action() for action in action_list: self.action_buffer.add(action) self.action_nums = dict(Counter(self.action_nums) + Counter(action_num)) return self def get_action(self): return self.action_buffer, self.action_nums def clear_action(self): self.action_buffer.clear() self.action_nums = {} class socketer(object): def __init__(self,ip,port): self.ip = ip self.port = port self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.connect() def connect(self): while True: try: self.socket.close() self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.connect((self.ip, self.port)) print('connect success') return except socket.error as e: print('connect failed', e) time.sleep(1) def send(self, data): try: data = json.dumps(data) print(data) self.socket.send(bytes(data.encode('utf-8'))) except socket.error: self.connect() except: assert 0 class MinimalSubscriber(Node): def __init__(self, args): super().__init__('minimal_subscriber') self.subscription = self.create_subscription( PerceptionTargets, '/hobot_hand_gesture_detection', self.listener_callback, 10) self.subscription  # prevent unused variable warning self.socketer = socketer(ip=args.ip, port=args.port) self.game = Game() self.auto_thread = Thread(target=self.auto_step, args=()) self.auto_thread.start() def auto_step(self): need_hold_list = ['P1_RIGHT', 'P2_RIGHT', 'P1_LEFT', 'P2_LEFT',  'P1_DOWN', 'P2_DOWN'] #'P1_UP', 'P2_UP', old_action_list=[] old_action_num = {} while True: time.sleep(0.1) action_list, action_num = self.game.get_action() for act in old_action_list: if act in action_list: action_list.remove(act) old_action_list = action_list.copy() key_list = [] for act in action_list.copy(): key_ = ACTION2KEY[act] print(act, action_num) if act in need_hold_list and act in old_action_num.keys() and (action_num[act] >= old_action_num[act]-20 and action_num[act] > 10): key_+=':hold0.3s' key_list.append(key_) if key_list: self.socketer.send(key_list) old_action_num = action_num.copy() self.game.clear_action() def hand_match(self, hand_parser_list, body_parser_dict): def distance(x1, y1, x2, y2): return math.sqrt(math.pow(x1 - x2, 2) + math.pow(y1 - y2, 2)) hand_match_dict = {} for hand_info in hand_parser_list: min_distance = 10000 match_flag = (-1, 'left') for track_id in body_parser_dict.keys(): new_distance = distance(body_parser_dict[track_id][18].x, body_parser_dict[track_id][18].y, hand_info[1][0], hand_info[1][1]) if hand_info[1][1] > body_parser_dict[track_id][0].y: continue if new_distance < min_distance and new_distance < 40: min_distance = new_distance match_flag = (track_id, 'right') new_distance = distance(body_parser_dict[track_id][17].x, body_parser_dict[track_id][17].y, hand_info[1][0], hand_info[1][1]) if new_distance < min_distance and new_distance < 40: min_distance = new_distance match_flag = (track_id, 'left') if match_flag[0] != -1: hand_match_dict[match_flag] = hand_info[0] return hand_match_dict def get_body_hand_info(self, msg): body_parser_dict = {} hand_parser_list = [] for targeter in msg.targets: track_id = targeter.track_id if len(targeter.points) == 0: continue point_object = targeter.points[0] if point_object.type == 'body_kps': body_points = point_object.point body_points_confidence = point_object.confidence if sum(body_points_confidence)/len(body_points_confidence) < 0.7: break body_parser_dict[track_id] = body_points if point_object.type == 'hand_kps': average_x = 0.0 average_y = 0.0 hand_points = point_object.point for p in hand_points: average_x += p.x average_y += p.y average_x /= len(hand_points) average_y /= len(hand_points) if len(targeter.attributes) > 0 and targeter.attributes[0].type == 'gesture': gesture_id = targeter.attributes[0].value hand_parser_list.append((gesture_id, (average_x, average_y))) hand_match_dict = self.hand_match(hand_parser_list, body_parser_dict) return hand_match_dict, body_parser_dict def listener_callback(self, msg): # By monitoring the detected key points, the status information of the body and hands can be obtained. #fps = msg.fps #print(fps) hand_match_dict, body_parser_dict = self.get_body_hand_info(msg) self.game.push_state(hand_match_dict, body_parser_dict).refresh_action() return None def main(args): rclpy.init() minimal_subscriber = MinimalSubscriber(args) rclpy.spin(minimal_subscriber) # Destroy the node explicitly # (optional - otherwise it will be done automatically # when the garbage collector destroys the node object) minimal_subscriber.destroy_node() rclpy.shutdown() def parse_args(): description = "start web socket keyboard application" parser = argparse.ArgumentParser(description=description) parser.add_argument('--ip', help="the local ip number") parser.add_argument('--port', help='set listen port ', default=8000) args_ = parser.parse_args() return args_ if __name__ == '__main__': args = parse_args() main(args)

使用说明

  • 1 在windows 端 进入文件保存位置 输入cmd 运行准备工作 3中的代码文件;

python3 your_python_file --ip your_ip

  • 2 启动下载的游戏(启动之前,一定要先设置输入法为英文模式),启动代码如下,启动方式如之前介绍;

mame -keyboardprovider win32 sfiii3nr1

  • 3 在x3派上,先启动手势检测的示例,然后再新开一个终端,刷新化境变量

source /opt/tros/setup.bash

接着在终端运行保存进旭日x3派章节的python脚本(注意!!IP地址与第一步地址一样)。

python3 your_python_file --ip your_remote_computer_ip

成功后板端有如下输出

PC端分别如下所示

注:使用摄像头时,要保证摄像头能够采集全身信息,人体距离摄像头4~5米。

手势说明

投币:

开始(start):

上 or 跳:


下 or 蹲:

踢腿:

出拳:

左右:

文章参考自

原文章地址 https://developer.horizon.ai/forumDetail/112555512834430487

旭日x3派,手势识别之Momo Quanghuang学习记录相关推荐

  1. [首发] 多方位玩转“地平线新发布AIoT开发板——旭日X3派(Sunrise x3 Pi)” 插电!开机!轻松秒杀!

    有幸在发布会前拿到了开发板,可以提前对开发板测试,感受下新品AIoT的魅力.(我这个是体验装,不花钱,需要啥设备他们还得给我买→_→) 下面我将以自己的科研项目经历来对这款芯片进行评估,简单来说,就是 ...

  2. 智能搬运机器人系列之使用旭日X3派实现机器人防脱轨功能

    准备工作 (1)旭日X3派 本摄像头小车上位机采用旭日X3派开发板.开发环境为Ubuntu系统下的opencv-python环境.通过HDMI外接显示器实现对两个车载USB摄像头的监测与开发,进而感知 ...

  3. 旭日x3派个人配置总结(ubuntu server + xrdp)

    旭日x3派基本设置 旭日x3派使用文档 [首发]多方位玩转旭日x3派 XRDP+Xface4远程桌面设置 安装xrdp并解决闪退.黑屏问题 ROS2-Foxy配置 解决"Failed to ...

  4. 体验极速——在旭日X3派上使用双频1300M USB无线网卡

    上一篇博客<在旭日X3派开发板上使用USB Wifi来提高网络速度>提供一种低成本¥20的USB Wifi解决方案.这个模块的传输速度在10M/s以内,尽管满足正常的开发需求,但在项目应用 ...

  5. 旭日X3派更新最小启动固件

    当拿到旭日X3派时,我们需要选择一张SD卡来烧录系统固件.目前对SD卡的限制比较多,需要U10速度以上,最好是大厂出的新卡.对于一些旧卡,或者速度没有达到U10的卡,经常出现兼容性问题. 本文介绍通过 ...

  6. [旭日X3派] 初识篇 - 01

    简单介绍一下 旭日X3派:        地平线旭日®️ X3 派是一款面向生态开发者的嵌入式 AI 开发板,接口兼容树莓派,具有 5 TOPS 端侧推理与 4 核 ARM A53 处理能力. 可同时 ...

  7. 002_旭日X3派初探:TogetherROS安装

    文章目录 1. What is TogetherROS? 2. How to install TogetherROS? 2.1 准备工作 2.2 局域网连接 2.2.1 网线互联 2.2.2 通过SS ...

  8. AI 边缘计算平台 - RK3588 / 旭日 X3 派 / 爱芯派 AX620A / K510 简介

    今年的双 11,看起来好像没有往年那么火,各大厂家优惠的力度感觉也不是很大.盘点一下 AI 边缘计算平台,发现有几款性价比还比较高平台的加入,值得大家考察一番. 我将几款性价比还不错的平台做了整理,列 ...

  9. 在旭日X3派开发板上使用Intel Realsense深度相机

    在前文<多方位玩转"地平线新发布AIoT开发板--旭日X3派(Sunrise x3 Pi)" 插电!开机!轻松秒杀!>中,我们已经成功了使用了这个开发板. 深度相机目前 ...

  10. [旭日X3派] 初识篇 - 02

    开局先给整个详细产品参数~ 处理器 地平线旭日® X3M 芯片 CPU 四核 ARM Cortex-A53@1.2GHz BPU 双核 @1GHz,等效算力 5 TOPS 内存 2G/4G Byte ...

最新文章

  1. Day 04 第一印象可靠吗
  2. 【TensorFlow】笔记3:MNIST数字识别问题
  3. arcgis伪节点检查_arcgis建立拓扑分析(检验矢量图)
  4. Laravel自定义验证规则的实例与框架使用正则实例
  5. SAP PI screenshot
  6. 2017初级计算机试题,计算机基础知识试题(卷)与答案解析 2017年.doc
  7. 机房收费系统个人重构版:暮然回首,灯火阑珊
  8. 【原】公司P2P平台的功能拆分
  9. 【Hive】Hive 建表语句详解
  10. cef注入js_CefSharp JavaScript注入
  11. 2022-2027年中国SPA水疗行业市场调研及未来发展趋势预测报告
  12. 计算机包括台式机和笔记本,笔记本电脑与台式机怎样连接
  13. 2、硬件工程师之元器件学习—电阻(二)
  14. Python分析《哈哈哈哈哈》4万弹幕
  15. Yuga Labs「高处不胜寒」
  16. vue 仿网易云音乐项目
  17. python中py是什么意思_python中__init__.py是干什么的
  18. bcm4322linux驱动下载,苹果MAC BOOK PRO 5.5 2009年中 安装fedora26——broadcom BCM4322 无线驱动在fedora上的安装...
  19. 阿里面试:分析为什么B+树更适合作为索引的结构以及索引原理
  20. Stegsolve查看隐水印(暗水印)java jar包工具

热门文章

  1. echarts 基于个性化百度地图的迁徙图
  2. Delphi制作打印面签案例
  3. js2D物理引擎插件
  4. 【数码复印新生态】东芝泰格强势支持统信UOS
  5. XCode7 iOS8.X Simulator 离线下载地址
  6. android calendar控件,Android Calendar自定义日历控件
  7. 职称计算机考试题库破解版2017,2017职称计算机考试题库及答案
  8. 截止失真放大电路_音频放大器结构组成_音频放大器分类
  9. STL格式零件的基本操作
  10. 身份证号码识别(python)