警惕AI,我搭建了一个“枪枪爆头”的视觉AI自瞄程序,却引发了一场“山雨欲来”

前言

前段时间在网上看到《警惕AI外挂!我写了一个枪枪爆头的视觉AI,又亲手”杀死”了它》这个视频,引起了我极大的兴趣。

视频中提到,在国外有人给使命召唤做了个AI程序来实现 自动瞄准功能。它跟传统外挂不一样,该程序不需要用游戏内存数据,也不往服务器发送作弊指令,只是通过计算机视觉来分析游戏画面,定位敌人,把准星移动过去,跟人类玩家操作一模一样,因此反外挂程序无法检测到它。而且更恐怖的是这AI程序 全平台通用,不管是X-box,PS4还是手机,只要能把画面接出来,把操作送进去,就可以实现” 枪枪爆头“。

警惕AI,我搭建了一个“枪枪爆头”的视觉AI自瞄程序,却引发了一场“山雨欲来”

外网的那个开发者用的是 基于方框的目标检测,但是像射击游戏需要定位人体的场景,其实有比方框检测更好的算法。up主就利用了几个小时的时间就写出来了一个效果更好,功能更夸张的AI程序,也就是利用 人体关节点检测技术,通过大量真人图片训练出来的视觉AI,可以把视频和图片里人物的关节信息提取出来 并给出每个部位中心点的精确像素坐标,而且虽然训练的是是真人图片,但是给它游戏里的人物,他也一样能把人体关节定位出来。

可以说由于这类AI程序的出现,现在fps游戏的形式就是 山雨欲来风满楼,十分严峻啊!

下面,我们先开始介绍这个视觉AI自动瞄准的制作思路,然后再谈谈 这个问题带来的影响以及如何解决这个问题

一、核心功能设计

总体来说,我们首先需要训练好一个人体关节点检测的AI视觉模型,然后将游戏画面实时送入AI视觉模型中,再反馈出游戏人物各个部位的像素位置,然后确定瞄准点,并将鼠标移动到瞄准点位置。

拆解需求后,整理出核心功能如下:

  • 训练 人体关节点检测模型
  • 输入视频或图片到AI视觉模型,并 输出瞄准点位置
  • 自动操作鼠标移动到对应瞄准位置

最终想要实现的效果如下图所示:

警惕AI,我搭建了一个“枪枪爆头”的视觉AI自瞄程序,却引发了一场“山雨欲来”

二、核心实现步骤

1.训练 人体关节点检测模型

在这一部分,我打算使用由微软亚洲研究院和中科大提出High-Resoultion Net(HRNet)来进行人体关节点检测,该模型通过在高分辨率特征图主网络逐渐并行加入低分辨率特征图子网络,不同网络实现多尺度融合与特征提取实现的,所以在目前的通用数据集上取得了较好的结果。

1.1 HRNet代码库安装

按照官方的install指导命令,安装十分简单。我是采用本地源代码安装方式。

git clone https://github.com/leoxiaobin/deep-high-resolution-net.pytorch.git
python -m pip install -e deep-high-resolution-ne.pytorch

1.2 人体关键点数据集下载

首先打开COCO数据集官方下载链接

对于Images一栏的绿色框需要下载三个大的文件,分别对应的是训练集,验证集和测试集:

2017 Train images [118K/18GB]
2017 Val images [5K/1GB]
2017 Test images [41K/6GB]

对于Annotations一栏绿色框需要下载一个标注文件:

2017 Train/Val annotations [241MB]

将文件解压后,可以得到如下目录结构:

其中的 person_keypoints_train2017.jsonperson_keypoints_val2017.json 分别对应的人体关键点检测对应的训练集和验证集标注。

annotations
├── captions_train2017.json
├── captions_val2017.json
├── instances_train2017.json
├── instances_val2017.json
├── person_keypoints_train2017.json 人体关键点检测对应的训练集标注文件
└── person_keypoints_val2017.json 人体关键点检测对应的验证集标注文件

在本地代码库datasets目录下面新建立coco目录,将上面的训练集,验证集以及标注文件放到本地代码的coco目录下面

datasets
├── coco
│ ├── annotations
│ ├── test2017
│ ├── train2017
│ └── val2017

1.3 环境配置与模型训练

核心训练代码如下:

