From a03d4f34ff0b68f44310e27faee53e005983ef64 Mon Sep 17 00:00:00 2001 From: SnapOtter Date: Wed, 13 May 2026 17:17:32 +0800 Subject: [PATCH] fix(ai): tune scratch detection thresholds and remove erosive open step - Two-gate threshold: Otsu >= 60 uses Otsu; 40-59 uses fixed 100 (catches strong scratches on borderline images) - Remove morphological OPEN after component filtering: it was eroding thin scratch lines that were correctly detected - Lower Otsu gate from 60 to 40 to avoid false-negating borderline images --- packages/ai/python/restore.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/ai/python/restore.py b/packages/ai/python/restore.py index 226867c9..65b28f0d 100644 --- a/packages/ai/python/restore.py +++ b/packages/ai/python/restore.py @@ -91,16 +91,17 @@ def detect_scratches(img_bgr, _sensitivity=None): response_u8 = np.clip(response, 0, 255).astype(np.uint8) otsu_thresh, mask = cv2.threshold(response_u8, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) - if otsu_thresh < 60: + if otsu_thresh < 40: return np.zeros_like(gray) + # When Otsu is borderline, use a high fixed threshold to only catch strong scratches + if otsu_thresh < 60: + _, mask = cv2.threshold(response_u8, 100, 255, cv2.THRESH_BINARY) + # Connected component filtering mask = _filter_components(mask, h * w) - # Post-processing - kernel_open = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) - mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel_open) - + # Connect nearby scratch segments (no opening - it erodes thin scratch lines) kernel_close = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7)) mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel_close)