Skip to content

Repository files navigation

Handwriting-formatting-pipeline

An extension/pipeline to “My Text in Your Handwriting” by Tom Haines (thaines). Includes text formatting, limited Unicode→ASCII support, a print-formatting pipeline, and training-data processing macros/utils — plus a recommended training sheet.

MTYH app note: The repository's tools are also combined into the single Windows desktop app in the mtyh folder.

AUTO workflow: The MTYH sidebar now includes an AUTO page that formats the original text with the current formatter settings, runs HST headlessly one section at a time, and creates the final printable PDF. Generated page images use the chosen prefix and are removed after a successful PDF export.

Note: This is not a full installation guide for the original project. For setup, see: My Text in Your Handwriting (HELIT)


Modernized and optimized HELIT/HST source

The complete improved source is available in this repository's modern-hst branch. It modernizes the original HELIT handwriting tools for Ubuntu 24.04/WSL2, moves the active HST and LET paths from Python 2 to Python 3, and substantially speeds up handwriting line generation and image export.

The optimized compositor processes active pixels instead of repeatedly scanning the entire page, uses bounded allocations and cropped graph-cut workloads, adds OpenMP to suitable page-sized loops, and caches parsed PLY data and textures. On the validated synthetic 5411 × 5168 benchmark, total compositor time fell from 1.695 s to 0.190 s (8.9× faster), while peak memory fell from 1625 MiB to 362 MiB. The golden compositor test produced byte-for-byte identical output.

  • Read the full technical notes and benchmark in MODERNIZATION.txt.
  • Use scripts/install_ubuntu24.sh for a fresh Ubuntu 24.04 setup.
  • Launch the modern tools with scripts/launch_synthesis.sh and scripts/launch_annotation.sh, then run scripts/verify_modern.sh to verify the installation.

The Ubuntu 20.04/Python 2 notes below are retained as a legacy reference for the original upstream workflow.


Demo Video

Watch a full demonstration of the handwriting formatting and synthesis pipeline:

🎥 Demo Video: can be found in the assets folder

The demo walks through:

  • Formatting and synthesizing text
  • Generating printable pages

Legacy Ubuntu 20.04/Python 2 tips (what worked for me)

  1. Ubuntu 20.04.6 LTS (WSL2) — newer Ubuntu versions gave me issues with GTK/Python2 and inline C compilation.

  2. Python 2.7 runtime with:

    • python-gi, gir1.2-gtk-3.0 (GTK bindings)
    • python-cairo
    • python2-dev / python-dev, build-essential
    • numpy==1.16.6, scipy==0.19.1 (provides scipy.weave)
  3. If you hit missing imports (gi, cairo, weave), install the packages above and re-run.

  4. Use system Python 2 (not a Python 3 venv) for the LET/HST tools.


Build notes & fixes

Symptom

Running python2 main.py in helit/handwriting/let failed with:

ImportError: .../line_graph_c.so: undefined symbol: HalfToEdge

Cause

HalfToEdge was defined twice:

  • Correct, inline definition in helit/handwriting/let/line_graph/line_graph_c.h
  • A duplicate/conflicting definition left in helit/handwriting/let/line_graph/line_graph_c.c (≈ line 5935)

This duplicate caused compile/link/runtime symbol issues.

Fix (single source change)

Remove the duplicate from line_graph_c.c and rely on the header’s inline version.

Before (❌ in .c, around ~5935):

// line_graph_c.c — this should NOT exist here
Edge * HalfToEdge(HalfEdge * half) {
    return half ? half->edge : NULL;
}

After (✅ keep only in .h):

// line_graph_c.h — canonical definition
inline Edge * HalfToEdge(HalfEdge * half)
{
    if (half->reverse < half) half = half->reverse;
    return (Edge*)(void*)((char*)(void*)half - offsetof(Edge, pos));
}

Result

  • LET (Line Extraction & Tagging) launches and runs on Ubuntu 20.04.6 LTS with Python 2.7.
  • No other source edits were needed beyond removing the duplicate function.

Pipeline (end-to-end)

  1. Write & Scan

    • Handwrite samples on the training paper.
    • Scan the pages (recommended: 300–600 DPI).
  2. Clean Scans

    • Open scans in GIMP (or similar).
    • Add guide dots.
    • Run the Remove Yellow Lines filter at least twice.
  3. Split Training Data

    • Use the Training Data Splitter to cut pages into line/word samples.
    • Save outputs into a working directory, e.g.:
      ubuntu:/example/training-data/
      
  4. Launch Tagging GUI

    • Open the Tagging GUI and annotate the split samples.
  5. Format Target Text

    • Open the Text Formatter.
    • Format the text you want to generate.
  6. Synthesis GUI

    • Open the Synthesis GUI.
    • Paste the formatted text.
    • Load LineGraph and related models/resources.
    • Run synthesis and save the output images.
  7. Make Printable Sheets

    • Import the synthesized images into the Image → Printable GUI.
    • Generate printable pages (with guide lines).
    • Print the final output.

