-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfix_hsv.py
More file actions
280 lines (227 loc) · 10.3 KB
/
Copy pathfix_hsv.py
File metadata and controls
280 lines (227 loc) · 10.3 KB
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
import cv2
import numpy as np
from pathlib import Path
def nothing(x):
"""滑块回调函数"""
pass
def debug_hsv_color(image_paths):
"""
交互式HSV调试工具,用于找到最佳的颜色检测范围
支持多张图片同时显示对比
使用方法:
- 移动滑块调整颜色范围
- 找到最佳范围后,记录下数值
- 按 ESC 退出
"""
# 读取所有图片
images = []
hsv_images = []
for img_path in image_paths:
img = cv2.imread(img_path)
if img is None:
print(f"无法读取图像: {img_path}")
continue
images.append((img_path, img))
hsv_images.append(cv2.cvtColor(img, cv2.COLOR_BGR2HSV))
if not images:
print("没有成功读取到任何图片")
return
# 创建窗口和滑块
cv2.namedWindow('HSV Mask Debugger')
cv2.createTrackbar('H_Low', 'HSV Mask Debugger', 90, 180, nothing)
cv2.createTrackbar('H_High', 'HSV Mask Debugger', 130, 180, nothing)
cv2.createTrackbar('S_Low', 'HSV Mask Debugger', 50, 255, nothing)
cv2.createTrackbar('S_High', 'HSV Mask Debugger', 255, 255, nothing)
cv2.createTrackbar('V_Low', 'HSV Mask Debugger', 100, 255, nothing)
cv2.createTrackbar('V_High', 'HSV Mask Debugger', 255, 255, nothing)
print("HSV调试工具已启动")
print("调整滑块找到最佳的颜色范围")
print("操作说明:")
print("- 按 'S' 保存当前HSV范围配置")
print("- 按 'Q' 退出程序")
print(f"当前显示 {len(images)} 张图片")
def resize_to_fit(image, num_images, max_total_width=1800, max_total_height=1200):
"""
根据图片数量动态调整单张图片大小,确保1-6张图片都有良好显示效果
参数:
image: 输入图像
num_images: 图片总数
max_total_width: 总显示宽度上限
max_total_height: 总显示高度上限
"""
h, w = image.shape[:2]
# 根据图片数量调整单张图片的最大尺寸
if num_images <= 2:
# 1-2张图片,较大尺寸
max_width = 600
max_height = 450
elif num_images <= 4:
# 3-4张图片,中等尺寸
max_width = 500
max_height = 375
else:
# 5-6张图片,较小尺寸
max_width = 400
max_height = 300
# 计算缩放因子
scale = min(max_width/w, max_height/h, 1.0)
if scale < 1.0:
new_w = int(w * scale)
new_h = int(h * scale)
return cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_AREA)
return image
def create_display_grid(images, masks):
"""
创建1-6张图片的网格显示,优化布局效果
"""
display_rows = []
num_images = len(images)
if num_images == 0:
return np.zeros((100, 100, 3), dtype=np.uint8)
# 为每张图片创建原图+掩码的水平组合
combined_images = []
for (img_path, img), mask in zip(images, masks):
# 动态调整大小
resized_img = resize_to_fit(img, num_images)
resized_mask = resize_to_fit(cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR), num_images)
# 添加图片名称和统计信息
img_with_name = resized_img.copy()
mask_pixels = cv2.countNonZero(mask)
total_pixels = mask.shape[0] * mask.shape[1]
coverage = f"{mask_pixels / total_pixels * 100:.1f}"
cv2.putText(img_with_name, f"{Path(img_path).name}", (10, 25),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
cv2.putText(img_with_name, f"覆盖率: {coverage}%", (10, 50),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255), 1)
# 水平组合原图和掩码
combined = np.hstack([img_with_name, resized_mask])
combined_images.append(combined)
# 根据图片数量优化网格布局
if num_images <= 2:
max_cols = 1 # 1-2张图片,每行1组
else:
max_cols = 2 # 3-6张图片,每行2组
num_rows = (num_images + max_cols - 1) // max_cols
# 为每行创建组合
for i in range(num_rows):
row_images = combined_images[i*max_cols : (i+1)*max_cols]
# 确保所有行图像高度相同
max_height = max(img.shape[0] for img in row_images)
# 调整行内图像高度
adjusted_row = []
for img in row_images:
h, w = img.shape[:2]
if h < max_height:
# 垂直填充,保持居中
pad_top = (max_height - h) // 2
pad_bottom = max_height - h - pad_top
img = cv2.copyMakeBorder(img, pad_top, pad_bottom, 0, 0,
cv2.BORDER_CONSTANT, value=(20, 20, 20))
adjusted_row.append(img)
# 水平组合行内图像
row_combined = np.hstack(adjusted_row)
display_rows.append(row_combined)
# 确保所有行宽度相同,否则无法垂直堆叠
if len(display_rows) > 1:
max_row_width = max(row.shape[1] for row in display_rows)
# 为每行添加左右填充,使宽度一致
for i in range(len(display_rows)):
row = display_rows[i]
h, w = row.shape[:2]
if w < max_row_width:
# 水平居中填充
pad_left = (max_row_width - w) // 2
pad_right = max_row_width - w - pad_left
row = cv2.copyMakeBorder(row, 0, 0, pad_left, pad_right,
cv2.BORDER_CONSTANT, value=(20, 20, 20))
display_rows[i] = row
# 垂直组合所有行
final_display = np.vstack(display_rows)
return final_display
# 保存HSV配置的函数
def save_hsv_config():
"""保存当前HSV范围配置"""
# 读取当前滑块值
h_current = cv2.getTrackbarPos('H_Low', 'HSV Mask Debugger')
h_high_current = cv2.getTrackbarPos('H_High', 'HSV Mask Debugger')
s_current = cv2.getTrackbarPos('S_Low', 'HSV Mask Debugger')
s_high_current = cv2.getTrackbarPos('S_High', 'HSV Mask Debugger')
v_current = cv2.getTrackbarPos('V_Low', 'HSV Mask Debugger')
v_high_current = cv2.getTrackbarPos('V_High', 'HSV Mask Debugger')
# 保存所有图片的最终掩码
Path('output').mkdir(exist_ok=True)
masks_current = []
for hsv_img in hsv_images:
mask = cv2.inRange(hsv_img, np.array([h_current, s_current, v_current]),
np.array([h_high_current, s_high_current, v_high_current]))
masks_current.append(mask)
for i, ((img_path, _), mask) in enumerate(zip(images, masks_current)):
img_name = Path(img_path).stem
mask_path = f'output/{img_name}_best_mask.jpg'
cv2.imwrite(mask_path, mask)
print(f"✓ {img_name} 的最佳掩码已保存到 {mask_path}")
# 保存HSV范围到文件,供main.py使用
hsv_config = {
'lower_blue1': [h_current, s_current, v_current],
'upper_blue1': [h_high_current, s_high_current, v_high_current],
'lower_blue2': [h_current, s_current, v_current], # 可根据需要调整第二个范围
'upper_blue2': [h_high_current, s_high_current, v_high_current] # 可根据需要调整第二个范围
}
# 直接保存JSON配置
import json
hsv_config_file = Path('output') / 'hsv_config.json'
with open(hsv_config_file, 'w', encoding='utf-8') as f:
json.dump(hsv_config, f, ensure_ascii=False, indent=2)
print(f"✓ HSV范围已保存到 {hsv_config_file}")
while True:
# 读取滑块值
h_low = cv2.getTrackbarPos('H_Low', 'HSV Mask Debugger')
h_high = cv2.getTrackbarPos('H_High', 'HSV Mask Debugger')
s_low = cv2.getTrackbarPos('S_Low', 'HSV Mask Debugger')
s_high = cv2.getTrackbarPos('S_High', 'HSV Mask Debugger')
v_low = cv2.getTrackbarPos('V_Low', 'HSV Mask Debugger')
v_high = cv2.getTrackbarPos('V_High', 'HSV Mask Debugger')
lower = np.array([h_low, s_low, v_low])
upper = np.array([h_high, s_high, v_high])
# 为所有图片创建掩码
masks = []
for hsv_img in hsv_images:
mask = cv2.inRange(hsv_img, lower, upper)
masks.append(mask)
# 创建网格显示
display = create_display_grid(images, masks)
# 添加全局HSV参数信息
text = f"Lower: [{h_low}, {s_low}, {v_low}] Upper: [{h_high}, {s_high}, {v_high}]"
cv2.putText(display, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
# 添加操作提示
cv2.putText(display, "操作提示: Q-退出, S-保存配置", (10, display.shape[0]-20),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 1)
cv2.imshow('HSV Mask Debugger', display)
key = cv2.waitKey(1) & 0xFF
if key == ord('q') or key == ord('Q'): # Q 退出
break
elif key == ord('s') or key == ord('S'): # S 保存配置
save_hsv_config()
# 最终结果
print(f"\n最佳范围找到:")
print(f"lower_blue = np.array([{h_low}, {s_low}, {v_low}])")
print(f"upper_blue = np.array([{h_high}, {s_high}, {v_high}])")
# 自动保存最终配置
save_hsv_config()
cv2.destroyAllWindows()
if __name__ == "__main__":
# 示例:支持1-6张图片的演示
# 以下是不同数量图片的使用示例,根据需要取消注释相应行
# 1张图片
# image_paths = ['ticket.jpg']
# 2张图片
image_paths = ['ticket.jpg', 'ticket1.jpg']
# 3张图片(当前使用)
# image_paths = ['ticket.jpg', 'ticket1.jpg', 'ticket3.jpg']
# 4张图片
# image_paths = ['ticket.jpg', 'ticket1.jpg', 'ticket2.jpg', 'ticket3.jpg']
# 5张图片
# image_paths = ['ticket.jpg', 'ticket1.jpg', 'ticket3.jpg', 'ticket.jpg', 'ticket1.jpg']
# 6张图片
# image_paths = ['ticket.jpg', 'ticket1.jpg', 'ticket3.jpg', 'ticket.jpg', 'ticket1.jpg', 'ticket3.jpg']
debug_hsv_color(image_paths)