[Yolov5]利用Ai实现FPS游戏自动对准 yolov5fps自瞄

程序员 2024-9-15 11:41:34 29 0 来自 中国
文章先容
本日来分享一个这两天本身写的一个轻微痴肥一些的Yolov5 FPS跟枪的源码分析和原理解说吧。渴望可以对于没有什么头绪的朋侪有一些资助吧,我也是第一次做,各位有什么优化的方式可以留言指出,可以一起交换学习。
必要了解的东西和大概会碰到的问题
1.xy坐标点与当前鼠标的xy坐标点间隔计算
2.获取窗口句柄,本文利用的是根据窗口名称获取句柄
3.推理方式:本文利用的是GPU(为啥呢?速率快噻,由于我3060显卡噻~)。
4.屏幕宽高获取和仇人坐标获取和计算哪个是近来的仇人并控制鼠标去仇人身上和头上。(为什么说是身材和头部呢,由于另有一个方式,就是只必要仇人身材坐标就可以计算得出仇人头部坐标)干货噢~
5.另有鼠标按键状态获取。
正文开始吧,我们就重新开始代码分析吧。
先来一个两个xy坐标的间隔计算吧.
class Point():    def __init__(self, x1, y1, x2, y2):        self.x1 = x1        self.y1 = y1        self.x2 = x2        self.y2 = y2class Line(Point):    def __init__(self, x1, y1, x2, y2):        super().__init__(x1, y1, x2, y2)    def getlen(self):        changdu = math.sqrt(math.pow((self.x1 - self.x2), 2) + math.pow((self.y1 - self.y2), 2))        return changdu上面这段代码的利用方式如下
L1 = Line(x1, y1, x2, y2)  #传入两个xy坐标L1.getlen() #return出两个坐标点的直线间隔接下来直接上全代码分析吧,代码很痴肥,各位可以把类和方法分离出去,我比力懒,懒得弄。
# 这里是导入依靠,必要这些库import mathimport sysimport timeimport torchimport win32apiimport win32conimport win32guifrom PyQt5.QtWidgets import QApplicationfrom pynput.mouse import Controllerimport mouse#这里这俩class就是文章上面说的那个传入两个坐标点,计算直线间隔的class Point():    def __init__(self, x1, y1, x2, y2):        self.x1 = x1        self.y1 = y1        self.x2 = x2        self.y2 = y2class Line(Point):    def __init__(self, x1, y1, x2, y2):        super().__init__(x1, y1, x2, y2)    def getlen(self):        changdu = math.sqrt(math.pow((self.x1 - self.x2), 2) + math.pow((self.y1 - self.y2), 2))        return changdu#第一步:我们获取到某FPS游戏的窗口句柄hwnd = win32gui.FindWindow(None, "穿越火线")#这个方法是获取上面句柄窗口的窗口截图,用的是PyQt截图,有速率更快更好的方式的话可以换上#截图完毕后生存在根目次的cfbg.bmp文件def screen_record():    app = QApplication(sys.argv)    screen = QApplication.primaryScreen()    img = screen.grabWindow(hwnd).toImage()    img.save("cfbg.bmp")#这里就是调用我们那yolo模子来举行推理啦,我设置的是cuda,也就是英伟达的GPU,由于cpu太慢了。#假如本身的不能利用GPU推理的话把下面这两行改改,改成cpu的就可以了。device = torch.device("cuda")model = torch.hub.load('F:/yolov5-master', 'custom', 'F:/yolov5-master/yolov5n6.pt',                       source='local', force_reload=False)  # 加载本地模子# 这里是定义屏幕宽高[实在这俩就是游戏所对应的分辨率,好比:游戏里1920*1080这里就是1920*1080]game_width = 1024game_height = 768# 这边就是开始实时举行游戏窗口推理了#无穷循环 -> 截取屏幕 -> 推理模子获取到每个仇人坐标 -> 计算每个仇人中央坐标 -> 挑选间隔准星近来的仇人 -> 假如左键是按下状态则控制鼠标移动到仇人的身材或者头部(本文计算方式是移动到头部)while True:    # 截取屏幕    screen_record()    # 利用模子    model = model.to(device)    img = 'cfbg.bmp'     # 开始推理    results = model(img)    # 过滤模子    xmins = results.pandas().xyxy[0]['xmin']    ymins = results.pandas().xyxy[0]['ymin']    xmaxs = results.pandas().xyxy[0]['xmax']    ymaxs = results.pandas().xyxy[0]['ymax']    class_list = results.pandas().xyxy[0]['class']    confidences = results.pandas().xyxy[0]['confidence']    newlist = []    for xmin, ymin, xmax, ymax, classitem, conf in zip(xmins, ymins, xmaxs, ymaxs, class_list, confidences):        if classitem == 0 and conf > 0.5:            newlist.append([int(xmin), int(ymin), int(xmax), int(ymax), conf])    # 循环遍历每个仇人的坐标信息传入间隔计算方法获取每个仇人间隔鼠标的间隔    if len(newlist) > 0:        # 存放间隔数据        cdList = []        xyList = []        for listItem in newlist:            # 当前遍历的人物中央坐标            xindex = int(listItem[2] - (listItem[2] - listItem[0]) / 2)            yindex = int(listItem[3] - (listItem[3] - listItem[1]) / 2)            mouseModal = Controller()            x, y = mouseModal.position            L1 = Line(x, y, xindex, yindex)            # 获取到间隔而且存放在cdList聚会合            cdList.append(int(L1.getlen()))            xyList.append([xindex, yindex, listItem[0], listItem[1], listItem[2], listItem[3]])        # 这里就得到了间隔近来的仇人位置了        minCD = min(cdList)        # 假如仇人间隔鼠标坐标小于150则自动举行对准,这里可以改大改小,小的话跟枪会显得自然些        if minCD < 150:            for cdItem, xyItem in zip(cdList, xyList):                if cdItem == minCD:                    # 锁头算法:利用win32api获取左键按下状态,假如按下则开始自动跟枪                    if win32api.GetAsyncKeyState(0x01):                        # 控制鼠标移动到某个点:看不懂计算方式的话看文章下面解说吧O(∩_∩)O                        win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, int(xyItem[0] - game_width // 2),int(xyItem[1] - (game_height - (xyItem[3] - xyItem[5])) // 2), 0, 0)                    break好了,我们来解说下这行代码
win32api.mouse_event(鼠标活动:这里用的是MOVE相对移动, x坐标,y坐标, 0, 0)
第一个参数,先设定鼠标的活动:利用相对移动,为什么不消绝对移动呢,由于绝对移动在游戏里是无效的
第二个参数,x轴相对移动的间隔:仇人x坐标 - (屏幕宽度 / 2)
第三个参数,y轴相对移动的间隔:仇人y坐标 - (屏幕高度 - (仇人最大y坐标  - 仇人最小y坐标) / 2)
第一第二个参数相对来说比力好明白,但是大概有人对于第三个y的相对移动的计算方式有点懵,我画了个图,渴望可以看明白。


就如许把,大概有人问:我假如要用在其他fps游戏呢,我们只必要修改窗口名称参数和分辨率参数即可。
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-10-18 22:30, Processed in 0.188878 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表