├── README.md ├── lib └── MouseControl.dll ├── .idea ├── vcs.xml ├── misc.xml ├── .gitignore ├── inspectionProfiles │ ├── profiles_settings.xml │ └── Project_Default.xml ├── modules.xml ├── autoaim.iml └── deployment.xml ├── detect.py ├── nearest_can_see.py └── nearest.py /README.md: -------------------------------------------------------------------------------- 1 | # AimLab 2 | use cv2 3 | -------------------------------------------------------------------------------- /lib/MouseControl.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linsixi/aimlab_autoaim/HEAD/lib/MouseControl.dll -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # 默认忽略的文件 2 | /shelf/ 3 | /workspace.xml 4 | # 基于编辑器的 HTTP 客户端请求 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/autoaim.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /.idea/deployment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /detect.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import win32gui 4 | from mss import mss 5 | 6 | # 定义颜色过滤的参数 7 | lower_color = np.array([85, 210, 80]) 8 | upper_color = np.array([95, 245, 255]) 9 | 10 | # 定义滑块回调函数 11 | def update_lower_hue(val): 12 | lower_color[0] = val 13 | print(f"Lower Hue: {val}") 14 | 15 | def update_lower_sat(val): 16 | lower_color[1] = val 17 | print(f"Lower Saturation: {val}") 18 | 19 | def update_lower_val(val): 20 | lower_color[2] = val 21 | print(f"Lower Value: {val}") 22 | 23 | def update_upper_hue(val): 24 | upper_color[0] = val 25 | print(f"Upper Hue: {val}") 26 | 27 | def update_upper_sat(val): 28 | upper_color[1] = val 29 | print(f"Upper Saturation: {val}") 30 | 31 | def update_upper_val(val): 32 | upper_color[2] = val 33 | print(f"Upper Value: {val}") 34 | 35 | # 创建窗口 36 | cv2.namedWindow('Color Filter') 37 | 38 | # 创建滑块 39 | cv2.createTrackbar('Lower Hue', 'Color Filter', 85, 179, update_lower_hue) 40 | cv2.createTrackbar('Lower Saturation', 'Color Filter', 210, 255, update_lower_sat) 41 | cv2.createTrackbar('Lower Value', 'Color Filter', 80, 255, update_lower_val) 42 | cv2.createTrackbar('Upper Hue', 'Color Filter', 95, 179, update_upper_hue) 43 | cv2.createTrackbar('Upper Saturation', 'Color Filter', 245, 255, update_upper_sat) 44 | cv2.createTrackbar('Upper Value', 'Color Filter', 255, 255, update_upper_val) 45 | 46 | # 定义截屏函数 47 | def capture_screen(window_title, region_width=800, region_height=800): 48 | # 查找窗口句柄 49 | hwnd = win32gui.FindWindow(None, window_title) 50 | if hwnd == 0: 51 | print("No window found") 52 | return None # 如果没有找到窗口,返回None 53 | 54 | # 获取窗口的客户区域大小 55 | left, top, right, bottom = win32gui.GetClientRect(hwnd) 56 | 57 | # 计算中间区域的坐标 58 | middle_left = (right - left) // 2 - region_width // 2 59 | middle_top = (bottom - top) // 2 - region_height // 2 60 | middle_right = middle_left + region_width 61 | middle_bottom = middle_top + region_height 62 | 63 | # 将客户区域的左上角坐标转换为屏幕坐标 64 | client_left, client_top = win32gui.ClientToScreen(hwnd, (middle_left, middle_top)) 65 | 66 | # 将客户区域的右下角坐标转换为屏幕坐标 67 | client_right, client_bottom = win32gui.ClientToScreen(hwnd, (middle_right, middle_bottom)) 68 | 69 | # 使用 mss 截取指定区域 70 | with mss() as sct: 71 | monitor = {"left": client_left, "top": client_top, "width": region_width, "height": region_height} 72 | img = sct.grab(monitor) # 截取屏幕区域 73 | frame = np.array(img) # 转换为 numpy 数组 74 | frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR) # 转换为 BGR 格式 75 | return frame 76 | 77 | # 读取截屏区域的图像 78 | # 假设这里已经有一个函数 get_screenshot() 来获取截屏图像 79 | # frame = get_screenshot() 80 | frame = capture_screen("aimlab_tb") # 使用 capture_screen 函数获取截屏图像 81 | 82 | # 主循环,实时截取屏幕并应用颜色过滤 83 | while True: 84 | frame = capture_screen("aimlab_tb") # 使用 capture_screen 函数获取截屏图像 85 | if frame is None: 86 | break # 如果没有找到窗口,退出循环 87 | 88 | # 应用颜色过滤 89 | hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 90 | mask = cv2.inRange(hsv, lower_color, upper_color) 91 | result = cv2.bitwise_and(frame, frame, mask=mask) 92 | 93 | # 显示结果 94 | cv2.imshow('Color Filter', result) 95 | 96 | # 按 'q' 键退出循环 97 | if cv2.waitKey(1) & 0xFF == ord('q'): 98 | break 99 | 100 | # 释放资源 101 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /nearest_can_see.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | import cv2 3 | import numpy as np 4 | import win32gui 5 | from mss import mss 6 | import tkinter as tk 7 | 8 | # 调用驱动 9 | driver = ctypes.CDLL(r'lib/MouseControl.dll') 10 | 11 | # 定义全局变量 12 | controlling_mouse = False 13 | WINDOW_TITLE = "aimlab_tb" # 替换为你的窗口标题 14 | aimlab_tb_hwnd = None # 存储aimlab_tb窗口句柄 15 | middle_left = 0 # 中间区域坐标 16 | middle_top = 0 # 中间区域坐标 17 | 18 | 19 | class BoxInfo: 20 | def __init__(self, box, distance): 21 | self.box = box 22 | self.distance = distance 23 | 24 | 25 | def capture_screen(window_title, region_width=415, region_height=410): 26 | global aimlab_tb_hwnd, middle_left, middle_top 27 | if aimlab_tb_hwnd is None: 28 | aimlab_tb_hwnd = win32gui.FindWindow(None, window_title) 29 | if aimlab_tb_hwnd == 0: 30 | print("No window found") 31 | return None 32 | 33 | # 获取窗口的客户区域大小 34 | left, top, right, bottom = win32gui.GetClientRect(aimlab_tb_hwnd) 35 | client_width = right - left 36 | client_height = bottom - top 37 | 38 | # 计算中间区域的坐标 39 | middle_left = client_width // 2 - region_width // 2 40 | middle_top = client_height // 2 - region_height // 2 41 | 42 | # 将客户区域的左上角坐标转换为屏幕坐标 43 | client_left, client_top = win32gui.ClientToScreen(aimlab_tb_hwnd, (middle_left, middle_top)) 44 | 45 | # 使用 mss 截取指定区域 46 | with mss() as sct: 47 | monitor = {"left": client_left, "top": client_top, "width": region_width, "height": region_height} 48 | img = sct.grab(monitor) # 截取屏幕区域 49 | frame = np.array(img) # 转换为 numpy 数组 50 | frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR) # 转换为 BGR 格式 51 | return frame 52 | 53 | 54 | def detect_ball(frame): 55 | # 定义小球的 HSV 范围 56 | lower_color = np.array([85, 210, 80]) 57 | upper_color = np.array([95, 245, 255]) 58 | 59 | # 转换到 HSV 空间 60 | hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 61 | 62 | # 根据颜色范围创建掩码 63 | mask = cv2.inRange(hsv, lower_color, upper_color) 64 | 65 | # 查找轮廓 66 | contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 67 | 68 | # 直接在循环中计算最近的框体,避免额外的列表操作 69 | closest_box_info = None 70 | closest_distance = float('inf') 71 | screen_center_x = frame.shape[1] // 2 72 | screen_center_y = frame.shape[0] // 2 73 | 74 | for contour in contours: 75 | # 获取轮廓的边界框 76 | x, y, w, h = cv2.boundingRect(contour) 77 | center_x = (x + x + w) // 2 78 | center_y = (y + y + h) // 2 79 | distance = ((center_x - screen_center_x) ** 2 + (center_y - screen_center_y) ** 2) ** 0.5 80 | 81 | if distance < closest_distance: 82 | closest_box_info = BoxInfo((x, y, x + w, y + h), distance) 83 | closest_distance = distance 84 | 85 | # 绘制检测到的方框 86 | if closest_box_info: 87 | cv2.rectangle(frame, (closest_box_info.box[0], closest_box_info.box[1]), 88 | (closest_box_info.box[2], closest_box_info.box[3]), (0, 255, 0), 1) # 修改线宽为1 89 | 90 | return closest_box_info 91 | 92 | 93 | def run_detection(): 94 | global controlling_mouse 95 | 96 | while controlling_mouse: 97 | frame = capture_screen(WINDOW_TITLE) 98 | if frame is None: 99 | continue 100 | 101 | # 检测小球 102 | closest_box_info = detect_ball(frame) 103 | threshold = 0 # 初始值 104 | if closest_box_info: 105 | # 计算从屏幕中心到最近框体中心的向量 106 | target_x_frame = (closest_box_info.box[0] + closest_box_info.box[2]) // 2 107 | target_y_frame = (closest_box_info.box[1] + closest_box_info.box[3]) // 2 108 | vector_x = target_x_frame - frame.shape[1] // 2 109 | vector_y = target_y_frame - frame.shape[0] // 2 110 | 111 | # 设置一个阈值,当鼠标与目标的距离小于该阈值时,停止移动 112 | threshold = 14 # 设置阈值,越小越准,越慢 113 | 114 | # 绘制阈值框的范围 115 | if closest_box_info: 116 | target_x_frame = (closest_box_info.box[0] + closest_box_info.box[2]) // 2 117 | target_y_frame = (closest_box_info.box[1] + closest_box_info.box[3]) // 2 118 | threshold_box_size = threshold * 2 119 | cv2.rectangle(frame, (target_x_frame - threshold_box_size // 2, target_y_frame - threshold_box_size // 2), 120 | (target_x_frame + threshold_box_size // 2, target_y_frame + threshold_box_size // 2), 121 | (0, 0, 255), 1) # 修改线宽为1 122 | 123 | # 显示图像 124 | cv2.imshow('Detected Frame', frame) 125 | if cv2.waitKey(1) & 0xFF == ord('q'): 126 | break 127 | 128 | cv2.destroyAllWindows() 129 | 130 | 131 | def start_detection(): 132 | global controlling_mouse 133 | controlling_mouse = True 134 | run_detection() # 直接在主线程中运行检测逻辑 135 | 136 | 137 | def stop_detection(): 138 | global controlling_mouse 139 | controlling_mouse = False 140 | 141 | 142 | def exit_program(): 143 | global controlling_mouse 144 | controlling_mouse = False 145 | cv2.destroyAllWindows() 146 | root.quit() 147 | 148 | 149 | if __name__ == "__main__": 150 | # 创建主窗口并设置窗口标题 151 | root = tk.Tk() 152 | root.title("Control Window") 153 | 154 | # 创建并放置开始检测按钮 155 | start_button = tk.Button(root, text="Start Detection", command=start_detection) 156 | start_button.pack(pady=10) 157 | 158 | # 创建并放置停止控制按钮 159 | stop_button = tk.Button(root, text="Stop Control", command=stop_detection) 160 | stop_button.pack(pady=10) 161 | 162 | # 创建并放置退出程序按钮 163 | exit_button = tk.Button(root, text="Exit Program", command=exit_program) 164 | exit_button.pack(pady=10) 165 | 166 | # 进入Tkinter事件主循环 167 | root.mainloop() 168 | 169 | # 程序退出前打印信息 170 | print("Exiting...") 171 | -------------------------------------------------------------------------------- /nearest.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | import cv2 3 | import numpy as np 4 | import win32gui 5 | from mss import mss 6 | import tkinter as tk 7 | 8 | # 调用驱动 9 | driver = ctypes.CDLL(r'lib/MouseControl.dll') 10 | 11 | # 定义全局变量 12 | controlling_mouse = False 13 | WINDOW_TITLE = "aimlab_tb" # 替换为你的窗口标题 14 | aimlab_tb_hwnd = None # 存储aimlab_tb窗口句柄 15 | middle_left = 0 # 中间区域坐标 16 | middle_top = 0 # 中间区域坐标 17 | 18 | class BoxInfo: 19 | def __init__(self, box, distance): 20 | self.box = box 21 | self.distance = distance 22 | 23 | def capture_screen(window_title, region_width=415, region_height=410): 24 | global aimlab_tb_hwnd, middle_left, middle_top 25 | if aimlab_tb_hwnd is None: 26 | aimlab_tb_hwnd = win32gui.FindWindow(None, window_title) 27 | if aimlab_tb_hwnd == 0: 28 | print("No window found") 29 | return None 30 | 31 | # 获取窗口的客户区域大小 32 | left, top, right, bottom = win32gui.GetClientRect(aimlab_tb_hwnd) 33 | client_width = right - left 34 | client_height = bottom - top 35 | 36 | # 计算中间区域的坐标 37 | middle_left = client_width // 2 - region_width // 2 38 | middle_top = client_height // 2 - region_height // 2 39 | 40 | # 将客户区域的左上角坐标转换为屏幕坐标 41 | client_left, client_top = win32gui.ClientToScreen(aimlab_tb_hwnd, (middle_left, middle_top)) 42 | 43 | # 使用 mss 截取指定区域 44 | with mss() as sct: 45 | monitor = {"left": client_left, "top": client_top, "width": region_width, "height": region_height} 46 | img = sct.grab(monitor) # 截取屏幕区域 47 | frame = np.array(img) # 转换为 numpy 数组 48 | frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR) # 转换为 BGR 格式 49 | return frame 50 | 51 | def detect_ball(frame): 52 | # 定义小球的 HSV 范围 53 | lower_color = np.array([85, 210, 80]) 54 | upper_color = np.array([95, 245, 255]) 55 | 56 | # 转换到 HSV 空间 57 | hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 58 | 59 | # 根据颜色范围创建掩码 60 | mask = cv2.inRange(hsv, lower_color, upper_color) 61 | 62 | # 查找轮廓 63 | contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 64 | 65 | # 直接在循环中计算最近的框体,避免额外的列表操作 66 | closest_box_info = None 67 | closest_distance = float('inf') 68 | screen_center_x = frame.shape[1] // 2 69 | screen_center_y = frame.shape[0] // 2 70 | 71 | for contour in contours: 72 | # 获取轮廓的边界框 73 | x, y, w, h = cv2.boundingRect(contour) 74 | center_x = (x + x + w) // 2 75 | center_y = (y + y + h) // 2 76 | distance = ((center_x - screen_center_x) ** 2 + (center_y - screen_center_y) ** 2) ** 0.5 77 | 78 | if distance < closest_distance: 79 | closest_box_info = BoxInfo((x, y, x + w, y + h), distance) 80 | closest_distance = distance 81 | 82 | return closest_box_info 83 | 84 | def run_detection(): 85 | global controlling_mouse 86 | 87 | previous_vector_x = 0 # 保存上一次的移动向量x 88 | previous_vector_y = 0 # 保存上一次的移动向量y 89 | moved_count = 0 # 记录反向移动次数 90 | max_moved_count = 8 # 最大反向移动次数 91 | 92 | while controlling_mouse: 93 | frame = capture_screen(WINDOW_TITLE) 94 | if frame is None: 95 | continue 96 | 97 | # 检测小球 98 | closest_box_info = detect_ball(frame) 99 | 100 | if closest_box_info: 101 | # 计算从屏幕中心到最近框体中心的向量 102 | target_x_frame = (closest_box_info.box[0] + closest_box_info.box[2]) // 2 103 | target_y_frame = (closest_box_info.box[1] + closest_box_info.box[3]) // 2 104 | vector_x = target_x_frame - frame.shape[1] // 2 105 | vector_y = target_y_frame - frame.shape[0] // 2 106 | 107 | # 设置一个阈值,当鼠标与目标的距离小于该阈值时,停止移动 108 | threshold = 14 # 设置阈值,越小越准,越慢 109 | if closest_box_info.distance > threshold: 110 | # 将鼠标移动一个较小的向量的距离 111 | step_controller = 1 112 | move_mouse_by(vector_x * step_controller, vector_y * step_controller) # 减小步长 113 | else: 114 | click_mouse() 115 | 116 | # 更新上一次的移动向量 117 | previous_vector_x = vector_x 118 | previous_vector_y = vector_y 119 | moved_count = 0 # 重置反向移动计数器 120 | else: 121 | # 当没有检测到目标时,移动上一次向量的反方向 122 | if previous_vector_x != 0 or previous_vector_y != 0: 123 | if moved_count < max_moved_count: 124 | move_mouse_by(-previous_vector_x, -previous_vector_y) 125 | moved_count += 1 # 增加反向移动计数器 126 | 127 | def move_mouse_by(delta_x, delta_y): 128 | driver.move_R(int(delta_x), int(delta_y)) 129 | 130 | def click_mouse(): 131 | driver.click_Left_down() 132 | driver.click_Left_up() 133 | 134 | def start_detection(): 135 | global controlling_mouse 136 | controlling_mouse = True 137 | run_detection() # 直接在主线程中运行检测逻辑 138 | 139 | def stop_detection(): 140 | global controlling_mouse 141 | controlling_mouse = False 142 | 143 | def exit_program(): 144 | global controlling_mouse 145 | controlling_mouse = False 146 | cv2.destroyAllWindows() 147 | root.quit() 148 | 149 | if __name__ == "__main__": 150 | # 创建主窗口并设置窗口标题 151 | root = tk.Tk() 152 | root.title("Control Window") 153 | 154 | # 创建并放置开始检测按钮 155 | start_button = tk.Button(root, text="Start Detection", command=start_detection) 156 | start_button.pack(pady=10) 157 | 158 | # 创建并放置停止控制按钮 159 | stop_button = tk.Button(root, text="Stop Control", command=stop_detection) 160 | stop_button.pack(pady=10) 161 | 162 | # 创建并放置退出程序按钮 163 | exit_button = tk.Button(root, text="Exit Program", command=exit_program) 164 | exit_button.pack(pady=10) 165 | 166 | # 进入Tkinter事件主循环 167 | root.mainloop() 168 | 169 | # 程序退出前打印信息 170 | print("Exiting...") --------------------------------------------------------------------------------