基于yolov5的游戏目标识别与鼠标移动

文章介绍了如何利用yolov5模型进行游戏目标识别,并通过win32api控制鼠标移动实现自动瞄准功能。由于识别速度限制,瞄准过程较慢,大约1秒3帧,适用于静态目标。代码中包含自动瞄准线程和鼠标事件处理,以及模型显示功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于yolov5的游戏目标识别与鼠标移动

注:本外挂实际意义有限(甚至都算不上外挂),因为首先是因为yolov5的识别速度,在游戏中并不是直接将鼠标准星移到锁定目标的头上,因为通过yolov5的话,我们的鼠标移动是通过win32api,这种瞄准方式有个问题是我们很难直接通过直接移动鼠标像素点的方式锁定目标,而且还会因为游戏灵敏度的影响导致瞄准困难,所以我使用了是多次瞄准的方式,就是如果准星离头比较远的话,就一次移动100像素点左右,如果离得近的话就一次移动10像素点左右,这种方法的缺点就是我们瞄准的速度很慢,大概是1秒3帧左右,我的电脑是笔记本电脑,这种情况下1秒3帧已经是笔电的极限了

一、基本环境

系统环境:ubuntu 22.04

python环境:python 3.10

二、基本原理

  1. 对屏幕截图进行分析
  2. 使用yolov5对目标进行识别
  3. 得到识别目标的位置,计算距离
  4. 然后使用win32api对鼠标进行控制
  5. 通过多次移动鼠标准星瞄准目标

经过测试如果目标是静止的那么效果还算可以,如果是移动的那就玩了个大蛋。

三、重要代码讲解

这个是自动瞄准的代码

import threading

import pythoncom

from DetectEnemy import *
import PyHook3 as pyhook

# 这个是判断右键是否按下的
right_button_press = False


def AutoAim():
    global right_button_press
    # 这个函数就是自动瞄准的线程,我们是按下右键的时候会进行自动瞄准
    while True:
        if right_button_press:
            # 首先截图
            pic = save_pictures()
            # 然后进行分析
            result = detect(pic)
            # 然后获得射击目标
            person = get_person(result)
            if not person:
                continue
            # 然后获得射击位置
            location = shooting_location(person)
            print(location)
            # 然后鼠标移动到射击位置
            mouse_move(location)

            # 这是进行测试的代码,使用时注释掉
            # model_show(result)
        else:
            continue


def funcRightDown(event):
    global right_button_press
    if (event.MessageName != "mouse_move"):
        print("AutoAiming start")
        if right_button_press:
            right_button_press=False
        else:
            right_button_press = True
    return True


def funcRightUp(event):
    global right_button_press
    if (event.MessageName != "mouse_move"):
        print("AutoAiming stop")
        right_button_press = False
    return True


auto_aiming_thread = threading.Thread(target=AutoAim)
MouseManger = pyhook.HookManager()
if __name__ == '__main__':
    auto_aiming_thread.start()
    MouseManger.MouseRightDown = funcRightDown
    # MouseManger.MouseRightUp = funcRightUp
    MouseManger.HookMouse()
    # 循环监听
    pythoncom.PumpMessages()

这个是DetectEnemy.py的代码

import mss as mss
import numpy as np
import torch
import cv2
import win32api
import win32con
import win32gui
import win32print
from pymouse import PyMouse

# 首先我们初始化我们的model
device = 'cuda:0' if torch.cuda.is_available() else 'cpu'  # 这个是检测有没有安装cuda,如果没有就用cpu
model = torch.hub.load('ultralytics\yolov5', 'yolov5n', source='local').to(device)  # 加载我们的model,我们使用的是yolov5n
# 然后我们初始化截图的软件
m = mss.mss()
mt = mss.tools


def detect(img):
    # 这个是用来进行检测的函数
    result = model(img).pandas().xyxy[0].to_dict('index')
    return result


def save_pictures():
    hDC = win32gui.GetDC(0)
    w = win32print.GetDeviceCaps(hDC, win32con.DESKTOPHORZRES)  # 横向分辨率
    h = win32print.GetDeviceCaps(hDC, win32con.DESKTOPVERTRES)  # 纵向分辨率
    img = m.grab((0, 0, w, h))
    mt.to_png(img.rgb, img.size, 6, "pic/cs.png")
    # 返回一个字符串只是为了方便
    return "pic/cs.png"


def get_person(result: dict):
    person = {}
    person_max = 0  # 这个是人的面积,如果面积越大说明离得越进,先射击这个人
    for key in result.keys():
        if result[key]["name"] == "person":
            xmin = int(result[key]['xmin'])
            ymin = int(result[key]['ymin'])
            xmax = int(result[key]['xmax'])
            ymax = int(result[key]['ymax'])

            if (xmax - xmin) * (ymax - ymin) > person_max:
                person = result[key]
    # 现在person就是我们要射击的人
    return person


def shooting_location(person: dict):
    # 因为神经网络无法识别head位置,我们就以上四分之一位置当作头的位置
    locationx = (person['xmin'] + person['xmax']) / 2
    locationy = (person['ymin'] + person['ymax']) / 2-(person['ymax']-person['ymin'])/4
    location = {"x": locationx, 'y': locationy}
    return location


def mouse_move(location: dict):
    # 得到坐标之后 就准备射击
    # 这种情况下我们得使用win32api进行鼠标模拟,如果使用pymouse,对于这种设射击游戏是不能移动的
    # mouse_event的move函数是要计算出坐标才对
    l1=location['x']
    l2=location['y']
    mouse_location = PyMouse().position()
    if abs(mouse_location[0] - l1) > 150:
        x = 100
        if mouse_location[0] - l1 > 0:
            x = -100
    elif abs(mouse_location[0] - l1) > 80:
        x = 40
        if mouse_location[0] - l1 > 0:
            x = -40
    else:
        x = 10
        if mouse_location[0] - l1 > 0:
            x = -10

    if abs(mouse_location[1] - l2) > 150:
        y = 100
        if mouse_location[1] - l2 > 0:
            y = -100
    elif abs(mouse_location[1] - l2) > 80:
        y = 40
        if mouse_location[1] - l2 > 0:
            y = -40
    else:
        y = 10
        if mouse_location[1] - l2 > 0:
            y = -10
    win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, x, y)


def model_show(result,pic):
    picture = cv2.imread(pic)
    print(type(result[0]['xmin']))
    xmin = int(result[0]['xmin'])
    ymin = int(result[0]['ymin'])
    xmax = int(result[0]['xmax'])
    ymax = int(result[0]['ymax'])
    cv2.rectangle(picture, (xmin, ymin), (xmax, ymax), (0, 0, 255), 2)
    cv2.imshow("cs", picture)
    cv2.imwrite('pic/pic-1-test.png', picture)
    cv2.waitKey(0)

这个model_show是可以展示出一个图片和识别框的,到时候可以把AutoAiming中的那个注释恢复就可以用了,大概就是这样。

四、model_show的展示

在这里插入图片描述

五、简单的补充

这个效果真的不好,希望各位看了不要骂我,不过跟着学学联系一下神经网络还是不错的,我主要是想联系联系ML方法使用以方便开学后继续跟老师做项目。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值