def train(config, train_loader, model, criterion, optimizer, epoch,
          output_dir, tb_log_dir, writer_dict):
    batch_time = AverageMeter()
    data_time = AverageMeter()
    losses = AverageMeter()
    acc = AverageMeter()
    # switch to train mode
    model.train()
    end = time.time()
    for i, (input, target, target_weight, meta) in enumerate(train_loader):
        data_time.update(time.time() - end)
        outputs = model(input)
        target = target.cuda(non_blocking=True)
        target_weight = target_weight.cuda(non_blocking=True)
        if isinstance(outputs, list):
            loss = criterion(outputs[0], target, target_weight)
            for output in outputs[1:]:
                loss += criterion(output, target, target_weight)
        else:
            output = outputs
            loss = criterion(output, target, target_weight)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        # measure accuracy and record loss
        losses.update(loss.item(), input.size(0))
        _, avg_acc, cnt, pred = accuracy(output.detach().cpu().numpy(),
                                         target.detach().cpu().numpy())
        acc.update(avg_acc, cnt)
        batch_time.update(time.time() - end)
        end = time.time()
        if i % config.PRINT_FREQ == 0:
            msg = 'Epoch: [{0}][{1}/{2}]\t' \
                  'Time {batch_time.val:.3f}s ({batch_time.avg:.3f}s)\t' \
                  'Speed {speed:.1f} samples/s\t' \
                  'Data {data_time.val:.3f}s ({data_time.avg:.3f}s)\t' \
                  'Loss {loss.val:.5f} ({loss.avg:.5f})\t' \
                  'Accuracy {acc.val:.3f} ({acc.avg:.3f})'.format(
                      epoch, i, len(train_loader), batch_time=batch_time,
                      speed=input.size(0)/batch_time.val,
                      data_time=data_time, loss=losses, acc=acc)
            logger.info(msg)
            writer = writer_dict['writer']
            global_steps = writer_dict['train_global_steps']
            writer.add_scalar('train_loss', losses.val, global_steps)
            writer.add_scalar('train_acc', acc.val, global_steps)
            writer_dict['train_global_steps'] = global_steps + 1
            prefix = '{}_{}'.format(os.path.join(output_dir, 'train'), i)
            save_debug_images(config, input, meta, target, pred*4, output,
                              prefix)

训练结果:

警惕AI,我搭建了一个“枪枪爆头”的视觉AI自瞄程序,却引发了一场“山雨欲来”

2.输入视频或图片实时反馈瞄准点坐标

2.1 实时读取屏幕画面

import pyautogui
img = pyautogui.screenshot()

在一个 1920×1080 的屏幕上, screenshot()函数要消耗100微秒,基本达到实时传入游戏画面要求。

如果不需要截取整个屏幕,还有一个可选的region参数。你可以把截取区域的左上角XY坐标值和宽度、高度传入截取。

im = pyautogui.screenshot(region=(0, 0, 300 ,400))

警惕AI,我搭建了一个“枪枪爆头”的视觉AI自瞄程序,却引发了一场“山雨欲来”

2.2 读取图片反馈坐标

parser.add_argument('--keypoints', help='f:full body 17 keypoints,h:half body 11 keypoints,sh:small half body 6 keypotins')
hp = PoseEstimation(config=args.keypoints, device="cuda:0")

可以选择人体关节点检测数目,包括上半身6个关键点、上半身11个关键点以及全身17个关键点,然后构建探测器。

人体关节点对应序号:

“keypoints”: { 0: “nose”, 1: “left_eye”, 2: “right_eye”, 3: “left_ear”, 4: “right_ear”, 5: “left_shoulder”, 6: “right_shoulder”, 7: “left_elbow”, 8: “right_elbow”, 9: “left_wrist”, 10: “right_wrist”, 11: “left_hip”, 12: “right_hip”, 13: “left_knee”, 14: “right_knee”, 15: “left_ankle”, 16: “right_ankle” }

因此如果为了自动瞄准头部实现”枪枪爆头”,仅需要反馈 0: “nose”的坐标点就行了。

代码如下:

location=hp.detect_head(img_path, detect_person=True, waitKey=0)

def detect_head(self, image_path, detect_person=True, waitKey=0):

    bgr_image = cv2.imread(image_path)
    kp_points, kp_scores, boxes = self.detect_image(bgr_image,
                                                    threshhold=self.threshhold,
                                                    detect_person=detect_person)
    return kp_points[0][0]

输出结果: [701.179 493.55]

警惕AI,我搭建了一个“枪枪爆头”的视觉AI自瞄程序,却引发了一场“山雨欲来”

可以看到虽然训练的是真人图片,但是给它游戏里的人物,它也一样能把人体关节定位出来。

