arpita-sethii commited on
Commit
6709ff1
Β·
1 Parent(s): 2e7c80f

Add pinned versions and step-by-step run guide

Browse files
Files changed (2) hide show
  1. README.md +175 -0
  2. requirements.txt +51 -0
README.md ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ tags:
4
+ - eye-tracking
5
+ - gaze-estimation
6
+ - computer-vision
7
+ - onnx
8
+ - ux-research
9
+ library_name: onnx
10
+ pipeline_tag: image-classification
11
+ ---
12
+
13
+ # InsightUX β€” Webcam Eye-Tracking UX Research Browser
14
+
15
+ A webcam-based gaze tracking system that turns any consumer laptop into a UX
16
+ research tool. Browse a website, and get back a heatmap, an attention timeline,
17
+ and a ranked list of which page elements actually held your gaze.
18
+
19
+ No specialist hardware β€” just a webcam.
20
+
21
+ **This is a local desktop app, not a hosted demo.** It needs a physical
22
+ webcam, a native window, and full-screen capture β€” none of which exist on a
23
+ server, so it cannot run as a Hugging Face Space. Clone it and run it on your
24
+ own machine.
25
+
26
+ ## Requirements before you start
27
+
28
+ - **Windows** (uses WebView2 via pywebview's WinForms backend)
29
+ - **Python 3.11 exactly** β€” mediapipe's legacy face-mesh API this project
30
+ depends on does not exist on Python 3.12+
31
+ - A working webcam
32
+
33
+ ## How to run β€” step by step
34
+
35
+ ### 1. Clone the repo
36
+
37
+ ```bash
38
+ git clone https://huggingface.co/<your-username>/insightux
39
+ cd insightux
40
+ ```
41
+
42
+ ### 2. Create and activate a virtual environment
43
+
44
+ ```bash
45
+ python -m venv venv
46
+ venv\Scripts\activate
47
+ ```
48
+
49
+ ### 3. Install dependencies β€” use the pinned versions
50
+
51
+ ```bash
52
+ pip install -r requirements.txt
53
+ ```
54
+
55
+ **Do not `pip install --upgrade` pywebview or pythonnet.** `requirements.txt`
56
+ pins `pywebview==4.4.1` and `pythonnet==3.0.3` deliberately β€” newer versions
57
+ have a bug in their Windows backend that freezes the app window and floods
58
+ the console with:
59
+ ```
60
+ AccessibilityObject.Bounds.Empty.Empty.Empty.Empty...
61
+ ```
62
+ If you already have a newer version installed globally, this install step
63
+ will replace it with the working one.
64
+
65
+ ### 4. Calibrate β€” required, per person, per setup
66
+
67
+ ```bash
68
+ python calibrate.py
69
+ ```
70
+ Sit normally at your usual distance from the screen, look at each of the 16
71
+ dots as they appear. Takes about a minute. This is **per-person and
72
+ per-setup** β€” your eyes, your camera, your screen size. Everyone using this
73
+ must run it themselves; it is not something you can copy from someone else.
74
+
75
+ Re-run it if your lighting, seating position, or camera position changes
76
+ noticeably.
77
+
78
+ At the end it prints an honest quality readout, including whether the model
79
+ can actually see where you're looking on each axis:
80
+ ```
81
+ HORIZONTAL yaw vs screen-X : r = +0.995
82
+ VERTICAL pitch vs screen-Y: r = +0.883
83
+ ```
84
+ If either number is low, the report will say so plainly and explain why β€”
85
+ that means the model isn't seeing that axis, and no amount of recalibrating
86
+ will fix it.
87
+
88
+ ### 5. (Optional) Check your accuracy
89
+
90
+ ```bash
91
+ python validate.py
92
+ ```
93
+ Flashes 9 test dots and reports your real error in pixels. Good for knowing
94
+ what to expect before relying on a session.
95
+
96
+ ### 6. Run the browser
97
+
98
+ ```bash
99
+ python browser_session.py
100
+ ```
101
+ - Opens on an InsightUX-branded search page. Type a search term (goes to
102
+ real Google results) or a URL (goes straight there).
103
+ - Land on the page you want to study, **click on blank space on the page**
104
+ (not a text field), then press **S** to start eye-tracking.
105
+ - Press **E** to stop. A full report β€” heatmap over real screenshots,
106
+ ranked attention list, dwell timeline β€” generates and opens automatically.
107
+
108
+ ## What's in this repo
109
+
110
+ | File | Purpose |
111
+ |---|---|
112
+ | `models/gaze_cnn_v4.onnx` (+ `.onnx.data`) | Binocular gaze CNN (EfficientNet-B0 backbone, dual eye patches + head pose) |
113
+ | `models/model_v4.py` | Model architecture definition, used during calibration fine-tuning |
114
+ | `checkpoints/best_model_v4.pt` | PyTorch checkpoint for fine-tuning |
115
+ | `calibrate.py` | Per-user calibration β€” 16-point, live blink/lighting rejection, honest quality report |
116
+ | `validate.py` | Measures real accuracy in pixels after calibration |
117
+ | `browser_session.py` | The research browser β€” search, track, auto-report |
118
+ | `analysis.py` | Builds the session report (heatmaps over real screenshots) |
119
+ | `inference_pipeline.py` | ONNX inference + RBF gaze→screen calibration mapping |
120
+ | `preprocessing/preprocessing_pipeline.py` | Eye patch normalization, head pose estimation, illumination correction |
121
+
122
+ ## Calibration is per-person and per-setup β€” not included in this repo
123
+
124
+ `calibration.pkl` (generated by `calibrate.py`) encodes *your* eye geometry,
125
+ *your* camera characteristics, and *your* screen size. It is deliberately
126
+ **not** in this repo β€” it would be useless to anyone else and it's personal
127
+ data. Run `calibrate.py` yourself; it takes about a minute.
128
+
129
+ ## Accuracy β€” honest numbers
130
+
131
+ This is a webcam system, not a Tobii. Expect roughly **5–10% of screen
132
+ diagonal** mean error after a good calibration. That's enough for coarse AOI
133
+ attribution (navbar vs hero vs footer) and heatmaps. It is **not** enough for
134
+ reading-level analysis (which word you're on).
135
+
136
+ Vertical accuracy is typically a bit looser than horizontal β€” looking down
137
+ partially occludes the iris under the eyelid, a physical limit of webcam
138
+ gaze estimation, not a bug. Calibration automatically checks whether eye
139
+ aperture (eyelid closing as you look down) tracks vertical position better
140
+ than the model's raw output, and uses whichever signal is actually stronger.
141
+
142
+ ## Known limitations
143
+
144
+ - Windows-only (pywebview + WebView2 backend). Other platforms untested.
145
+ - Head movement during a session degrades accuracy β€” the calibration assumes
146
+ a roughly stable head pose.
147
+ - No lens distortion correction β€” `solvePnP` assumes zero distortion, which
148
+ costs some accuracy near frame edges.
149
+
150
+ ## Troubleshooting
151
+
152
+ **Window freezes with `AccessibilityObject.Bounds.Empty.Empty.Empty...`
153
+ spamming the console:**
154
+ Confirm you actually have the pinned versions installed, not newer ones:
155
+ ```bash
156
+ pip uninstall pywebview pythonnet -y
157
+ pip install pywebview==4.4.1 pythonnet==3.0.3
158
+ ```
159
+ If it persists after that, turn off **Xbox Game Bar** (Settings β†’ Gaming β†’
160
+ Xbox Game Bar) and any overlay software (Discord overlay, GeForce
161
+ Experience, OBS), then **restart your PC** β€” those hooks stay loaded until a
162
+ real reboot. Last resort: install `PyQt5` + `PyQtWebEngine` (see
163
+ `requirements.txt`) and switch the GUI backend as described there.
164
+
165
+ **"No calibration.pkl found" when pressing S:**
166
+ Run `python calibrate.py` first β€” it must exist before `browser_session.py`
167
+ can track anything.
168
+
169
+ **Can't type in the search box:**
170
+ Click directly into the search field first β€” this can happen if the window
171
+ just opened and hasn't fully grabbed keyboard focus yet.
172
+
173
+ ## License
174
+
175
+ MIT.
requirements.txt ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # =============================================================================
2
+ # InsightUX β€” pinned requirements
3
+ #
4
+ # Python 3.11 is REQUIRED. mediapipe's legacy solutions.face_mesh API (which
5
+ # this project depends on for face landmarks) does not exist on newer
6
+ # mediapipe builds for Python 3.12+.
7
+ #
8
+ # Install with:
9
+ # pip install -r requirements.txt
10
+ # =============================================================================
11
+
12
+ # --- Core CV / inference ---
13
+ opencv-python==4.10.0.84
14
+ mediapipe==0.10.18
15
+ onnxruntime==1.19.2
16
+ numpy==1.26.4
17
+ scipy==1.13.1
18
+ Pillow==10.4.0
19
+
20
+ # --- Screen capture / automation ---
21
+ pyautogui==0.9.54
22
+
23
+ # --- pywebview: PINNED, DO NOT UPGRADE WITHOUT TESTING ---
24
+ # Newer pywebview versions (5.x+) have a bug in their Windows WinForms
25
+ # backend that triggers an infinite recursion walking the window's
26
+ # accessibility tree, freezing the entire window and flooding the console
27
+ # with:
28
+ # AccessibilityObject.Bounds.Empty.Empty.Empty.Empty...
29
+ # These two versions are the confirmed-working combination β€” install exactly
30
+ # these, not "latest":
31
+ pywebview==4.4.1
32
+ pythonnet==3.0.3
33
+
34
+ # --- Optional: calibration fine-tuning ---
35
+ # calibrate.py degrades gracefully and skips fine-tuning if torch is absent,
36
+ # so this is only needed if you want the fine-tuning step during calibration.
37
+ torch==2.4.1
38
+ torchvision==0.19.1
39
+
40
+ # --- Optional fallback GUI backend ---
41
+ # If the pywebview freeze happens even after pinning the versions above
42
+ # (rare β€” usually caused by Xbox Game Bar or another accessibility-hooking
43
+ # overlay app running in the background), install these and change the last
44
+ # line of browser_session.py from:
45
+ # webview.start(debug=True)
46
+ # to:
47
+ # webview.start(gui='qt', debug=True)
48
+ # Qt does not use the buggy WinForms accessibility chain, so this class of
49
+ # freeze cannot happen with it.
50
+ # PyQt5==5.15.10
51
+ # PyQtWebEngine==5.15.6