Software engineer in Tunis. I build whole products — the architecture, the model, and the interface that carries them. Founder of GeoSoul.
A Tunisian fashion platform where anyone designs a garment in 3D in the browser, publishes it, and earns on every sale. No stock, no packing, nothing upfront. I founded it, and I built the 3D.
Cache the bytes, not the scene
I did not model these garments, so the obvious lever — lighter meshes — was never mine to pull. The catalogue was 227 MB of GLB; a single t-shirt was 47 MB of it.
Draco took the catalogue to 17 MB and that t-shirt to 4.8. But compression only fixes the wire. The decoder undoes it on arrival: 4.8 MB becomes 73.4 MB of buffers, 1.79 million triangles, 251 ms of work — for one garment.
So I used the lever I had. Cache the compressed bytes, decode on demand, dispose the previous model before building the next. Thirteen garments in the catalogue, one ever resident.
And this is a workaround, not the fix. The real optimisation is lighter geometry, and that work is next. The two compound: together they reach far below where either lands alone.
Tick8ing in Tunis — formerly DevYourApp, the engineering arm of cyber-web.be in Belgium. Two years as its frontend engineer, on two products either side of one platform.
A Tunisian insurer’s claim forms arrive as photographs of paper — half printed, half filled in by hand at the roadside, on a bonnet, in whatever light there was. Until this, an agent typed every field off the paper by hand. I built the pipeline that reads them instead, and the platform around it.
01 — the data
There was no dataset. So I manufactured one.
This was the first AI project the company had ever run, and the digitisation everyone assumed had already happened had not. No archive of filled forms, no labels, no precedent to copy. What I was handed on day one was a model to train and a blank constat amiable.
So I scanned the paper and defined it. Every text field, every checkbox, the two identity blocks, the signature strips, the collision sketch — each one a named class with a known position on the page. That map is the first artefact of the project, and the pipeline is still measuring itself against it three stages later.
Then a generator filled it. Python, OpenCV, Albumentations, PIL: plausible names, addresses, plate numbers and dates set in handwriting faces, boxes ticked at random, a sketch drawn in the accident square. Every sample was written out with its own annotation file, so the labels were exact by construction rather than by hand.
Clean forms would have taught it nothing. Rotation and skew, lighting swings, blur, ink and coffee stains, shadows and reflections, scan noise, a desk behind the page or nothing behind it at all — twelve structural variants per sample, about 4,600 images, split 70 / 20 / 10.


02 — the detections
A trained model is not a working one.
YOLO with oriented boxes, trained on that set, validates at precision 0.82, recall 0.90, mAP50 0.88. Respectable numbers. Then you hand it a photograph taken at the roadside and it returns the mess on the left: the same field claimed three times, boxes tilted off their rows, confidences in the forties, detections drifting out into the margin.
Raw detectionsAfter the penalty passDrag to compare
The fix was to use the one thing the model cannot see — that this is a fixed document. Every field’s position is already known, from the map built in the first pass. So the photograph is fitted to that template, and each detection is scored on how far its centre has drifted from where its field has to be.
The penalty is exponential, so it grows faster the farther out you go. A box slightly off its row is nudged; a box in the wrong section is destroyed.
d = |c_det − c_exp| / √(w² + h²)penalty = exp(5·d) − 1score = clamp(2 − 5·penalty, 0.3, 2.0)conf_adj = conf × scoreA well-placed detection is boosted up to ×2. A stray one is cut to ×0.3.Then group by class, sort by adjusted confidence, keep exactly one. The duplicates collapse, and what survives is what was in the right place all along.
03 — the reading
The budget was zero, so the engine had to be free.
Not a small budget — zero. And nobody writes an OCR engine from scratch inside six months, so the field was whatever cost nothing. I ran four of them over the same crops rather than taking anyone’s word for it.
SpaceOCR won every column by a distance: 6% character error against EasyOCR’s 28, and the fastest of the four. That is what shipped. But 6% is measured over the whole document, and the whole document is mostly print — the handwriting is where the errors live, and the handwriting is the part that matters.
So the output is treated as a signal, not an answer. Rules typed by field: a date is JJ/MM/AAAA or it is wrong, a plate has a shape, a leading digit that only exists because the field’s printed rule was read as a 1 comes off. Required fields validated rather than assumed. And every address round-tripped through the Google Maps API — which is what turns Toris Sidi Hossine back into Sidi Hassine.
Same crops, four engines
| Engine | CER | WER | F1 | ms/img |
|---|---|---|---|---|
| EasyOCR | 28% | 35% | 70 | 210 |
| Tesseract | 32% | 40% | 65 | 180 |
| SpaceOCRshipped | 6% | 10% | 92 | 140 |
| TrOCR | 25% | 32% | 68 | 160 |
What the rules recover
"103111/2022""03/11/2022""12019""2019"".5049TU217""5049 TUN 217""Toris Sidi Hossine""Sidi Hassine, Tunisia""Hassine\n9. Identita""Hassine""ger de A ou B)\nsed un o nidos n.s abubinos""" droppedFail processing and the claim is rejected before an agent opens it. Pass, and it is assigned — the agent can send it back for more, and closes it either way.
A global marketplace for travel itineraries: build a multi-day route, publish it, sell it. I designed the architecture from the concept up, led every phase of development, and it scaled into a UK-registered company.
Software engineer in Tunis, computer-engineering degree from Esprit, specialised in software architecture. The part that matters is what has shipped: a founded product running custom WebGL in production, an end-to-end computer-vision pipeline for an insurer, and two years on a ticketing platform that venues across Belgium sell through.
I work across the whole stack, and I care most about the seam where engineering becomes something you can feel — the frame budget, the gesture, the moment a model turns into an interface.
Frontend engineer at Tick8ing in Tunis, two years in — formerly DevYourApp, the engineering arm of cyber-web.be in Belgium. Angular on the platform; Python on the model-training and IoT missions beside it.
A product to build, a model to ship, or an interface that has to feel like something. Write to me.
