计算边框粗细 (Stroke Width) 逻辑:沿四边向内扫描,寻找颜色突变点,多个采样点综合取中位数。 优化: - 提高突变阈值(35),减少误检 - 限制最大宽度(8像素),避免过粗 - 大多数边框在 1-5 像素
(image: np.ndarray, bbox: list, max_width: int = 8)
| 183 | |
| 184 | # ======================== 边框宽度检测 ======================== |
| 185 | def calculate_stroke_width(image: np.ndarray, bbox: list, max_width: int = 8) -> int: |
| 186 | """ |
| 187 | 计算边框粗细 (Stroke Width) |
| 188 | 逻辑:沿四边向内扫描,寻找颜色突变点,多个采样点综合取中位数。 |
| 189 | |
| 190 | 优化: |
| 191 | - 提高突变阈值(35),减少误检 |
| 192 | - 限制最大宽度(8像素),避免过粗 |
| 193 | - 大多数边框在 1-5 像素 |
| 194 | """ |
| 195 | x1, y1, x2, y2 = map(int, bbox) |
| 196 | h, w = image.shape[:2] |
| 197 | |
| 198 | x1, y1 = max(0, x1), max(0, y1) |
| 199 | x2, y2 = min(w, x2), min(h, y2) |
| 200 | |
| 201 | roi = image[y1:y2, x1:x2] |
| 202 | if roi.size == 0: |
| 203 | return 1 |
| 204 | |
| 205 | roi_h, roi_w = roi.shape[:2] |
| 206 | roi_gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY) |
| 207 | |
| 208 | scan_limit = min(max_width, roi_w // 2 - 1, roi_h // 2 - 1) |
| 209 | if scan_limit < 1: |
| 210 | return 1 |
| 211 | |
| 212 | detected_widths = [] |
| 213 | |
| 214 | def scan_line(pixels, limit): |
| 215 | if len(pixels) < limit + 1: |
| 216 | return None |
| 217 | diffs = np.abs(np.diff(pixels[:limit+2].astype(int))) |
| 218 | threshold = 35 # 提高阈值,减少误检(原值20太敏感) |
| 219 | candidates = np.where(diffs > threshold)[0] |
| 220 | if len(candidates) > 0: |
| 221 | return candidates[0] + 1 |
| 222 | return None |
| 223 | |
| 224 | num_samples = 5 |
| 225 | |
| 226 | # Top Edge |
| 227 | for i in range(1, num_samples + 1): |
| 228 | x = int(roi_w * i / (num_samples + 1)) |
| 229 | col = roi_gray[:, x] |
| 230 | w_val = scan_line(col, scan_limit) |
| 231 | if w_val: |
| 232 | detected_widths.append(w_val) |
| 233 | |
| 234 | # Bottom Edge |
| 235 | for i in range(1, num_samples + 1): |
| 236 | x = int(roi_w * i / (num_samples + 1)) |
| 237 | col = roi_gray[::-1, x] |
| 238 | w_val = scan_line(col, scan_limit) |
| 239 | if w_val: |
| 240 | detected_widths.append(w_val) |
| 241 | |
| 242 | # Left Edge |
no test coverage detected