# huaweidomain77/watermark-extractor architecture

> Architecture diagram of the GitHub repository huaweidomain77/watermark-extractor, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-10-01). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/huaweidomain77/watermark-extractor
- Repository: https://github.com/huaweidomain77/watermark-extractor

## Overview

Watermark Extractor is a Gradio application for reading red watermark fields from survey photos and checking extracted coordinates against a master site file. Users upload images, run extraction, review results, and can optionally upload a master file for distance validation. The extraction orchestrator locates and isolates watermark text, tries local OCR with rotations and validation, and has a documented OpenAI fallback. The excerpts show core image-processing and OCR dependencies; some application wiring is only visible in the SOURCE INDEX, and the master-file relationship is documented rather than traced through the UI code.

Main entry points: [`core/extractor.py`](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/extractor.py) (Extraction orchestrator), [`core/openai_client.py`](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/openai_client.py) (Vision fallback), [`core/text_regions.py`](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/text_regions.py) (Text region detection), [`app.py`](https://github.com/huaweidomain77/watermark-extractor/blob/main/app.py) (Gradio app)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ui["User interface"]
  node_app["Gradio app<br/>[app.py]"]
end

subgraph group_extract["Extraction workflow"]
  node_orchestrator["Extraction orchestrator<br/>[extractor.py]"]
  node_distance["Site distance check<br/>[distance.py]"]
end

subgraph group_vision["Image analysis"]
  node_corner["Watermark locator<br/>[corners.py]"]
  node_isolate["Watermark isolator<br/>[watermark.py]"]
  node_orientation["Orientation detection<br/>[rotations.py]"]
  node_redmask["Red mask<br/>[red_mask.py]"]
  node_textregions["Text region detection<br/>[text_regions.py]"]
  node_preprocess["MSER preprocessing<br/>[preprocess.py]"]
end

subgraph group_verify["OCR and validation"]
  node_tesseract["Local OCR"]
  node_openai["Vision fallback<br/>[openai_client.py]"]
  node_quality["OCR quality gate<br/>[quality_gate.py]"]
  node_validation["Extraction validation<br/>[validation.py]"]
  node_helpers["Shared helpers<br/>[helpers.py]"]
end

node_user(("Survey user"))
node_ai_service(("OpenAI service"))
node_master["Master site file"]

node_user -->|"uploads images"| node_app
node_app -->|"runs extraction"| node_orchestrator
node_app -->|"checks distance"| node_distance
node_orchestrator -->|"locates watermark"| node_corner
node_orchestrator -->|"isolates text"| node_isolate
node_orchestrator -->|"chooses rotations"| node_orientation
node_orchestrator -->|"runs OCR"| node_tesseract
node_orchestrator -->|"fallback extraction"| node_openai
node_orchestrator -->|"validates fields"| node_validation
node_corner -->|"scores red pixels"| node_redmask
node_corner -->|"filters text"| node_textregions
node_isolate -->|"masks red pixels"| node_redmask
node_isolate -->|"selects text regions"| node_textregions
node_orientation -->|"masks raw image"| node_redmask
node_orientation -->|"filters raw image"| node_textregions
node_textregions -->|"prepares for MSER"| node_preprocess
node_tesseract -->|"normalizes extracted fields"| node_helpers
node_openai -->|"normalizes extracted fields"| node_helpers
node_openai -->|"gates response"| node_quality
node_openai -->|"requests vision extraction"| node_ai_service
node_distance -->|"matches site IDs"| node_master
node_user -.->|"uploads site file"| node_master

click node_app "https://github.com/huaweidomain77/watermark-extractor/blob/main/app.py"
click node_orchestrator "https://github.com/huaweidomain77/watermark-extractor/blob/main/core/extractor.py"
click node_corner "https://github.com/huaweidomain77/watermark-extractor/blob/main/core/corners.py"
click node_isolate "https://github.com/huaweidomain77/watermark-extractor/blob/main/core/watermark.py"
click node_orientation "https://github.com/huaweidomain77/watermark-extractor/blob/main/core/rotations.py"
click node_redmask "https://github.com/huaweidomain77/watermark-extractor/blob/main/core/red_mask.py"
click node_textregions "https://github.com/huaweidomain77/watermark-extractor/blob/main/core/text_regions.py"
click node_preprocess "https://github.com/huaweidomain77/watermark-extractor/blob/main/core/preprocess.py"
click node_tesseract "https://github.com/huaweidomain77/watermark-extractor/blob/main/core/tesseract_client.py"
click node_openai "https://github.com/huaweidomain77/watermark-extractor/blob/main/core/openai_client.py"
click node_quality "https://github.com/huaweidomain77/watermark-extractor/blob/main/core/quality_gate.py"
click node_validation "https://github.com/huaweidomain77/watermark-extractor/blob/main/core/validation.py"
click node_helpers "https://github.com/huaweidomain77/watermark-extractor/blob/main/utils/helpers.py"
click node_distance "https://github.com/huaweidomain77/watermark-extractor/blob/main/core/distance.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_user toneBlue
class node_orchestrator,node_distance toneAmber
class node_corner,node_isolate,node_orientation,node_redmask,node_textregions,node_preprocess toneMint
class node_tesseract,node_openai,node_quality,node_validation,node_helpers toneRose
class node_ai_service,node_master toneIndigo
```

## Components

### User interface

- [Gradio app](https://github.com/huaweidomain77/watermark-extractor/blob/main/app.py): `app.py`

### Extraction workflow

- [Extraction orchestrator](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/extractor.py): `core/extractor.py`
- [Site distance check](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/distance.py): `core/distance.py`

### Image analysis

- [Watermark locator](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/corners.py): `core/corners.py`
- [Watermark isolator](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/watermark.py): `core/watermark.py`
- [Orientation detection](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/rotations.py): `core/rotations.py`
- [Red mask](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/red_mask.py): `core/red_mask.py`
- [Text region detection](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/text_regions.py): `core/text_regions.py`
- [MSER preprocessing](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/preprocess.py): `core/preprocess.py`

### OCR and validation

- [Local OCR](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/tesseract_client.py): `core/tesseract_client.py`
- [Vision fallback](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/openai_client.py): `core/openai_client.py`
- [OCR quality gate](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/quality_gate.py): `core/quality_gate.py`
- [Extraction validation](https://github.com/huaweidomain77/watermark-extractor/blob/main/core/validation.py): `core/validation.py`
- [Shared helpers](https://github.com/huaweidomain77/watermark-extractor/blob/main/utils/helpers.py): `utils/helpers.py`

### Other components

- **Survey user**
- **OpenAI service**
- **Master site file**

## Connections

- Survey user → Gradio app: uploads images (evidence: `README.md`)
- Gradio app → Extraction orchestrator: runs extraction (evidence: `app.py`)
- Gradio app → Site distance check: checks distance (evidence: `app.py`)
- Extraction orchestrator → Watermark locator: locates watermark (evidence: `core/extractor.py`)
- Extraction orchestrator → Watermark isolator: isolates text (evidence: `core/extractor.py`)
- Extraction orchestrator → Orientation detection: chooses rotations (evidence: `core/extractor.py`)
- Extraction orchestrator → Local OCR: runs OCR (evidence: `core/extractor.py`)
- Extraction orchestrator → Vision fallback: fallback extraction (evidence: `core/extractor.py`)
- Extraction orchestrator → Extraction validation: validates fields (evidence: `core/extractor.py`)
- Watermark locator → Red mask: scores red pixels (evidence: `core/corners.py`)
- Watermark locator → Text region detection: filters text (evidence: `core/corners.py`)
- Watermark isolator → Red mask: masks red pixels (evidence: `core/watermark.py`)
- Watermark isolator → Text region detection: selects text regions (evidence: `core/watermark.py`)
- Orientation detection → Red mask: masks raw image (evidence: `core/rotations.py`)
- Orientation detection → Text region detection: filters raw image (evidence: `core/rotations.py`)
- Text region detection → MSER preprocessing: prepares for MSER (evidence: `core/text_regions.py`)
- Local OCR → Shared helpers: normalizes extracted fields (evidence: `core/tesseract_client.py`)
- Vision fallback → Shared helpers: normalizes extracted fields (evidence: `core/openai_client.py`)
- Vision fallback → OCR quality gate: gates response (evidence: `core/openai_client.py`)
- Vision fallback → OpenAI service: requests vision extraction (evidence: `core/openai_client.py`)
- Site distance check → Master site file: matches site IDs (evidence: `README.md`)
- Survey user → Master site file: uploads site file (evidence: `README.md`)
