Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Word Solver CV

An end-to-end computer vision and OCR system that turns an iPhone screenshot of a 5×5 Russian word game into ranked word suggestions.

CI Python 3.12 OpenCV Docker

Watch the 25-second demo · Read the technical article · Русская версия

Word Solver CV end-to-end system architecture

Why this project matters

Word Solver CV is more than an OCR notebook. It connects a real mobile workflow to an image-processing pipeline, a custom search algorithm, and a containerized server:

  1. An iOS Shortcut captures the game screenshot.
  2. A Pythonista client sends the image to the server over a bounded TCP protocol.
  3. OpenCV crops, cleans, sharpens, and splits the board into 25 letter cells.
  4. Tesseract recognizes Russian characters.
  5. A recursive solver prunes impossible branches using dictionary prefixes.
  6. Ranked results return to the iPhone through the same request connection.

The original system was built and published in 2021. This repository preserves that case study while refreshing its runtime, networking, tests, and documentation for reproducibility.

Verified project facts

  • 5×5 board with 25 individually segmented letter cells.
  • 123,509 unique words in the preserved project dictionary.
  • 14-second end-to-end run documented in the original article and demo environment.
  • In one preserved 25-cell test, the selected legacy Tesseract engine mode recognized 100% of cells, compared with 91% for the tested LSTM configuration. This is a project-specific comparison, not a general OCR benchmark.
  • The accompanying 18-minute Habr article showed 9.3K reach when rechecked in July 2026.

Stack

Python · OpenCV · Tesseract OCR · NumPy · TCP sockets · Docker · iOS Shortcuts · Pythonista

How the solver works

For every board position, the solver explores the eight neighboring cells. A cell cannot be reused within one candidate word. Before following a branch, it checks whether the current letter sequence is a prefix of at least one dictionary word. That prefix pruning removes paths that cannot produce a valid result.

The server loads the dictionary once, processes each image in memory, and returns a structured JSON response containing:

  • the 25 recognized letters;
  • words ordered by length and then alphabetically;
  • total word count;
  • server-side processing time.

Quick start with Docker

Requirements: Docker with Compose and Python 3.10+ for the zero-dependency demo client.

git clone https://github.com/voropaevv/words_solver_cv.git
cd words_solver_cv
docker compose up --build

In a second terminal:

python3 client_demo.py

The container is exposed only on 127.0.0.1:50000 by default. This is intentional: the protocol is designed for a trusted local network and does not implement authentication or encryption.

To let an iPhone on the same trusted LAN reach the server:

WORD_SOLVER_BIND_ADDRESS=0.0.0.0 docker compose up --build

Do not expose port 50000 directly to the public internet.

Run directly with Python

Install Tesseract and create a virtual environment:

python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt

The repository includes the exact official Russian model used by the original pipeline. Point Tesseract at it and start the server:

export TESSDATA_PREFIX="$PWD"
python main.py --host 127.0.0.1 --port 50000

Then run python client_demo.py in another terminal.

iPhone and Pythonista setup

  1. Copy client_iphone.py and protocol.py into the same Pythonista directory.
  2. Set SERVER_HOST in client_iphone.py to the trusted LAN address of the server.
  3. Recreate the iOS Shortcut shown below and name it WordsSolverCV.
  4. Start the server with WORD_SOLVER_BIND_ADDRESS=0.0.0.0.

iOS Shortcut flow

The Pythonista script reads the screenshot from the clipboard, sends one framed request, copies the returned words back to the clipboard, and resumes the Shortcut.

Configuration

Environment variable Default Purpose
WORD_SOLVER_HOST 127.0.0.1 Socket host; Compose overrides the container to 0.0.0.0
WORD_SOLVER_PORT 50000 TCP port
WORD_SOLVER_TIMEOUT_SECONDS 30 Per-connection timeout
WORD_SOLVER_MAX_IMAGE_BYTES 10485760 Maximum accepted image frame
WORD_SOLVER_DICTIONARY dictionary/words_rus.txt Dictionary path
WORD_SOLVER_BIND_ADDRESS 127.0.0.1 Host interface published by Docker Compose

Equivalent server CLI flags are available through python main.py --help.

Tests and quality checks

python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements-dev.txt
ruff check .
pytest
docker build -t words-solver-cv:test .

The automated suite covers the prefix-pruned solver, board validation, framing and JSON transport, image preprocessing and 25-cell segmentation, and a structured server response. It combines deterministic OCR doubles with a real 25-cell fixture that runs against the vendored official Russian model.

Repository map

main.py                 TCP server and in-memory request pipeline
protocol.py             bounded length-prefixed transport
cv_recognition.py       OpenCV preprocessing and Tesseract OCR
words_solver.py         board, dictionary, and prefix-pruned search
client_demo.py          zero-dependency desktop demo client
client_iphone.py        Pythonista / iOS Shortcuts client
dictionary/             preserved 123,509-word project dictionary
notebooks/              original algorithm and OCR explorations
explanatory_media/      original architecture, Shortcut, and demo assets
tests/                  deterministic test suite

Historical scope and limitations

  • The crop and cell geometry target the preserved 828×1792 screenshot layout. Supporting other games or screen sizes requires calibration or board detection.
  • The current server is intentionally sequential because the original use case is one personal device on a local network.
  • The server now bounds frames and timeouts, but it does not authenticate clients or encrypt traffic.
  • The word list reflects the rules and sources available in 2021 and still contains entries that would benefit from linguistic cleanup.
  • The repository is a documented portfolio case, not an actively operated game service.

Data and licensing note

No project-wide license is declared yet. The provenance of the aggregated 2021 word list is incomplete, so public availability must not be interpreted as permission to reuse every asset. The vendored rus.traineddata file is an exact copy of the official tesseract-ocr/tessdata Russian model distributed under Apache-2.0. See THIRD_PARTY_NOTICES.md for checksums and boundaries.

Author

Built by Vlad Voropaev.

For the implementation story, design decisions, visual preprocessing stages, and the original measured run, read the full Habr article.

About

End-to-end computer vision and OCR system that turns iPhone screenshots into ranked Russian word candidates using Python, OpenCV, Tesseract, TCP and Docker.

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages