├── 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 |
5 |
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 |
4 |
5 |
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 |
4 |
5 |
14 |
15 |
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...")
--------------------------------------------------------------------------------