askakalsky commited on
Commit
5de5b2e
·
verified ·
1 Parent(s): 406bb7f

Upload README.md with huggingface_hub

Browse files
Files changed (1) hide show
  1. README.md +111 -0
README.md ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Ukrainian Passport Series/Number OCR
2
+
3
+ Automatic recognition of the series and number from Ukrainian internal passports (старого зразка).
4
+
5
+ The system reads the dot-matrix perforated 8-character string — **2 Cyrillic letters + 6 digits** — from a full passport photo.
6
+
7
+ ```
8
+ НР 430098
9
+ ^^─────── series (one of: А В Е К М Н О Р С Т И Ю)
10
+ ^^^^^^ number (6 digits)
11
+ ```
12
+
13
+ ---
14
+
15
+ ## Pipeline
16
+
17
+ ```
18
+ passport image
19
+
20
+
21
+ YOLO detector ← finds the dotted strip (class: "Dotted")
22
+
23
+
24
+ preprocessing ← grayscale → denoise → Otsu binarisation
25
+
26
+
27
+ CRNN recognizer ← CNN + biGRU + 8 position heads → "НР430098"
28
+
29
+
30
+ {"series": "НР", "number": "430098", "confidence": 0.97}
31
+ ```
32
+
33
+ ---
34
+
35
+ ## Quick start
36
+
37
+ ```bash
38
+ pip install -r requirements.txt
39
+
40
+ python pipeline.py passport.jpg
41
+ python pipeline.py passport.jpg --show
42
+ ```
43
+
44
+ Output:
45
+ ```
46
+ Result: НР430098
47
+ Series: НР
48
+ Number: 430098
49
+ Confidence: 97.3% [OK]
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Python API
55
+
56
+ ```python
57
+ from pipeline import PassportOCR
58
+
59
+ ocr = PassportOCR()
60
+ result = ocr("passport.jpg")
61
+
62
+ print(result["full"]) # "НР430098"
63
+ print(result["series"]) # "НР"
64
+ print(result["number"]) # "430098"
65
+ print(result["confidence"]) # 0.9734
66
+ print(result["readable"]) # True
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Models
72
+
73
+ | Model | Architecture | Purpose |
74
+ |-------|-------------|---------|
75
+ | `models/detector.pt` | YOLOv8n fine-tuned | Locates the dotted strip on the passport page |
76
+ | `models/recognizer.pth` | CNN + biGRU | Reads the 8-character string from the strip |
77
+
78
+ The recognizer is trained on **80 000 synthetic images** generated with a custom dot-matrix Cyrillic font, with heavy augmentation (rotation ±20°, perspective, noise, donut dots, shadow stripes, inversion).
79
+
80
+ Val character accuracy: **96.1%** | Full-string accuracy on real passports: **~95%**
81
+
82
+ ---
83
+
84
+ ## Training
85
+
86
+ ```bash
87
+ # Generate synthetic training data
88
+ cd train
89
+ python generate_sequences.py --n-samples 80000
90
+
91
+ # Train the recognizer
92
+ python train_sequence.py --epochs 35 --batch-size 64
93
+ ```
94
+
95
+ To retrain the YOLO detector, annotate passport images with the "Dotted" class and run standard YOLOv8 training.
96
+
97
+ ---
98
+
99
+ ## Series letters
100
+
101
+ Valid Ukrainian passport series letters: `А В Е К М Н О Р С Т И Ю`
102
+
103
+ The model enforces positional constraints: positions 0–1 accept only series letters, positions 2–7 accept only digits.
104
+
105
+ ---
106
+
107
+ ## Limitations
108
+
109
+ - Works on Ukrainian **internal** passports (старого зразка, до 2016 року)
110
+ - Requires the dot-matrix strip to be visible and not heavily physically damaged
111
+ - Very low contrast or extreme blur may result in `readable: False`