基于YoloV5的游戏自瞄框架

分类: 365bet亚洲投注网址 时间: 2025-11-13 13:28:27 作者: admin 阅读: 3671
基于YoloV5的游戏自瞄框架

本项目仅限于学习交流不可商用,不可用于非法用途(包括但不限于:用于制作游戏外挂等)。

一开始是觉得不应该讲得太详细,但实际上不管是原理还是代码,在网上都是一找一大堆了,真有心也能拿去用了,还是记录一下。

实现一个AI自瞄,基本是三步走,屏幕截图——目标检测——鼠标移动,只有目标检测这一步需要用到AI,接下来各个部分分开讲一下。

首先是屏幕截图,如果确定要用Pytorch作为框架的话,那么Python的截图方法主要是三种:

第一种是用PIL或者Pillow进行图像处理,这两个库是大部分Python图像处理类的项目都会有的库,优点是很方便,但是效率不怎么样。

第二种是用pyautogui,这个库是自动化图形界面库,除了截图以外还能够控制鼠标,但是可能是为了跨平台使用,pyautogui的运行速度也很差,在我的电脑上截一张图需要0.02s左右,额,我跑一次Yolo才0.04秒,这都占一半时间了

第三种是用win32api,这个是微软给的应用程序编程接口,可以进行截图,缺点是代码比较长,不能跨平台,但是应该也没人会用Linux,Mac打游戏吧。

除此之外还有一些其他方法,比方说OBS提供了Python的api用于构建脚本,这个效率也很高,毕竟广泛用于直播推流,但是OBS是写在C平台上的,如果是用TensorFlow会比较方便。

在GitHub上有一个快速截图的库:d3dshot,至少在我测试下来,这个速度应该是最快的,但是缺点是一旦切屏出去了,截图就会出问题,没找出问题在哪。

这样看来最适合的截图库就只剩下了win32api和d3dshot,时间上差不多,但是win32api似乎BUG更少。

键盘事件监听在开始之前我们需要监听键盘的动作,这一部分通过pynput实现:

mode = False

def on_press(key):

global mode

if key == keyboard.Key.f11:

mode = not mode

def on_release(key):

"""松开按键时执行。"""

# if key == keyboard.Key.esc:

# pass

pass

if __name__ == '__main__':

listener = keyboard.Listener(

on_press=on_press,

on_release=on_release)

listener.start()这样就可以通过f11来进行开启或关闭,当然也可以改成别的按键,因为python貌似并没有哪个库支持鼠标侧键的读取,所以可以在鼠标驱动写一个简单的按键触发。

屏幕截取def window_prepare():

hwnd = 0 # 窗口的编号,0号表示当前活跃窗口

# 根据窗口句柄获取窗口的设备上下文DC(Divice Context)

hwnd_dc = win32gui.GetWindowDC(hwnd)

# 根据窗口的DC获取mfcDC

mfc_dc = win32ui.CreateDCFromHandle(hwnd_dc)

# mfcDC创建可兼容的DC

save_dc = mfc_dc.CreateCompatibleDC()

# 创建bigmap准备保存图片

save_bit_map = win32ui.CreateBitmap()

# 获取监控器信息

width = 640

height = 360

# 为bitmap开辟空间

save_bit_map.CreateCompatibleBitmap(mfc_dc, width, height)

return save_bit_map, save_dc, mfc_dc, width, height

def window_capture(save_bit_map, save_dc, mfc_dc, width, height):

# 高度saveDC,将截图保存到saveBitmap中

save_dc.SelectObject(save_bit_map)

# 截取从左上角(0,0)长宽为(w,h)的图片

# saveDC.BitBlt((0, 0), (w, h), mfcDC, (0, 0), win32con.SRCCOPY)

save_dc.BitBlt((0, 0), (width, height), mfc_dc, (640, 360), win32con.SRCCOPY)

signed_ints_array = save_bit_map.GetBitmapBits(True)

