# Guide: Tiền xử lý & Cleanup Header cho Pali-Taykha

> Ngày: 2026-06-08 | Phiên bản cuối: v5

---

## 1. Preprocess ảnh scan (giấy kém chất lượng)

**Vấn đề:** Giấy mỏng, chữ mờ, thấu quang → OCR kém.

**Giải pháp:** Adaptive Thresholding + Morphology

### Thông số chuẩn (đã kiểm chứng trên trang 14)

```yaml
preprocessing:
  bilateral_d: 9
  bilateral_sigmaColor: 75
  bilateral_sigmaSpace: 75
  adaptive_threshold:
    method: ADAPTIVE_THRESH_GAUSSIAN_C
    block_size: 21
    C: 25
  morphology:
    kernel: [3, 3]
    mode: MORPH_CLOSE
  output:
    dpi: 300
    format: png
```

### Script: `cleanup_pali_taykha_v5.py`

```bash
# Bước 1: Trích xuất PDF → PNG (300 DPI)
pdftoppm -r 300 -png input.pdf raw_pages/page

# Bước 2: Xử lý ảnh → PDF sạch
python3 preprocess_all.py

# Bước 3: OCR với Cloud Vision
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/google_service_account.json"
python3 scripts/ocr_pdf_to_raw.py "pdf/clean/input-clean.pdf" "zen-ocr-pdf" "ocr/raw/"

# Bước 4: Cleanup header
python3 scripts/cleanup_pali_taykha_v5.py
```

### Kết quả
- PDF gốc 21.7 MB → PDF sạch 5.6 MB (-74%)
- Raw PNG 144 MB → Cleaned PNG 5.7 MB (-96%)
- OCR JSON 4.2 MB → Markdown 86 KB

---

## 2. Cleanup Header — Chiến lược v5

### Nguyên lý

**Phát hiện header zone qua tọa độ (không dùng pattern text)**

1. **Header zone:** tất cả block có `y_min < 0.15` (tỉ lệ chiều cao trang)
2. **Có số trang trong zone → xóa TOÀN BỘ block**
3. **Prefix matching** xử lý block merge (Cloud Vision gộp header + body)
4. **Footer artifacts** — block ở `y > 0.85` bị Cloud Vision đẩy lên đầu text

### Vì sao v5 hoạt động tốt hơn các phiên bản trước

| Phiên bản | Cách tiếp cận | Vấn đề |
|-----------|--------------|--------|
| v1-v2 | Text matching | Không bắt được header lặp ít |
| v3 | Frequency analysis | Sót header xuất hiện 1 lần (`န'ပါ...`, page 19) |
| v4 | Tọa độ Y overlap với số trang | Sót block merge (header+body gộp chung) |
| **v5** | **y_min < 0.15 + prefix + footer** | **✅ 100%** |

### Các edge case đã xử lý

| Edge Case | Giải pháp |
|-----------|-----------|
| Block merge (header + body gộp 1 block, y_max vượt ngưỡng) | Dùng `y_min` thay vì `y_max`, kết hợp prefix matching |
| Footer artifact (block ở đáy trang bị đẩy lên đầu text) | Thu thập tất cả block `y > 0.85` vào `footer_texts` |
| Header không có số trang rõ ràng (page 14: `P` thay vì số) | Single-char ở rìa trái/phải cũng tính là "page number" |
| `ပါဠိသိက္ခာ` xuất hiện trong body | Chỉ xóa ở 10 dòng đầu, không ảnh hưởng body |
| Số `1` cô lập sau header đã xóa | Single-digit artifact ngay sau dòng đã xóa → cũng xóa |

### Pattern header của Pali-Taykha (သောဠသမကျမ်း)

| Trang | Vị trí trái | Vị trí giữa | Vị trí phải |
|-------|------------|------------|------------|
| Chẵn (10,12,14...) | Số trang (`၄`, `၁၀`...) | `ပါဠိသိက္ခာ` | `ပထမ` / `ဒုတိယ` |
| Lẻ (11,13,15...) | `အခန်း` | Chapter title | Số trang |

### Watermark cố định

```
Scanned with
CS CamScanner
```
→ Xuất hiện ở **100% trang** → xóa bằng regex.

---

## 3. Cấu trúc thư mục output

```
010-pali-thaykha/
├── Pali-Taykha-page-001-044.pdf           # PDF gốc (21.7 MB)
├── preprocess-config.yaml                  # Thông số làm sạch ảnh
├── guide/
│   └── cleanup-guide.md                    # File này
├── pdf/clean/
│   └── Pali-Taykha-page-001-044-clean.pdf  # PDF sạch (5.6 MB)
├── ocr/raw/                                # 15 JSON Cloud Vision (4.2 MB)
├── extracted/
│   ├── output-*.md                         # 15 file markdown theo batch
│   └── Pali-Taykha-full.md                 # Merged (86 KB, 44 trang)
├── raw_pages/                              # 44 PNG gốc 300 DPI (144 MB)
├── cleaned/                                # 44 PNG đã xử lý (5.7 MB)
├── _backup/                                # File test cũ
└── scripts (trong workspace chính):
    ├── preprocess_all.py                   # Xử lý ảnh hàng loạt
    └── cleanup_pali_taykha_v5.py           # Cleanup header
```

---

## 4. Bài học

1. **Luôn kiểm tra tọa độ block trước khi chọn chiến lược cleanup** — mỗi sách có layout khác nhau
2. **Block merge là kẻ thù lớn nhất** — Cloud Vision thường gộp header + body, cần prefix matching
3. **Footer artifact** — Cloud Vision đôi khi đẩy text cuối trang lên đầu `fullTextAnnotation.text`
4. **y_min tốt hơn y_max** để bắt block merge (y_min luôn nằm trong header zone dù block đã merge)
5. **Ngưỡng 0.15 là "điểm ngọt"** — đủ thấp để không bắt nhầm body text, đủ cao để bắt header merge