深度神经网络之所以厉害,就是因为它有一定的演绎推广能力。没见过的东西,他也能靠着层次线索分析一波,结果往往也挺准。而且游戏场景是现实场景的简化之后的结果,环境和光影都要简单的多,能把现实世界分析明白的视觉AI,对付个3D游戏更是小菜一碟了。

3.自动移动鼠标到对应的坐标点

3.1 移动鼠标

移动到指定位置:

pyautogui.moveTo(100,300,duration=1)

将鼠标移动到指定的坐标;duration 的作用是设置移动时间,所有的gui函数都有这个参数,而且都是可选参数。

获取鼠标位置:

print(pyautogui.position())   # 得到当前鼠标位置;输出:Point(x=200, y=800)

3.2 控制鼠标点击

单击鼠标:

点击鼠标
pyautogui.click(10,10)   # 鼠标点击指定位置,默认左键
pyautogui.click(10,10,button='left')  # 单击左键
pyautogui.click(1000,300,button='right')  # 单击右键
pyautogui.click(1000,300,button='middle')  # 单击中间

双击鼠标:

pyautogui.doubleClick(10,10)  # 指定位置,双击左键
pyautogui.rightClick(10,10)   # 指定位置,双击右键
pyautogui.middleClick(10,10)  # 指定位置,双击中键

点击 & 释放:

pyautogui.mouseDown()   # 鼠标按下
pyautogui.mouseUp()    # 鼠标释放

至此, 视觉AI自瞄程序已经基本设计完成。最终实现效果可以参见这个up主的视频。

【亦】警惕AI外挂!我写了一个枪枪爆头的视觉AI,又亲手”杀死”了它

三、引发的思考

也正如up主所说,视觉AI给FPS游戏带来的这一轮重大危机!

这类视觉AI程序目前存在三个威胁:

  • 准确性
  • 隐蔽性
  • 通用性

第一个威胁就是 超越人类的准确性。虽然人脑的高层次演绎归纳能力是远胜于AI的,但是在低级信息处理速度和精确度上,人类就很难比得过专精某个功能的AI了,比如在人体关节定位这件事上,给出人体每个部位的中心位置只需要几毫秒,而且精确到像素点,而同样一张图片给人类看个几毫秒,都不一定能够看清人在哪,更别说定位关节移动鼠标了。

第二个威胁就是 无法被外挂程序检测的隐蔽性。和传统外挂不一样,传统外挂要操作游戏的内存数据或者文件数据,从而获取游戏世界的信息。让开挂的人打出一些正常玩家不可能实现的作弊操作。而视觉AI是完全独立于游戏数据之外的,和人一样,也是通过实时观察画面发送鼠标和键盘指令,所以传统的反外挂程序只能反个寂寞。

第三个威胁就是 适用全平台的通用性。首先这个AI视觉模型是通过大量真人照片训练出来的,但是能够识别游戏中的人物,这意味着可以攻陷大部分FPS游戏。AI操作游戏和人操作游戏交互方式是没区别的,所以衍生出更大的问题,只要能把画面接入到这个模型中,就可以攻陷任意一种游戏平台,包括电脑、主机、手机等,无论你做的多封闭,生态维护的多好,在视觉AI面前众生平等。

那么我们该 如何解决这个问题呢

up主提到可以通过算法检测游戏异常操作,这也是一种思路,但是实现起来还是比较困难,毕竟可以让AI更像人类的操作。

而我想到之前比较火的deepfake,那么我们是不是可以通过对抗样本来解决这个问题呢,使得视觉AI识别错误?

说了那么多,其实也没有什么好的结论,只能说 技术的发展是在不断对抗中前进以及规范

参考:

Deep High-Resolution Representation Learning for Human Pose Estimationhttps://github.com/leoxiaobin/deep-high-resolution-net.pytorch

2D Pose人体关键点实时检测(Python/Android /C++ Demo)

实战Detectron2— 训练人体关键点检测

PyQt5 实时获取屏幕界面图像,python3使用matplotlib

警惕AI外挂!我写了一个枪枪爆头的视觉AI,又亲手”杀死”了它

今天我们就到这里,明天继续努力!

警惕AI,我搭建了一个“枪枪爆头”的视觉AI自瞄程序,却引发了一场“山雨欲来”

如果该文章对您有所帮助,麻烦点赞,关注,收藏三连支持下!

创作不易,白嫖不好,各位的支持和认可,是我创作的最大动力!

如果本篇博客有任何错误,请批评指教,不胜感激 !!!