The manual steps above are still available. For the automated route, open AUTO in MTYH, paste the unformatted text, enter an image prefix and final PDF name, then click Run Automatic Workflow. AUTO uses the live Text Formatter and Stitch Export settings, loads every .line_graph from the configured Examples folder (not Style), saves temporary pages under output images/AUTO, and writes the result under for printing/AUTO. Zero-overlap PDF exports are streamed page by page to keep large batches substantially lighter on memory.

Training Paper

Print at 100% scale on Letter/A4.

Training paper preview

Cutting & Processing Raw Data

  1. Open Scanned Sheet

    • Open your scanned training sheet in an image editor (e.g., GIMP).
    • Recommended scan: 300–600 DPI, full color.
  2. Add Black Reference Dots

    • Place small black dots at both ends of each yellow line.
    • These dots serve as reference points after the yellow lines are removed.
  3. Remove Yellow Lines

    • Run the “Remove Yellow Lines” filter twice.
    • This clears the guide lines while keeping your handwriting intact.
  4. Run the Macro Cutter

    • Launch the provided macro. Configure its output name and counter in the Python file first.
    • Cut every two yellow boxes — each cut should contain one full line of written text.
    • Make sure the black reference dots remain in the cropped images (used later for alignment).
  5. Export and Import

    • Save all processed line images.
    • Import the resulting dataset into your Ubuntu environment for tagging and training.

Example

Yellow line cleanup and cutting example


Annotating (how I did it)

I couldn’t follow the YouTube walkthrough from Thaines at first and burned ~30 lines of data. Here’s the approach that finally worked for me.

  • Leading underscores for spaced-onset letters

    • If a letter begins after a space, add a leading underscore before that letter and keep the entire cursive connector on the front of the letter (but not the back).
    • Example (word start and word end):
      marton_marton_
  • Word-final handling

    • Mirror the rule at the end of the word: keep the trailing connector fully with the ending letter, then add an underscore after it (see example above).
  • Capitals

    • Capitals only work well if they’re connected to the rest of the word by the baseline/connector.
    • Practical tip: write your capitals in cursive so the M (for example) connects to the rest of arton. Otherwise the model has trouble learning the glyph transitions.
  • Manual vs. auto-annotate

    • I don’t recommend the auto-annotate for this setup. It likely works for some, but I got better quality by doing it manually and keeping a smaller, higher-quality glyph set.
  • What this yielded for me

    • After 25 hours of manual annotation (~100–120 LineGraphs, including capitals, letters, and symbols), my dataset could generate in Spanish, English, Catalan, and French.

Text Formatter & Image→Printable (notes)

  • These tools are tuned to what worked for my handwriting. You may need to adjust:
    • In the Synthesis GUI: line height and related attributes.
    • In the Text Formatter script: desired letters/words per line.
  • Don’t be surprised if your outputs look off initially—tweak spacing and line metrics to match your writing size.

Notes on Letter/Unicode Support

  • Currently the pipeline supports ASCII only (no direct Unicode), so characters like à aren’t natively handled.
  • Temporary workaround: I use a mapping key that substitutes ASCII symbols for those letters during formatting.
  • Future plan: contribute common accented-letter support (e.g., à/á/è/é/ñ/ç) upstream in the main project.

Example: Before vs. After Processing

Current Settings

Raw image 1
Raw image 2
Raw image 3


Before

(Example of generated text)

Before processing


After

(Text with added lines and formatting)

After processing


Ethical Use Note

This project and its extensions are intended solely for personal, educational, and research use — for studying handwriting synthesis, data formatting, and text rendering workflows.

Please use responsibly and avoid:

  • Reproducing or mimicking another person’s handwriting without their explicit consent
  • Using generated handwriting to forge, deceive, or impersonate individuals
  • Distributing trained models or datasets that contain private or copyrighted content

Always respect data privacy, authorship, and the ethical guidelines of your institution or community.
The goal is to explore technology creatively and transparently — not to mislead or exploit.

Contact: mailto:martonvegh2009@gmail.com

About

Optimized Ubuntu pipeline for Tom Haines's My Text in Your Handwriting, with faster synthesis, text formatting, training-data tools, and printable PDF export.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages