Files
unredact/tests/test_alignment.py
T
Alex-GilbertandClaude Opus 4.6 8d82054b5d feat: overlay calibration with word-by-word rendering
- Render each word at its OCR'd position instead of whole lines,
  so word spacing matches the original document exactly
- Add y-offset correction using glyph bounding box
- Add fine-grained font size search (±3 around coarse best, step 1)
- Add alignment quality test (48.9% hit rate, >30% threshold)
- Add scipy to dev dependencies

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 19:04:40 -06:00

52 lines
1.8 KiB
Python

from pathlib import Path
import numpy as np
from PIL import Image
from scipy.ndimage import binary_dilation
from unredact.pipeline.rasterize import rasterize_pdf
from unredact.pipeline.ocr import ocr_page
from unredact.pipeline.font_detect import detect_font
from unredact.pipeline.overlay import render_overlay
def test_overlay_alignment_score(sample_pdf: Path):
"""Measure how well the overlay aligns with the original text.
Strategy: compare the overlay-only green pixels against the original
dark text pixels. Where they overlap (within a few pixels tolerance),
that's a hit. We want a reasonable hit rate.
"""
pages = rasterize_pdf(sample_pdf, first_page=1, last_page=1)
page = pages[0]
lines = ocr_page(page)
font_match = detect_font(lines, page)
overlay = render_overlay(page, lines, font_match)
orig_arr = np.array(page.convert("L")) # grayscale
overlay_arr = np.array(overlay)
# Original dark text pixels (< 128 on grayscale)
text_mask = orig_arr < 128
# Overlay green pixels (green channel > 100)
green_mask = overlay_arr[:, :, 1] > 100
# How many text pixels have green overlay nearby (within 3px tolerance)?
green_dilated = binary_dilation(green_mask, iterations=3)
overlap = text_mask & green_dilated
if text_mask.sum() == 0:
return
hit_rate = overlap.sum() / text_mask.sum()
print(f"\nAlignment hit rate: {hit_rate:.1%}")
print(f" Text pixels: {text_mask.sum()}")
print(f" Green pixels: {green_mask.sum()}")
print(f" Overlap pixels: {overlap.sum()}")
# We want at least 30% of text pixels to have overlay nearby
# (not 100% because redaction boxes are dark too, and headers/footers
# may use different fonts)
assert hit_rate > 0.3, f"Overlay alignment too low: {hit_rate:.1%}"