diff --git a/klausur-service/backend/page_crop.py b/klausur-service/backend/page_crop.py index 1356fdd..108e095 100644 --- a/klausur-service/backend/page_crop.py +++ b/klausur-service/backend/page_crop.py @@ -535,19 +535,30 @@ def _detect_gutter_continuity( if region_w <= 2 * margin + 10: return None - # Scan from edge inward to find where frac drops below transition threshold + # Find the peak of dark fraction (gutter center). + # For right gutters the peak is near the edge; for left gutters + # (V-shaped spine shadow) the peak may be well inside the region. transition_thresh = 0.50 + peak_frac = float(np.max(frac_smooth[margin:region_w - margin])) + + if peak_frac < 0.70: + logger.debug( + "%s gutter: peak dark fraction %.2f < 0.70", side.capitalize(), peak_frac, + ) + return None + + peak_x = int(np.argmax(frac_smooth[margin:region_w - margin])) + margin gutter_inner = None # local x in search_region if side == "right": - # Scan from right edge (region_w - 1) inward (toward 0) - for x in range(region_w - 1 - margin, margin, -1): + # Scan from peak toward the page center (leftward) + for x in range(peak_x, margin, -1): if frac_smooth[x] < transition_thresh: - gutter_inner = x + 1 # crop just past the transition + gutter_inner = x + 1 break else: - # Scan from left edge (0) inward (toward region_w) - for x in range(margin, region_w - margin): + # Scan from peak toward the page center (rightward) + for x in range(peak_x, region_w - margin): if frac_smooth[x] < transition_thresh: gutter_inner = x - 1 break