A full-stack web app that takes a line-drawn map or region diagram, detects the closed regions, builds an adjacency graph, and applies a four-color graph coloring algorithm. The result is returned as a colored map along with debug views for detected regions, boundaries, adjacency data, and color assignments.
- Upload an image from the browser.
- Detect closed regions with OpenCV image preprocessing and connected components.
- Build an adjacency graph from neighboring regions.
- Color the graph with up to four colors using a backtracking solver.
- Display the final colored map, detected-region debug view, boundary mask, adjacency graph, and color assignment JSON.
- Run locally with Python/Node.js or with Docker Compose.
- Backend: FastAPI, Uvicorn, OpenCV, NumPy
- Frontend: React 18, Vite
- Packaging:
uv,requirements.txt, Docker, Docker Compose
.
|-- main.py # FastAPI app and /process-map endpoint
|-- backend/
| |-- image_processing.py # Decode, preprocess, and detect regions
| |-- graph_builder.py # Build adjacency graph from region labels
| |-- coloring.py # Four-color backtracking solver
| `-- renderer.py # Render colored/debug images as PNG/base64
|-- frontned/ # React/Vite frontend
| |-- src/App.jsx # Upload UI and result rendering
| |-- package.json
| `-- Dockerfile
|-- Dockerfile # Backend Docker image
|-- docker-compose.yml # Backend + frontend services
|-- pyproject.toml # Python project metadata
|-- requirements.txt # Locked Python dependencies
|-- image.png # Sample/local test image
`-- validate.py # Local coloring validation script
Note: the frontend directory is currently named frontned, so commands use that
spelling.
- The frontend sends an uploaded image to
POST /process-map. - The backend decodes the file into an OpenCV BGR image.
- The image is converted to grayscale, blurred, edge-detected, dilated, and morphologically closed to create a boundary mask.
- Enclosed regions are found with flood fill and connected components.
- Region labels are converted into an adjacency graph.
- The graph is colored with a four-color backtracking algorithm.
- The API returns base64 PNG images and JSON metadata to the frontend.
From the project root:
docker compose up --buildThen open:
- Frontend: http://localhost:5173
- Backend health check: http://localhost:8000
- API docs: http://localhost:8000/docs
Use Python 3.12.
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
uvicorn main:app --reload --host 127.0.0.1 --port 8000The backend will be available at http://127.0.0.1:8000.
Open a second terminal:
cd frontned
npm install
npm run devThe frontend will be available at http://localhost:5173.
The React app currently calls the backend at http://127.0.0.1:8000.
Returns a simple health-check response:
{
"message": "Map Coloring API is running"
}Accepts a multipart image upload using the form field name file.
Example with PowerShell:
curl.exe -X POST "http://127.0.0.1:8000/process-map" -F "file=@image.png"Successful responses include:
num_regions: number of detected closed regionsadjacency: adjacency graph as JSONcoloring: region-to-color assignmentcolored_image_base64: final colored map PNGdebug_regions_base64: debug image showing detected regionsline_mask_base64: boundary mask PNG
For best results, use images with:
- Clear, high-contrast boundaries.
- Closed regions with no gaps in the lines.
- Minimal noise, shading, or textured backgrounds.
- Regions large enough to pass the current minimum area filter.
If the API cannot detect closed regions, it returns a 400 response asking for a
cleaner map with closed boundaries.
The repository includes a local validation script that reads image.png, runs
the preprocessing, graph construction, and coloring pipeline, then reports
whether the coloring is valid:
python validate.pyDuring region detection, backend/image_processing.py writes the current label
matrix to output.txt for debugging.