Original: https://blog.csdn.net/kobepaul123/article/details/120153967
Author: Yunlord
Title: 警惕AI,我搭建了一个“枪枪爆头”的视觉AI自瞄程序,却引发了一场“山雨欲来”

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/777199/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Scrapy抓取网易job数据

    项目:爬取网易job的数据 shell 命令指示符 import scrapy class WangyiItem(scrapy.Item): name = scrapy.Field…

    Python 2023年10月4日
    045
  • 如何在 Jenkins CI/CD 流水线中保护密钥?

    CI/CD 流水线是 DevOps 团队软件交付过程的基本组成部分。该流水线利用自动化和持续监控来实现软件的无缝交付。通过持续自动化,确保 CI/CD 流水线每一步的安全性非常重要…

    Python 2023年10月22日
    037
  • 最近大火的高性能计算ChatGPT究竟是什么?

    LLM | ChatGPT | Google PPO | Open AI | LaMDA 随着深度学习、高性能计算、数据分析、数据挖掘、LLM、PPO、NLP等技术的快速发展,Ch…

    Python 2023年11月3日
    045
  • python 调整子图布局_matplotlib中精确调整子图形大小

    我在A4纸上绘制一些索引数据,用3×2行列的6幅图像绘制。我已经得到了基本的代码工作,它将这个数据帧数据绘制成以下6个图。在def plot_idx(df,image,k…

    Python 2023年9月4日
    034
  • task1-3:第一章:第三节探索性数据分析

    task1-3:第一章:第三节探索性数据分析 * – 1 第一章:探索性数据分析 – + * 开始之前,导入numpy、pandas包和数据 + 1.6 了…

    Python 2023年8月17日
    055
  • Python 的切片为什么不会索引越界?

    切片(slice)是 Python 中一种很有特色的特性,在正式开始之前,我们先来复习一下关于切片的知识吧。 切片主要用于序列对象中,根据索引间隔截取索引的内容。 [En] Sli…

    Python 2023年5月24日
    093
  • pytest基础

    关于pytest的学习 模块安装安装 模块基本使用 几个重要函数 * 装饰器 生成报告文件 模块安装安装 由于我预先安装了anaconda,所以在anaconda中安装当然也可以在…

    Python 2023年9月13日
    042
  • 在阿里云服务器上部署一个flask项目

    部署flask项目时,通常都是使用WSGI应用服务器搭配Nginx作为反向代理实现的。常用的WSGI服务器有gunicorn和uwsgi,本项目将使用Nginx反向代理搭配guni…

    Python 2023年8月9日
    063
  • 数据清洗Chap4——dataframe操作

    1.在数据中,选择需要的行或者列2.基础索引方式,就是直接引用3.iloc[行索引名称或者条件,列索引名称或者标签]4.iloc[行索引位置,列索引位置]5.注意,区分loc和il…

    Python 2023年8月16日
    056
  • python两人一碰_Pygame,同一组中两个对象之间的碰撞

    我还不确定你想达到什么目标,但我认为这个例子会对你有所帮助。在 当精灵离开屏幕时,我调用reset_pos方法,在这个方法中我迭代三个生成点,将位置设置为一个接一个地生成,然后我使…

    Python 2023年9月24日
    044
  • Python 并发编程

    目录 一. 为什么需要引入并发编程呢? 二. 怎么样选择多线程,多进程和多协程? 1. CPU 密集型与 I/O 密集型 2. 多线程,多进程和多协程的对比 三. python 的…

    Python 2023年8月14日
    050
  • NGINX的配置和基本使用

    Linux NGINX NGINX:engine X ,2002年开发,分为社区版和商业版(nginx plus ) 社区版:分为主线版(开发版,奇数),稳定版(偶数) Nginx…

    Python 2023年10月12日
    058
  • pytest+allure的应用

    allure报告可以包含很多详细的信息描述测试用例,包括epic、feature、story、title、issue、testcase、severity等 方法作用说明@allur…

    Python 2023年9月13日
    068
  • C. Building a Fence(范围判定)

    Problem – 1469C – Codeforces 你想建造一个由n个相等部分组成的栅栏。所有部分的宽度都等于1,高度都等于k。 不幸的是,篱笆下面的…

    Python 2023年9月29日
    058
  • ChatGPT怎么突然变得这么强?华人博士万字长文深度拆解GPT-3.5能力起源

    文章目录 * – 一、2020 版初代 GPT-3 与大规模预训练 – 二、从 2020 版 GPT-3 到 2022 版 ChatGPT – …

    Python 2023年11月3日
    045
  • 基于django中间件的编程思想

    基于django中间件的编程思想 在django中,中间件的形式全部写成了列表套字符串的形式 MIDDLEWARE = [ ‘django.middleware.security….

    Python 2023年11月1日
    031
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球