Overview
simple_image_ai holds the AI helpers for simple_image, running ONNX models through simple_onnx. It is pure Eiffel: no Python at run time.
Its first helper is a person cutout: a mask of the people in a photo, from u2net_human_seg,
the model rembg uses.
Part of the Simple Eiffel ecosystem.
Quick Start
Installation
- Set the environment variable:
export SIMPLE_EIFFEL=/d/prod - Add to your ECF file:
<library name="simple_image_ai" location="$SIMPLE_EIFFEL/simple_image_ai/simple_image_ai.ecf"/>
Cut Out a Person and Add a Glow
local
ai: SIMPLE_IMAGE_AI
do
create ai.make
cutout := ai.new_cutout (ai.rembg_model_path) -- loads in about 2 seconds; keep it
if cutout.is_ready and then attached cutout.cut_out (photo) as al_person then
glow := al_person.alpha
glow.grow (6)
glow.blur (10)
canvas.fill_through (glow, 0xFFFFD34D, 0, 0)
canvas.place (al_person, 0, 0)
else
print (cutout.last_error)
end
end
The model file is expected at %USERPROFILE%\.rembg\models\u2net_human_seg\u2net_human_seg.onnx,
where rembg keeps it. The ONNX Runtime DLL must be on the PATH.
Key Features
Person Mask
mask_for gives an IMG_MASK of the people in a photo, the same size as the photo.
Person Cutout
cut_out gives a copy with the background transparent: largest piece kept, color under alpha 0 kept.
rembg's Recipe
Lanczos to 320x320, divide by the largest value, mean and standard deviation per channel, channels first.
Pure Eiffel
simple_onnx runs the model; no Python at run time.
Fast
About 260 milliseconds per 1920x1080 frame on the CPU, against 2-3 seconds through Python.
Error Reporting
A missing or unloadable model is reported through last_error; check is_ready.
API Reference
SIMPLE_IMAGE_AI (Facade)
AI helpers for simple_image, on simple_onnx.
Initialization
Ready.
Helpers
A person cutout running the u2net_human_seg model at the path (check is_ready; loading takes about 2 seconds, so keep it).
Model files
Where rembg keeps u2net_human_seg: %USERPROFILE%\.rembg\models\u2net_human_seg\u2net_human_seg.onnx.
IMG_CUTOUT
Person cutout: a mask of the people in a photo, from the u2net_human_seg model on simple_onnx (the model rembg uses).
Initialization
Load the model at the path (about 2 seconds; do it once).
Access
Coverage of the people in the image (same size; 255 = person), or Void (see last_error). Alpha in the image is ignored, as rembg ignores it.
A copy of the image with the people kept and the rest transparent (largest piece only), or Void (see last_error).
Status
Was the model loaded?
Why the model did not load or the last run failed (empty when all is well).
Constants
The model's square input size (320).
Measured Against rembg
On a 1920x1080 video frame, the Eiffel mask was compared with rembg's own mask of the same frame (measured 2026-10-11):
| Measure | Result |
|---|---|
| Intersection over union at 128 | 0.9997 |
| Mean difference | 0.09 levels |
| Largest difference | 8 levels (edge pixels, from resize rounding) |
| Time per frame, Eiffel on the CPU | about 260 milliseconds |
| Time per frame, through Python | 2-3 seconds |
| Model run against Python | matches to 5.4e-7 (debate 01 in simple_image's .eiffel-workflow) |
Testing
/d/prod/ec.sh test -config simple_image_ai.ecf -target simple_image_ai_tests
PATH="/d/prod/simple_onnx/lib/onnxruntime/lib:/d/prod/simple_cairo:$PATH" ./EIFGENs/simple_image_ai_tests/F_code/simple_image_ai.exe
The photo tests need a photo of a person at data/input/person.png and rembg's mask of it at
data/expected/person_mask_rembg.png, made by .eiffel-workflow/evidence/rembg_reference.py
(an evidence tool, not product code). Test photos are never committed; without them those tests
print SKIPPED.
Dependencies
- simple_image
- simple_onnx (with input staged in C memory, 2026-10-11)
- The ONNX Runtime DLL on the
PATH - The model file (
u2net_human_seg.onnx)