DONGMIN02/READING-TRACE-GAZE
0
Reading Trace — L2CS gaze service (Method A)
The YAML block above is for Hugging Face Spaces (Docker SDK, port 7860). It is ignored elsewhere.
A tiny WebSocket service that runs [L2CS-Net](https://github.com/Ahmednull/L2CS-Net) (appearance-based 3D gaze estimation) on incoming webcam frames and returns gaze angles. The browser (lib/gaze/l2csRemoteTracker.ts) fits a linear model from the 9-point calibration to map those angles → a screen coordinate.
browser --binary JPEG (320×240, ~15 fps)--> /ws
server --JSON-----------------------------> {"yaw": rad, "pitch": rad, "fx": 0..1, "fy": 0..1, "faces": n}Privacy: unlike WebGazer / WebEyeTrack, this mode sends camera frames off the device to this server. The app discloses that when the L2CS engine is active. Host it yourself; don't point it at an untrusted server.
Run locally
cd server
python -m venv .venv && . .venv/Scripts/activate # PowerShell: .venv\Scripts\Activate.ps1
pip install -r requirements.txt
python download_weights.py # ~90 MB into ./models/
uvicorn main:app --host 0.0.0.0 --port 7860Check: curl http://localhost:7860/health → {"status":"ok",...}. Then run the web app with:
NEXT_PUBLIC_GAZE_ENGINE=l2cs
NEXT_PUBLIC_L2CS_URL=ws://localhost:7860/wsDeploy
Hugging Face Space (Docker) — easiest
- Create a Docker Space.
- Push this
server/folder as the Space repo root (Dockerfileat root). - Space builds; the model is baked in during build.
- Endpoint:
wss://<user>-<space>.hf.space/ws. - For anything more than light demo use, upgrade the Space hardware to a T4.
Railway / Render / Fly.io
Point the service at this folder; they detect the Dockerfile and inject $PORT. Endpoint: wss://<your-app>/ws.
Then set the web app env (Vercel)
vercel env add NEXT_PUBLIC_GAZE_ENGINE production # value: l2cs
vercel env add NEXT_PUBLIC_L2CS_URL production # value: wss://<host>/ws
vercel deploy --prodIf NEXT_PUBLIC_L2CS_URL is unset or the socket fails, the app automatically falls back to WebGazer.
Notes / tuning
- Face detector:
l2cs-net'sPipelineuses RetinaFace by default. On CPU expect ~5–10 fps; the browser caps sending at ~15 fps and waits for each reply, so it self-throttles. - Weights link rot: override with
L2CS_WEIGHTS_URL(direct) orL2CS_GDRIVE_ID, or dropL2CSNet_gaze360.pklintoserver/models/by hand. - Accuracy ceiling: L2CS gives a robust gaze direction; screen-pixel accuracy still depends on head distance + calibration. Expect it to beat WebGazer mainly on head-movement robustness, not to be pixel-perfect.
