--- license: cc-by-nc-4.0 language: - tr library_name: keras pipeline_tag: image-to-text tags: - ocr - text-recognition - turkish - tinyml - tflite - int8 - crnn - ctc - microcontroller --- # erdem-ocr: Turkish line OCR for microcontrollers > **Newer version:** [inviolus/InviolusOCR](https://huggingface.co/inviolus/InviolusOCR) (2026-10-31) is smaller and its int8 file reads 78% of held-out lines exactly instead of 33%. A compact CNN + BiLSTM + CTC recognizer for **one cropped line of printed Turkish text**, built to eventually run on a microcontroller-class device. It ships as a float Keras model and a **full-int8 TensorFlow Lite** model (~650 KB). > **Türkçe özet:** Mikrodenetleyiciler için tasarlanmış, tek satır basılı > Türkçe metni okuyan küçük bir OCR modeli (yaklaşık 631 bin parametre, > int8 TFLite dosyası yaklaşık 650 KB). Ticari olmayan kullanım içindir > (CC BY-NC 4.0). ## Files | File | What it is | |---|---| | `erdem_ocr.keras` | Float recognition model, input `(batch, 32, 160, 1)`, output `(batch, 40, 90)` softmax | | `erdem_ocr_int8.tflite` | Full-int8 export, static batch 1, input `[1, 32, 160, 1]` int8, output `[1, 40, 90]` int8 | | `alphabet.json` | Character set and blank index used to decode the output | ## Model - **Input:** one horizontal text line, grayscale, resized to 160×32 (width×height), scaled to `[-1, 1]` (`pixel / 127.5 - 1`). - **Architecture:** 4 conv + batch-norm + pool blocks, 2 × bidirectional LSTM (96 units), dense softmax. 631,226 parameters. - **Output:** 40 timesteps × 90 classes. Class `0` is padding (never predicted), classes `1..88` are the characters of `alphabet.json` in order, class `89` is the CTC blank. - **Character set:** digits, ASCII letters, `ç ğ ı İ ö ş ü Ç Ğ Ö Ş Ü`, space and `.,:;!?-_/()'%`. Up to 24 characters per line. - **Decoding:** greedy CTC (argmax per step, collapse repeats, drop blanks). - **int8 quantization:** input scale `0.00784`, zero point `-1`; output scale `0.00390625`, zero point `-128`. - **Not included:** text detection. The model expects a line that has already been cropped. ## Usage ```python import json import numpy as np import tensorflow as tf alphabet = json.load(open("alphabet.json", encoding="utf-8"))["alphabet"] BLANK = len(alphabet) + 1 def preprocess(path): image = tf.io.decode_image(tf.io.read_file(path), channels=1, expand_animations=False) image = tf.image.resize(image, [32, 160]) return (tf.cast(image, tf.float32) / 127.5 - 1.0).numpy() def decode(ids): text, previous = [], None for i in ids: if i != previous and 0 < i < BLANK: text.append(alphabet[i - 1]) previous = i return "".join(text) model = tf.keras.models.load_model("erdem_ocr.keras", compile=False) probabilities = model.predict(preprocess("line.png")[np.newaxis]) print(decode(probabilities[0].argmax(-1))) ``` ## Results Exact-line accuracy (whole line correct) and character error rate (CER) of the float model, on data it was not trained on: | Test set | Samples | Exact line | CER | |---|---:|---:|---:| | TS-TR official test split (real scene text) | 2,078 | 45.33% | 24.17% | | Held-out synthetic + real + Zenodo lines | 3,234 | 58.23% | 12.61% | | of which Zenodo (clean printed lines) | 200 | 91.00% | 1.61% | | Small real-photo test set | 66 | 19.70% | 50.21% | **int8 TFLite model:** on the 3,993-row held-out split it reads **10.5%** of lines exactly (CER 21.7%), against 55.7% for the float model. The quantization loss is large and unresolved, so treat the `.tflite` file as an experimental export. ## Limitations - Printed text only; no handwriting, curved text or full pages. - Works best on clean, high-contrast lines; real scene text is still weak. - The int8 model loses most of the float model's accuracy (see above). - Text detection and line cropping must be done before this model runs. ## Training data - Synthetic Turkish lines rendered from a 50k-word Turkish word list in several fonts, with blur, noise and perspective changes. - [Turkish Scene Text Recognition (TS-TR)](https://www.kaggle.com/datasets/serdaryildiz/turkish-scene-text-recognition-dataset), Serdar Yıldız, CC BY-NC 4.0. - [Turkish OCR Text Image Dataset](https://zenodo.org/records/21923181), Zenodo, CC BY 4.0. - A small number of the author's own photographs of printed text. Training/validation splits are group-disjoint (no font, background or source group appears in both). ## License Because the training data includes TS-TR (CC BY-NC 4.0), this model is released under **[Creative Commons Attribution-NonCommercial 4.0](https://creativecommons.org/licenses/by-nc/4.0/)**: - You may use, share and adapt the model for **non-commercial** purposes. - You must credit this model and the datasets listed above. - Commercial use is not permitted. The training code is MIT-licensed: [ErdemWilkinson/InviolusOCR](https://github.com/ErdemWilkinson/InviolusOCR). ## Version Trained 2026-10-09. Later versions of this model score higher (65% exact on TS-TR) but were trained with a dataset whose license is not stated, so they are not published here.