使用YOLOv3目标检测制作CSGO自瞄AI外挂

Jade ·
更新时间:2024-09-22
· 848 次阅读

先放下视频效果吧:bilibili视频效果
pytorch版本
csgo设置:

鼠标设置中:灵敏度调8,关闭原始数据输入 视频设置中:窗口化运行,并拖放到屏幕左上角(我的移动鼠标的参数是根据这里的坐标写的,不然移动鼠标不准,大家可以自己测试下全屏时,移动鼠标的输入量和准星的移动对应关系)

python库:

获取截图:PIL 目标检测:YOLOv3相关依赖 控制鼠标:pyautogui

代码是在Pytorch版yolov3代码中文注释详解基础上修改的,
基本是上文的原文,就自己按照理解修改了下注释。
完整工程下载连接
以下是我改的CSGO.py:
其中, 自己实测的数据:游戏中移动像素数=moveRel输入 / 1.56,可能不精准,由于游戏中,准星(光标)始终在最中间,没法用moveTo来精准控制。应该有更好的方法,大家可以自己试下

def arg_parse(): # 创建一个ArgumentParser对象,格式: 参数名, 目标参数(dest是字典的key),帮助信息,默认值,类型 parser = argparse.ArgumentParser(description='YOLO v3 检测模型') parser.add_argument("--bs", dest="bs", help="Batch size,默认为 1", default=1) parser.add_argument("--confidence", dest="confidence", help="目标检测结果置信度阈值", default=0.5) parser.add_argument("--nms_thresh", dest="nms_thresh", help="NMS非极大值抑制阈值", default=0.4) parser.add_argument("--cfg", dest='cfgfile', help="配置文件", default="cfg/yolov3.cfg", type=str) parser.add_argument("--weights", dest='weightsfile', help="模型权重", default="yolov3.weights", type=str) parser.add_argument("--reso", dest='reso', help="网络输入分辨率. 分辨率越高,则准确率越高; 反之亦然", default="416", type=str) parser.add_argument("--video", dest="videofile", help="待检测视频目录", default="video.avi", type=str) return parser.parse_args() '''读取这些预设参数进来''' args = arg_parse() # args是一个namespace类型的变量,即argparse.Namespace, 可以像easydict一样使用,就像一个字典,key来索引变量的值 batch_size = int(args.bs) confidence = float(args.confidence) nms_thesh = float(args.nms_thresh) start = 0 MouseX, MouseY = pyautogui.position() # 当前鼠标位置,防止CSGO窗口位置不准造成偏差 CUDA = torch.cuda.is_available() # GPU环境是否可用 num_classes = 80 # coco 数据集有80类 # 初始化网络并载入权重 print("载入神经网络....") model = Darknet(args.cfgfile) # Darknet类中初始化时得到了网络结构和网络的参数信息,保存在net_info,module_list中 model.load_weights(args.weightsfile) # 将权重文件载入,并复制给对应的网络结构model中 print("模型加载成功.") # 网络输入数据大小 model.net_info["height"] = args.reso # 416 model类中net_info是一个字典。’’height’’是图片的宽高,因为图片缩放到416x416,所以宽高一样大 inp_dim = int(model.net_info["height"]) # 416 inp_dim是网络输入图片尺寸(如416*416) assert inp_dim % 32 == 0 # 如果设定的输入图片的尺寸不是32的位数或者不大于32,抛出异常 assert inp_dim > 32 # 如果GPU可用, 模型切换到cuda中运行 if CUDA: model.cuda() # 变成测试模式,这主要是对dropout和batch normalization的操作在训练和测试的时候是不一样的 model.eval() while 1: frame = ImageGrab.grab((0, 32, 1280, 500)) # 读入成功,ret=1,frame为图片 frame = cv2.cvtColor(np.array(frame), cv2.COLOR_RGB2BGR) # Img——>cv2 img = prep_image(frame, inp_dim) # 1*3*416*416 im_dim = frame.shape[1], frame.shape[0] # 保存原始大小:(640, 480) im_dim = torch.FloatTensor(im_dim).repeat(1, 2) # 重复一次 [640,480,640,480]对应[x1,y1,x2,y2] if CUDA: im_dim = im_dim.cuda() img = img.cuda() # 只进行前向计算,不计算梯度 with torch.no_grad(): # 得到每个预测方框在输入网络图片(416x416)坐标系中的坐标和宽高以及目标得分以及各个类别得分(x,y,w,h,s,s_cls1,s_cls2...) # 并且将tensor的维度转换成(batch_size, grid_size*grid_size*num_anchors, 5+类别数量) output = model(Variable(img), CUDA) # 1*10647*85 # 将方框属性转换成(ind,x1,y1,x2,y2,s,s_cls,index_cls),去掉低分,NMS等操作,得到在输入网络坐标系中的最终预测结果 # ind 是这个方框所属图片在这个batch中的序号, # (第几张,左上x,左上y,右下x,右下y,bbox置信度,目标种类得分,什么物体) output = write_results(output, confidence, num_classes, nms_conf=nms_thesh) # 目标数n*8 # 如果没有对象 if type(output) == int: continue # 不再执行以下,重新读图 ''' 坐标转换为实际原图坐标''' # 将图片的尺寸的行数 重复 对象的数量 次 im_dim = im_dim.repeat(output.size(0), 1) # 得到每个方框所在图片缩放系数 # scaling_factor = torch.min(416/im_dim,1)[0].view(-1,1)#这是源代码,下面是我修改的代码 scaling_factor = torch.min(int(args.reso) / im_dim, 1)[0].view(-1, 1) # 将方框的坐标(x1,y1,x2,y2)转换为相对于填充后的图片中包含原始图片区域(如416*312区域)的计算方式。 output[:, [1, 3]] -= (inp_dim - scaling_factor * im_dim[:, 0].view(-1, 1)) / 2 output[:, [2, 4]] -= (inp_dim - scaling_factor * im_dim[:, 1].view(-1, 1)) / 2 # 将坐标映射回原始图片 output[:, 1:5] /= scaling_factor # 将超过了原始图片范围的方框坐标限定在图片范围之内 for i in range(output.shape[0]): output[i, [1, 3]] = torch.clamp(output[i, [1, 3]], 0.0, im_dim[i, 0]) output[i, [2, 4]] = torch.clamp(output[i, [2, 4]], 0.0, im_dim[i, 1]) # (第几张,左上x,左上y,右下x,右下y,bbox置信度,目标种类得分,什么物体) output = output[output[:, 7] == 0, :] # 只保存是 人 的 if output.shape[0] == 0: # 如果没有人(有物体) continue # 不再执行以下,重新读图 # 对最近的目标攻击: x = output[:, 1] + output[:, 3] x = x / 2 - MouseX null, index_x = torch.min(abs(x), 0) x = int(x[index_x]) y = 0.6*output[index_x][2] + 0.4*output[index_x][4] # 具体0.4、0.6的关系看情况,打头还是哪儿 y = int(y) - MouseY # 自己实测的数据:游戏中移动像素数=moveRel输入 / 1.56 currentMouseX = x / 1.56 currentMouseY = y / 1.56 pyautogui.moveRel(currentMouseX, currentMouseY) # 这两步占用一半时间(各0.1s) pyautogui.click() # time.sleep(0.02) # 开几枪也是自己改 # pyautogui.click() # time.sleep(0.02) # pyautogui.click() # time.sleep(0.02) # pyautogui.click() time.sleep(0.2) 不知语冰 原创文章 37获赞 51访问量 4万+ 关注 私信 展开阅读全文
作者:不知语冰



csgo

需要 登录 后方可回复, 如果你还没有账号请 注册新账号