用OpenCV玩《铁拳》!!!

本文介绍了一种使用OpenCV和Python实现的手势控制系统,该系统可以将玩家的手势转化为《铁拳》游戏中的动作。通过跟踪脸部和设置虚拟开关,系统可以根据玩家的动作执行游戏中的前进、跳跃、蹲下等操作。文中详细阐述了实现这一概念的两种方法,以及实际操作中的注意事项和技巧。
摘要由CSDN通过智能技术生成

点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

用手势导航可以完成GTAV,那么这一思想也能带入到别的游戏中。因此,我们的第一选择是打格斗游戏,并且该类别中最好的游戏之一是《铁拳》(SFTK)。主要概念很简单,无论人类玩家会采取什么行动(例如拳打),游戏中的玩家都会复制相同的动作。因此,为了实现这个想法,我们想出了两种方法。

首先,一种是较为复杂的方法:把我们的200+图像做不同的动作(如冲压,跳跃)等,然后用它来训练模型,以不同的姿势或者动作之间进行分类,并模拟它在游戏。但是这种方法存在一些问题。

显而易见,我们必须给自己拍很多张照片,每个类别中要有200张以上。这将非常忙碌,并且为了概括起见,我们还需要不同大小,背景和光照条件不同的人的图像。这可能会花费很多时间。

第二种方法是简单地使用我们以前在Virtual Switch and Gesture Gaming中的项目中的想法,为了概念验证,我们决定采用第二种方法。


概念

其工作背后的主要概念非常容易,只是有一个虚拟开关,只要按下该开关,就可以模拟游戏中相应的动作(踢)。

步骤

  1. 跟踪脸部。

  2. 将边界框wrt移到bbox面。

  3. 使用特定区域作为专用于特定操作的虚拟交换机

Bbox(边界框)是用于指代感兴趣区域(矩形/框内)的术语。

我们跟踪人脸,并且虚拟开关框相对于人脸移动。因此,为了在游戏中移动而使用的逻辑是:

  1. 当我们前进一定的门槛时,玩家也将开始前进,反之亦然。

  2. 我们存储一条穿过脸部中心的水平线。如果我们跳跃并越过中心线一个阈值,则玩家也会跳跃。同样,当我们走到线下时,玩家将蹲下。

Setup.ipynb->

在此笔记本中,我们将定义人类玩家开始的初始位置。因此,将通过跟踪算法从该位置跟踪他。首先,设置相机并将其放置在固定位置。然后,我们将只跟踪面部来跟踪人类玩家在游戏中的位置,因此执行“面部”框单元格,然后:

  1. 从开始的位置做准备。

  2. 计时器结束后,在脸部周围放置一个bbox。

现在,如果您还想为新操作添加新的开关,则可以运行“按钮”单元,然后:

  1. 设置n。这是总数。要添加的开关数量。

  2. 保持脸部收件箱为准,并进行操作(例如踢)。然后在您要分配用于踢脚动作的区域周围打一个方框。

  3. 要保存以供以后使用,请复制打印的输出并将其粘贴到Switch.py上。

请注意,开关0将映射到操作键0。因此,将操作映射到类Action中的键。

