“枪枪爆头”!用 Python 写个了使命召唤外挂 | 文末赠书
前言
核心功能设计
训练人体关节点检测模型 输入视频或图片到AI视觉模型,并输出瞄准点位置。 自动操作鼠标移动到对应瞄准位置
核心实现步骤
1.训练人体关节点检测模型
1.1 HRNet代码库安装
git clone https://github.com/leoxiaobin/deep-high-resolution-net.pytorch.git
python -m pip install -e deep-high-resolution-ne.pytorch
1.2 人体关键点数据集下载
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)
2.输入视频或图片实时反馈瞄准点坐标
2.1 实时读取屏幕画面
import pyautogui
img = pyautogui.screenshot()
在一个 1920×1080 的屏幕上,screenshot()函数要消耗100微秒,基本达到实时传入游戏画面要求。
如果不需要截取整个屏幕,还有一个可选的region参数。你可以把截取区域的左上角XY坐标值和宽度、高度传入截取。
im = pyautogui.screenshot(region=(0, 0, 300 ,400))
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]
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自瞄程序已经基本设计完成。
引发的思考
这类视觉AI程序目前存在三个威胁:
准确性
隐蔽性
通用性
第一个威胁就是超越人类的准确性。虽然人脑的高层次演绎归纳能力是远胜于AI的,但是在低级信息处理速度和精确度上,人类就很难比得过专精某个功能的AI了,比如在人体关节定位这件事上,给出人体每个部位的中心位置只需要几毫秒,而且精确到像素点,而同样一张图片给人类看个几毫秒,都不一定能够看清人在哪,更别说定位关节移动鼠标了。
第二个威胁就是无法被外挂程序检测的隐蔽性。和传统外挂不一样,传统外挂要操作游戏的内存数据或者文件数据,从而获取游戏世界的信息。让开挂的人打出一些正常玩家不可能实现的作弊操作。而视觉AI是完全独立于游戏数据之外的,和人一样,也是通过实时观察画面发送鼠标和键盘指令,所以传统的反外挂程序只能反个寂寞。
第三个威胁就是适用全平台的通用性。首先这个AI视觉模型是通过大量真人照片训练出来的,但是能够识别游戏中的人物,这意味着可以攻陷大部分FPS游戏。AI操作游戏和人操作游戏交互方式是没区别的,所以衍生出更大的问题,只要能把画面接入到这个模型中,就可以攻陷任意一种游戏平台,包括电脑、主机、手机等,无论你做的多封闭,生态维护的多好,在视觉AI面前众生平等。
那么我们该如何解决这个问题呢?
up主提到可以通过算法检测游戏异常操作,这也是一种思路,但是实现起来还是比较困难,毕竟可以让AI更像人类的操作。
而我想到之前比较火的deepfake,那么我们是不是可以通过对抗样本来解决这个问题呢,使得视觉AI识别错误?
在评论区留言你对本文的观点
技术技术
分享
点收藏
点点赞
点在看