# OCR Troubleshooting — Binarization Fallback

## Problem
Some scanned PDF pages return empty text when processed with standard `ocrmypdf` + `pdftotext` or `tesseract`. The pages appear to have content visually but the OCR engine produces zero characters.

## Diagnosis
Check if tesseract output is empty:
```bash
tesseract page.jpg stdout -l chi_sim | wc -c
# If 0 chars → page needs binarization
```

Check image statistics to confirm it's not truly blank:
```python
from PIL import Image
import numpy as np
arr = np.array(Image.open('page.jpg').convert('L'))
print(f'mean={arr.mean():.0f} std={arr.std():.0f}')
# If std > 25 → image has content, OCR failure is processing issue
```

## Fix: Binarization (threshold=140)
Convert to pure black-and-white before re-running tesseract:

```python
from PIL import Image
import numpy as np

img = Image.open('page.jpg').convert('L')
arr = np.array(img)
threshold = 140  # Adjust if needed (120-160 range)
arr = (arr < threshold).astype(np.uint8) * 255
Image.fromarray(arr).save('page_bw.png')
```

Then run tesseract on the binarized image:
```bash
tesseract page_bw.png stdout -l chi_sim
```

## Vision Tool Timeout Fix
If `vision_analyze` times out on scanned pages:
1. Check `~/.hermes/config.yaml` → `vision.timeout` (default 30s is too short for large images)
2. Increase to 90s: `sed -i 's/timeout: 30/timeout: 90/' ~/.hermes/config.yaml`
3. Compress images before sending: resize to 850x1100, quality=60 (~80-120KB per page)
4. Send one page at a time, not multiple simultaneously

## Workflow for Scanned Contracts
1. `ocrmypdf -l chi_sim --skip-text input.pdf output_ocr.pdf`
2. `pdftotext output_ocr.pdf - | wc -c` — check if text layer exists
3. If empty pages: `pdftoppm -jpeg -r 300 input.pdf pages/page` → binarize → tesseract
4. Combine: original tesseract pages + binarized pages into single .md file
5. For remaining garbled fields: use `vision_analyze` on compressed page images
