An extension/pipeline to “My Text in Your Handwriting” by 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
mtyhfolder.
Note: This is not a full installation guide for the original project. For setup, see: My Text in Your Handwriting (HELIT)
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
-
Ubuntu 20.04.6 LTS (WSL2) — newer Ubuntu versions gave me issues with GTK/Python2 and inline C compilation.
-
Python 2.7 runtime with:
python-gi,gir1.2-gtk-3.0(GTK bindings)python-cairopython2-dev/python-dev,build-essentialnumpy==1.16.6,scipy==0.19.1(providesscipy.weave)
-
If you hit missing imports (
gi,cairo,weave), install the packages above and re-run. -
Use system Python 2 (not a Python 3 venv) for the LET/HST tools.
Running python2 main.py in helit/handwriting/let failed with:
ImportError: .../line_graph_c.so: undefined symbol: HalfToEdge
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.
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));
}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.
-
Write & Scan
- Handwrite samples on the training paper.
- Scan the pages (recommended: 300–600 DPI).
-
Clean Scans
- Open scans in GIMP (or similar).
- add guide dots
- Run Remove yellow filter 2x minimum
-
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/
-
Launch Tagging GUI
- Open the Tagging GUI and annotate the split samples.
-
Format Target Text
- Open the Text Formatter.
- Format the text you want to generate
-
Synthesis GUI
- Open the Synthesis GUI.
- Paste the formatted text.
- Load LineGraph and related models/resources.
- Run synthesis and save the output images.
-
Make Printable Sheets
- Import the synthesized images into the Image → Printable GUI.
- Generate printable pages (with guide lines).
- Print the final output.
- The paper is lined and printed in yellow so the Remove Yellow Lines filter can cleanly erase the guides after scanning.
- Download:
- Google Doc: https://docs.google.com/document/d/1u1kvDfMi5yQU8kDDmUCosf0y4eZML-CktD-G0D4UOqk/edit?usp=sharing
- Or use the copy included in this repo.
Print at 100% scale on Letter/A4.
-
Open Scanned Sheet
- Open your scanned training sheet in an image editor (e.g., GIMP).
- Recommended scan: 300–600 DPI, full color.
-
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.
-
Remove Yellow Lines
- Run the “Remove Yellow Lines” filter twice.
- This clears the guide lines while keeping your handwriting intact.
-
Run the Macro Cutter
- Launch the macro i provided note(name and counter have to be configured in python file)
- 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).
-
Export and Import
- Save all processed line images.
- Import the resulting dataset into your Ubuntu environment for tagging and training.
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.
- 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.
- 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 of a text generated )
(text with added lines and formated)
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