class Buttons:
    
    def __init__(self, n=0, bbox_body=(), training=False):
        self.training = training
        if not training: # automatically set the buttons values if not training mode
            self.set_buttons()
        else:
            self.n = n
            self.bbox_switch = []
            self.bbox_body = bbox_body
            self.center_point = get_centroid(self.bbox_body) # center point of face


        self.buttons_bbox_init()
        self.action = Actions(self.center_point) # calling the Actions object


    
    def set_buttons(self):
        self.bbox_body, self.center_point, self.n, self.bbox_switch = buttons_data


    
    def buttons_bbox_init(self): # to setup the regions of action (bbox of switch)
        self.switches = [] # the switch object
        self.bbox_center = [] # the coordinates of bbox of switch wrt to the face
        
        for i in range(self.n):
            if not self.training: # copy the switch data, if already done the setup
                bbox = self.bbox_switch[i]
                s = Switch(self.bbox_body, bbox)
            else: # else, select the region for switch
                s = Switch(self.bbox_body)
                self.bbox_switch.append(s.bbox)
            self.switches.append(s)
            self.bbox_center.append(self.bbox_wrt_center(s.bbox)) #now bbox is wrt origin            
            
        if self.training: # prints the values of bbox of body and switch
            print(f'bbox_body = {self.bbox_body} \nbbox_switch = {self.bbox_switch}')
    
    # Calculates the distance of bbox from center point (face). Then this is used to get new position
    # of switch when the positoin of face changes.
    def bbox_wrt_center(self, bbox):
        center_x, center_y = self.center_point #starting center point, find switch pos, wrt starting bbox
        x, y, w, h = bbox
        dx, dy = x - center_x, y - center_y
        return dx, dy, w, h
    
    # updates to the new position of bbox switch, wrt to face
    def bbox_update(self, bbox):
        curr_x, curr_y = self.curr_center #cetner curr point of body
        dx, dy, w, h = bbox
        x = dx + curr_x
        y = dy + curr_y
        return x, y, w, h
        
    
    def run(self, frame, curr_center):
        self.curr_center = curr_center
        for i in range(self.n):
            s, bbox = self.switches[i], self.bbox_center[i]
            s.bbox = self.bbox_update(bbox)
            pressed = s.update(frame)
            if pressed:
                self.action.press_val(i)
        self.action.action_movement(curr_center)


Gameplay.ipynb->

我们将初始化按钮对象,其中将包含所有虚拟交换机,通过训练为False将使其使用默认值。

button = Buttons(training=False)
tracker = cv2.TrackerCSRT_create()
fvs = cv2.VideoCapture(path)
TIMER_SETUP = 3
t = time.time()


while True:
    frame = get_framecv2(fvs)    
    curr = (time.time() - t)
    if curr > TIMER_SETUP or frame is None:
        break
    cv2.putText(frame, str(int(TIMER_SETUP - curr)+1), (225,255), cv2.FONT_HERSHEY_SIMPLEX, 1.5, COLOR_RED, 4)
    cv2.putText(frame, 'Keep your face inside the box', POS_SCREEN, cv2.FONT_HERSHEY_SIMPLEX, 1, COLOR_RED, 4)
    drawbox(True, bbox, frame)    
    cv2.imshow("Tracking", frame)
    cv2.waitKey(1)


tracker.init(frame, BB)


#After the timer finishes, now your actions will be recorded, and will be mapped to key in game.
while True:
    frame = get_framecv2(fvs)
    if frame is None:
        break        
    copy = frame.copy()
    _, bbox = tracker.update(frame) 
    drawbox(True, bbox, frame)
    button.run(frame, get_centroid(bbox))    


    cv2.imshow("Tracking", frame) # orig video frames


    k = cv2.waitKey(1)


    if k == 13: #13 is the Enter Key
        break
    
cv2.destroyAllWindows()
fvs.release()

唯一的变化是,我们将当前帧传递给button对象,该对象将跟踪位置的变化以及与所按下的虚拟开关相对应的游戏中要执行的动作。

Switch.py->

该脚本包含所有基本功能,交换机—此类用于实现虚拟交换机。

按钮-此类用于:

  1. 存储所有Switch对象

  2. 通过当前帧来决定要按下哪个开关。

bbox_wrt_center:此函数用于计算开关wrt到脸部中心的坐标。这样做是为了在我们移动时,开关也相应地移动。运行—此功能获取当前帧,并将其传递到开关。如果按下任何开关(返回True),则在游戏中按下与该开关相对应的动作。

动作:此类用于将Switch与游戏中相应的动作键(打孔,向左移动)映射。注意—我们尚未在其他PC上进行过测试,因此,如果某项操作在您的PC上不起作用,请尝试为Pressley和ReleaseKey之间的时间间隔设置不同的值。

注意:

  1. 确保视频质量良好并且光线充足。由于它是通过计算噪声来工作的,因此低图像质量或低光照可能会导致某些异常。

  2. 您可以使用背景减法器的history参数,并根据需要更改开关的阈值。

结论

因此,这是我们尝试使用图像处理技能来创建一种有趣的玩《铁拳》游戏的方法。这只是对该想法的实验,将来,我们可能会使用一些更好的技术来获得更好的结果。

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲

在「小白学视觉」公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲

在「小白学视觉」公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白学视觉

您的赞赏是我们坚持下去的动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值