An automated computer vision and OCR pipeline to extract, clean, and name individual character portraits from large collage sheets with various border styles and grid arrangements.
flowchart TD
subgraph "Parent Formats (inside images/)"
P1[images/Parent1: White Borders]
P2[images/Parent2: Black Borders]
P3[images/Parent3: Borderless Grid]
end
P1 -->|Step 1: Morphological Segregation| C1(images/pic_cropped/Parent1/)
P2 -->|Step 1: Morphological Segregation| C2(images/pic_cropped/Parent2/)
P3 -->|Step 1: Mathematical Grid Division| C3(images/pic_cropped/Parent3/)
C1 -->|Step 2: Trim White Borders| CL(images/pic_cleaned/)
C2 -->|Step 2: Trim Black Borders| CL
C3 -->|Step 2: Direct Pass-Through Copy| CL
CL -->|Step 3: OCR & Fuzzy Speaker Matching| F(images/pic_final/ - Numbered JPG Portraits)
- Multi-format Collage Segregation (
1segregate_parent_images.py):- White Borders (
Parent1): Row-by-row morphological line detection (intensity 240–255) saved intoimages/pic_cropped/Parent1/. - Black Borders (
Parent2): Row-by-row morphological line detection (intensity 0–25) saved intoimages/pic_cropped/Parent2/. - Borderless Sheets (
Parent3): Mathematical grid division (default 3×3, customizable like 6×6) saved intoimages/pic_cropped/Parent3/.
- White Borders (
- Intelligent Multi-Source Border Cleaning (
2clean_borders.py):- Automatically cleans white borders from
images/pic_cropped/Parent1/, cleans black borders fromimages/pic_cropped/Parent2/, and passes through borderless crops fromimages/pic_cropped/Parent3/directly intoimages/pic_cleaned/. - Also supports selective single-color runs (
--color whiteor--color black).
- Automatically cleans white borders from
- OCR Label Extraction & Speaker Matching (
3ocr_and_rename.py):- Multi-region OCR with image preprocessing variations (contrast normalization, Otsu thresholding, inversions).
- High-accuracy fuzzy string matching against known speakers from
prayers_index.jsonusingrapidfuzz. - Persistent OCR Cache (
ocr_cache.json): Real-time disk caching enables instant (<1s) re-runs when cleaning or formatting changes without repeated slow OCR calls. - Generates web-optimized
.jpgimages (at 100% quality) with sequential numbering ({slug}-1.jpg,{slug}-2.jpg) and primary fallback portraits ({slug}.jpg).
ImageTransformationPipeline/
├── images/
│ ├── Parent1/ # Input collage sheets with white borders
│ ├── Parent2/ # Input collage sheets with black borders
│ ├── Parent3/ # Input borderless collage sheets
│ ├── pic_cropped/ # Raw cropped panels grouped by parent
│ │ ├── Parent1/
│ │ ├── Parent2/
│ │ └── Parent3/
│ ├── pic_cleaned/ # Trimmed & consolidated crops from Step 2
│ └── pic_final/ # Final named JPG portraits and OCR cache
│ └── ocr_cache.json
├── prayers_index.json # Reference index of speakers for fuzzy matching
├── unique_speakers.txt # Speaker alias list (optional)
├── 1segregate_parent_images.py
├── 2clean_borders.py
├── 3ocr_and_rename.py
├── requirements.txt
├── LICENSE
└── README.md
Ensure Python 3.9+ is installed. Clone the repository and install dependencies:
git clone https://github.com/ankurgupta10/ImageTransformationPipeline.git
cd ImageTransformationPipeline
pip install -r requirements.txt- Windows: Install Tesseract-OCR for Windows (default installation path:
C:\Program Files\Tesseract-OCR\tesseract.exe). - Linux (Ubuntu/Debian):
sudo apt-get update && sudo apt-get install -y tesseract-ocr - macOS:
brew install tesseract
Place your collage sheets in images/Parent1/, images/Parent2/, or images/Parent3/, then run:
# Process all parent folders automatically into images/pic_cropped/Parent{1,2,3}/ (Parent3 uses default 3x3 grid):
python 1segregate_parent_images.py
# Or customize grid for Parent3 sheets (e.g. 6x6 or 4x4 grid):
python 1segregate_parent_images.py -g 6x6
# Or process a specific folder / file:
python 1segregate_parent_images.py -i images/Parent1
python 1segregate_parent_images.py -i images/Parent2/sample.png
python 1segregate_parent_images.py -i images/Parent3 -m borderless --grid 6x6| Flag | Description | Default |
|---|---|---|
-i, --input |
Input parent image folder(s) or file(s) | images/Parent1, images/Parent2, images/Parent3 |
-o, --output |
Base output directory for crops | images/pic_cropped |
-m, --mode |
Segregation mode: auto, white, black, borderless |
auto |
-g, --grid |
Grid dimensions for borderless mode (3x3, 6x6, 4x4, 3) |
3x3 |
--seg-thresh |
Custom line intensity threshold | 240 (white) / 25 (black) |
--format |
Output image format (png, webp, jpg) |
png |
Clean residual borders and consolidate all crops into images/pic_cleaned/:
# Auto-mode: Cleans white from Parent1, black from Parent2, and copies Parent3 directly:
python 2clean_borders.py
# Clean only white borders (Parent1 crops):
python 2clean_borders.py --color white
# Clean only black borders (Parent2 crops):
python 2clean_borders.py --color black
# Clean a specific file or folder:
python 2clean_borders.py -i images/pic_cropped/Parent1/sample_cell_01.png| Flag | Description | Default |
|---|---|---|
-i, --input |
Input image file(s) or folder(s) | None (auto images/pic_cropped/Parent{1,2,3}) |
-o, --output |
Output folder for cleaned & normalized images | images/pic_cleaned |
--color |
Mode: auto, all, white, black, borderless |
auto |
--thresh |
Grayscale threshold | 230 (white) / 25 (black) |
--max-trim |
Maximum percentage to trim per side | 0.10 (10%) |
--min-ratio |
Minimum border line ratio to trigger trim | 0.50 (50%) |
--format |
Optional format conversion (png, webp, jpg) |
Original |
Extract text labels, fuzzy-match character names against prayers_index.json, and output structured portrait assets:
# Standard run (uses cache where available, runs OCR on new crops):
python 3ocr_and_rename.py
# Force re-running OCR on all images (ignores cache):
python 3ocr_and_rename.py --force-ocr
# Crop portrait area only (exclude label banner):
python 3ocr_and_rename.py --crop-portrait| Flag | Description | Default |
|---|---|---|
-i, --input |
Input directory of crops | images/pic_cleaned |
-o, --output |
Target directory for final portraits | images/pic_final |
--cache-file |
Path to persistent OCR cache | images/pic_final/ocr_cache.json |
--force-ocr |
Force OCR on all files ignoring cache | False |
--index |
Path to speaker database JSON | prayers_index.json |
--crop-portrait |
Crop upper portrait area only | False |
--format |
Output format (jpg, jpeg, webp, png) |
jpg |
--quality |
Compression quality (1-100) | 100 |
This project is licensed under the MIT License.