img = np.frombuffer(signed_ints_array, dtype='uint8')

img.shape = (height, width, 4)

img0 = img[:, :, :3]

return img0程序初始化阶段先运行window_prepare,之后通过键盘控制是否循环触发window_capture,捕获屏幕中央640x360的空间,进行检测,移动鼠标。(我这里的分辨率是1920x1080)

检测的部分跟之前的行人检测的demo是一致的,这里就不提了。总之是把截图丢给YoloV5,跑出结果后把坐标返回。

行人检测demo | 莉莉娅! (diduseemyelk.github.io)

当然我们这里还有一个小问题,YoloV5跑完之后的结果坐标默认是按照置信度进行排序的,但很显然,如果有多个目标的时候,一般采取就近原则,谁离准心近,就瞄哪,所以还有一个小函数计算哪一组坐标离准心最近。

def closest(self, boxes):

distance_list = []

for (x1, y1, x2, y2, label, conf) in boxes:

mid_x = (x1 + x2) / 2

mid_y = (y1 + y2) / 2

distance = (mid_x - 960)**2 + (mid_y - 540)**2

distance_list.append(distance)

value = min(distance_list)

index = distance_list.index(value)

return index鼠标移动鼠标的移动也有很多库可以用,还是跟上面一样,pyautogui的效率很低,我很难想象只是移动一下鼠标的操作,在pyautogui上都需要0.02s,GitHub上有一个mouse的第三方库,用这个库实现的话耗时是检测不到的。

具体代码我们连着前面两部分一起讲

def aiming(save_bit_map, save_dc, mfc_dc, width, height):

# 读取每帧图片

im = window_capture(save_bit_map, save_dc, mfc_dc, width, height)

bboxes = detector.detect(im)

# 如果画面中有bbox,即detector探测到待检测对象

if len(bboxes) > 0:

box_index = detector.closest(bboxes)

check_point_x = int(bboxes[box_index][0] + ((bboxes[box_index][2] - bboxes[box_index][0]) * 0.5)) + 640

check_point_y = int(bboxes[box_index][1] + ((bboxes[box_index][3] - bboxes[box_index][1]) * 0.5)) + 360

move_x = int(1.4 * (check_point_x - 960))

move_y = int(1.4 * (check_point_y - 540))

mouse.move(move_x, move_y, absolute=False, duration=0)

pass

else:

passcheck_point_x和check_point_y是目标检测的中心点,这个点是离准心最近的点。但是值得注意的是,并不是直接把这个参数扔进去move就可以了,因为这种第一人称射击游戏,他都不需要记录你鼠标的位置,只需要记录你鼠标相对位移,并根据你的DPI和鼠标灵敏度进行转向即可。虽然这个目标离你的准心差了可能200个像素点,但转动和平移是两件事情,如何保证你转动过后目标恰好就在你的准心上呢?这就需要用到球面理论去进行计算了。

但是在游戏里,人物模型是有大小的,对于很远的人物,Yolo识别不出来,对于很近的人物,人物HitBox又足够大,即便第一时间没有瞄到最中央,仍然能够命中,因此很大程度上,我们不需要百分百精确地计算出move_x和move_y,完全可以利用中间的线性区域作线性拟合,找到一个经验常数,能够从check_point_x和check_point_y生成出误差较小的move_x和move_y即可,不同的分辨率可能会有所不同,我这分辨率取1.4差不多是比较稳定的。最后用mouse.move函数进行鼠标操作,这里的duration是指延迟,就是执行这个鼠标操作的耗时,如果取0.1的话其实会看起来比较丝滑。

ok最后附上一段bot测试吧。

相关文章

如何查看电脑连接的Wi-Fi密码?
如何开通和使用PayPal账户?全面指南
新车购置流程详解:线上订车与线下交付步骤
阴阳师逢魔之时答案大全 快速查找逢魔答案