mgamsby-lattice commited on
Commit
91eb9f0
·
verified ·
1 Parent(s): 23c4336

Upload sensAI-Edge-Vision-Engine-SDK with upload_repo.py

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +37 -38
  2. Dockerfile +27 -25
  3. app.py +302 -301
  4. download_examples.py +124 -124
  5. install_eve.py +104 -104
  6. requirements.txt +8 -8
  7. shared/assets/EULA.md +21 -21
  8. shared/eula_tab.py +47 -47
  9. shared/eve_app_tabs.py +276 -276
  10. shared/eve_inference_handlers.py +509 -485
  11. shared/eve_messages.py +257 -231
  12. shared/eve_python/ctypes_enum.py +10 -0
  13. shared/eve_python/eve_sdk.py +388 -297
  14. shared/eve_python/eve_sdk_structs.py +2 -3
  15. shared/eve_python/structs/CAlgorithms.py +27 -27
  16. shared/eve_python/structs/CBasicStructs.py +92 -86
  17. shared/eve_python/structs/CCameraStructs.py +66 -48
  18. shared/eve_python/structs/CDetectionStructs.py +44 -38
  19. shared/eve_python/structs/CFaceData.py +61 -55
  20. shared/eve_python/structs/CFaceIdStructs.py +68 -68
  21. shared/eve_python/structs/CFpgaData.py +350 -350
  22. shared/eve_python/structs/CHandGesture.py +105 -144
  23. shared/eve_python/structs/CImageManipulation.py +12 -12
  24. shared/eve_python/structs/CKarolinska.py +57 -57
  25. shared/eve_python/structs/CLandmarkMaps.py +40 -40
  26. shared/eve_python/structs/CLicenseResult.py +10 -0
  27. shared/eve_python/structs/CROIStructs.py +29 -29
  28. shared/eve_python/structs/CVisualSpeechStructs.py +18 -18
  29. shared/eve_python/structs/EveAlgorithm.py +5 -5
  30. shared/eve_python/structs/EveAlgorithmStructs.py +14 -14
  31. shared/eve_python/structs/EveCallbackReturnData.py +13 -13
  32. shared/eve_python/structs/EveCamera.py +5 -5
  33. shared/eve_python/structs/EveCameraStructs.py +47 -27
  34. shared/eve_python/structs/EveConfigurationParameters.py +45 -36
  35. shared/eve_python/structs/EveControlInterface.py +10 -9
  36. shared/eve_python/structs/EveControlOption.py +8 -8
  37. shared/eve_python/structs/EveErrors.py +26 -22
  38. shared/eve_python/structs/EveFaceId.py +5 -5
  39. shared/eve_python/structs/EveFaceIdStructs.py +31 -31
  40. shared/eve_python/structs/EveFaceTracker.py +5 -5
  41. shared/eve_python/structs/EveFaceTrackerStructs.py +40 -40
  42. shared/eve_python/structs/EveFpga.py +7 -7
  43. shared/eve_python/structs/EveFpgaStructs.py +24 -24
  44. shared/eve_python/structs/EveHandGesture.py +5 -5
  45. shared/eve_python/structs/EveHandGestureStructs.py +35 -48
  46. shared/eve_python/structs/EveImage.py +5 -5
  47. shared/eve_python/structs/EveImageManipulation.py +5 -5
  48. shared/eve_python/structs/EveImageManipulationStructs.py +12 -12
  49. shared/eve_python/structs/EveImageStructs.py +53 -38
  50. shared/eve_python/structs/EveKarolinska.py +5 -5
.gitattributes CHANGED
@@ -1,38 +1,37 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
36
- *.mp4 filter=lfs diff=lfs merge=lfs -text
37
- *.deb filter=lfs diff=lfs merge=lfs -text
38
- examples_fid/example_couple.jpg filter=lfs diff=lfs merge=lfs -text
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ *.mp4 filter=lfs diff=lfs merge=lfs -text
37
+ *.deb filter=lfs diff=lfs merge=lfs -text
 
Dockerfile CHANGED
@@ -1,25 +1,27 @@
1
- # syntax=docker/dockerfile:1
2
- FROM python:3.11
3
-
4
- RUN apt-get update && apt-get install -y ffmpeg libopenblas-dev libopencv-dev qt6-base-dev qt6-multimedia-dev libssl-dev mesa-opencl-icd libboost-all-dev libturbojpeg0-dev ocl-icd-opencl-dev clinfo ocl-icd-libopencl1 && rm -rf /var/lib/apt/lists
5
-
6
- ARG HF_TOKEN=""
7
-
8
- RUN pip install --no-cache-dir huggingface-hub
9
- COPY install_eve.py /tmp/install_eve.py
10
- RUN --mount=type=secret,id=MODEL_ACCESS_TOKEN \
11
- HF_TOKEN="$HF_TOKEN" python /tmp/install_eve.py && rm /tmp/install_eve.py
12
-
13
- RUN useradd -m -u 1000 user
14
- USER user
15
- ENV PATH="/home/user/.local/bin:$PATH"
16
-
17
- WORKDIR /app
18
-
19
- COPY --chown=user ./requirements.txt requirements.txt
20
- RUN pip install --no-cache-dir --upgrade -r requirements.txt
21
-
22
- RUN mkdir -p /home/user/.config
23
-
24
- COPY --chown=user . /app
25
- CMD ["python", "app.py"]
 
 
 
1
+ # syntax=docker/dockerfile:1
2
+ FROM python:3.11
3
+
4
+ RUN apt-get update && apt-get install -y ffmpeg libopenblas-dev libopencv-dev qt6-base-dev qt6-multimedia-dev libssl-dev mesa-opencl-icd libboost-all-dev libturbojpeg0-dev ocl-icd-opencl-dev clinfo ocl-icd-libopencl1 && rm -rf /var/lib/apt/lists
5
+
6
+ ARG HF_TOKEN=""
7
+
8
+ RUN pip install --no-cache-dir huggingface-hub
9
+ COPY install_eve.py /tmp/install_eve.py
10
+ RUN --mount=type=secret,id=MODEL_ACCESS_TOKEN \
11
+ HF_TOKEN="$HF_TOKEN" python /tmp/install_eve.py && rm /tmp/install_eve.py
12
+
13
+ RUN useradd -m -u 1000 user
14
+ USER user
15
+ ENV PATH="/home/user/.local/bin:$PATH"
16
+
17
+ WORKDIR /app
18
+
19
+ COPY --chown=user ./requirements.txt requirements.txt
20
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
21
+
22
+ RUN mkdir -p /home/user/.config
23
+
24
+ COPY --chown=user . /app
25
+ RUN --mount=type=secret,id=MODEL_ACCESS_TOKEN,uid=1000 \
26
+ HF_TOKEN="$HF_TOKEN" python download_examples.py
27
+ CMD ["python", "app.py"]
app.py CHANGED
@@ -1,301 +1,302 @@
1
- import atexit
2
- import os
3
- import sys
4
- from pathlib import Path
5
-
6
- import gradio as gr
7
-
8
- sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent / "shared"))
9
- sys.path.insert(0, str(Path(__file__).resolve().parent / "shared"))
10
-
11
- from env_utils import load_dotenv_if_present, require_secrets
12
- from eula_tab import build_eula_tab
13
- from eve_app_tabs import build_live_inference_tab, build_offline_inference_tab
14
- from eve_inference_handlers import EveAppHandlers, patch_video_for_external_urls
15
- from eve_worker_pool import EveWorkerPool
16
- from face_id_tab import FaceIdTab
17
- from live_inference import (
18
- TAB_SWITCH_AUTO_STOP_JS,
19
- RtcConfigProvider,
20
- patch_aioice_stun_transaction,
21
- patch_aiortc_h264_nvenc,
22
- patch_fastrtc_frame_queue,
23
- patch_fastrtc_yuv420p_output,
24
- )
25
- from live_stream_manager import LiveStreamManager
26
- from log_utils import log_cpu_info, setup_logger
27
- from session_tracker import SessionTracker
28
- from usage_analytics import UsageTracker
29
- from video_file_server import VideoFileServer
30
- from video_processing import VideoLimits, get_example_videos, wire_video_upload
31
-
32
-
33
- def _build_feature_checkboxes(
34
- hint: str = "",
35
- ) -> tuple[gr.Checkbox, gr.Checkbox, gr.Checkbox, gr.Checkbox]:
36
- """Build the EVE feature checkbox group used by both tabs.
37
-
38
- Must be called inside a Gradio layout context.
39
- """
40
- with gr.Group():
41
- label = "<p><b>Features</b>"
42
- if hint:
43
- label += f" — <em>{hint}</em>"
44
- label += "</p>"
45
- gr.HTML(label)
46
- cb_face = gr.Checkbox(label="Face Detection", value=True)
47
- cb_person = gr.Checkbox(label="Person Detection", value=True)
48
- cb_face_id = gr.Checkbox(label="Face Identification", value=False)
49
- cb_hand_gesture = gr.Checkbox(label="Hand Detection", value=False)
50
- return cb_face, cb_person, cb_face_id, cb_hand_gesture
51
-
52
-
53
- if __name__ == "__main__":
54
-
55
- patch_fastrtc_frame_queue()
56
- patch_fastrtc_yuv420p_output()
57
- patch_aioice_stun_transaction()
58
- patch_aiortc_h264_nvenc()
59
-
60
- load_dotenv_if_present()
61
- logger = setup_logger(name="app")
62
- log_cpu_info(logger)
63
- require_secrets("MODEL_ACCESS_TOKEN")
64
-
65
- tracker = UsageTracker(
66
- repo_id=os.environ.get("ANALYTICS_REPO_ID", "LatticeSemi/PRIVATE-Demo-Analytics-v1.0"),
67
- )
68
- tracker.log("server", "server_start")
69
-
70
- max_workers = int(os.environ.get("MAX_WORKERS", os.cpu_count()))
71
- max_ram_gb = float(os.environ.get("MAX_RAM_GB", 32))
72
- pool = EveWorkerPool(max_workers=max_workers, max_ram_gb=max_ram_gb, ram_headroom_gb=2.0)
73
-
74
- # FPS cap: each live stream runs between MAX_TARGET_FPS (idle) and
75
- # MIN_TARGET_FPS (full load). Set either to 0 to disable the cap.
76
- max_fps_raw = float(os.environ.get("MAX_TARGET_FPS", "24"))
77
- min_fps_raw = float(os.environ.get("MIN_TARGET_FPS", "15"))
78
- max_fps: float | None = max_fps_raw if max_fps_raw > 0 else None
79
- min_fps: float | None = min_fps_raw if min_fps_raw > 0 else None
80
-
81
- camera_width = int(os.environ.get("CAMERA_WIDTH", 640))
82
- camera_height = int(os.environ.get("CAMERA_HEIGHT", 360))
83
-
84
- stream_manager = LiveStreamManager(
85
- pool,
86
- session_lifetime_seconds=60 * 4,
87
- max_fps=max_fps,
88
- min_fps=min_fps,
89
- tracker=tracker,
90
- )
91
-
92
- session_tracker = SessionTracker(pool=pool, tracker=tracker, logger=logger)
93
-
94
- # Separate HTTP server for video output — bypasses Chrome's per-origin
95
- # connection limit that blocks /file= requests while SSE connections are open.
96
- video_server: VideoFileServer | None = None
97
- # TODO: Put that under an env var, for debug purposes, locally, for more than 2 tabs.
98
- """if not os.environ.get("SPACE_ID"):
99
- gradio_cache = os.path.join(tempfile.gettempdir(), "gradio")
100
- os.makedirs(gradio_cache, exist_ok=True)
101
- video_server = VideoFileServer(root_dir=gradio_cache, logger=logger)
102
- video_server.start()"""
103
-
104
- handlers = EveAppHandlers(
105
- pool=pool,
106
- stream_manager=stream_manager,
107
- sessions=session_tracker,
108
- logger=logger,
109
- max_fps=max_fps,
110
- min_fps=min_fps,
111
- video_server=video_server,
112
- )
113
-
114
- def _shutdown() -> None:
115
- session_tracker.shutdown()
116
- stream_manager.shutdown()
117
- tracker.log("server", "server_stop")
118
- tracker.shutdown()
119
-
120
- atexit.register(_shutdown)
121
-
122
- EXAMPLE_VIDEOS = get_example_videos()
123
- VIDEO_LIMITS = VideoLimits()
124
- rtc_config_provider = RtcConfigProvider()
125
-
126
- face_id_tab = FaceIdTab(
127
- pool,
128
- max_users=2,
129
- examples_dir="./examples_fid",
130
- accept_video=True,
131
- video_limits=VideoLimits(max_file_size_mb=150, max_duration_seconds=60),
132
- tracker=tracker,
133
- )
134
-
135
- with gr.Blocks(
136
- title="Eve HMI Demo",
137
- theme=gr.themes.Default(
138
- text_size=gr.themes.sizes.text_lg,
139
- primary_hue=gr.themes.colors.yellow,
140
- ),
141
- css=(
142
- f"#webrtc-stream-col {{ max-width: {camera_width}px !important; margin: 0 auto; }}"
143
- " .gradio-container h1, .gradio-container .md h1 { font-size: 2.25rem !important; }"
144
- " .gradio-container h2, .gradio-container .md h2 { font-size: 1.75rem !important; }"
145
- " .gradio-container h3, .gradio-container .md h3 { font-size: 1.4rem !important; }"
146
- " .gradio-container button[role='tab'],"
147
- " .gradio-container button[role='tab'] *"
148
- " { text-decoration: underline !important; }"
149
- " .gradio-container .tab-container {"
150
- " height: auto !important;"
151
- " overflow: visible !important;"
152
- " gap: 4px !important;"
153
- " border-bottom: 2px solid var(--border-color-primary) !important; }"
154
- " .gradio-container .tab-container::after { display: none !important; }"
155
- " .gradio-container button[role='tab'] {"
156
- " height: auto !important;"
157
- " padding: 10px 20px !important;"
158
- " border: 1px solid var(--border-color-primary) !important;"
159
- " border-bottom: none !important;"
160
- " border-radius: 8px 8px 0 0 !important;"
161
- " background: var(--background-fill-secondary) !important;"
162
- " margin-bottom: -2px !important; }"
163
- " .gradio-container button[role='tab'].selected {"
164
- " background: var(--primary-500) !important;"
165
- " color: var(--neutral-950) !important;"
166
- " border-color: var(--primary-500) !important;"
167
- " font-weight: 600 !important; }"
168
- " .gradio-container button[role='tab'].selected::after { display: none !important; }"
169
- ),
170
- head=TAB_SWITCH_AUTO_STOP_JS,
171
- ) as demo:
172
- gr.Markdown("# Lattice sensAI Edge Vision Engine SDK")
173
- gr.Markdown(
174
- "Our SDK solves the human sensing challenges by outputting ready-to-use data."
175
- " Our models have a low computation footprint and are ideal for 0.5-2 TOPS devices"
176
- " like FPGAs, SOCs and small NPUs.\n\n"
177
- # TODO: Insert performance summary table
178
- "To access the EVE SDK, fill the form on this [page](https://huggingface.co/LatticeSemi/sensAI-Edge-Vision-Engine-SDK-Packages) and follow the instructions for download."
179
- " For any questions or support, please reach out to us at evehelp@latticesemi.com.\n\n"
180
- "You can also preview the EVE SDK with the following tabs:\n\n"
181
- "- <u>Live Inference</u> to run it live from your webcam\n"
182
- "- <u>Offline Inference</u> to test it with videos you can upload\n"
183
- "- Use the <u>Face ID Registration</u> tab to register face(s) you can use in either Live or Offline Inference to test the Face ID model.\n\n"
184
- "> Note: For demo purposes, execution of the AI pipeline and image draw operations are all performed on a Hugging Face CPU server. Performance may vary based on the number of concurrent users.\n"
185
- "\n\n"
186
- )
187
-
188
- session_registry = gr.State(value={})
189
- session_hash_state = gr.State(value="unknown")
190
-
191
- with gr.Tabs() as tabs:
192
- (
193
- _live_tab,
194
- webrtc_stream,
195
- (live_cb_face, live_cb_person, live_cb_face_id, live_cb_hand_gesture),
196
- ) = build_live_inference_tab(
197
- rtc_configuration=lambda: rtc_config_provider.get(),
198
- feature_checkbox_builder=_build_feature_checkboxes,
199
- extras_builder=lambda: face_id_tab.build_summary(height=80, scale=1),
200
- max_fps=int(max_fps) if max_fps else 30,
201
- width=camera_width,
202
- height=camera_height,
203
- )
204
-
205
- (
206
- video_tab,
207
- input_video,
208
- output_video,
209
- (cb_face, cb_person, cb_face_id, cb_hand_gesture),
210
- process_btn,
211
- example_dataset,
212
- ) = build_offline_inference_tab(
213
- feature_checkbox_builder=_build_feature_checkboxes,
214
- example_videos=EXAMPLE_VIDEOS,
215
- video_limits=VIDEO_LIMITS,
216
- extras_builder=lambda: face_id_tab.build_summary(height=80, scale=1),
217
- )
218
- patch_video_for_external_urls(output_video)
219
-
220
- face_id_tab.build()
221
-
222
- build_eula_tab()
223
-
224
- if os.environ.get("ENABLE_PROFILER", "").strip() not in ("", "0", "false"):
225
- from profiler_tab import build_profiler_tab
226
-
227
- build_profiler_tab(pool)
228
-
229
- # --- Offline Inference wiring ---
230
- wire_video_upload(input_video, output_video, process_btn, example_dataset, VIDEO_LIMITS)
231
-
232
- process_btn.click(
233
- fn=handlers.run_eve_inference,
234
- inputs=[
235
- input_video,
236
- cb_face,
237
- cb_person,
238
- cb_face_id,
239
- cb_hand_gesture,
240
- session_registry,
241
- ],
242
- outputs=[output_video, session_registry],
243
- concurrency_limit=pool.worker_count,
244
- ).then(
245
- fn=face_id_tab.refresh_all,
246
- inputs=[session_registry],
247
- outputs=face_id_tab.all_slot_components,
248
- )
249
-
250
- # --- Face ID wiring (self-contained in FaceIdTab) ---
251
- face_id_tab.wire(session_registry)
252
-
253
- # Refresh summary thumbnails when switching to tabs that show them
254
- for tab in (video_tab, _live_tab):
255
- tab.select(
256
- fn=face_id_tab.refresh_summary,
257
- inputs=[session_registry],
258
- outputs=face_id_tab.summary_components,
259
- )
260
-
261
- # --- Usage analytics ---
262
- tabs.select(fn=session_tracker.on_tab_switch, inputs=[], outputs=[])
263
-
264
- live_feature_inputs = [live_cb_face, live_cb_person, live_cb_face_id, live_cb_hand_gesture]
265
- for cb in live_feature_inputs:
266
- cb.change(fn=handlers.on_live_feature_change, inputs=live_feature_inputs, outputs=[])
267
-
268
- # --- Live Inference wiring ---
269
- # FastRTC defaults concurrency_limit to 1 which causes Gradio's queue
270
- # to reject new WebRTC connections with "Too many concurrent connections".
271
- # Since process_live_frame is non-blocking (shows an overlay while
272
- # waiting for a worker), we allow MORE streams than workers so that
273
- # queued users see a "waiting" overlay instead of a connection error.
274
- webrtc_stream.stream(
275
- fn=handlers.process_live_frame,
276
- inputs=[
277
- webrtc_stream,
278
- live_cb_face,
279
- live_cb_person,
280
- live_cb_face_id,
281
- live_cb_hand_gesture,
282
- session_registry,
283
- session_hash_state,
284
- ],
285
- outputs=[webrtc_stream],
286
- concurrency_limit=pool.worker_count + 8,
287
- )
288
-
289
- # --- Session tracking ---
290
- demo.load(session_tracker.on_load, outputs=[session_hash_state])
291
- demo.unload(handlers.cleanup_session)
292
-
293
- if tracker.enabled:
294
- gr.HTML(
295
- "<p style='font-size:0.8em;color:#888;text-align:center;margin-top:1em'>"
296
- "This demo collects anonymous usage data (session activity, feature usage) "
297
- "to improve the experience. No personal information is stored.</p>"
298
- )
299
-
300
- demo.queue()
301
- demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
 
 
1
+ import atexit
2
+ import os
3
+ import sys
4
+ from pathlib import Path
5
+
6
+ import gradio as gr
7
+
8
+ APP_DIR = Path(__file__).resolve().parent
9
+ sys.path.insert(0, str(APP_DIR.parent.parent / "shared"))
10
+ sys.path.insert(0, str(APP_DIR / "shared"))
11
+
12
+ from env_utils import load_dotenv_if_present, require_secrets
13
+ from eula_tab import build_eula_tab
14
+ from eve_app_tabs import build_live_inference_tab, build_offline_inference_tab
15
+ from eve_inference_handlers import EveAppHandlers, patch_video_for_external_urls
16
+ from eve_worker_pool import EveWorkerPool
17
+ from face_id_tab import FaceIdTab
18
+ from live_inference import (
19
+ TAB_SWITCH_AUTO_STOP_JS,
20
+ RtcConfigProvider,
21
+ patch_aioice_stun_transaction,
22
+ patch_aiortc_h264_nvenc,
23
+ patch_fastrtc_frame_queue,
24
+ patch_fastrtc_yuv420p_output,
25
+ )
26
+ from live_stream_manager import LiveStreamManager
27
+ from log_utils import log_cpu_info, setup_logger
28
+ from session_tracker import SessionTracker
29
+ from usage_analytics import UsageTracker
30
+ from video_file_server import VideoFileServer
31
+ from video_processing import VideoLimits, get_example_videos, wire_video_upload
32
+
33
+
34
+ def _build_feature_checkboxes(
35
+ hint: str = "",
36
+ ) -> tuple[gr.Checkbox, gr.Checkbox, gr.Checkbox, gr.Checkbox]:
37
+ """Build the EVE feature checkbox group used by both tabs.
38
+
39
+ Must be called inside a Gradio layout context.
40
+ """
41
+ with gr.Group():
42
+ label = "<p><b>Features</b>"
43
+ if hint:
44
+ label += f"<em>{hint}</em>"
45
+ label += "</p>"
46
+ gr.HTML(label)
47
+ cb_face = gr.Checkbox(label="Face Detection", value=True)
48
+ cb_person = gr.Checkbox(label="Person Detection", value=True)
49
+ cb_face_id = gr.Checkbox(label="Face Identification", value=False)
50
+ cb_hand_gesture = gr.Checkbox(label="Hand Detection", value=False)
51
+ return cb_face, cb_person, cb_face_id, cb_hand_gesture
52
+
53
+
54
+ if __name__ == "__main__":
55
+
56
+ patch_fastrtc_frame_queue()
57
+ patch_fastrtc_yuv420p_output()
58
+ patch_aioice_stun_transaction()
59
+ patch_aiortc_h264_nvenc()
60
+
61
+ load_dotenv_if_present()
62
+ logger = setup_logger(name="app")
63
+ log_cpu_info(logger)
64
+ require_secrets("MODEL_ACCESS_TOKEN")
65
+
66
+ tracker = UsageTracker(
67
+ repo_id=os.environ.get("ANALYTICS_REPO_ID", "LatticeSemi/PRIVATE-Demo-Analytics-v1.0"),
68
+ )
69
+ tracker.log("server", "server_start")
70
+
71
+ max_workers = int(os.environ.get("MAX_WORKERS", os.cpu_count()))
72
+ max_ram_gb = float(os.environ.get("MAX_RAM_GB", 32))
73
+ pool = EveWorkerPool(max_workers=max_workers, max_ram_gb=max_ram_gb, ram_headroom_gb=2.0)
74
+
75
+ # FPS cap: each live stream runs between MAX_TARGET_FPS (idle) and
76
+ # MIN_TARGET_FPS (full load). Set either to 0 to disable the cap.
77
+ max_fps_raw = float(os.environ.get("MAX_TARGET_FPS", "24"))
78
+ min_fps_raw = float(os.environ.get("MIN_TARGET_FPS", "15"))
79
+ max_fps: float | None = max_fps_raw if max_fps_raw > 0 else None
80
+ min_fps: float | None = min_fps_raw if min_fps_raw > 0 else None
81
+
82
+ camera_width = int(os.environ.get("CAMERA_WIDTH", 640))
83
+ camera_height = int(os.environ.get("CAMERA_HEIGHT", 360))
84
+
85
+ stream_manager = LiveStreamManager(
86
+ pool,
87
+ session_lifetime_seconds=60 * 4,
88
+ max_fps=max_fps,
89
+ min_fps=min_fps,
90
+ tracker=tracker,
91
+ )
92
+
93
+ session_tracker = SessionTracker(pool=pool, tracker=tracker, logger=logger)
94
+
95
+ # Separate HTTP server for video output bypasses Chrome's per-origin
96
+ # connection limit that blocks /file= requests while SSE connections are open.
97
+ video_server: VideoFileServer | None = None
98
+ # TODO: Put that under an env var, for debug purposes, locally, for more than 2 tabs.
99
+ """if not os.environ.get("SPACE_ID"):
100
+ gradio_cache = os.path.join(tempfile.gettempdir(), "gradio")
101
+ os.makedirs(gradio_cache, exist_ok=True)
102
+ video_server = VideoFileServer(root_dir=gradio_cache, logger=logger)
103
+ video_server.start()"""
104
+
105
+ handlers = EveAppHandlers(
106
+ pool=pool,
107
+ stream_manager=stream_manager,
108
+ sessions=session_tracker,
109
+ logger=logger,
110
+ max_fps=max_fps,
111
+ min_fps=min_fps,
112
+ video_server=video_server,
113
+ )
114
+
115
+ def _shutdown() -> None:
116
+ session_tracker.shutdown()
117
+ stream_manager.shutdown()
118
+ tracker.log("server", "server_stop")
119
+ tracker.shutdown()
120
+
121
+ atexit.register(_shutdown)
122
+
123
+ EXAMPLE_VIDEOS = get_example_videos(str(APP_DIR / "examples"))
124
+ VIDEO_LIMITS = VideoLimits()
125
+ rtc_config_provider = RtcConfigProvider()
126
+
127
+ face_id_tab = FaceIdTab(
128
+ pool,
129
+ max_users=2,
130
+ examples_dir=str(APP_DIR / "examples_fid"),
131
+ accept_video=True,
132
+ video_limits=VideoLimits(max_file_size_mb=150, max_duration_seconds=60),
133
+ tracker=tracker,
134
+ )
135
+
136
+ with gr.Blocks(
137
+ title="Eve HMI Demo",
138
+ theme=gr.themes.Default(
139
+ text_size=gr.themes.sizes.text_lg,
140
+ primary_hue=gr.themes.colors.yellow,
141
+ ),
142
+ css=(
143
+ f"#webrtc-stream-col {{ max-width: {camera_width}px !important; margin: 0 auto; }}"
144
+ " .gradio-container h1, .gradio-container .md h1 { font-size: 2.25rem !important; }"
145
+ " .gradio-container h2, .gradio-container .md h2 { font-size: 1.75rem !important; }"
146
+ " .gradio-container h3, .gradio-container .md h3 { font-size: 1.4rem !important; }"
147
+ " .gradio-container button[role='tab'],"
148
+ " .gradio-container button[role='tab'] *"
149
+ " { text-decoration: underline !important; }"
150
+ " .gradio-container .tab-container {"
151
+ " height: auto !important;"
152
+ " overflow: visible !important;"
153
+ " gap: 4px !important;"
154
+ " border-bottom: 2px solid var(--border-color-primary) !important; }"
155
+ " .gradio-container .tab-container::after { display: none !important; }"
156
+ " .gradio-container button[role='tab'] {"
157
+ " height: auto !important;"
158
+ " padding: 10px 20px !important;"
159
+ " border: 1px solid var(--border-color-primary) !important;"
160
+ " border-bottom: none !important;"
161
+ " border-radius: 8px 8px 0 0 !important;"
162
+ " background: var(--background-fill-secondary) !important;"
163
+ " margin-bottom: -2px !important; }"
164
+ " .gradio-container button[role='tab'].selected {"
165
+ " background: var(--primary-500) !important;"
166
+ " color: var(--neutral-950) !important;"
167
+ " border-color: var(--primary-500) !important;"
168
+ " font-weight: 600 !important; }"
169
+ " .gradio-container button[role='tab'].selected::after { display: none !important; }"
170
+ ),
171
+ head=TAB_SWITCH_AUTO_STOP_JS,
172
+ ) as demo:
173
+ gr.Markdown("# Lattice sensAI Edge Vision Engine SDK")
174
+ gr.Markdown(
175
+ "Our SDK solves the human sensing challenges by outputting ready-to-use data."
176
+ " Our models have a low computation footprint and are ideal for 0.5-2 TOPS devices"
177
+ " like FPGAs, SOCs and small NPUs.\n\n"
178
+ # TODO: Insert performance summary table
179
+ "To access the EVE SDK, fill the form on this [page](https://huggingface.co/LatticeSemi/sensAI-Edge-Vision-Engine-SDK-Packages) and follow the instructions for download."
180
+ " For any questions or support, please reach out to us at evehelp@latticesemi.com.\n\n"
181
+ "You can also preview the EVE SDK with the following tabs:\n\n"
182
+ "- <u>Live Inference</u> to run it live from your webcam\n"
183
+ "- <u>Offline Inference</u> to test it with videos you can upload\n"
184
+ "- Use the <u>Face ID Registration</u> tab to register face(s) you can use in either Live or Offline Inference to test the Face ID model.\n\n"
185
+ "> Note: For demo purposes, execution of the AI pipeline and image draw operations are all performed on a Hugging Face CPU server. Performance may vary based on the number of concurrent users.\n"
186
+ "\n\n"
187
+ )
188
+
189
+ session_registry = gr.State(value={})
190
+ session_hash_state = gr.State(value="unknown")
191
+
192
+ with gr.Tabs() as tabs:
193
+ (
194
+ _live_tab,
195
+ webrtc_stream,
196
+ (live_cb_face, live_cb_person, live_cb_face_id, live_cb_hand_gesture),
197
+ ) = build_live_inference_tab(
198
+ rtc_configuration=lambda: rtc_config_provider.get(),
199
+ feature_checkbox_builder=_build_feature_checkboxes,
200
+ extras_builder=lambda: face_id_tab.build_summary(height=80, scale=1),
201
+ max_fps=int(max_fps) if max_fps else 30,
202
+ width=camera_width,
203
+ height=camera_height,
204
+ )
205
+
206
+ (
207
+ video_tab,
208
+ input_video,
209
+ output_video,
210
+ (cb_face, cb_person, cb_face_id, cb_hand_gesture),
211
+ process_btn,
212
+ example_dataset,
213
+ ) = build_offline_inference_tab(
214
+ feature_checkbox_builder=_build_feature_checkboxes,
215
+ example_videos=EXAMPLE_VIDEOS,
216
+ video_limits=VIDEO_LIMITS,
217
+ extras_builder=lambda: face_id_tab.build_summary(height=80, scale=1),
218
+ )
219
+ patch_video_for_external_urls(output_video)
220
+
221
+ face_id_tab.build()
222
+
223
+ build_eula_tab()
224
+
225
+ if os.environ.get("ENABLE_PROFILER", "").strip() not in ("", "0", "false"):
226
+ from profiler_tab import build_profiler_tab
227
+
228
+ build_profiler_tab(pool)
229
+
230
+ # --- Offline Inference wiring ---
231
+ wire_video_upload(input_video, output_video, process_btn, example_dataset, VIDEO_LIMITS)
232
+
233
+ process_btn.click(
234
+ fn=handlers.run_eve_inference,
235
+ inputs=[
236
+ input_video,
237
+ cb_face,
238
+ cb_person,
239
+ cb_face_id,
240
+ cb_hand_gesture,
241
+ session_registry,
242
+ ],
243
+ outputs=[output_video, session_registry],
244
+ concurrency_limit=pool.worker_count,
245
+ ).then(
246
+ fn=face_id_tab.refresh_all,
247
+ inputs=[session_registry],
248
+ outputs=face_id_tab.all_slot_components,
249
+ )
250
+
251
+ # --- Face ID wiring (self-contained in FaceIdTab) ---
252
+ face_id_tab.wire(session_registry)
253
+
254
+ # Refresh summary thumbnails when switching to tabs that show them
255
+ for tab in (video_tab, _live_tab):
256
+ tab.select(
257
+ fn=face_id_tab.refresh_summary,
258
+ inputs=[session_registry],
259
+ outputs=face_id_tab.summary_components,
260
+ )
261
+
262
+ # --- Usage analytics ---
263
+ tabs.select(fn=session_tracker.on_tab_switch, inputs=[], outputs=[])
264
+
265
+ live_feature_inputs = [live_cb_face, live_cb_person, live_cb_face_id, live_cb_hand_gesture]
266
+ for cb in live_feature_inputs:
267
+ cb.change(fn=handlers.on_live_feature_change, inputs=live_feature_inputs, outputs=[])
268
+
269
+ # --- Live Inference wiring ---
270
+ # FastRTC defaults concurrency_limit to 1 which causes Gradio's queue
271
+ # to reject new WebRTC connections with "Too many concurrent connections".
272
+ # Since process_live_frame is non-blocking (shows an overlay while
273
+ # waiting for a worker), we allow MORE streams than workers so that
274
+ # queued users see a "waiting" overlay instead of a connection error.
275
+ webrtc_stream.stream(
276
+ fn=handlers.process_live_frame,
277
+ inputs=[
278
+ webrtc_stream,
279
+ live_cb_face,
280
+ live_cb_person,
281
+ live_cb_face_id,
282
+ live_cb_hand_gesture,
283
+ session_registry,
284
+ session_hash_state,
285
+ ],
286
+ outputs=[webrtc_stream],
287
+ concurrency_limit=pool.worker_count + 8,
288
+ )
289
+
290
+ # --- Session tracking ---
291
+ demo.load(session_tracker.on_load, outputs=[session_hash_state])
292
+ demo.unload(handlers.cleanup_session)
293
+
294
+ if tracker.enabled:
295
+ gr.HTML(
296
+ "<p style='font-size:0.8em;color:#888;text-align:center;margin-top:1em'>"
297
+ "This demo collects anonymous usage data (session activity, feature usage) "
298
+ "to improve the experience. No personal information is stored.</p>"
299
+ )
300
+
301
+ demo.queue()
302
+ demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
download_examples.py CHANGED
@@ -1,124 +1,124 @@
1
- """Download example media from the LatticeSemi/Demo-Examples-v1.0 dataset.
2
-
3
- Runs at Docker build time (after ``COPY --chown=user . /app``) to populate the
4
- demo's ``examples*/`` subfolders from the shared HF dataset. Mirrors the
5
- dataset layout: every file under ``<DEMO>/`` in the dataset is copied to the
6
- same relative path locally (``<DEMO>/examples/foo.mp4`` -> ``./examples/foo.mp4``).
7
-
8
- Auth order — same as ``install_eve.py``:
9
-
10
- 1. Docker BuildKit secret ``MODEL_ACCESS_TOKEN``
11
- 2. ``HF_TOKEN`` env / build arg
12
- 3. No token — works only if the dataset is public.
13
-
14
- Local-dev fallback: if the download fails (offline, no token, dataset private),
15
- but a sibling ``examples*/`` folder already contains files, succeed with a
16
- warning so manual placement / pre-existing files keep working. If neither
17
- the download nor any local file is present, crash loud with the dataset URL
18
- and the token-fix hint.
19
- """
20
-
21
- import os
22
- import shutil
23
- import sys
24
- from pathlib import Path
25
-
26
- from huggingface_hub import HfApi, hf_hub_download
27
-
28
- DEMO = "eve_hmi"
29
- DATASET = "LatticeSemi/Demo-Examples-v1.0"
30
- SECRET_PATH = "/run/secrets/MODEL_ACCESS_TOKEN"
31
-
32
-
33
- def get_token() -> tuple[str | None, str]:
34
- """Return an HF token from the first available source, or None.
35
-
36
- Falls through past the secret file on PermissionError — BuildKit mounts
37
- the secret as root by default; the Dockerfile must pass ``uid=1000`` for
38
- a non-root user to read it. Falling through lets ``HF_TOKEN`` still work
39
- if the mount permissions are misconfigured.
40
- """
41
- if os.path.isfile(SECRET_PATH):
42
- try:
43
- with open(SECRET_PATH) as f:
44
- token = f.read().strip()
45
- if token:
46
- return token, "build secret (MODEL_ACCESS_TOKEN)"
47
- except PermissionError as exc:
48
- print(
49
- f"[download_examples] WARNING: cannot read {SECRET_PATH}: {exc}. "
50
- f"Add ``uid=1000`` to the secret mount in the Dockerfile.",
51
- file=sys.stderr,
52
- )
53
- token = os.environ.get("HF_TOKEN", "").strip()
54
- if token:
55
- return token, "build arg (HF_TOKEN)"
56
- return None, "no auth"
57
-
58
-
59
- def has_local_examples() -> bool:
60
- """True iff any ``examples*`` sibling dir contains at least one file."""
61
- cwd = Path(".")
62
- if not cwd.is_dir():
63
- return False
64
- for entry in cwd.iterdir():
65
- if entry.is_dir() and entry.name.startswith("examples"):
66
- if any(p.is_file() for p in entry.rglob("*")):
67
- return True
68
- return False
69
-
70
-
71
- def main() -> int:
72
- token, source = get_token()
73
- print(f"[download_examples] demo={DEMO} dataset={DATASET} auth={source}")
74
-
75
- download_error: str | None = None
76
- downloaded = 0
77
- try:
78
- api = HfApi()
79
- files = api.list_repo_files(DATASET, repo_type="dataset", token=token)
80
- prefix = f"{DEMO}/"
81
- wanted = [f for f in files if f.startswith(prefix)]
82
- if not wanted:
83
- download_error = f"dataset has no files under '{prefix}'"
84
- for remote in wanted:
85
- cached = hf_hub_download(
86
- repo_id=DATASET,
87
- repo_type="dataset",
88
- filename=remote,
89
- token=token,
90
- )
91
- local = Path(remote[len(prefix) :])
92
- local.parent.mkdir(parents=True, exist_ok=True)
93
- shutil.copy2(cached, local)
94
- downloaded += 1
95
- except Exception as exc: # noqa: BLE001 — broad catch by design at build time
96
- download_error = f"{type(exc).__name__}: {exc}"
97
-
98
- if downloaded > 0:
99
- print(f"[download_examples] OK: downloaded {downloaded} files")
100
- return 0
101
-
102
- if has_local_examples():
103
- print(
104
- f"[download_examples] WARNING: download failed — {download_error}.\n"
105
- f" Falling back to existing local example files.",
106
- file=sys.stderr,
107
- )
108
- return 0
109
-
110
- print(
111
- f"FATAL: no example files for '{DEMO}'.\n"
112
- f" Download from {DATASET} failed: {download_error or 'no files retrieved'}\n"
113
- f" Fix one of:\n"
114
- f" - HF Space: set MODEL_ACCESS_TOKEN secret with read access to the dataset.\n"
115
- f" - Local dev: run `hf auth login`, or manually drop files into the demo's\n"
116
- f" examples*/ subfolders from\n"
117
- f" https://huggingface.co/datasets/{DATASET}/tree/main/{DEMO}",
118
- file=sys.stderr,
119
- )
120
- return 1
121
-
122
-
123
- if __name__ == "__main__":
124
- sys.exit(main())
 
1
+ """Download example media from the LatticeSemi/Demo-Examples-v1.0 dataset.
2
+
3
+ Runs at Docker build time (after ``COPY --chown=user . /app``) to populate the
4
+ demo's ``examples*/`` subfolders from the shared HF dataset. Mirrors the
5
+ dataset layout: every file under ``<DEMO>/`` in the dataset is copied to the
6
+ same relative path locally (``<DEMO>/examples/foo.mp4`` -> ``./examples/foo.mp4``).
7
+
8
+ Auth order — same as ``install_eve.py``:
9
+
10
+ 1. Docker BuildKit secret ``MODEL_ACCESS_TOKEN``
11
+ 2. ``HF_TOKEN`` env / build arg
12
+ 3. No token — works only if the dataset is public.
13
+
14
+ Local-dev fallback: if the download fails (offline, no token, dataset private),
15
+ but a sibling ``examples*/`` folder already contains files, succeed with a
16
+ warning so manual placement / pre-existing files keep working. If neither
17
+ the download nor any local file is present, crash loud with the dataset URL
18
+ and the token-fix hint.
19
+ """
20
+
21
+ import os
22
+ import shutil
23
+ import sys
24
+ from pathlib import Path
25
+
26
+ from huggingface_hub import HfApi, hf_hub_download
27
+
28
+ DEMO = "eve_hmi"
29
+ DATASET = "LatticeSemi/Demo-Examples-v1.0"
30
+ SECRET_PATH = "/run/secrets/MODEL_ACCESS_TOKEN"
31
+
32
+
33
+ def get_token() -> tuple[str | None, str]:
34
+ """Return an HF token from the first available source, or None.
35
+
36
+ Falls through past the secret file on PermissionError — BuildKit mounts
37
+ the secret as root by default; the Dockerfile must pass ``uid=1000`` for
38
+ a non-root user to read it. Falling through lets ``HF_TOKEN`` still work
39
+ if the mount permissions are misconfigured.
40
+ """
41
+ if os.path.isfile(SECRET_PATH):
42
+ try:
43
+ with open(SECRET_PATH) as f:
44
+ token = f.read().strip()
45
+ if token:
46
+ return token, "build secret (MODEL_ACCESS_TOKEN)"
47
+ except PermissionError as exc:
48
+ print(
49
+ f"[download_examples] WARNING: cannot read {SECRET_PATH}: {exc}. "
50
+ f"Add ``uid=1000`` to the secret mount in the Dockerfile.",
51
+ file=sys.stderr,
52
+ )
53
+ token = os.environ.get("HF_TOKEN", "").strip()
54
+ if token:
55
+ return token, "build arg (HF_TOKEN)"
56
+ return None, "no auth"
57
+
58
+
59
+ def has_local_examples() -> bool:
60
+ """True iff any ``examples*`` sibling dir contains at least one file."""
61
+ cwd = Path(".")
62
+ if not cwd.is_dir():
63
+ return False
64
+ for entry in cwd.iterdir():
65
+ if entry.is_dir() and entry.name.startswith("examples"):
66
+ if any(p.is_file() for p in entry.rglob("*")):
67
+ return True
68
+ return False
69
+
70
+
71
+ def main() -> int:
72
+ token, source = get_token()
73
+ print(f"[download_examples] demo={DEMO} dataset={DATASET} auth={source}")
74
+
75
+ download_error: str | None = None
76
+ downloaded = 0
77
+ try:
78
+ api = HfApi()
79
+ files = api.list_repo_files(DATASET, repo_type="dataset", token=token)
80
+ prefix = f"{DEMO}/"
81
+ wanted = [f for f in files if f.startswith(prefix)]
82
+ if not wanted:
83
+ download_error = f"dataset has no files under '{prefix}'"
84
+ for remote in wanted:
85
+ cached = hf_hub_download(
86
+ repo_id=DATASET,
87
+ repo_type="dataset",
88
+ filename=remote,
89
+ token=token,
90
+ )
91
+ local = Path(remote[len(prefix) :])
92
+ local.parent.mkdir(parents=True, exist_ok=True)
93
+ shutil.copy2(cached, local)
94
+ downloaded += 1
95
+ except Exception as exc: # noqa: BLE001 — broad catch by design at build time
96
+ download_error = f"{type(exc).__name__}: {exc}"
97
+
98
+ if downloaded > 0:
99
+ print(f"[download_examples] OK: downloaded {downloaded} files")
100
+ return 0
101
+
102
+ if has_local_examples():
103
+ print(
104
+ f"[download_examples] WARNING: download failed — {download_error}.\n"
105
+ f" Falling back to existing local example files.",
106
+ file=sys.stderr,
107
+ )
108
+ return 0
109
+
110
+ print(
111
+ f"FATAL: no example files for '{DEMO}'.\n"
112
+ f" Download from {DATASET} failed: {download_error or 'no files retrieved'}\n"
113
+ f" Fix one of:\n"
114
+ f" - HF Space: set MODEL_ACCESS_TOKEN secret with read access to the dataset.\n"
115
+ f" - Local dev: run `hf auth login`, or manually drop files into the demo's\n"
116
+ f" examples*/ subfolders from\n"
117
+ f" https://huggingface.co/datasets/{DATASET}/tree/main/{DEMO}",
118
+ file=sys.stderr,
119
+ )
120
+ return 1
121
+
122
+
123
+ if __name__ == "__main__":
124
+ sys.exit(main())
install_eve.py CHANGED
@@ -1,104 +1,104 @@
1
- """Download and install the Eve SDK .deb package from HuggingFace Hub.
2
-
3
- Called during Docker build. Tries authentication in order:
4
-
5
- 1. Docker BuildKit secret ``MODEL_ACCESS_TOKEN`` (HF Spaces — automatic)
6
- 2. ``HF_TOKEN`` build arg (local builds)
7
- 3. No token (public repos only)
8
-
9
- Local usage::
10
-
11
- docker build --build-arg HF_TOKEN=$(cat ~/.cache/huggingface/token) \
12
- -t eve ./src/demos/eve_hmi
13
- """
14
-
15
- import os
16
- import re
17
- import shutil
18
- import subprocess
19
- import sys
20
-
21
- from huggingface_hub import hf_hub_download
22
-
23
- EVE_REPO = "LatticeSemi/PRIVATE-Edge-Vision-Engine-EVE-v7.1"
24
- EVE_DEB = "LINUX_X86-15-7.1-eve-sensai_7.1.15~git20260424.20d1a1a_amd64.deb"
25
- EVE_LICENSE_REPO = "LatticeSemi/PRIVATE-Edge-Vision-Engine-EVE-v7.0-License"
26
- EVE_LICENSE = "libEveDevLicense.so"
27
- SECRET_PATH = "/run/secrets/MODEL_ACCESS_TOKEN"
28
- DOWNLOAD_DIR = "/tmp/eve"
29
-
30
-
31
- def get_token():
32
- """Return an HF token from the first available source, or None."""
33
- # 1. Docker BuildKit secret (HF Spaces injects MODEL_ACCESS_TOKEN automatically)
34
- if os.path.isfile(SECRET_PATH):
35
- with open(SECRET_PATH) as f:
36
- token = f.read().strip()
37
- if token:
38
- return token, "build secret (MODEL_ACCESS_TOKEN)"
39
-
40
- # 2. HF_TOKEN build arg forwarded as env var
41
- token = os.environ.get("HF_TOKEN", "").strip()
42
- if token:
43
- return token, "build arg (HF_TOKEN)"
44
-
45
- # 3. No token — will only work for public repos
46
- return None, "no auth (will fail for private repos)"
47
-
48
-
49
- def get_license_destination_path() -> str:
50
- """Parse the .deb package of EVE to extract the version."""
51
- # Alright so regexes are fun, what we want here is to extract the version
52
- # of EVE's package since we need to copy the license into EVE's install
53
- # folder which is /opt/EVE-version-Source/lib.
54
- # For example, in LINUX_X86-531-dev-eve-development_7.0.531~git20260309.c5f1ee6_amd64.deb,
55
- # we want the version extracted to be 7.0.531.
56
- match = re.search(r"(?<=_)\d+(?:\.\d+)+(?=~)", EVE_DEB)
57
- if not match:
58
- raise RuntimeError("Could not parse EVE's package version.")
59
-
60
- version = match.group()
61
-
62
- return f"/opt/EVE-{version}-Source/lib"
63
-
64
-
65
- def main():
66
- token, auth_source = get_token()
67
-
68
- if token is None and "PRIVATE" in EVE_REPO:
69
- print(
70
- f"ERROR: No authentication token found.\n"
71
- f" Repo '{EVE_REPO}' is private and requires a token.\n"
72
- f" On HF Spaces: set MODEL_ACCESS_TOKEN as a Space secret.\n"
73
- f" Locally: docker build --build-arg HF_TOKEN=$(cat ~/.cache/huggingface/token) ...",
74
- file=sys.stderr,
75
- )
76
- sys.exit(1)
77
-
78
- print(f"Downloading Eve SDK from {EVE_REPO} using {auth_source}...")
79
-
80
- deb_path = hf_hub_download(
81
- repo_id=EVE_REPO,
82
- filename=EVE_DEB,
83
- local_dir=DOWNLOAD_DIR,
84
- token=token,
85
- )
86
-
87
- print(f"Installing {deb_path}...")
88
- subprocess.run(["apt-get", "install", "-y", deb_path], check=True)
89
-
90
- license_path = hf_hub_download(
91
- repo_id=EVE_LICENSE_REPO, filename=EVE_LICENSE, local_dir=DOWNLOAD_DIR, token=token
92
- )
93
-
94
- destination_path = get_license_destination_path()
95
-
96
- print(f"Installing {license_path}...")
97
- subprocess.run(["mv", license_path, destination_path], check=True)
98
-
99
- shutil.rmtree(DOWNLOAD_DIR, ignore_errors=True)
100
- print("Eve SDK installed successfully.")
101
-
102
-
103
- if __name__ == "__main__":
104
- main()
 
1
+ """Download and install the Eve SDK .deb package from HuggingFace Hub.
2
+
3
+ Called during Docker build. Tries authentication in order:
4
+
5
+ 1. Docker BuildKit secret ``MODEL_ACCESS_TOKEN`` (HF Spaces — automatic)
6
+ 2. ``HF_TOKEN`` build arg (local builds)
7
+ 3. No token (public repos only)
8
+
9
+ Local usage::
10
+
11
+ docker build --build-arg HF_TOKEN=$(cat ~/.cache/huggingface/token) \
12
+ -t eve ./src/demos/eve_hmi
13
+ """
14
+
15
+ import os
16
+ import re
17
+ import shutil
18
+ import subprocess
19
+ import sys
20
+
21
+ from huggingface_hub import hf_hub_download
22
+
23
+ EVE_REPO = "LatticeSemi/PRIVATE-Edge-Vision-Engine-EVE-v7.2"
24
+ EVE_DEB = "LINUX_X86-10-7.2-eve-sensai_7.2.10~git20260515.8139998_amd64.deb"
25
+ EVE_LICENSE_REPO = "LatticeSemi/PRIVATE-Edge-Vision-Engine-EVE-v7.0-License"
26
+ EVE_LICENSE = "libEveDevLicense.so"
27
+ SECRET_PATH = "/run/secrets/MODEL_ACCESS_TOKEN"
28
+ DOWNLOAD_DIR = "/tmp/eve"
29
+
30
+
31
+ def get_token():
32
+ """Return an HF token from the first available source, or None."""
33
+ # 1. Docker BuildKit secret (HF Spaces injects MODEL_ACCESS_TOKEN automatically)
34
+ if os.path.isfile(SECRET_PATH):
35
+ with open(SECRET_PATH) as f:
36
+ token = f.read().strip()
37
+ if token:
38
+ return token, "build secret (MODEL_ACCESS_TOKEN)"
39
+
40
+ # 2. HF_TOKEN build arg forwarded as env var
41
+ token = os.environ.get("HF_TOKEN", "").strip()
42
+ if token:
43
+ return token, "build arg (HF_TOKEN)"
44
+
45
+ # 3. No token — will only work for public repos
46
+ return None, "no auth (will fail for private repos)"
47
+
48
+
49
+ def get_license_destination_path() -> str:
50
+ """Parse the .deb package of EVE to extract the version."""
51
+ # Alright so regexes are fun, what we want here is to extract the version
52
+ # of EVE's package since we need to copy the license into EVE's install
53
+ # folder which is /opt/EVE-version-Source/lib.
54
+ # For example, in LINUX_X86-531-dev-eve-development_7.0.531~git20260309.c5f1ee6_amd64.deb,
55
+ # we want the version extracted to be 7.0.531.
56
+ match = re.search(r"(?<=_)\d+(?:\.\d+)+(?=~)", EVE_DEB)
57
+ if not match:
58
+ raise RuntimeError("Could not parse EVE's package version.")
59
+
60
+ version = match.group()
61
+
62
+ return f"/opt/EVE-{version}-Source/lib"
63
+
64
+
65
+ def main():
66
+ token, auth_source = get_token()
67
+
68
+ if token is None and "PRIVATE" in EVE_REPO:
69
+ print(
70
+ f"ERROR: No authentication token found.\n"
71
+ f" Repo '{EVE_REPO}' is private and requires a token.\n"
72
+ f" On HF Spaces: set MODEL_ACCESS_TOKEN as a Space secret.\n"
73
+ f" Locally: docker build --build-arg HF_TOKEN=$(cat ~/.cache/huggingface/token) ...",
74
+ file=sys.stderr,
75
+ )
76
+ sys.exit(1)
77
+
78
+ print(f"Downloading Eve SDK from {EVE_REPO} using {auth_source}...")
79
+
80
+ deb_path = hf_hub_download(
81
+ repo_id=EVE_REPO,
82
+ filename=EVE_DEB,
83
+ local_dir=DOWNLOAD_DIR,
84
+ token=token,
85
+ )
86
+
87
+ print(f"Installing {deb_path}...")
88
+ subprocess.run(["apt-get", "install", "-y", deb_path], check=True)
89
+
90
+ license_path = hf_hub_download(
91
+ repo_id=EVE_LICENSE_REPO, filename=EVE_LICENSE, local_dir=DOWNLOAD_DIR, token=token
92
+ )
93
+
94
+ destination_path = get_license_destination_path()
95
+
96
+ print(f"Installing {license_path}...")
97
+ subprocess.run(["mv", license_path, destination_path], check=True)
98
+
99
+ shutil.rmtree(DOWNLOAD_DIR, ignore_errors=True)
100
+ print("Eve SDK installed successfully.")
101
+
102
+
103
+ if __name__ == "__main__":
104
+ main()
requirements.txt CHANGED
@@ -1,8 +1,8 @@
1
- av
2
- gradio==5.50.0
3
- fastrtc==0.0.34
4
- huggingface-hub==1.5.0
5
- opencv-python
6
- dotenv
7
- twilio
8
- psutil
 
1
+ av
2
+ gradio==5.50.0
3
+ fastrtc==0.0.34
4
+ huggingface-hub==1.5.0
5
+ opencv-python
6
+ dotenv
7
+ twilio
8
+ psutil
shared/assets/EULA.md CHANGED
@@ -1,21 +1,21 @@
1
- # DEMO EVALUATION END USER LICENSE AGREEMENT
2
-
3
- IMPORTANT: BY DOWNLOADING, INSTALLING, ACTIVATING, ACCESSING, OR USING THE SOFTWARE, YOU AGREE TO THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT USE THE SOFTWARE.
4
-
5
- This Demo Evaluation End User License Agreement ("Agreement") is between Lattice Semiconductor Corporation ("Lattice") and the person or entity using the Software ("Licensee"). The individual accepting this Agreement represents and warrants that they have authority to bind Licensee.
6
-
7
- **1. Software.** "Software" means the demo version of the software, in object code form only, together with related documentation, materials, updates, license keys, and any output or data generated by the Software, provided by Lattice.
8
-
9
- **2. License Grant.** Subject to this Agreement, Lattice grants Licensee a limited, non-exclusive, non-transferable, non-sublicensable, revocable license to use the Software solely for Licensee's internal, non-commercial evaluation and demonstration purposes, only to assess the Software and determine whether to request a longer-term testing license from Lattice. The Software may be used only by Licensee's employees at a single site. No other rights are granted by implication, estoppel, or otherwise.
10
-
11
- **3. License Key; Revocation.** Use of the Software is controlled by a license key or similar activation mechanism. Lattice may revoke, suspend, disable, or refuse to renew any license key at any time, with or without cause, and without notice or liability. Upon expiration, revocation, suspension, or disablement of the license key, Licensee's right to use the Software immediately terminates and Licensee must comply with Section 8(b).
12
-
13
- **4. Restrictions.** Licensee may not, and may not permit or enable any third party to: (a) use the Software for production, commercial, or revenue-generating purposes; (b) sell, license, sublicense, rent, lease, lend, distribute, transfer, or disclose the Software or any portion thereof to any third party; (c) copy, modify, adapt, translate, or create derivative works of the Software; (d) reverse engineer, decompile, disassemble, or otherwise attempt to discover the source code, algorithms, data structures, or underlying ideas of the Software, except to the limited extent such restriction is expressly prohibited by applicable law; (e) remove, alter, or obscure any proprietary, copyright, trademark, or other notices; (f) use the Software or any information derived from it to develop, improve, train, or benchmark any competing product, service, or technology; (g) publish or disclose any benchmark, test, performance, or evaluation results related to the Software without Lattice's prior written consent; (h) use the Software in violation of any applicable law or regulation; or (i) circumvent or attempt to circumvent any technical protection measures in the Software.
14
-
15
- **5. Ownership; Confidentiality; Feedback.** The Software is licensed, not sold. Lattice and its licensors retain all right, title, and interest in and to the Software, all derivatives and improvements thereof, and all related intellectual property rights worldwide. No license or right is granted to any Lattice patent, trade secret, or trademark. The Software, its features, performance characteristics, and all information relating thereto constitute confidential and proprietary trade secrets of Lattice. Licensee will protect the Software using at least the same degree of care it uses for its own confidential information, but no less than reasonable care, and will not disclose or provide access to the Software except to employees or contractors with a need to know who are bound by written confidentiality obligations no less protective than this Agreement. Any suggestions, ideas, feedback, evaluation results, or other input provided by Licensee regarding the Software ("Feedback") are assigned to Lattice and may be used by Lattice for any purpose without restriction, compensation, or obligation. To the extent such assignment is not enforceable, Licensee grants Lattice a perpetual, irrevocable, worldwide, royalty-free, fully sublicensable license to use and exploit the Feedback.
16
-
17
- **6. Disclaimer.** THE SOFTWARE IS PROVIDED "AS IS" AND "AS AVAILABLE," WITHOUT WARRANTY OF ANY KIND. TO THE MAXIMUM EXTENT PERMITTED BY LAW, LATTICE DISCLAIMS ALL EXPRESS, IMPLIED, STATUTORY, AND OTHER WARRANTIES, INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, NON-INFRINGEMENT, AND ACCURACY. LATTICE DOES NOT WARRANT THAT THE SOFTWARE WILL BE ERROR-FREE, UNINTERRUPTED, SECURE, OR FREE OF HARMFUL COMPONENTS.
18
-
19
- **7. Limitation of Liability.** TO THE MAXIMUM EXTENT PERMITTED BY LAW, LATTICE AND ITS LICENSORS, DIRECTORS, OFFICERS, AND EMPLOYEES WILL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES, OR FOR ANY LOSS OF PROFITS, REVENUE, DATA, BUSINESS, GOODWILL, OR USE, ARISING OUT OF OR RELATED TO THIS AGREEMENT OR THE SOFTWARE, REGARDLESS OF THE THEORY OF LIABILITY AND EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. LATTICE'S TOTAL AGGREGATE LIABILITY ARISING OUT OF OR RELATED TO THIS AGREEMENT OR THE SOFTWARE WILL NOT EXCEED US$100. THESE LIMITATIONS APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
20
-
21
- **8. Termination.** (a) This Agreement begins upon first use of the Software and terminates automatically upon breach by Licensee, expiration or revocation of the license key, or upon thirty (30) days' notice by Lattice. Lattice may terminate immediately if Licensee breaches Sections 4 or 5. (b) Upon termination, Licensee must immediately cease all use of the Software, permanently delete or destroy all copies (including backups), and certify such destruction in writing to Lattice within five (5) business days.
 
1
+ # DEMO EVALUATION END USER LICENSE AGREEMENT
2
+
3
+ IMPORTANT: BY DOWNLOADING, INSTALLING, ACTIVATING, ACCESSING, OR USING THE SOFTWARE, YOU AGREE TO THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT USE THE SOFTWARE.
4
+
5
+ This Demo Evaluation End User License Agreement ("Agreement") is between Lattice Semiconductor Corporation ("Lattice") and the person or entity using the Software ("Licensee"). The individual accepting this Agreement represents and warrants that they have authority to bind Licensee.
6
+
7
+ **1. Software.** "Software" means the demo version of the software, in object code form only, together with related documentation, materials, updates, license keys, and any output or data generated by the Software, provided by Lattice.
8
+
9
+ **2. License Grant.** Subject to this Agreement, Lattice grants Licensee a limited, non-exclusive, non-transferable, non-sublicensable, revocable license to use the Software solely for Licensee's internal, non-commercial evaluation and demonstration purposes, only to assess the Software and determine whether to request a longer-term testing license from Lattice. The Software may be used only by Licensee's employees at a single site. No other rights are granted by implication, estoppel, or otherwise.
10
+
11
+ **3. License Key; Revocation.** Use of the Software is controlled by a license key or similar activation mechanism. Lattice may revoke, suspend, disable, or refuse to renew any license key at any time, with or without cause, and without notice or liability. Upon expiration, revocation, suspension, or disablement of the license key, Licensee's right to use the Software immediately terminates and Licensee must comply with Section 8(b).
12
+
13
+ **4. Restrictions.** Licensee may not, and may not permit or enable any third party to: (a) use the Software for production, commercial, or revenue-generating purposes; (b) sell, license, sublicense, rent, lease, lend, distribute, transfer, or disclose the Software or any portion thereof to any third party; (c) copy, modify, adapt, translate, or create derivative works of the Software; (d) reverse engineer, decompile, disassemble, or otherwise attempt to discover the source code, algorithms, data structures, or underlying ideas of the Software, except to the limited extent such restriction is expressly prohibited by applicable law; (e) remove, alter, or obscure any proprietary, copyright, trademark, or other notices; (f) use the Software or any information derived from it to develop, improve, train, or benchmark any competing product, service, or technology; (g) publish or disclose any benchmark, test, performance, or evaluation results related to the Software without Lattice's prior written consent; (h) use the Software in violation of any applicable law or regulation; or (i) circumvent or attempt to circumvent any technical protection measures in the Software.
14
+
15
+ **5. Ownership; Confidentiality; Feedback.** The Software is licensed, not sold. Lattice and its licensors retain all right, title, and interest in and to the Software, all derivatives and improvements thereof, and all related intellectual property rights worldwide. No license or right is granted to any Lattice patent, trade secret, or trademark. The Software, its features, performance characteristics, and all information relating thereto constitute confidential and proprietary trade secrets of Lattice. Licensee will protect the Software using at least the same degree of care it uses for its own confidential information, but no less than reasonable care, and will not disclose or provide access to the Software except to employees or contractors with a need to know who are bound by written confidentiality obligations no less protective than this Agreement. Any suggestions, ideas, feedback, evaluation results, or other input provided by Licensee regarding the Software ("Feedback") are assigned to Lattice and may be used by Lattice for any purpose without restriction, compensation, or obligation. To the extent such assignment is not enforceable, Licensee grants Lattice a perpetual, irrevocable, worldwide, royalty-free, fully sublicensable license to use and exploit the Feedback.
16
+
17
+ **6. Disclaimer.** THE SOFTWARE IS PROVIDED "AS IS" AND "AS AVAILABLE," WITHOUT WARRANTY OF ANY KIND. TO THE MAXIMUM EXTENT PERMITTED BY LAW, LATTICE DISCLAIMS ALL EXPRESS, IMPLIED, STATUTORY, AND OTHER WARRANTIES, INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, NON-INFRINGEMENT, AND ACCURACY. LATTICE DOES NOT WARRANT THAT THE SOFTWARE WILL BE ERROR-FREE, UNINTERRUPTED, SECURE, OR FREE OF HARMFUL COMPONENTS.
18
+
19
+ **7. Limitation of Liability.** TO THE MAXIMUM EXTENT PERMITTED BY LAW, LATTICE AND ITS LICENSORS, DIRECTORS, OFFICERS, AND EMPLOYEES WILL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES, OR FOR ANY LOSS OF PROFITS, REVENUE, DATA, BUSINESS, GOODWILL, OR USE, ARISING OUT OF OR RELATED TO THIS AGREEMENT OR THE SOFTWARE, REGARDLESS OF THE THEORY OF LIABILITY AND EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. LATTICE'S TOTAL AGGREGATE LIABILITY ARISING OUT OF OR RELATED TO THIS AGREEMENT OR THE SOFTWARE WILL NOT EXCEED US$100. THESE LIMITATIONS APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
20
+
21
+ **8. Termination.** (a) This Agreement begins upon first use of the Software and terminates automatically upon breach by Licensee, expiration or revocation of the license key, or upon thirty (30) days' notice by Lattice. Lattice may terminate immediately if Licensee breaches Sections 4 or 5. (b) Upon termination, Licensee must immediately cease all use of the Software, permanently delete or destroy all copies (including backups), and certify such destruction in writing to Lattice within five (5) business days.
shared/eula_tab.py CHANGED
@@ -1,47 +1,47 @@
1
- """EULA tab for Gradio demos.
2
-
3
- Displays the End User License Agreement as a read-only Markdown tab.
4
- The EULA text is loaded from ``shared/assets/EULA.md`` so it can be
5
- updated without changing any Python code.
6
-
7
- Usage::
8
-
9
- with gr.Blocks() as demo:
10
- with gr.Tabs():
11
- build_eula_tab()
12
- """
13
-
14
- from pathlib import Path
15
-
16
- import gradio as gr
17
-
18
- _ASSETS_DIR = Path(__file__).resolve().parent / "assets"
19
- _DEFAULT_EULA_PATH = _ASSETS_DIR / "EULA.md"
20
-
21
-
22
- def build_eula_tab(
23
- eula_path: str | Path | None = None,
24
- tab_label: str = "EULA",
25
- ) -> gr.TabItem:
26
- """Create a tab displaying the EULA as Markdown.
27
-
28
- Must be called inside a ``gr.Tabs()`` context.
29
-
30
- Args:
31
- eula_path: Path to a Markdown file. Defaults to ``shared/assets/EULA.md``.
32
- tab_label: Label shown on the tab. Defaults to ``"EULA"``.
33
-
34
- Returns:
35
- The ``gr.TabItem`` component.
36
- """
37
- path = Path(eula_path) if eula_path is not None else _DEFAULT_EULA_PATH
38
-
39
- if path.is_file():
40
- content = path.read_text(encoding="utf-8")
41
- else:
42
- content = f"_EULA file not found. Expected location:_ `{path}`"
43
-
44
- with gr.TabItem(tab_label) as tab:
45
- gr.Markdown(content)
46
-
47
- return tab
 
1
+ """EULA tab for Gradio demos.
2
+
3
+ Displays the End User License Agreement as a read-only Markdown tab.
4
+ The EULA text is loaded from ``shared/assets/EULA.md`` so it can be
5
+ updated without changing any Python code.
6
+
7
+ Usage::
8
+
9
+ with gr.Blocks() as demo:
10
+ with gr.Tabs():
11
+ build_eula_tab()
12
+ """
13
+
14
+ from pathlib import Path
15
+
16
+ import gradio as gr
17
+
18
+ _ASSETS_DIR = Path(__file__).resolve().parent / "assets"
19
+ _DEFAULT_EULA_PATH = _ASSETS_DIR / "EULA.md"
20
+
21
+
22
+ def build_eula_tab(
23
+ eula_path: str | Path | None = None,
24
+ tab_label: str = "EULA",
25
+ ) -> gr.TabItem:
26
+ """Create a tab displaying the EULA as Markdown.
27
+
28
+ Must be called inside a ``gr.Tabs()`` context.
29
+
30
+ Args:
31
+ eula_path: Path to a Markdown file. Defaults to ``shared/assets/EULA.md``.
32
+ tab_label: Label shown on the tab. Defaults to ``"EULA"``.
33
+
34
+ Returns:
35
+ The ``gr.TabItem`` component.
36
+ """
37
+ path = Path(eula_path) if eula_path is not None else _DEFAULT_EULA_PATH
38
+
39
+ if path.is_file():
40
+ content = path.read_text(encoding="utf-8")
41
+ else:
42
+ content = f"_EULA file not found. Expected location:_ `{path}`"
43
+
44
+ with gr.TabItem(tab_label) as tab:
45
+ gr.Markdown(content)
46
+
47
+ return tab
shared/eve_app_tabs.py CHANGED
@@ -1,276 +1,276 @@
1
- """Tab builders for EVE-based Gradio demos.
2
-
3
- Both tabs (Offline Inference, Live Inference) follow the same pattern:
4
-
5
- - Outer ``gr.TabItem`` with the demo-supplied label.
6
- - Demo-specific feature checkboxes built via a caller-provided callable so
7
- each demo defines its own feature set (Face Detection / Person /
8
- Hand Detection / Face ID / …).
9
- - Optional ``extras_builder`` hook for demo-specific extras inside the tab
10
- (e.g. eve_hmi's Face ID summary thumbnails).
11
-
12
- The tab builders return the underlying components so the caller can wire
13
- events (``process_btn.click``, ``webrtc_stream.stream``, etc.) outside.
14
- """
15
-
16
- from __future__ import annotations
17
-
18
- from dataclasses import dataclass
19
- from typing import Callable, TypeVar
20
-
21
- import gradio as gr
22
-
23
- from live_inference import RtcConfigurationInput, build_webrtc_stream
24
- from video_processing import VideoLimits, build_video_constraints_accordion
25
-
26
- # The exact tuple of Checkbox components is demo-specific. We let the
27
- # caller's checkbox-builder define the shape and return it transparently.
28
- TCheckboxes = TypeVar("TCheckboxes")
29
-
30
-
31
- def build_offline_inference_tab(
32
- *,
33
- feature_checkbox_builder: Callable[..., TCheckboxes],
34
- example_videos: list,
35
- video_limits: VideoLimits,
36
- extras_builder: Callable[[], None] | None = None,
37
- tab_label: str = "Offline Inference",
38
- feature_hint: str = "applied when processing starts",
39
- ) -> tuple[
40
- gr.TabItem,
41
- gr.Video,
42
- gr.Video,
43
- TCheckboxes,
44
- gr.Button,
45
- gr.Dataset,
46
- ]:
47
- """Build the Offline Inference tab. Must be called inside a ``gr.Tabs`` context.
48
-
49
- Args:
50
- feature_checkbox_builder: Callable that builds the demo's feature
51
- checkboxes inside the tab. Receives the keyword ``hint`` (a
52
- short string shown next to the "Features" heading). Returns a
53
- tuple of ``gr.Checkbox`` instances — the same tuple is returned
54
- unchanged so the caller can wire events.
55
- example_videos: Pre-loaded example videos (list of ``[path]`` rows).
56
- video_limits: Upload constraints rendered in the accordion.
57
- extras_builder: Optional callable invoked after the input/output
58
- video columns to add demo-specific widgets (e.g. a Face ID
59
- summary). Called inside the same row, so it shares horizontal
60
- space with the videos.
61
- tab_label: Tab label text (default ``"Offline Inference"``).
62
- feature_hint: Short hint shown next to the Features heading.
63
-
64
- Returns:
65
- ``(tab, input_video, output_video, checkboxes, process_btn, example_dataset)``.
66
- ``checkboxes`` is exactly what ``feature_checkbox_builder`` returned.
67
- """
68
- with gr.TabItem(tab_label) as video_tab:
69
- with gr.Accordion("Instructions", open=False):
70
- gr.Markdown(
71
- "1. Select the features that will be processed on the video\n"
72
- "2. Select a video (or upload your own in the Input Video frame)\n"
73
- "3. Press the **Process Video** button\n\n"
74
- "Once the video has been processed, you can play the video in the "
75
- "Output Video frame"
76
- )
77
-
78
- checkboxes = feature_checkbox_builder(hint=feature_hint)
79
-
80
- with gr.Accordion("Video Examples", open=True):
81
- example_dataset = gr.Dataset(
82
- components=[gr.Video(visible=False)],
83
- samples=example_videos,
84
- show_label=False,
85
- )
86
-
87
- process_btn = gr.Button("Process Video", variant="primary", interactive=False)
88
-
89
- build_video_constraints_accordion(video_limits)
90
-
91
- with gr.Row(equal_height=True):
92
- with gr.Column(scale=5):
93
- input_video = gr.Video(label="Input Video", sources=["upload", "webcam"])
94
- with gr.Column(scale=5):
95
- output_video = gr.Video(label="Output Video")
96
- if extras_builder is not None:
97
- extras_builder()
98
-
99
- return video_tab, input_video, output_video, checkboxes, process_btn, example_dataset
100
-
101
-
102
- @dataclass
103
- class ImageOrVideoOfflineTab:
104
- """Components returned by :func:`build_image_or_video_offline_tab`.
105
-
106
- The image/video accordions are exposed so the caller can wire mutual
107
- exclusion (expanding one collapses the other) — same pattern as
108
- :class:`face_id_tab.FaceIdTab`.
109
- """
110
-
111
- tab: gr.TabItem
112
- image_input: gr.Image
113
- video_input: gr.Video
114
- image_output: gr.Image
115
- video_output: gr.Video
116
- checkboxes: object # demo-specific (radio, checkbox tuple, etc.)
117
- process_btn: gr.Button
118
- image_example_dataset: gr.Dataset | None
119
- video_example_dataset: gr.Dataset | None
120
- image_accordion: gr.Accordion
121
- video_accordion: gr.Accordion
122
-
123
-
124
- def build_image_or_video_offline_tab(
125
- *,
126
- feature_checkbox_builder: Callable[..., TCheckboxes],
127
- image_examples: list | None,
128
- video_examples: list | None,
129
- video_limits: VideoLimits,
130
- tab_label: str = "Offline Inference",
131
- feature_hint: str = "applied when processing starts",
132
- ) -> ImageOrVideoOfflineTab:
133
- """Build an Offline Inference tab that accepts image OR video.
134
-
135
- Pattern: two mutually-exclusive accordions on the input side ("Input
136
- from an Image" / "Input from a Video"), one Process button, two
137
- output components (image + video) shown side-by-side. Caller is
138
- responsible for:
139
-
140
- - Wiring ``image_accordion`` / ``video_accordion`` mutual exclusion
141
- (one-liner per side, see ``face_id_tab.FaceIdTab.wire``).
142
- - Routing ``process_btn.click`` to a handler that dispatches by
143
- which input is populated.
144
- - Toggling output visibility based on which branch ran.
145
-
146
- Args:
147
- feature_checkbox_builder: Callable that builds the demo's feature
148
- checkboxes/radio inside the tab. Called with keyword
149
- ``hint=feature_hint``.
150
- image_examples: Pre-loaded image examples (list of ``[path]``
151
- rows) or ``None`` to skip the examples accordion.
152
- video_examples: Same for videos.
153
- video_limits: Upload constraints rendered inside the video
154
- accordion.
155
- tab_label: Tab label text.
156
- feature_hint: Short hint shown next to the Features heading.
157
- """
158
- with gr.TabItem(tab_label) as tab:
159
- with gr.Accordion("Instructions", open=False):
160
- gr.Markdown(
161
- "1. Select the model that will be used for object detection\n"
162
- "2. Choose between processing an **Image** or a **Video**:\n"
163
- " - For an image: select an example or upload your own, then press "
164
- "**Process**.\n"
165
- " - For a video: expand the video section, select an example or "
166
- "upload your own, then press **Process**.\n\n"
167
- "Once processing is complete, the annotated result appears on the "
168
- "right (image or video, depending on the input)."
169
- )
170
-
171
- checkboxes = feature_checkbox_builder(hint=feature_hint)
172
-
173
- with gr.Row():
174
- # --- Left column: input ---
175
- with gr.Column(scale=5):
176
- image_example_dataset: gr.Dataset | None = None
177
- video_example_dataset: gr.Dataset | None = None
178
-
179
- with gr.Accordion(
180
- "Input from an Image", open=True
181
- ) as image_accordion:
182
- if image_examples:
183
- with gr.Accordion("Image Examples", open=True):
184
- image_example_dataset = gr.Dataset(
185
- components=[gr.Image(visible=False)],
186
- samples=image_examples,
187
- show_label=False,
188
- )
189
- image_input = gr.Image(
190
- label="Input Image",
191
- sources=["upload", "webcam"],
192
- type="filepath",
193
- )
194
-
195
- with gr.Accordion(
196
- "Input from a Video", open=False
197
- ) as video_accordion:
198
- if video_examples:
199
- with gr.Accordion("Video Examples", open=True):
200
- video_example_dataset = gr.Dataset(
201
- components=[gr.Video(visible=False)],
202
- samples=video_examples,
203
- show_label=False,
204
- )
205
- build_video_constraints_accordion(video_limits)
206
- video_input = gr.Video(
207
- label="Input Video", sources=["upload", "webcam"]
208
- )
209
-
210
- process_btn = gr.Button(
211
- "Process", variant="primary", interactive=False
212
- )
213
-
214
- # --- Right column: output (image OR video, toggled by handler) ---
215
- with gr.Column(scale=5):
216
- image_output = gr.Image(label="Output Image", visible=True)
217
- video_output = gr.Video(label="Output Video", visible=False)
218
-
219
- return ImageOrVideoOfflineTab(
220
- tab=tab,
221
- image_input=image_input,
222
- video_input=video_input,
223
- image_output=image_output,
224
- video_output=video_output,
225
- checkboxes=checkboxes,
226
- process_btn=process_btn,
227
- image_example_dataset=image_example_dataset,
228
- video_example_dataset=video_example_dataset,
229
- image_accordion=image_accordion,
230
- video_accordion=video_accordion,
231
- )
232
-
233
-
234
- def build_live_inference_tab(
235
- *,
236
- rtc_configuration: RtcConfigurationInput,
237
- feature_checkbox_builder: Callable[..., TCheckboxes],
238
- extras_builder: Callable[[], None] | None = None,
239
- max_fps: int = 15,
240
- width: int = 640,
241
- height: int = 360,
242
- tab_label: str = "Live Inference",
243
- description_html: str = (
244
- "<p>Use your webcam for real-time inference. "
245
- "Select features below, then grant camera access when prompted.</p>"
246
- ),
247
- ) -> tuple[gr.TabItem, object, TCheckboxes]:
248
- """Build the Live Inference tab with feature checkboxes + WebRTC stream.
249
-
250
- Args:
251
- rtc_configuration: ICE configuration dict, callable that returns
252
- one, or ``None`` for direct connection. A callable is invoked
253
- per-connection by FastRTC, allowing credential refresh.
254
- feature_checkbox_builder: Callable that builds the demo's feature
255
- checkboxes (same shape as in the offline tab).
256
- extras_builder: Optional callable invoked after the WebRTC stream
257
- for demo-specific widgets (e.g. Face ID summary).
258
- max_fps: Maximum frame rate requested from the browser camera.
259
- width / height: Camera frame dimensions in pixels.
260
- tab_label: Tab label text.
261
- description_html: Optional HTML shown above the stream.
262
-
263
- Returns:
264
- ``(tab, webrtc_stream, checkboxes)``.
265
- """
266
- with gr.TabItem(tab_label) as tab:
267
- if description_html:
268
- gr.HTML(description_html)
269
- checkboxes = feature_checkbox_builder()
270
- webrtc_stream = build_webrtc_stream(
271
- rtc_configuration, max_fps=max_fps, width=width, height=height
272
- )
273
- if extras_builder is not None:
274
- extras_builder()
275
-
276
- return tab, webrtc_stream, checkboxes
 
1
+ """Tab builders for EVE-based Gradio demos.
2
+
3
+ Both tabs (Offline Inference, Live Inference) follow the same pattern:
4
+
5
+ - Outer ``gr.TabItem`` with the demo-supplied label.
6
+ - Demo-specific feature checkboxes built via a caller-provided callable so
7
+ each demo defines its own feature set (Face Detection / Person /
8
+ Hand Detection / Face ID / …).
9
+ - Optional ``extras_builder`` hook for demo-specific extras inside the tab
10
+ (e.g. eve_hmi's Face ID summary thumbnails).
11
+
12
+ The tab builders return the underlying components so the caller can wire
13
+ events (``process_btn.click``, ``webrtc_stream.stream``, etc.) outside.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ from dataclasses import dataclass
19
+ from typing import Callable, TypeVar
20
+
21
+ import gradio as gr
22
+
23
+ from live_inference import RtcConfigurationInput, build_webrtc_stream
24
+ from video_processing import VideoLimits, build_video_constraints_accordion
25
+
26
+ # The exact tuple of Checkbox components is demo-specific. We let the
27
+ # caller's checkbox-builder define the shape and return it transparently.
28
+ TCheckboxes = TypeVar("TCheckboxes")
29
+
30
+
31
+ def build_offline_inference_tab(
32
+ *,
33
+ feature_checkbox_builder: Callable[..., TCheckboxes],
34
+ example_videos: list,
35
+ video_limits: VideoLimits,
36
+ extras_builder: Callable[[], None] | None = None,
37
+ tab_label: str = "Offline Inference",
38
+ feature_hint: str = "applied when processing starts",
39
+ ) -> tuple[
40
+ gr.TabItem,
41
+ gr.Video,
42
+ gr.Video,
43
+ TCheckboxes,
44
+ gr.Button,
45
+ gr.Dataset,
46
+ ]:
47
+ """Build the Offline Inference tab. Must be called inside a ``gr.Tabs`` context.
48
+
49
+ Args:
50
+ feature_checkbox_builder: Callable that builds the demo's feature
51
+ checkboxes inside the tab. Receives the keyword ``hint`` (a
52
+ short string shown next to the "Features" heading). Returns a
53
+ tuple of ``gr.Checkbox`` instances — the same tuple is returned
54
+ unchanged so the caller can wire events.
55
+ example_videos: Pre-loaded example videos (list of ``[path]`` rows).
56
+ video_limits: Upload constraints rendered in the accordion.
57
+ extras_builder: Optional callable invoked after the input/output
58
+ video columns to add demo-specific widgets (e.g. a Face ID
59
+ summary). Called inside the same row, so it shares horizontal
60
+ space with the videos.
61
+ tab_label: Tab label text (default ``"Offline Inference"``).
62
+ feature_hint: Short hint shown next to the Features heading.
63
+
64
+ Returns:
65
+ ``(tab, input_video, output_video, checkboxes, process_btn, example_dataset)``.
66
+ ``checkboxes`` is exactly what ``feature_checkbox_builder`` returned.
67
+ """
68
+ with gr.TabItem(tab_label) as video_tab:
69
+ with gr.Accordion("Instructions", open=False):
70
+ gr.Markdown(
71
+ "1. Select the features that will be processed on the video\n"
72
+ "2. Select a video (or upload your own in the Input Video frame)\n"
73
+ "3. Press the **Process Video** button\n\n"
74
+ "Once the video has been processed, you can play the video in the "
75
+ "Output Video frame"
76
+ )
77
+
78
+ checkboxes = feature_checkbox_builder(hint=feature_hint)
79
+
80
+ with gr.Accordion("Video Examples", open=True):
81
+ example_dataset = gr.Dataset(
82
+ components=[gr.Video(visible=False)],
83
+ samples=example_videos,
84
+ show_label=False,
85
+ )
86
+
87
+ process_btn = gr.Button("Process Video", variant="primary", interactive=False)
88
+
89
+ build_video_constraints_accordion(video_limits)
90
+
91
+ with gr.Row(equal_height=True):
92
+ with gr.Column(scale=5):
93
+ input_video = gr.Video(label="Input Video", sources=["upload", "webcam"])
94
+ with gr.Column(scale=5):
95
+ output_video = gr.Video(label="Output Video")
96
+ if extras_builder is not None:
97
+ extras_builder()
98
+
99
+ return video_tab, input_video, output_video, checkboxes, process_btn, example_dataset
100
+
101
+
102
+ @dataclass
103
+ class ImageOrVideoOfflineTab:
104
+ """Components returned by :func:`build_image_or_video_offline_tab`.
105
+
106
+ The image/video accordions are exposed so the caller can wire mutual
107
+ exclusion (expanding one collapses the other) — same pattern as
108
+ :class:`face_id_tab.FaceIdTab`.
109
+ """
110
+
111
+ tab: gr.TabItem
112
+ image_input: gr.Image
113
+ video_input: gr.Video
114
+ image_output: gr.Image
115
+ video_output: gr.Video
116
+ checkboxes: object # demo-specific (radio, checkbox tuple, etc.)
117
+ process_btn: gr.Button
118
+ image_example_dataset: gr.Dataset | None
119
+ video_example_dataset: gr.Dataset | None
120
+ image_accordion: gr.Accordion
121
+ video_accordion: gr.Accordion
122
+
123
+
124
+ def build_image_or_video_offline_tab(
125
+ *,
126
+ feature_checkbox_builder: Callable[..., TCheckboxes],
127
+ image_examples: list | None,
128
+ video_examples: list | None,
129
+ video_limits: VideoLimits,
130
+ tab_label: str = "Offline Inference",
131
+ feature_hint: str = "applied when processing starts",
132
+ ) -> ImageOrVideoOfflineTab:
133
+ """Build an Offline Inference tab that accepts image OR video.
134
+
135
+ Pattern: two mutually-exclusive accordions on the input side ("Input
136
+ from an Image" / "Input from a Video"), one Process button, two
137
+ output components (image + video) shown side-by-side. Caller is
138
+ responsible for:
139
+
140
+ - Wiring ``image_accordion`` / ``video_accordion`` mutual exclusion
141
+ (one-liner per side, see ``face_id_tab.FaceIdTab.wire``).
142
+ - Routing ``process_btn.click`` to a handler that dispatches by
143
+ which input is populated.
144
+ - Toggling output visibility based on which branch ran.
145
+
146
+ Args:
147
+ feature_checkbox_builder: Callable that builds the demo's feature
148
+ checkboxes/radio inside the tab. Called with keyword
149
+ ``hint=feature_hint``.
150
+ image_examples: Pre-loaded image examples (list of ``[path]``
151
+ rows) or ``None`` to skip the examples accordion.
152
+ video_examples: Same for videos.
153
+ video_limits: Upload constraints rendered inside the video
154
+ accordion.
155
+ tab_label: Tab label text.
156
+ feature_hint: Short hint shown next to the Features heading.
157
+ """
158
+ with gr.TabItem(tab_label) as tab:
159
+ with gr.Accordion("Instructions", open=False):
160
+ gr.Markdown(
161
+ "1. Select the model that will be used for object detection\n"
162
+ "2. Choose between processing an **Image** or a **Video**:\n"
163
+ " - For an image: select an example or upload your own, then press "
164
+ "**Process**.\n"
165
+ " - For a video: expand the video section, select an example or "
166
+ "upload your own, then press **Process**.\n\n"
167
+ "Once processing is complete, the annotated result appears on the "
168
+ "right (image or video, depending on the input)."
169
+ )
170
+
171
+ checkboxes = feature_checkbox_builder(hint=feature_hint)
172
+
173
+ with gr.Row():
174
+ # --- Left column: input ---
175
+ with gr.Column(scale=5):
176
+ image_example_dataset: gr.Dataset | None = None
177
+ video_example_dataset: gr.Dataset | None = None
178
+
179
+ with gr.Accordion(
180
+ "Input from an Image", open=True
181
+ ) as image_accordion:
182
+ if image_examples:
183
+ with gr.Accordion("Image Examples", open=True):
184
+ image_example_dataset = gr.Dataset(
185
+ components=[gr.Image(visible=False)],
186
+ samples=image_examples,
187
+ show_label=False,
188
+ )
189
+ image_input = gr.Image(
190
+ label="Input Image",
191
+ sources=["upload", "webcam"],
192
+ type="filepath",
193
+ )
194
+
195
+ with gr.Accordion(
196
+ "Input from a Video", open=False
197
+ ) as video_accordion:
198
+ if video_examples:
199
+ with gr.Accordion("Video Examples", open=True):
200
+ video_example_dataset = gr.Dataset(
201
+ components=[gr.Video(visible=False)],
202
+ samples=video_examples,
203
+ show_label=False,
204
+ )
205
+ build_video_constraints_accordion(video_limits)
206
+ video_input = gr.Video(
207
+ label="Input Video", sources=["upload", "webcam"]
208
+ )
209
+
210
+ process_btn = gr.Button(
211
+ "Process", variant="primary", interactive=False
212
+ )
213
+
214
+ # --- Right column: output (image OR video, toggled by handler) ---
215
+ with gr.Column(scale=5):
216
+ image_output = gr.Image(label="Output Image", visible=True)
217
+ video_output = gr.Video(label="Output Video", visible=False)
218
+
219
+ return ImageOrVideoOfflineTab(
220
+ tab=tab,
221
+ image_input=image_input,
222
+ video_input=video_input,
223
+ image_output=image_output,
224
+ video_output=video_output,
225
+ checkboxes=checkboxes,
226
+ process_btn=process_btn,
227
+ image_example_dataset=image_example_dataset,
228
+ video_example_dataset=video_example_dataset,
229
+ image_accordion=image_accordion,
230
+ video_accordion=video_accordion,
231
+ )
232
+
233
+
234
+ def build_live_inference_tab(
235
+ *,
236
+ rtc_configuration: RtcConfigurationInput,
237
+ feature_checkbox_builder: Callable[..., TCheckboxes],
238
+ extras_builder: Callable[[], None] | None = None,
239
+ max_fps: int = 15,
240
+ width: int = 640,
241
+ height: int = 360,
242
+ tab_label: str = "Live Inference",
243
+ description_html: str = (
244
+ "<p>Use your webcam for real-time inference. "
245
+ "Select features below, then grant camera access when prompted.</p>"
246
+ ),
247
+ ) -> tuple[gr.TabItem, object, TCheckboxes]:
248
+ """Build the Live Inference tab with feature checkboxes + WebRTC stream.
249
+
250
+ Args:
251
+ rtc_configuration: ICE configuration dict, callable that returns
252
+ one, or ``None`` for direct connection. A callable is invoked
253
+ per-connection by FastRTC, allowing credential refresh.
254
+ feature_checkbox_builder: Callable that builds the demo's feature
255
+ checkboxes (same shape as in the offline tab).
256
+ extras_builder: Optional callable invoked after the WebRTC stream
257
+ for demo-specific widgets (e.g. Face ID summary).
258
+ max_fps: Maximum frame rate requested from the browser camera.
259
+ width / height: Camera frame dimensions in pixels.
260
+ tab_label: Tab label text.
261
+ description_html: Optional HTML shown above the stream.
262
+
263
+ Returns:
264
+ ``(tab, webrtc_stream, checkboxes)``.
265
+ """
266
+ with gr.TabItem(tab_label) as tab:
267
+ if description_html:
268
+ gr.HTML(description_html)
269
+ checkboxes = feature_checkbox_builder()
270
+ webrtc_stream = build_webrtc_stream(
271
+ rtc_configuration, max_fps=max_fps, width=width, height=height
272
+ )
273
+ if extras_builder is not None:
274
+ extras_builder()
275
+
276
+ return tab, webrtc_stream, checkboxes
shared/eve_inference_handlers.py CHANGED
@@ -1,485 +1,509 @@
1
- """Offline + live inference handlers shared by EVE-based Gradio demos.
2
-
3
- The two main handlers (``run_eve_inference`` for the Offline Inference tab,
4
- ``process_live_frame`` for the Live Inference tab) used to live in
5
- ``eve_hmi/app.py``. They are bundled on an ``EveAppHandlers`` instance so
6
- demos can wire them with one ``handlers = EveAppHandlers(...)`` line and
7
- re-use them as Gradio callbacks.
8
-
9
- Face ID is opt-in: pass an empty / ``None`` ``registry`` and Face ID
10
- behaviour is bypassed (gallery restore is skipped, the ``face_id`` flag
11
- still travels through ``FeatureFlags`` so the EVE SDK can act on it).
12
- """
13
-
14
- from __future__ import annotations
15
-
16
- import logging
17
- import os
18
- import shutil
19
- import tempfile
20
- import threading
21
- import time
22
- import uuid
23
- from typing import TYPE_CHECKING
24
-
25
- import cv2
26
- import gradio as gr
27
- import numpy as np
28
-
29
- from eve_messages import FeatureFlags
30
- from eve_worker_pool import log_worker_activity
31
- from face_id_tab import FaceEntry # runtime import: Gradio resolves type hints at wire time
32
- from frame_drawing import draw_countdown_banner, draw_overlay, draw_session_timer
33
-
34
- if TYPE_CHECKING:
35
- from eve_worker_pool import EveWorkerPool
36
- from live_stream_manager import LiveStreamManager
37
- from session_tracker import SessionTracker
38
- from video_file_server import VideoFileServer
39
-
40
-
41
- def patch_video_for_external_urls(video_component: gr.Video) -> None:
42
- """Patch a ``gr.Video`` so HTTP(S) URLs bypass Gradio's safehttpx download.
43
-
44
- Gradio's default postprocessing fetches HTTP URLs via ``safehttpx``,
45
- which refuses localhost / private IPs. Setting both ``FileData.path``
46
- and ``FileData.url`` short-circuits the cache logic in
47
- ``async_move_files_to_cache`` so the browser plays the URL directly.
48
- """
49
- from gradio.components.video import VideoData
50
- from gradio.data_classes import FileData
51
-
52
- original = video_component.postprocess
53
-
54
- def _postprocess(value): # type: ignore[no-untyped-def]
55
- if isinstance(value, str) and value.startswith(("http://", "https://")):
56
- return VideoData(video=FileData(path=value, url=value))
57
- return original(value)
58
-
59
- video_component.postprocess = _postprocess # type: ignore[assignment]
60
-
61
-
62
- class EveAppHandlers:
63
- """Gradio-callable handlers for EVE offline + live inference.
64
-
65
- Args:
66
- pool: The shared worker pool.
67
- stream_manager: ``LiveStreamManager`` driving WebRTC streams.
68
- sessions: ``SessionTracker`` for analytics + idle reaping.
69
- logger: Logger used for per-session log lines.
70
- max_fps / min_fps: FPS bounds forwarded to ``send_process_video``
71
- (controls the worker-side encoding rate).
72
- video_server: Optional local HTTP server for processed videos.
73
- When set, processed clips are returned as URLs instead of raw
74
- paths so Chrome's per-origin connection limit doesn't block
75
- playback while SSE is open.
76
- """
77
-
78
- def __init__(
79
- self,
80
- pool: EveWorkerPool,
81
- stream_manager: LiveStreamManager,
82
- sessions: SessionTracker,
83
- logger: logging.Logger,
84
- max_fps: float | None,
85
- min_fps: float | None,
86
- video_server: VideoFileServer | None = None,
87
- ) -> None:
88
- self._pool = pool
89
- self._stream = stream_manager
90
- self._sessions = sessions
91
- self._logger = logger
92
- self._max_fps = max_fps
93
- self._min_fps = min_fps
94
- self._video_server = video_server
95
- self._live_logged: set[str] = set()
96
- self._live_logged_lock = threading.Lock()
97
-
98
- # ----- offline inference -------------------------------------------------
99
-
100
- def run_eve_inference(
101
- self,
102
- input_video: str,
103
- face_detection: bool,
104
- person_detection: bool,
105
- face_id: bool,
106
- hand_gesture: bool,
107
- registry: dict[int, FaceEntry] | None,
108
- mod_model: str | None = None,
109
- request: gr.Request | None = None,
110
- progress: gr.Progress = gr.Progress(),
111
- ) -> tuple[str | None, dict[int, FaceEntry]]:
112
- """Process an uploaded video through one EVE worker, end-to-end.
113
-
114
- The whole read → infer → encode → write loop happens inside the
115
- worker process so the asyncio event loop stays free for SSE
116
- delivery. The main thread only forwards the path/config and
117
- relays small progress dicts.
118
-
119
- Returns ``(output_url_or_path, registry)``. ``registry`` is
120
- returned unchanged when Face ID is disabled, or with ``sdk_id``
121
- fields refreshed from the worker's gallery-restore results.
122
- """
123
- registry = registry or {}
124
- session = request.session_hash[:8]
125
- self._sessions.track(
126
- request.session_hash,
127
- "video_process",
128
- face_detection=face_detection,
129
- person_detection=person_detection,
130
- face_id=face_id,
131
- hand_gesture=hand_gesture,
132
- mod_model=mod_model,
133
- )
134
-
135
- fps, width, height, total_frames = _read_video_metadata(input_video)
136
- if total_frames <= 0:
137
- raise gr.Error("Could not read any frames from the video.")
138
-
139
- features = FeatureFlags(
140
- face_detection=face_detection,
141
- person_detection=person_detection,
142
- face_id=face_id,
143
- hand_gesture=hand_gesture,
144
- mod_model=mod_model,
145
- )
146
-
147
- gallery_paths: list[str] = []
148
- remove_all_users = False
149
- if face_id and registry:
150
- gallery_paths = [entry.path for entry in registry.values()]
151
- elif face_id:
152
- remove_all_users = True
153
-
154
- # Write directly into Gradio's cache so postprocessing skips the
155
- # expensive hash_file + shutil.copy2 that would block the asyncio
156
- # event loop.
157
- gradio_cache = os.path.join(tempfile.gettempdir(), "gradio")
158
- session_out = os.path.join(gradio_cache, f"eve_{request.session_hash}")
159
- os.makedirs(session_out, exist_ok=True)
160
- output_path = os.path.join(session_out, f"output_{uuid.uuid4().hex[:8]}.mp4")
161
-
162
- self._logger.info(f"[{session}] run_eve_inference: waiting for worker...")
163
- # Only emit queue events when we actually have to wait — matches the
164
- # live queue behaviour so dashboards don't show phantom peaks.
165
- will_wait = self._pool.idle_count == 0
166
- if will_wait:
167
- self._sessions.track(request.session_hash, "offline_queue_enter")
168
- t0 = time.monotonic()
169
- worker = self._pool.acquire(
170
- request.session_hash,
171
- timeout=300.0,
172
- progress=progress,
173
- eta_fn=self._stream.estimated_wait,
174
- )
175
- if will_wait:
176
- self._sessions.track(
177
- request.session_hash,
178
- "offline_queue_exit",
179
- wait_seconds=round(time.monotonic() - t0, 1),
180
- )
181
- log_worker_activity(
182
- self._logger, "acquired", "video-processing", self._pool, worker.worker_id
183
- )
184
- try:
185
- frames_processed, gallery_results = worker.send_process_video(
186
- input_path=input_video,
187
- output_path=output_path,
188
- features=features,
189
- gallery_paths=gallery_paths,
190
- remove_all_users=remove_all_users,
191
- fps=fps,
192
- width=width,
193
- height=height,
194
- total_frames=total_frames,
195
- progress=progress,
196
- max_fps=self._max_fps,
197
- min_fps=self._min_fps,
198
- )
199
- self._logger.info(
200
- f"[{session}] run_eve_inference: done, {frames_processed} frames processed"
201
- )
202
- finally:
203
- self._pool.release(worker)
204
- log_worker_activity(
205
- self._logger, "released", "video-processing", self._pool, worker.worker_id
206
- )
207
- self._sessions.track(
208
- request.session_hash,
209
- "video_process_complete",
210
- duration_seconds=round(time.monotonic() - t0, 1),
211
- )
212
-
213
- if gallery_results:
214
- for entry, r in zip(registry.values(), gallery_results):
215
- entry.sdk_id = r.user_id if r.success else None
216
-
217
- if self._video_server is not None:
218
- rel_path = os.path.relpath(output_path, gradio_cache)
219
- video_result: str | None = self._video_server.build_url(rel_path, request)
220
- else:
221
- video_result = output_path
222
-
223
- return video_result, registry
224
-
225
- # ----- offline image inference -------------------------------------------
226
-
227
- def run_eve_image_inference(
228
- self,
229
- input_image: str | None,
230
- face_detection: bool,
231
- person_detection: bool,
232
- face_id: bool,
233
- hand_gesture: bool,
234
- registry: dict[int, FaceEntry] | None,
235
- mod_model: str | None = None,
236
- request: gr.Request | None = None,
237
- progress: gr.Progress = gr.Progress(),
238
- ) -> tuple[np.ndarray | None, dict[int, FaceEntry]]:
239
- """Run a single image through one EVE worker, end-to-end.
240
-
241
- Single-frame variant of :meth:`run_eve_inference`. Loads the image
242
- as BGR, sends one ``InferenceCmd`` to the worker (the same path
243
- that powers live inference), and returns the annotated result as
244
- an RGB ``np.ndarray`` ready for ``gr.Image``.
245
-
246
- Returns ``(annotated_image_rgb_or_None, registry)``. Registry is
247
- returned unchanged — single-image inference does not refresh
248
- Face ID gallery state.
249
- """
250
- if not input_image:
251
- raise gr.Error("Please upload an image.")
252
-
253
- registry = registry or {}
254
- session = request.session_hash[:8] if request is not None else "?"
255
- if request is not None:
256
- self._sessions.track(
257
- request.session_hash,
258
- "image_process",
259
- face_detection=face_detection,
260
- person_detection=person_detection,
261
- face_id=face_id,
262
- hand_gesture=hand_gesture,
263
- mod_model=mod_model,
264
- )
265
-
266
- frame = cv2.imread(input_image)
267
- if frame is None:
268
- raise gr.Error(f"Could not read image: {input_image}")
269
-
270
- features = FeatureFlags(
271
- face_detection=face_detection,
272
- person_detection=person_detection,
273
- face_id=face_id,
274
- hand_gesture=hand_gesture,
275
- mod_model=mod_model,
276
- )
277
-
278
- self._logger.info(f"[{session}] run_eve_image_inference: waiting for worker...")
279
- will_wait = self._pool.idle_count == 0
280
- if will_wait and request is not None:
281
- self._sessions.track(request.session_hash, "offline_queue_enter")
282
- t0 = time.monotonic()
283
- worker = self._pool.acquire(
284
- request.session_hash if request is not None else "image",
285
- timeout=300.0,
286
- progress=progress,
287
- eta_fn=self._stream.estimated_wait,
288
- )
289
- if will_wait and request is not None:
290
- self._sessions.track(
291
- request.session_hash,
292
- "offline_queue_exit",
293
- wait_seconds=round(time.monotonic() - t0, 1),
294
- )
295
- log_worker_activity(
296
- self._logger, "acquired", "image-processing", self._pool, worker.worker_id
297
- )
298
- try:
299
- result = worker.send_inference(frame, features)
300
- self._logger.info(f"[{session}] run_eve_image_inference: done")
301
- finally:
302
- self._pool.release(worker)
303
- log_worker_activity(
304
- self._logger, "released", "image-processing", self._pool, worker.worker_id
305
- )
306
- if request is not None:
307
- self._sessions.track(
308
- request.session_hash,
309
- "image_process_complete",
310
- duration_seconds=round(time.monotonic() - t0, 1),
311
- )
312
-
313
- # Worker returns BGR (matches live-inference frame format); Gradio's
314
- # gr.Image expects RGB.
315
- result_rgb = cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
316
- return result_rgb, registry
317
-
318
- # ----- live inference ----------------------------------------------------
319
-
320
- def process_live_frame(
321
- self,
322
- frame: np.ndarray,
323
- face_detection: bool,
324
- person_detection: bool,
325
- face_id: bool,
326
- hand_gesture: bool,
327
- registry: dict[int, FaceEntry] | None,
328
- session_hash: str,
329
- mod_model: str | None = None,
330
- ):
331
- # Return type intentionally unannotated: actual return is
332
- # ``np.ndarray | fastrtc.CloseStream | None`` but ``CloseStream`` is
333
- # only imported lazily inside the function (avoids pulling fastrtc
334
- # into module scope), and Gradio/FastRTC may run ``get_type_hints``
335
- # on bound handlers — a forward-ref string would break that.
336
- """Run a single WebRTC frame through an EVE worker.
337
-
338
- A worker is acquired on the first frame and held for the lifetime of
339
- the stream. Returns the frame with an overlay while waiting for a
340
- worker, or a ``CloseStream`` when the session ends so the UI can
341
- reset to ``Start Inference``.
342
-
343
- ``gr.Request`` is not available inside FastRTC stream handlers, so
344
- the Gradio session hash is passed through ``gr.State``. FastRTC's
345
- per-connection ``webrtc_id`` is still pulled from
346
- ``current_context`` to track worker assignment per peer.
347
- """
348
- if frame is None:
349
- return None
350
-
351
- from fastrtc.utils import current_context
352
-
353
- connection_id = current_context.get().webrtc_id
354
- worker, reason = self._stream.get_or_acquire(connection_id, session_hash, registry or {})
355
- if worker is None:
356
- if reason == "waiting":
357
- pos, total = self._stream.waiting_position(connection_id)
358
- eta = self._stream.estimated_wait(pos)
359
- eta_text = ""
360
- if eta is not None:
361
- eta_mins = max(0.5, round(eta / 30) * 0.5)
362
- eta_text = f"\nest. wait ~{eta_mins:g} minutes"
363
- if total > 1:
364
- return draw_overlay(frame, f"In queue {eta_text}")
365
- return draw_overlay(frame, f"Waiting for available worker...{eta_text}")
366
- with self._live_logged_lock:
367
- self._live_logged.discard(connection_id)
368
- from fastrtc import CloseStream
369
-
370
- return CloseStream(reason or "Stream ended")
371
-
372
- bridge = self._stream.get_bridge(connection_id)
373
- if bridge is None or not bridge.is_alive:
374
- self._stream.release(connection_id)
375
- return draw_overlay(frame, "Inference error - retrying...")
376
-
377
- with self._live_logged_lock:
378
- first_frame = connection_id not in self._live_logged
379
- if first_frame:
380
- self._live_logged.add(connection_id)
381
- if first_frame:
382
- self._sessions.track(
383
- session_hash,
384
- "live_start",
385
- face_detection=face_detection,
386
- person_detection=person_detection,
387
- face_id=face_id,
388
- hand_gesture=hand_gesture,
389
- mod_model=mod_model,
390
- )
391
-
392
- features = FeatureFlags(
393
- face_detection=face_detection,
394
- person_detection=person_detection,
395
- face_id=face_id,
396
- hand_gesture=hand_gesture,
397
- mod_model=mod_model,
398
- )
399
- try:
400
- result = bridge.submit_and_get_latest(frame, features)
401
- if result is None:
402
- # First frame no inference result yet, show camera feed
403
- return frame
404
-
405
- remaining = self._stream.countdown_remaining(connection_id)
406
- if remaining is not None:
407
- secs = int(remaining) + 1
408
- result = draw_countdown_banner(result, f"Other users waiting - stopping in {secs}s")
409
-
410
- session_left = self._stream.session_remaining(connection_id)
411
- if session_left is not None:
412
- result = draw_session_timer(result, session_left)
413
-
414
- return result
415
- except (BrokenPipeError, EOFError, OSError):
416
- # Worker pipe is gone (shutdown or crash) — release quietly
417
- self._stream.release(connection_id)
418
- return None
419
- except Exception as exc:
420
- self._logger.error(f"Live inference error: {exc}")
421
- self._stream.release(connection_id)
422
- return draw_overlay(frame, "Inference error - retrying...")
423
-
424
- def on_live_feature_change(
425
- self,
426
- face_detection: bool,
427
- person_detection: bool,
428
- face_id: bool,
429
- hand_gesture: bool,
430
- mod_model: str | None = None,
431
- request: gr.Request | None = None,
432
- ) -> None:
433
- """Track changes to the Live tab's feature checkboxes."""
434
- self._sessions.track(
435
- request.session_hash,
436
- "live_feature_change",
437
- face_detection=face_detection,
438
- person_detection=person_detection,
439
- face_id=face_id,
440
- hand_gesture=hand_gesture,
441
- mod_model=mod_model,
442
- )
443
-
444
- # ----- session cleanup ---------------------------------------------------
445
-
446
- def cleanup_session(self, request: gr.Request) -> None:
447
- """Gradio ``demo.unload`` handler — close the session + delete cache."""
448
- self._sessions.on_unload(request)
449
-
450
- gradio_cache = os.path.join(tempfile.gettempdir(), "gradio")
451
- session_out = os.path.join(gradio_cache, f"eve_{request.session_hash}")
452
- if os.path.isdir(session_out):
453
- shutil.rmtree(session_out, ignore_errors=True)
454
- self._logger.debug(f"Session cleanup: removed {session_out}")
455
-
456
-
457
- def _read_video_metadata(path: str) -> tuple[float, int, int, int]:
458
- """Return ``(fps, width, height, total_frames)`` for a video file.
459
-
460
- Webcam-recorded WebM blobs frequently lie in their headers (fps=0,
461
- fps=1000 from ms timestamps, or no frame count) so we fall back to a
462
- full decode pass when the headers look implausible.
463
- """
464
- cap = cv2.VideoCapture(path)
465
- fps = cap.get(cv2.CAP_PROP_FPS)
466
- width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
467
- height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
468
- total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
469
-
470
- if fps <= 0 or fps > 240 or total_frames <= 0 or width <= 0 or height <= 0:
471
- frame_count = 0
472
- duration_ms = 0.0
473
- while True:
474
- ret, frame = cap.read()
475
- if not ret:
476
- break
477
- if frame_count == 0:
478
- height, width = frame.shape[:2]
479
- frame_count += 1
480
- duration_ms = cap.get(cv2.CAP_PROP_POS_MSEC)
481
- total_frames = frame_count
482
- if fps <= 0 or fps > 240:
483
- fps = total_frames / (duration_ms / 1000.0) if duration_ms > 0 else 30.0
484
- cap.release()
485
- return fps, width, height, total_frames
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Offline + live inference handlers shared by EVE-based Gradio demos.
2
+
3
+ The two main handlers (``run_eve_inference`` for the Offline Inference tab,
4
+ ``process_live_frame`` for the Live Inference tab) used to live in
5
+ ``eve_hmi/app.py``. They are bundled on an ``EveAppHandlers`` instance so
6
+ demos can wire them with one ``handlers = EveAppHandlers(...)`` line and
7
+ re-use them as Gradio callbacks.
8
+
9
+ Face ID is opt-in: pass an empty / ``None`` ``registry`` and Face ID
10
+ behaviour is bypassed (gallery restore is skipped, the ``face_id`` flag
11
+ still travels through ``FeatureFlags`` so the EVE SDK can act on it).
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import logging
17
+ import os
18
+ import shutil
19
+ import tempfile
20
+ import threading
21
+ import time
22
+ import uuid
23
+ from collections.abc import Mapping
24
+ from typing import TYPE_CHECKING
25
+
26
+ import cv2
27
+ import gradio as gr
28
+ import numpy as np
29
+ from eve_messages import FeatureFlags, ModelConfig
30
+ from eve_worker_pool import log_worker_activity
31
+ from face_id_tab import (
32
+ FaceEntry, # runtime import: Gradio resolves type hints at wire time
33
+ )
34
+ from frame_drawing import draw_countdown_banner, draw_overlay, draw_session_timer
35
+
36
+ if TYPE_CHECKING:
37
+ from eve_worker_pool import EveWorkerPool
38
+ from live_stream_manager import LiveStreamManager
39
+ from session_tracker import SessionTracker
40
+ from video_file_server import VideoFileServer
41
+
42
+
43
+ def patch_video_for_external_urls(video_component: gr.Video) -> None:
44
+ """Patch a ``gr.Video`` so HTTP(S) URLs bypass Gradio's safehttpx download.
45
+
46
+ Gradio's default postprocessing fetches HTTP URLs via ``safehttpx``,
47
+ which refuses localhost / private IPs. Setting both ``FileData.path``
48
+ and ``FileData.url`` short-circuits the cache logic in
49
+ ``async_move_files_to_cache`` so the browser plays the URL directly.
50
+ """
51
+ from gradio.components.video import VideoData
52
+ from gradio.data_classes import FileData
53
+
54
+ original = video_component.postprocess
55
+
56
+ def _postprocess(value): # type: ignore[no-untyped-def]
57
+ if isinstance(value, str) and value.startswith(("http://", "https://")):
58
+ return VideoData(video=FileData(path=value, url=value))
59
+ return original(value)
60
+
61
+ video_component.postprocess = _postprocess # type: ignore[assignment]
62
+
63
+
64
+ class EveAppHandlers:
65
+ """Gradio-callable handlers for EVE offline + live inference.
66
+
67
+ Args:
68
+ pool: The shared worker pool.
69
+ stream_manager: ``LiveStreamManager`` driving WebRTC streams.
70
+ sessions: ``SessionTracker`` for analytics + idle reaping.
71
+ logger: Logger used for per-session log lines.
72
+ max_fps / min_fps: FPS bounds forwarded to ``send_process_video``
73
+ (controls the worker-side encoding rate).
74
+ video_server: Optional local HTTP server for processed videos.
75
+ When set, processed clips are returned as URLs instead of raw
76
+ paths so Chrome's per-origin connection limit doesn't block
77
+ playback while SSE is open.
78
+ mod_model_registry: Maps a model-name string (the value carried by a
79
+ demo's MOD radio) to the ``ModelConfig`` the worker should load.
80
+ Demos that do not use MOD (e.g. eve_hmi) omit it; in that case a
81
+ model name resolves to ``None`` and MOD stays off.
82
+ """
83
+
84
+ def __init__(
85
+ self,
86
+ pool: EveWorkerPool,
87
+ stream_manager: LiveStreamManager,
88
+ sessions: SessionTracker,
89
+ logger: logging.Logger,
90
+ max_fps: float | None,
91
+ min_fps: float | None,
92
+ video_server: VideoFileServer | None = None,
93
+ mod_model_registry: Mapping[str, ModelConfig] | None = None,
94
+ ) -> None:
95
+ self._pool = pool
96
+ self._stream = stream_manager
97
+ self._sessions = sessions
98
+ self._logger = logger
99
+ self._max_fps = max_fps
100
+ self._min_fps = min_fps
101
+ self._video_server = video_server
102
+ self._mod_model_registry = mod_model_registry or {}
103
+ self._live_logged: set[str] = set()
104
+ self._live_logged_lock = threading.Lock()
105
+
106
+ def _resolve_mod_model(self, mod_model: str | None) -> ModelConfig | None:
107
+ """Resolve a MOD radio value to the ``ModelConfig`` the worker loads.
108
+
109
+ ``None`` / empty (MOD off, or a demo with no MOD radio) yields
110
+ ``None``. An unknown name with no registry entry falls back to a
111
+ bare ``ModelConfig`` (no path) so the SDK's bundled default model is
112
+ used rather than failing.
113
+ """
114
+ if not mod_model:
115
+ return None
116
+ config = self._mod_model_registry.get(mod_model)
117
+ if config is None:
118
+ self._logger.warning(f"Unknown MOD model {mod_model!r}; using bundled default")
119
+ return ModelConfig(name=mod_model)
120
+ return config
121
+
122
+ # ----- offline inference -------------------------------------------------
123
+
124
+ def run_eve_inference(
125
+ self,
126
+ input_video: str,
127
+ face_detection: bool,
128
+ person_detection: bool,
129
+ face_id: bool,
130
+ hand_gesture: bool,
131
+ registry: dict[int, FaceEntry] | None,
132
+ mod_model: str | None = None,
133
+ request: gr.Request | None = None,
134
+ progress: gr.Progress = gr.Progress(),
135
+ ) -> tuple[str | None, dict[int, FaceEntry]]:
136
+ """Process an uploaded video through one EVE worker, end-to-end.
137
+
138
+ The whole read → infer → encode → write loop happens inside the
139
+ worker process so the asyncio event loop stays free for SSE
140
+ delivery. The main thread only forwards the path/config and
141
+ relays small progress dicts.
142
+
143
+ Returns ``(output_url_or_path, registry)``. ``registry`` is
144
+ returned unchanged when Face ID is disabled, or with ``sdk_id``
145
+ fields refreshed from the worker's gallery-restore results.
146
+ """
147
+ registry = registry or {}
148
+ session = request.session_hash[:8]
149
+ self._sessions.track(
150
+ request.session_hash,
151
+ "video_process",
152
+ face_detection=face_detection,
153
+ person_detection=person_detection,
154
+ face_id=face_id,
155
+ hand_gesture=hand_gesture,
156
+ mod_model=mod_model,
157
+ )
158
+
159
+ fps, width, height, total_frames = _read_video_metadata(input_video)
160
+ if total_frames <= 0:
161
+ raise gr.Error("Could not read any frames from the video.")
162
+
163
+ features = FeatureFlags(
164
+ face_detection=face_detection,
165
+ person_detection=person_detection,
166
+ face_id=face_id,
167
+ hand_gesture=hand_gesture,
168
+ mod_model_config=self._resolve_mod_model(mod_model),
169
+ )
170
+
171
+ gallery_paths: list[str] = []
172
+ remove_all_users = False
173
+ if face_id and registry:
174
+ gallery_paths = [entry.path for entry in registry.values()]
175
+ elif face_id:
176
+ remove_all_users = True
177
+
178
+ # Write directly into Gradio's cache so postprocessing skips the
179
+ # expensive hash_file + shutil.copy2 that would block the asyncio
180
+ # event loop.
181
+ gradio_cache = os.path.join(tempfile.gettempdir(), "gradio")
182
+ session_out = os.path.join(gradio_cache, f"eve_{request.session_hash}")
183
+ os.makedirs(session_out, exist_ok=True)
184
+ output_path = os.path.join(session_out, f"output_{uuid.uuid4().hex[:8]}.mp4")
185
+
186
+ self._logger.info(f"[{session}] run_eve_inference: waiting for worker...")
187
+ # Only emit queue events when we actually have to wait — matches the
188
+ # live queue behaviour so dashboards don't show phantom peaks.
189
+ will_wait = self._pool.idle_count == 0
190
+ if will_wait:
191
+ self._sessions.track(request.session_hash, "offline_queue_enter")
192
+ t0 = time.monotonic()
193
+ worker = self._pool.acquire(
194
+ request.session_hash,
195
+ timeout=300.0,
196
+ progress=progress,
197
+ eta_fn=self._stream.estimated_wait,
198
+ )
199
+ if will_wait:
200
+ self._sessions.track(
201
+ request.session_hash,
202
+ "offline_queue_exit",
203
+ wait_seconds=round(time.monotonic() - t0, 1),
204
+ )
205
+ log_worker_activity(
206
+ self._logger, "acquired", "video-processing", self._pool, worker.worker_id
207
+ )
208
+ try:
209
+ frames_processed, gallery_results = worker.send_process_video(
210
+ input_path=input_video,
211
+ output_path=output_path,
212
+ features=features,
213
+ gallery_paths=gallery_paths,
214
+ remove_all_users=remove_all_users,
215
+ fps=fps,
216
+ width=width,
217
+ height=height,
218
+ total_frames=total_frames,
219
+ progress=progress,
220
+ max_fps=self._max_fps,
221
+ min_fps=self._min_fps,
222
+ )
223
+ self._logger.info(
224
+ f"[{session}] run_eve_inference: done, {frames_processed} frames processed"
225
+ )
226
+ finally:
227
+ self._pool.release(worker)
228
+ log_worker_activity(
229
+ self._logger, "released", "video-processing", self._pool, worker.worker_id
230
+ )
231
+ self._sessions.track(
232
+ request.session_hash,
233
+ "video_process_complete",
234
+ duration_seconds=round(time.monotonic() - t0, 1),
235
+ )
236
+
237
+ if gallery_results:
238
+ for entry, r in zip(registry.values(), gallery_results):
239
+ entry.sdk_id = r.user_id if r.success else None
240
+
241
+ if self._video_server is not None:
242
+ rel_path = os.path.relpath(output_path, gradio_cache)
243
+ video_result: str | None = self._video_server.build_url(rel_path, request)
244
+ else:
245
+ video_result = output_path
246
+
247
+ return video_result, registry
248
+
249
+ # ----- offline image inference -------------------------------------------
250
+
251
+ def run_eve_image_inference(
252
+ self,
253
+ input_image: str | None,
254
+ face_detection: bool,
255
+ person_detection: bool,
256
+ face_id: bool,
257
+ hand_gesture: bool,
258
+ registry: dict[int, FaceEntry] | None,
259
+ mod_model: str | None = None,
260
+ request: gr.Request | None = None,
261
+ progress: gr.Progress = gr.Progress(),
262
+ ) -> tuple[np.ndarray | None, dict[int, FaceEntry]]:
263
+ """Run a single image through one EVE worker, end-to-end.
264
+
265
+ Single-frame variant of :meth:`run_eve_inference`. Loads the image
266
+ as BGR, sends one ``InferenceCmd`` to the worker (the same path
267
+ that powers live inference), and returns the annotated result as
268
+ an RGB ``np.ndarray`` ready for ``gr.Image``.
269
+
270
+ Returns ``(annotated_image_rgb_or_None, registry)``. Registry is
271
+ returned unchanged — single-image inference does not refresh
272
+ Face ID gallery state.
273
+ """
274
+ if not input_image:
275
+ raise gr.Error("Please upload an image.")
276
+
277
+ registry = registry or {}
278
+ session = request.session_hash[:8] if request is not None else "?"
279
+ if request is not None:
280
+ self._sessions.track(
281
+ request.session_hash,
282
+ "image_process",
283
+ face_detection=face_detection,
284
+ person_detection=person_detection,
285
+ face_id=face_id,
286
+ hand_gesture=hand_gesture,
287
+ mod_model=mod_model,
288
+ )
289
+
290
+ frame = cv2.imread(input_image)
291
+ if frame is None:
292
+ raise gr.Error(f"Could not read image: {input_image}")
293
+
294
+ features = FeatureFlags(
295
+ face_detection=face_detection,
296
+ person_detection=person_detection,
297
+ face_id=face_id,
298
+ hand_gesture=hand_gesture,
299
+ mod_model_config=self._resolve_mod_model(mod_model),
300
+ )
301
+
302
+ self._logger.info(f"[{session}] run_eve_image_inference: waiting for worker...")
303
+ will_wait = self._pool.idle_count == 0
304
+ if will_wait and request is not None:
305
+ self._sessions.track(request.session_hash, "offline_queue_enter")
306
+ t0 = time.monotonic()
307
+ worker = self._pool.acquire(
308
+ request.session_hash if request is not None else "image",
309
+ timeout=300.0,
310
+ progress=progress,
311
+ eta_fn=self._stream.estimated_wait,
312
+ )
313
+ if will_wait and request is not None:
314
+ self._sessions.track(
315
+ request.session_hash,
316
+ "offline_queue_exit",
317
+ wait_seconds=round(time.monotonic() - t0, 1),
318
+ )
319
+ log_worker_activity(
320
+ self._logger, "acquired", "image-processing", self._pool, worker.worker_id
321
+ )
322
+ try:
323
+ result = worker.send_inference(frame, features)
324
+ self._logger.info(f"[{session}] run_eve_image_inference: done")
325
+ finally:
326
+ self._pool.release(worker)
327
+ log_worker_activity(
328
+ self._logger, "released", "image-processing", self._pool, worker.worker_id
329
+ )
330
+ if request is not None:
331
+ self._sessions.track(
332
+ request.session_hash,
333
+ "image_process_complete",
334
+ duration_seconds=round(time.monotonic() - t0, 1),
335
+ )
336
+
337
+ # Worker returns BGR (matches live-inference frame format); Gradio's
338
+ # gr.Image expects RGB.
339
+ result_rgb = cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
340
+ return result_rgb, registry
341
+
342
+ # ----- live inference ----------------------------------------------------
343
+
344
+ def process_live_frame(
345
+ self,
346
+ frame: np.ndarray,
347
+ face_detection: bool,
348
+ person_detection: bool,
349
+ face_id: bool,
350
+ hand_gesture: bool,
351
+ registry: dict[int, FaceEntry] | None,
352
+ session_hash: str,
353
+ mod_model: str | None = None,
354
+ ):
355
+ # Return type intentionally unannotated: actual return is
356
+ # ``np.ndarray | fastrtc.CloseStream | None`` but ``CloseStream`` is
357
+ # only imported lazily inside the function (avoids pulling fastrtc
358
+ # into module scope), and Gradio/FastRTC may run ``get_type_hints``
359
+ # on bound handlers — a forward-ref string would break that.
360
+ """Run a single WebRTC frame through an EVE worker.
361
+
362
+ A worker is acquired on the first frame and held for the lifetime of
363
+ the stream. Returns the frame with an overlay while waiting for a
364
+ worker, or a ``CloseStream`` when the session ends so the UI can
365
+ reset to ``Start Inference``.
366
+
367
+ ``gr.Request`` is not available inside FastRTC stream handlers, so
368
+ the Gradio session hash is passed through ``gr.State``. FastRTC's
369
+ per-connection ``webrtc_id`` is still pulled from
370
+ ``current_context`` to track worker assignment per peer.
371
+ """
372
+ if frame is None:
373
+ return None
374
+
375
+ from fastrtc.utils import current_context
376
+
377
+ connection_id = current_context.get().webrtc_id
378
+ worker, reason = self._stream.get_or_acquire(connection_id, session_hash, registry or {})
379
+ if worker is None:
380
+ if reason == "waiting":
381
+ pos, total = self._stream.waiting_position(connection_id)
382
+ eta = self._stream.estimated_wait(pos)
383
+ eta_text = ""
384
+ if eta is not None:
385
+ eta_mins = max(0.5, round(eta / 30) * 0.5)
386
+ eta_text = f"\nest. wait ~{eta_mins:g} minutes"
387
+ if total > 1:
388
+ return draw_overlay(frame, f"In queue {eta_text}")
389
+ return draw_overlay(frame, f"Waiting for available worker...{eta_text}")
390
+ with self._live_logged_lock:
391
+ self._live_logged.discard(connection_id)
392
+ from fastrtc import CloseStream
393
+
394
+ return CloseStream(reason or "Stream ended")
395
+
396
+ bridge = self._stream.get_bridge(connection_id)
397
+ if bridge is None or not bridge.is_alive:
398
+ self._stream.release(connection_id)
399
+ return draw_overlay(frame, "Inference error - retrying...")
400
+
401
+ with self._live_logged_lock:
402
+ first_frame = connection_id not in self._live_logged
403
+ if first_frame:
404
+ self._live_logged.add(connection_id)
405
+ if first_frame:
406
+ self._sessions.track(
407
+ session_hash,
408
+ "live_start",
409
+ face_detection=face_detection,
410
+ person_detection=person_detection,
411
+ face_id=face_id,
412
+ hand_gesture=hand_gesture,
413
+ mod_model=mod_model,
414
+ )
415
+
416
+ features = FeatureFlags(
417
+ face_detection=face_detection,
418
+ person_detection=person_detection,
419
+ face_id=face_id,
420
+ hand_gesture=hand_gesture,
421
+ mod_model_config=self._resolve_mod_model(mod_model),
422
+ )
423
+ try:
424
+ result = bridge.submit_and_get_latest(frame, features)
425
+ if result is None:
426
+ # First frame — no inference result yet, show camera feed
427
+ return frame
428
+
429
+ remaining = self._stream.countdown_remaining(connection_id)
430
+ if remaining is not None:
431
+ secs = int(remaining) + 1
432
+ result = draw_countdown_banner(result, f"Other users waiting - stopping in {secs}s")
433
+
434
+ session_left = self._stream.session_remaining(connection_id)
435
+ if session_left is not None:
436
+ result = draw_session_timer(result, session_left)
437
+
438
+ return result
439
+ except (BrokenPipeError, EOFError, OSError):
440
+ # Worker pipe is gone (shutdown or crash) — release quietly
441
+ self._stream.release(connection_id)
442
+ return None
443
+ except Exception as exc:
444
+ self._logger.error(f"Live inference error: {exc}")
445
+ self._stream.release(connection_id)
446
+ return draw_overlay(frame, "Inference error - retrying...")
447
+
448
+ def on_live_feature_change(
449
+ self,
450
+ face_detection: bool,
451
+ person_detection: bool,
452
+ face_id: bool,
453
+ hand_gesture: bool,
454
+ mod_model: str | None = None,
455
+ request: gr.Request | None = None,
456
+ ) -> None:
457
+ """Track changes to the Live tab's feature checkboxes."""
458
+ self._sessions.track(
459
+ request.session_hash,
460
+ "live_feature_change",
461
+ face_detection=face_detection,
462
+ person_detection=person_detection,
463
+ face_id=face_id,
464
+ hand_gesture=hand_gesture,
465
+ mod_model=mod_model,
466
+ )
467
+
468
+ # ----- session cleanup ---------------------------------------------------
469
+
470
+ def cleanup_session(self, request: gr.Request) -> None:
471
+ """Gradio ``demo.unload`` handler — close the session + delete cache."""
472
+ self._sessions.on_unload(request)
473
+
474
+ gradio_cache = os.path.join(tempfile.gettempdir(), "gradio")
475
+ session_out = os.path.join(gradio_cache, f"eve_{request.session_hash}")
476
+ if os.path.isdir(session_out):
477
+ shutil.rmtree(session_out, ignore_errors=True)
478
+ self._logger.debug(f"Session cleanup: removed {session_out}")
479
+
480
+
481
+ def _read_video_metadata(path: str) -> tuple[float, int, int, int]:
482
+ """Return ``(fps, width, height, total_frames)`` for a video file.
483
+
484
+ Webcam-recorded WebM blobs frequently lie in their headers (fps=0,
485
+ fps=1000 from ms timestamps, or no frame count) so we fall back to a
486
+ full decode pass when the headers look implausible.
487
+ """
488
+ cap = cv2.VideoCapture(path)
489
+ fps = cap.get(cv2.CAP_PROP_FPS)
490
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
491
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
492
+ total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
493
+
494
+ if fps <= 0 or fps > 240 or total_frames <= 0 or width <= 0 or height <= 0:
495
+ frame_count = 0
496
+ duration_ms = 0.0
497
+ while True:
498
+ ret, frame = cap.read()
499
+ if not ret:
500
+ break
501
+ if frame_count == 0:
502
+ height, width = frame.shape[:2]
503
+ frame_count += 1
504
+ duration_ms = cap.get(cv2.CAP_PROP_POS_MSEC)
505
+ total_frames = frame_count
506
+ if fps <= 0 or fps > 240:
507
+ fps = total_frames / (duration_ms / 1000.0) if duration_ms > 0 else 30.0
508
+ cap.release()
509
+ return fps, width, height, total_frames
shared/eve_messages.py CHANGED
@@ -1,231 +1,257 @@
1
- """IPC message dataclasses for the Eve worker pool.
2
-
3
- All types are picklable and sent over ``multiprocessing.Pipe`` between the
4
- main Gradio process and Eve SDK worker processes.
5
- """
6
-
7
- from dataclasses import dataclass
8
-
9
- # ---------------------------------------------------------------------------
10
- # Shared data types
11
- # ---------------------------------------------------------------------------
12
-
13
-
14
- @dataclass
15
- class CalibrationResultMsg:
16
- """Picklable mirror of ``eve_wrapper.CalibrationResult``."""
17
-
18
- success: bool
19
- user_id: int
20
- message: str
21
-
22
-
23
- @dataclass
24
- class FeatureFlags:
25
- """Feature toggle bundle sent with inference / configure commands."""
26
-
27
- face_detection: bool = True
28
- person_detection: bool = True
29
- face_id: bool = False
30
- hand_gesture: bool = False
31
- # None = MOD off. Otherwise a model-name string (e.g. "GMOD-80",
32
- # "AMOD-8", "OMOD") that the worker resolves to the EVE SDK MOD model.
33
- # Defaulted so existing demos keep their pickle shape unchanged.
34
- mod_model: str | None = None
35
-
36
-
37
- @dataclass
38
- class SerializedFrame:
39
- """Picklable representation of a numpy ndarray frame."""
40
-
41
- data: bytes
42
- shape: tuple[int, ...]
43
- dtype: str
44
-
45
-
46
- # ---------------------------------------------------------------------------
47
- # Commands (main process → worker process)
48
- # ---------------------------------------------------------------------------
49
-
50
-
51
- @dataclass
52
- class InferenceCmd:
53
- frame_bytes: bytes
54
- shape: tuple[int, ...]
55
- dtype: str
56
- features: FeatureFlags
57
-
58
-
59
- @dataclass
60
- class ConfigureFeaturesCmd:
61
- features: FeatureFlags
62
-
63
-
64
- @dataclass
65
- class CalibrateNewUserCmd:
66
- frames_data: list[SerializedFrame]
67
-
68
-
69
- @dataclass
70
- class RemoveAllUsersCmd:
71
- pass
72
-
73
-
74
- @dataclass
75
- class RestoreGalleryCmd:
76
- frames_per_user_data: list[list[SerializedFrame]]
77
-
78
-
79
- @dataclass
80
- class EnableFaceIdCmd:
81
- enabled: bool
82
-
83
-
84
- @dataclass
85
- class ProcessVideoCmd:
86
- input_path: str
87
- output_path: str
88
- features: FeatureFlags
89
- gallery_paths: list[str]
90
- remove_all_users: bool
91
- fps: float
92
- width: int
93
- height: int
94
- total_frames: int
95
- max_fps: float | None = None
96
- min_fps: float | None = None
97
-
98
-
99
- @dataclass
100
- class ShutdownCmd:
101
- pass
102
-
103
-
104
- @dataclass
105
- class StartProfilingCmd:
106
- pass
107
-
108
-
109
- @dataclass
110
- class StopProfilingCmd:
111
- pass
112
-
113
-
114
- @dataclass
115
- class GetProfileStatsCmd:
116
- pass
117
-
118
-
119
- @dataclass
120
- class GetTimingStatsCmd:
121
- reset: bool = True
122
-
123
-
124
- WorkerCmd = (
125
- InferenceCmd
126
- | ConfigureFeaturesCmd
127
- | CalibrateNewUserCmd
128
- | RemoveAllUsersCmd
129
- | RestoreGalleryCmd
130
- | EnableFaceIdCmd
131
- | ProcessVideoCmd
132
- | ShutdownCmd
133
- | StartProfilingCmd
134
- | StopProfilingCmd
135
- | GetProfileStatsCmd
136
- | GetTimingStatsCmd
137
- )
138
-
139
-
140
- # ---------------------------------------------------------------------------
141
- # Responses (worker process → main process)
142
- # ---------------------------------------------------------------------------
143
-
144
-
145
- @dataclass
146
- class ReadyResponse:
147
- pid: int
148
-
149
-
150
- @dataclass
151
- class ErrorResponse:
152
- error: str
153
-
154
-
155
- @dataclass
156
- class HeartbeatResponse:
157
- pass
158
-
159
-
160
- @dataclass
161
- class OkResponse:
162
- pass
163
-
164
-
165
- @dataclass
166
- class InferenceResponse:
167
- frame_bytes: bytes
168
- shape: tuple[int, ...]
169
- dtype: str
170
-
171
-
172
- @dataclass
173
- class CalibrateOkResponse:
174
- result: CalibrationResultMsg
175
-
176
-
177
- @dataclass
178
- class RemoveUsersOkResponse:
179
- result: bool
180
-
181
-
182
- @dataclass
183
- class RestoreGalleryOkResponse:
184
- results: list[CalibrationResultMsg]
185
-
186
-
187
- @dataclass
188
- class GalleryRestoredResponse:
189
- results: list[CalibrationResultMsg]
190
-
191
-
192
- @dataclass
193
- class ProgressResponse:
194
- current: int
195
- total: int
196
-
197
-
198
- @dataclass
199
- class VideoProcessingDoneResponse:
200
- frames_processed: int
201
- gallery_results: list[CalibrationResultMsg]
202
- recycle: bool
203
-
204
-
205
- @dataclass
206
- class ProfileStatsResponse:
207
- stats_data: bytes # marshalled pstats data
208
-
209
-
210
- @dataclass
211
- class TimingStatsResponse:
212
- """Per-SDK-call timing data from EveWrapper."""
213
-
214
- stats: dict[str, tuple[int, float]] # {name: (call_count, total_seconds)}
215
-
216
-
217
- WorkerResponse = (
218
- ReadyResponse
219
- | ErrorResponse
220
- | HeartbeatResponse
221
- | OkResponse
222
- | InferenceResponse
223
- | CalibrateOkResponse
224
- | RemoveUsersOkResponse
225
- | RestoreGalleryOkResponse
226
- | GalleryRestoredResponse
227
- | ProgressResponse
228
- | VideoProcessingDoneResponse
229
- | ProfileStatsResponse
230
- | TimingStatsResponse
231
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """IPC message dataclasses for the Eve worker pool.
2
+
3
+ All types are picklable and sent over ``multiprocessing.Pipe`` between the
4
+ main Gradio process and Eve SDK worker processes.
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+
9
+ # ---------------------------------------------------------------------------
10
+ # Shared data types
11
+ # ---------------------------------------------------------------------------
12
+
13
+
14
+ @dataclass
15
+ class CalibrationResultMsg:
16
+ """Picklable mirror of ``eve_wrapper.CalibrationResult``."""
17
+
18
+ success: bool
19
+ user_id: int
20
+ message: str
21
+
22
+
23
+ @dataclass
24
+ class ModelConfig:
25
+ """Resolved EVE object-detection (MOD) model description.
26
+
27
+ Carries everything ``eve_wrapper.enable_object_detection`` needs to
28
+ configure one MOD model. ``model_path`` of ``None`` / ``""`` selects the
29
+ EVE SDK's bundled default model (GMOD-80); a path loads that ``.tflite``
30
+ and applies ``class_names``. ``None`` thresholds fall back to the SDK
31
+ defaults. Picklable so it can ride inside ``FeatureFlags`` to a worker.
32
+
33
+ Attributes:
34
+ name: Human-facing model name (e.g. ``"AMOD-8"``); used for logging.
35
+ model_path: Absolute path to the model file, or ``None`` for bundled.
36
+ class_names: Ordered class labels matching the model's output indices,
37
+ or ``None`` to keep the SDK's default class table.
38
+ nms_threshold: Optional non-max-suppression score threshold override.
39
+ iou_threshold: Optional IoU threshold override.
40
+ """
41
+
42
+ name: str
43
+ model_path: str | None = None
44
+ class_names: tuple[str, ...] | None = None
45
+ nms_threshold: float | None = None
46
+ iou_threshold: float | None = None
47
+
48
+
49
+ @dataclass
50
+ class FeatureFlags:
51
+ """Feature toggle bundle sent with inference / configure commands."""
52
+
53
+ face_detection: bool = True
54
+ person_detection: bool = True
55
+ face_id: bool = False
56
+ hand_gesture: bool = False
57
+ # None = MOD off. Otherwise the resolved MOD model the worker should load.
58
+ # Defaulted so demos that don't use MOD (e.g. eve_hmi) keep their pickle
59
+ # shape unchanged.
60
+ mod_model_config: ModelConfig | None = None
61
+
62
+
63
+ @dataclass
64
+ class SerializedFrame:
65
+ """Picklable representation of a numpy ndarray frame."""
66
+
67
+ data: bytes
68
+ shape: tuple[int, ...]
69
+ dtype: str
70
+
71
+
72
+ # ---------------------------------------------------------------------------
73
+ # Commands (main process → worker process)
74
+ # ---------------------------------------------------------------------------
75
+
76
+
77
+ @dataclass
78
+ class InferenceCmd:
79
+ frame_bytes: bytes
80
+ shape: tuple[int, ...]
81
+ dtype: str
82
+ features: FeatureFlags
83
+
84
+
85
+ @dataclass
86
+ class ConfigureFeaturesCmd:
87
+ features: FeatureFlags
88
+
89
+
90
+ @dataclass
91
+ class CalibrateNewUserCmd:
92
+ frames_data: list[SerializedFrame]
93
+
94
+
95
+ @dataclass
96
+ class RemoveAllUsersCmd:
97
+ pass
98
+
99
+
100
+ @dataclass
101
+ class RestoreGalleryCmd:
102
+ frames_per_user_data: list[list[SerializedFrame]]
103
+
104
+
105
+ @dataclass
106
+ class EnableFaceIdCmd:
107
+ enabled: bool
108
+
109
+
110
+ @dataclass
111
+ class ProcessVideoCmd:
112
+ input_path: str
113
+ output_path: str
114
+ features: FeatureFlags
115
+ gallery_paths: list[str]
116
+ remove_all_users: bool
117
+ fps: float
118
+ width: int
119
+ height: int
120
+ total_frames: int
121
+ max_fps: float | None = None
122
+ min_fps: float | None = None
123
+
124
+
125
+ @dataclass
126
+ class ShutdownCmd:
127
+ pass
128
+
129
+
130
+ @dataclass
131
+ class StartProfilingCmd:
132
+ pass
133
+
134
+
135
+ @dataclass
136
+ class StopProfilingCmd:
137
+ pass
138
+
139
+
140
+ @dataclass
141
+ class GetProfileStatsCmd:
142
+ pass
143
+
144
+
145
+ @dataclass
146
+ class GetTimingStatsCmd:
147
+ reset: bool = True
148
+
149
+
150
+ WorkerCmd = (
151
+ InferenceCmd
152
+ | ConfigureFeaturesCmd
153
+ | CalibrateNewUserCmd
154
+ | RemoveAllUsersCmd
155
+ | RestoreGalleryCmd
156
+ | EnableFaceIdCmd
157
+ | ProcessVideoCmd
158
+ | ShutdownCmd
159
+ | StartProfilingCmd
160
+ | StopProfilingCmd
161
+ | GetProfileStatsCmd
162
+ | GetTimingStatsCmd
163
+ )
164
+
165
+
166
+ # ---------------------------------------------------------------------------
167
+ # Responses (worker process → main process)
168
+ # ---------------------------------------------------------------------------
169
+
170
+
171
+ @dataclass
172
+ class ReadyResponse:
173
+ pid: int
174
+
175
+
176
+ @dataclass
177
+ class ErrorResponse:
178
+ error: str
179
+
180
+
181
+ @dataclass
182
+ class HeartbeatResponse:
183
+ pass
184
+
185
+
186
+ @dataclass
187
+ class OkResponse:
188
+ pass
189
+
190
+
191
+ @dataclass
192
+ class InferenceResponse:
193
+ frame_bytes: bytes
194
+ shape: tuple[int, ...]
195
+ dtype: str
196
+
197
+
198
+ @dataclass
199
+ class CalibrateOkResponse:
200
+ result: CalibrationResultMsg
201
+
202
+
203
+ @dataclass
204
+ class RemoveUsersOkResponse:
205
+ result: bool
206
+
207
+
208
+ @dataclass
209
+ class RestoreGalleryOkResponse:
210
+ results: list[CalibrationResultMsg]
211
+
212
+
213
+ @dataclass
214
+ class GalleryRestoredResponse:
215
+ results: list[CalibrationResultMsg]
216
+
217
+
218
+ @dataclass
219
+ class ProgressResponse:
220
+ current: int
221
+ total: int
222
+
223
+
224
+ @dataclass
225
+ class VideoProcessingDoneResponse:
226
+ frames_processed: int
227
+ gallery_results: list[CalibrationResultMsg]
228
+ recycle: bool
229
+
230
+
231
+ @dataclass
232
+ class ProfileStatsResponse:
233
+ stats_data: bytes # marshalled pstats data
234
+
235
+
236
+ @dataclass
237
+ class TimingStatsResponse:
238
+ """Per-SDK-call timing data from EveWrapper."""
239
+
240
+ stats: dict[str, tuple[int, float]] # {name: (call_count, total_seconds)}
241
+
242
+
243
+ WorkerResponse = (
244
+ ReadyResponse
245
+ | ErrorResponse
246
+ | HeartbeatResponse
247
+ | OkResponse
248
+ | InferenceResponse
249
+ | CalibrateOkResponse
250
+ | RemoveUsersOkResponse
251
+ | RestoreGalleryOkResponse
252
+ | GalleryRestoredResponse
253
+ | ProgressResponse
254
+ | VideoProcessingDoneResponse
255
+ | ProfileStatsResponse
256
+ | TimingStatsResponse
257
+ )
shared/eve_python/ctypes_enum.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ from enum import IntEnum
2
+
3
+
4
+ # Taken from https://v4.chriskrycho.com/2015/ctypes-structures-and-dll-exports.html
5
+ class CtypesEnum(IntEnum):
6
+ """A ctypes-compatible IntEnum superclass."""
7
+
8
+ @classmethod
9
+ def from_param(cls, obj):
10
+ return int(obj)
shared/eve_python/eve_sdk.py CHANGED
@@ -1,297 +1,388 @@
1
- import ctypes
2
- from . import eve_sdk_structs as structs
3
-
4
- EveProcessingCallbackFn = ctypes.CFUNCTYPE(None, ctypes.POINTER(structs.EveProcessingCallbackReturnData))
5
-
6
- class EveSDK:
7
- def __init__(self, dll_path: str):
8
- self.cdll = ctypes.CDLL(dll_path)
9
- # EveCameraApi.h
10
- self.cdll.EveGetFormats.restype = structs.EveCameraFormats
11
- self.cdll.EveGetFormats.argtypes = [ctypes.c_uint, structs.CCameraFormat]
12
- self.cdll.EveGetCamera.restype = structs.EveCamera
13
- self.cdll.EveGetCamera.argtypes = [ctypes.c_uint]
14
- self.cdll.EveSetCamera.restype = structs.EveError
15
- self.cdll.EveSetCamera.argtypes = [ctypes.c_uint, structs.CCameraFormat]
16
- # EveControlInterface.h
17
- self.cdll.CreateEve.restype = structs.EveError
18
- self.cdll.CreateEve.argtypes = [structs.EveStartupParameters]
19
- self.cdll.EveRegisterDataCallback.restype = structs.EveError
20
- self.cdll.EveRegisterDataCallback.argtypes = [EveProcessingCallbackFn]
21
- self.cdll.StartEve.restype = structs.EveError
22
- self.cdll.StartEve.argtypes = []
23
- self.cdll.StartEveWithParameters.restype = structs.EveError
24
- self.cdll.StartEveWithParameters.argtypes = [structs.EveProcessingParameters]
25
- self.cdll.EveSendImageForProcessing.restype = structs.EveError
26
- self.cdll.EveSendImageForProcessing.argtypes = [structs.EveInputImage]
27
- self.cdll.EveSendImageForProcessingWithParams.restype = structs.EveError
28
- self.cdll.EveSendImageForProcessingWithParams.argtypes = [structs.EveInputImage, structs.CCameraParameters]
29
- self.cdll.ShutdownEve.restype = structs.EveError
30
- self.cdll.ShutdownEve.argtypes = []
31
-
32
- # EveKarolinska.h
33
- self.cdll.EveConfigureKarolinska.restype = structs.EveKarolinskaOptions
34
- self.cdll.EveConfigureKarolinska.argtypes = [structs.EveKarolinskaOptions]
35
-
36
- self.cdll.EveGetKarolinskaData.restype = structs.EveKarolinskaData
37
- self.cdll.EveGetKarolinskaData.argtypes = []
38
-
39
- # EveFaceId.h
40
- self.cdll.EveConfigureFaceId.restype = structs.EveFaceIdOptions
41
- self.cdll.EveConfigureFaceId.argtypes = [structs.EveFaceIdOptions]
42
- self.cdll.EveFaceIdCalibrateCurrent.restype = structs.EveError
43
- self.cdll.EveFaceIdCalibrateCurrent.argtypes = []
44
- self.cdll.EveFaceIdCalibrateNew.restype = structs.EveError
45
- self.cdll.EveFaceIdCalibrateNew.argtypes = []
46
- self.cdll.EveFaceIdForceIdentify.restype = structs.EveError
47
- self.cdll.EveFaceIdForceIdentify.argtypes = []
48
- self.cdll.EveFaceIdRemoveCurrent.restype = structs.EveError
49
- self.cdll.EveFaceIdRemoveCurrent.argtypes = []
50
- self.cdll.EveFaceIdRemoveAll.restype = structs.EveError
51
- self.cdll.EveFaceIdRemoveAll.argtypes = []
52
- self.cdll.EveFaceIdReloadGallery.restype = structs.EveError
53
- self.cdll.EveFaceIdReloadGallery.argtypes = []
54
- self.cdll.EveFaceIdCommandWaiting.restype = ctypes.c_uint
55
- self.cdll.EveFaceIdCommandWaiting.argtypes = []
56
- self.cdll.EveGetFaceIdData.restype = structs.EveFaceIdData
57
- self.cdll.EveGetFaceIdData.argtypes = []
58
- self.cdll.EveSendFaceIdCommand.restype = structs.EveFaceIdCommandStruct
59
- self.cdll.EveSendFaceIdCommand.argtypes = [structs.EveFaceIdCommandStruct]
60
- # EveFaceTracker.h
61
- self.cdll.EveConfigureFaceTracker.restype = structs.EveFaceTrackerOptions
62
- self.cdll.EveConfigureFaceTracker.argtypes = [structs.EveFaceTrackerOptions]
63
- self.cdll.EveGetAllFaceData.restype = structs.EveAllFacesData
64
- self.cdll.EveGetAllFaceData.argtypes = []
65
- # EveFpga.h
66
- self.cdll.EveConfigureFpga.restype = structs.EveFpgaOptions
67
- self.cdll.EveConfigureFpga.argtypes = [structs.EveFpgaOptions]
68
- self.cdll.EveConfigureFpgaDebug.restype = structs.EveFpgaDebugOptions
69
- self.cdll.EveConfigureFpgaDebug.argtypes = [structs.EveFpgaDebugOptions]
70
- self.cdll.QueryFpgaSetting.restype = structs.EveError
71
- self.cdll.QueryFpgaSetting.argtypes = [structs.pipeline_config_t, ctypes.c_bool]
72
- self.cdll.QueryFpgaSettings.restype = structs.EveError
73
- self.cdll.QueryFpgaSettings.argtypes = [ctypes.c_uint16, ctypes.c_uint32, ctypes.c_bool]
74
- self.cdll.SendSetSetting.restype = structs.EveError
75
- self.cdll.SendSetSetting.argtypes = [structs.pipeline_config_t]
76
- self.cdll.PopQueuedSetting.restype = structs.CFpgaGetSetting
77
- self.cdll.PopQueuedSetting.argtypes = []
78
- self.cdll.EveGetFpgaData.restype = structs.EveFpgaData
79
- self.cdll.EveGetFpgaData.argtypes = []
80
- self.cdll.FpgaReadJson.restype = structs.EveFpgaJsonMetadata
81
- self.cdll.FpgaReadJson.argtypes = []
82
- self.cdll.EveSendImageForProcessingWithFpgaData.restype = structs.EveError
83
- self.cdll.EveSendImageForProcessingWithFpgaData.argtypes = [structs.EveInputImage, structs.EveFpgaManualData]
84
-
85
- # EveImageManipulation.h
86
- self.cdll.EveConfigureImageManipulation.restype = structs.EveImageManipulationOptions
87
- self.cdll.EveConfigureImageManipulation.argtypes = [structs.EveImageManipulationOptions]
88
-
89
- # EveImage.h
90
- self.cdll.EveGetProcessedImage.restype = structs.EveProcessedImage
91
- self.cdll.EveGetProcessedImage.argtypes = []
92
- self.cdll.EveGetProcessedFrameTime.restype = structs.EveProcessedFrameTime
93
- self.cdll.EveGetProcessedFrameTime.argtypes = []
94
- self.cdll.EveConfigureProcessedImage.restype = structs.EveImageFormatRequest
95
- self.cdll.EveConfigureProcessedImage.argtypes = [structs.EveImageFormatRequest]
96
-
97
- # EveObjectDetection.h
98
- self.cdll.EveConfigureObjectDetection.restype = structs.EveObjectDetectionOptions
99
- self.cdll.EveConfigureObjectDetection.argtypes = []
100
- self.cdll.EveConfigurePersonDetection.restype = structs.EvePersonDetectionOptions
101
- self.cdll.EveConfigurePersonDetection.argtypes = []
102
- self.cdll.EveGetObjectDetectionData.restype = structs.EveDetectionData
103
- self.cdll.EveGetObjectDetectionData.argtypes = []
104
- self.cdll.EveCopyObjectDetectionData.restype = structs.EveDetectionData
105
- self.cdll.EveCopyObjectDetectionData.argtypes = []
106
- self.cdll.EveGetPersonDetectionData.restype = structs.EveDetectionData
107
- self.cdll.EveGetPersonDetectionData.argtypes = []
108
- self.cdll.EveCopyPersonDetectionData.restype = structs.EveDetectionData
109
- self.cdll.EveCopyPersonDetectionData.argtypes = []
110
- self.cdll.DeleteDetectionData.restype = structs.EveError
111
- self.cdll.DeleteDetectionData.argtypes = [structs.EveDetectionData]
112
- # EveROI.h
113
- self.cdll.EveConfigureROIs.restype = structs.EveROIOptions
114
- self.cdll.EveConfigureROIs.argtypes = [structs.EveROIOptions]
115
- self.cdll.EveGetROIScoreData.restype = structs.EveROIScoreData
116
- self.cdll.EveGetROIScoreData.argtypes = []
117
- # EveHandGesture.h
118
- self.cdll.EveConfigureHandGesture.restype = structs.EveHandGestureOptions
119
- self.cdll.EveConfigureHandGesture.argtypes = [structs.EveHandGestureOptions]
120
- self.cdll.EveGetHandGestureData.restype = structs.EveHandGestureData
121
- self.cdll.EveGetHandGestureData.argtypes = []
122
- self.cdll.EveCopyHandGestureData.restype = structs.EveHandGestureData
123
- self.cdll.EveCopyHandGestureData.argtypes = []
124
- self.cdll.EveDeleteHandGestureData.restype = structs.EveError
125
- self.cdll.EveDeleteHandGestureData.argtypes = [structs.EveHandGestureData]
126
- self.cdll.EveGetStaticGestureDetections.restype = structs.EveStaticGestureData
127
- self.cdll.EveGetStaticGestureDetections.argtypes = []
128
- self.cdll.EveGetDynamicGestureDetections.restype = structs.EveDynamicGestureData
129
- self.cdll.EveGetDynamicGestureDetections.argtypes = []
130
-
131
-
132
- # EveCamera.h
133
- def EveGetFormats(self, cameraId: ctypes.c_uint, filter: structs.CCameraFormat) -> structs.EveCameraFormats:
134
- return self.cdll.EveGetFormats(cameraId, filter)
135
-
136
- def EveGetCamera(self, cameraId: ctypes.c_uint) -> structs.EveCamera:
137
- return self.cdll.EveGetCamera(cameraId)
138
-
139
- def EveSetCamera(self, cameraId: ctypes.c_uint, filter: structs.CCameraFormat) -> structs.EveError:
140
- return self.cdll.EveSetCamera(cameraId, filter)
141
-
142
- # EveControlInterface.h
143
- def CreateEve(self, options: structs.EveStartupParameters) -> structs.EveError:
144
- return self.cdll.CreateEve(options)
145
-
146
- def EveRegisterDataCallback(self, callback) -> structs.EveError:
147
- return self.cdll.EveRegisterDataCallback(callback)
148
-
149
- def StartEve(self) -> structs.EveError:
150
- return self.cdll.StartEve()
151
-
152
- def StartEveWithParameters(self, parameters: structs.EveProcessingParameters) -> structs.EveError:
153
- return self.cdll.StartEveWithParameters(parameters)
154
-
155
- def EveSendImageForProcessing(self, image: structs.EveInputImage) -> structs.EveError:
156
- return self.cdll.EveSendImageForProcessing(image)
157
-
158
- def EveSendImageForProcessingWithParams(self, image: structs.EveInputImage, params: structs.CCameraParameters) -> structs.EveError:
159
- return self.cdll.EveSendImageForProcessingWithParams(image, params)
160
-
161
- def EveSendFpgaDataManually(self, image: structs.EveFpgaManualData) -> structs.EveError:
162
- return self.cdll.EveSendFpgaDataManually(image)
163
-
164
- def ShutdownEve(self) -> structs.EveError:
165
- return self.cdll.ShutdownEve()
166
-
167
- # EveFaceId.h
168
- def EveConfigureFaceId(self, options: structs.EveFaceIdOptions) -> structs.EveFaceIdOptions:
169
- return self.cdll.EveConfigureFaceId(options)
170
-
171
- def EveFaceIdCalibrateCurrent(self) -> structs.EveError:
172
- return self.cdll.EveFaceIdCalibrateCurrent()
173
-
174
- def EveFaceIdCalibrateNew(self) -> structs.EveError:
175
- return self.cdll.EveFaceIdCalibrateNew()
176
-
177
- def EveFaceIdForceIdentify(self) -> structs.EveError:
178
- return self.cdll.EveFaceIdForceIdentify()
179
-
180
- def EveFaceIdRemoveCurrent(self) -> structs.EveError:
181
- return self.cdll.EveFaceIdRemoveCurrent()
182
-
183
- def EveFaceIdRemoveAll(self) -> structs.EveError:
184
- return self.cdll.EveFaceIdRemoveAll()
185
-
186
- def EveFaceIdReloadGallery(self) -> structs.EveError:
187
- return self.cdll.EveFaceIdReloadGallery()
188
-
189
- def EveFaceIdCommandWaiting(self) -> ctypes.c_uint:
190
- return self.cdll.EveFaceIdCommandWaiting()
191
-
192
- def EveGetFaceIdData(self) -> structs.EveFaceIdData:
193
- return self.cdll.EveGetFaceIdData()
194
-
195
- def EveSendFaceIdCommand(self, command: structs.EveFaceIdCommandStruct) -> structs.EveFaceIdCommandStruct:
196
- return self.cdll.EveSendFaceIdCommand(command)
197
-
198
- # EveFaceTracker.h
199
- def EveConfigureFaceTracker(self, options: structs.EveFaceTrackerOptions) -> structs.EveFaceTrackerOptions:
200
- return self.cdll.EveConfigureFaceTracker(options)
201
-
202
- def EveGetAllFaceData(self) -> structs.EveAllFacesData:
203
- return self.cdll.EveGetAllFaceData()
204
-
205
- # EveFpga.h
206
- def EveGetFpgaData(self) -> structs.EveFpgaData:
207
- return self.cdll.EveGetFpgaData()
208
-
209
- def EveConfigureFpga(self, options: structs.EveFpgaOptions) -> structs.EveFpgaOptions:
210
- return self.cdll.EveConfigureFpga(options)
211
-
212
- def EveConfigureFpgaDebug(self, options: structs.EveFpgaDebugOptions) -> structs.EveFpgaDebugOptions:
213
- return self.cdll.EveConfigureFpgaDebug(options)
214
-
215
- def QueryFpgaSetting(self, command: structs.pipeline_config_t, notify: ctypes.c_bool) -> structs.EveError:
216
- return self.cdll.QueryFpgaSetting(command, notify)
217
-
218
- def QueryFpgaSettings(self, typeMask: ctypes.c_uint16, settingsMask: ctypes.c_uint32, notify: ctypes.c_bool) -> structs.EveError:
219
- return self.cdll.QueryFpgaSettings(typeMask, settingsMask, notify)
220
-
221
- def SendSetSetting(self, command: structs.pipeline_config_t) -> structs.EveError:
222
- return self.cdll.SendSetSetting(command)
223
-
224
- def PopQueuedSetting(self) -> structs.CFpgaGetSetting:
225
- return self.cdll.PopQueuedSetting()
226
-
227
- def FpgaReadJson(self) -> structs.EveFpgaJsonMetadata:
228
- return self.cdll.FpgaReadJson()
229
-
230
- # EveKarolinksa.h
231
- def EveConfigureKarolinska(self, parameters: structs.EveKarolinskaOptions) -> structs.EveKarolinskaOptions:
232
- return self.cdll.EveConfigureKarolinska(parameters)
233
-
234
- def EveGetKarolinskaData(self) -> structs.EveKarolinskaData:
235
- return self.cdll.EveGetKarolinskaData()
236
-
237
- # EveImageManipulation.h
238
- def EveConfigureImageManipulation(self, options: structs.EveImageManipulationOptions) -> structs.EveImageManipulationOptions:
239
- return self.cdll.EveConfigureImageManipulation(options)
240
-
241
- # EveImage.h
242
- def EveGetProcessedImage(self) -> structs.EveProcessedImage:
243
- return self.cdll.EveGetProcessedImage()
244
-
245
- def EveGetProcessedFrameTime(self) -> structs.EveProcessedFrameTime:
246
- return self.cdll.EveGetProcessedFrameTime()
247
-
248
- def EveConfigureProcessedImage(self, fmt: structs.EveImageFormatRequest) -> structs.EveProcessedFrameTime:
249
- return self.cdll.EveConfigureProcessedImage(fmt)
250
-
251
- # EveObjectDetection.h
252
- def EveConfigureObjectDetection(self, enabled: structs.EveObjectDetectionOptions) -> structs.EveObjectDetectionOptions:
253
- return self.cdll.EveConfigureObjectDetection(enabled)
254
-
255
- def EveConfigurePersonDetection(self, enabled: structs.EvePersonDetectionOptions) -> structs.EvePersonDetectionOptions:
256
- return self.cdll.EveConfigurePersonDetection(enabled)
257
-
258
- def EveGetObjectDetectionData(self) -> structs.EveDetectionData:
259
- return self.cdll.EveGetObjectDetectionData()
260
-
261
- def EveCopyObjectDetectionData(self) -> structs.EveDetectionData:
262
- return self.cdll.EveCopyObjectDetectionData()
263
-
264
- def EveGetPersonDetectionData(self) -> structs.EveDetectionData:
265
- return self.cdll.EveGetPersonDetectionData()
266
-
267
- def EveCopyPersonDetectionData(self) -> structs.EveDetectionData:
268
- return self.cdll.EveCopyPersonDetectionData()
269
-
270
- def DeleteDetectionData(self, data: structs.EveDetectionData) -> structs.EveError:
271
- return self.cdll.DeleteDetectionData(data)
272
-
273
- # EveROI.h
274
- def EveConfigureROIs(self, options: structs.EveROIOptions) -> structs.EveError:
275
- return self.cdll.EveConfigureROIs(options)
276
-
277
- def EveGetROIScoreData(self) -> structs.EveROIScoreData:
278
- return self.cdll.EveGetROIScoreData()
279
-
280
- # EveHandGesture.h
281
- def EveConfigureHandGesture(self, options: structs.EveHandGestureOptions) -> structs.EveHandGestureOptions:
282
- return self.cdll.EveConfigureHandGesture(options)
283
-
284
- def EveGetHandGestureData(self) -> structs.EveHandGestureData:
285
- return self.cdll.EveGetHandGestureData()
286
-
287
- def EveCopyHandGestureData(self) -> structs.EveHandGestureData:
288
- return self.cdll.EveGetHandGestureData()
289
-
290
- def EveDeleteHandGestureData(self, data: structs.EveHandGestureData) -> structs.EveError:
291
- return self.cdll.EveGetHandGestureData(data)
292
-
293
- def EveGetStaticGestureDetections(self) -> structs.EveStaticGestureData:
294
- return self.cdll.EveGetStaticGestureDetections()
295
-
296
- def EveGetDynamicGestureDetections(self) -> structs.EveDynamicGestureData:
297
- return self.cdll.EveGetDynamicGestureDetections()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+
3
+ from . import eve_sdk_structs as structs
4
+
5
+ EveProcessingCallbackFn = ctypes.CFUNCTYPE(None, ctypes.POINTER(structs.EveProcessingCallbackReturnData))
6
+
7
+ class EveSDK:
8
+ def __init__(self, dll_path: str):
9
+ self.cdll = ctypes.CDLL(dll_path)
10
+ # EveCamera.h
11
+ self.cdll.EveGetFormats.restype = structs.EveCameraFormats
12
+ self.cdll.EveGetFormats.argtypes = [ctypes.c_uint, structs.CCameraFormat]
13
+ self.cdll.EveGetCamera.restype = structs.EveCamera
14
+ self.cdll.EveGetCamera.argtypes = [ctypes.c_uint]
15
+ self.cdll.EveSetCamera.restype = structs.EveError
16
+ self.cdll.EveSetCamera.argtypes = [ctypes.c_uint, structs.CCameraFormat]
17
+ self.cdll.EveGetNumberOfCameras.restype = structs.EveNumberOfCameras
18
+ self.cdll.EveGetNumberOfCameras.argtypes = []
19
+ self.cdll.EveGetMonitors.restype = structs.EveMonitors
20
+ self.cdll.EveGetMonitors.argtypes = []
21
+ self.cdll.EveChangeCameraLocation.restype = structs.EveCameraLocation
22
+ self.cdll.EveChangeCameraLocation.argtypes = [structs.EveCameraLocation]
23
+ self.cdll.EveGetLiveCameraParameters.restype = structs.EveCameraParameters
24
+ self.cdll.EveGetLiveCameraParameters.argtypes = []
25
+ # EveControlInterface.h
26
+ self.cdll.CreateEve.restype = structs.EveError
27
+ self.cdll.CreateEve.argtypes = [structs.EveStartupParameters]
28
+ self.cdll.EveRegisterDataCallback.restype = structs.EveError
29
+ self.cdll.EveRegisterDataCallback.argtypes = [EveProcessingCallbackFn]
30
+ self.cdll.StartEve.restype = structs.EveError
31
+ self.cdll.StartEve.argtypes = []
32
+ self.cdll.StartEveWithParameters.restype = structs.EveError
33
+ self.cdll.StartEveWithParameters.argtypes = [structs.EveProcessingParameters]
34
+ self.cdll.EveSendImageForProcessing.restype = structs.EveError
35
+ self.cdll.EveSendImageForProcessing.argtypes = [structs.EveInputImage]
36
+ self.cdll.EveSendImageForProcessingWithParams.restype = structs.EveError
37
+ self.cdll.EveSendImageForProcessingWithParams.argtypes = [structs.EveInputImage, structs.CCameraParameters]
38
+ self.cdll.ShutdownEve.restype = structs.EveError
39
+ self.cdll.ShutdownEve.argtypes = []
40
+ self.cdll.EveCheckForLicense.restype = structs.EveLicenseResult
41
+ self.cdll.EveCheckForLicense.argtypes = []
42
+ self.cdll.EveResetPipeline.restype = structs.EveError
43
+ self.cdll.EveResetPipeline.argtypes = []
44
+
45
+ # EveKarolinska.h
46
+ self.cdll.EveConfigureKarolinska.restype = structs.EveKarolinskaOptions
47
+ self.cdll.EveConfigureKarolinska.argtypes = [structs.EveKarolinskaOptions]
48
+
49
+ self.cdll.EveGetKarolinskaData.restype = structs.EveKarolinskaData
50
+ self.cdll.EveGetKarolinskaData.argtypes = []
51
+
52
+ # EveFaceId.h
53
+ self.cdll.EveConfigureFaceId.restype = structs.EveFaceIdOptions
54
+ self.cdll.EveConfigureFaceId.argtypes = [structs.EveFaceIdOptions]
55
+ self.cdll.EveFaceIdCalibrateCurrent.restype = structs.EveError
56
+ self.cdll.EveFaceIdCalibrateCurrent.argtypes = []
57
+ self.cdll.EveFaceIdCalibrateNew.restype = structs.EveError
58
+ self.cdll.EveFaceIdCalibrateNew.argtypes = []
59
+ self.cdll.EveFaceIdForceIdentify.restype = structs.EveError
60
+ self.cdll.EveFaceIdForceIdentify.argtypes = []
61
+ self.cdll.EveFaceIdRemoveCurrent.restype = structs.EveError
62
+ self.cdll.EveFaceIdRemoveCurrent.argtypes = []
63
+ self.cdll.EveFaceIdRemoveAll.restype = structs.EveError
64
+ self.cdll.EveFaceIdRemoveAll.argtypes = []
65
+ self.cdll.EveFaceIdReloadGallery.restype = structs.EveError
66
+ self.cdll.EveFaceIdReloadGallery.argtypes = []
67
+ self.cdll.EveFaceIdCommandWaiting.restype = ctypes.c_uint
68
+ self.cdll.EveFaceIdCommandWaiting.argtypes = []
69
+ self.cdll.EveGetFaceIdData.restype = structs.EveFaceIdData
70
+ self.cdll.EveGetFaceIdData.argtypes = []
71
+ self.cdll.EveSendFaceIdCommand.restype = structs.EveFaceIdCommandStruct
72
+ self.cdll.EveSendFaceIdCommand.argtypes = [structs.EveFaceIdCommandStruct]
73
+ # EveFaceTracker.h
74
+ self.cdll.EveConfigureFaceTracker.restype = structs.EveFaceTrackerOptions
75
+ self.cdll.EveConfigureFaceTracker.argtypes = [structs.EveFaceTrackerOptions]
76
+ self.cdll.EveGetEyesData.restype = structs.EveEyes
77
+ self.cdll.EveGetEyesData.argtypes = []
78
+ self.cdll.EveGetPupilsData.restype = structs.EvePupils
79
+ self.cdll.EveGetPupilsData.argtypes = []
80
+ self.cdll.EveGetAllFaceData.restype = structs.EveAllFacesData
81
+ self.cdll.EveGetAllFaceData.argtypes = []
82
+ # EveFpga.h
83
+ self.cdll.EveConfigureFpga.restype = structs.EveFpgaOptions
84
+ self.cdll.EveConfigureFpga.argtypes = [structs.EveFpgaOptions]
85
+ self.cdll.EveConfigureFpgaDebug.restype = structs.EveFpgaDebugOptions
86
+ self.cdll.EveConfigureFpgaDebug.argtypes = [structs.EveFpgaDebugOptions]
87
+ self.cdll.QueryFpgaSetting.restype = structs.EveError
88
+ self.cdll.QueryFpgaSetting.argtypes = [structs.pipeline_config_t, ctypes.c_bool]
89
+ self.cdll.QueryFpgaSettings.restype = structs.EveError
90
+ self.cdll.QueryFpgaSettings.argtypes = [ctypes.c_uint16, ctypes.c_uint32, ctypes.c_bool]
91
+ self.cdll.SendSetSetting.restype = structs.EveError
92
+ self.cdll.SendSetSetting.argtypes = [structs.pipeline_config_t]
93
+ self.cdll.PopQueuedSetting.restype = structs.CFpgaGetSetting
94
+ self.cdll.PopQueuedSetting.argtypes = []
95
+ self.cdll.EveGetFpgaData.restype = structs.EveFpgaData
96
+ self.cdll.EveGetFpgaData.argtypes = []
97
+ self.cdll.FpgaReadJson.restype = structs.EveFpgaJsonMetadata
98
+ self.cdll.FpgaReadJson.argtypes = []
99
+ self.cdll.FpgaReadData.restype = structs.EveFpgaData
100
+ self.cdll.FpgaReadData.argtypes = []
101
+ self.cdll.EveSendImageForProcessingWithFpgaData.restype = structs.EveError
102
+ self.cdll.EveSendImageForProcessingWithFpgaData.argtypes = [structs.EveInputImage, structs.EveFpgaManualData]
103
+
104
+ # EveImageManipulation.h
105
+ self.cdll.EveConfigureImageManipulation.restype = structs.EveImageManipulationOptions
106
+ self.cdll.EveConfigureImageManipulation.argtypes = [structs.EveImageManipulationOptions]
107
+
108
+ # EveImage.h
109
+ self.cdll.EveGetProcessedImage.restype = structs.EveProcessedImage
110
+ self.cdll.EveGetProcessedImage.argtypes = []
111
+ self.cdll.EveGetProcessedFrameTime.restype = structs.EveProcessedFrameTime
112
+ self.cdll.EveGetProcessedFrameTime.argtypes = []
113
+ self.cdll.EveConfigureProcessedImage.restype = structs.EveImageFormatRequest
114
+ self.cdll.EveConfigureProcessedImage.argtypes = [structs.EveImageFormatRequest]
115
+ self.cdll.EveConfigureRawImage.restype = structs.EveRawImageRequest
116
+ self.cdll.EveConfigureRawImage.argtypes = [structs.EveRawImageRequest]
117
+ self.cdll.EveGetRawImage.restype = structs.EveProcessedImage
118
+ self.cdll.EveGetRawImage.argtypes = []
119
+ self.cdll.EveGetJsonData.restype = structs.EveJsonData
120
+ self.cdll.EveGetJsonData.argtypes = []
121
+
122
+ # EveObjectDetection.h
123
+ self.cdll.EveConfigureObjectDetection.restype = structs.EveObjectDetectionOptions
124
+ self.cdll.EveConfigureObjectDetection.argtypes = [structs.EveObjectDetectionOptions]
125
+ self.cdll.EveGetDefaultObjectDetectionOptions.restype = structs.EveObjectDetectionOptions
126
+ self.cdll.EveGetDefaultObjectDetectionOptions.argtypes = []
127
+ self.cdll.EveConfigurePersonDetection.restype = structs.EvePersonDetectionOptions
128
+ self.cdll.EveConfigurePersonDetection.argtypes = [structs.EvePersonDetectionOptions]
129
+ self.cdll.EveGetObjectDetectionData.restype = structs.EveDetectionData
130
+ self.cdll.EveGetObjectDetectionData.argtypes = []
131
+ self.cdll.EveCopyObjectDetectionData.restype = structs.EveDetectionData
132
+ self.cdll.EveCopyObjectDetectionData.argtypes = []
133
+ self.cdll.EveGetPersonDetectionData.restype = structs.EveDetectionData
134
+ self.cdll.EveGetPersonDetectionData.argtypes = []
135
+ self.cdll.EveCopyPersonDetectionData.restype = structs.EveDetectionData
136
+ self.cdll.EveCopyPersonDetectionData.argtypes = []
137
+ self.cdll.DeleteDetectionData.restype = structs.EveError
138
+ self.cdll.DeleteDetectionData.argtypes = [structs.EveDetectionData]
139
+ # EveROI.h
140
+ self.cdll.EveConfigureROIs.restype = structs.EveROIOptions
141
+ self.cdll.EveConfigureROIs.argtypes = [structs.EveROIOptions]
142
+ self.cdll.EveGetROIScoreData.restype = structs.EveROIScoreData
143
+ self.cdll.EveGetROIScoreData.argtypes = []
144
+ # EveHandGesture.h
145
+ self.cdll.EveConfigureHandGesture.restype = structs.EveHandGestureOptions
146
+ self.cdll.EveConfigureHandGesture.argtypes = [structs.EveHandGestureOptions]
147
+ self.cdll.EveGetHandGestureData.restype = structs.EveHandGestureData
148
+ self.cdll.EveGetHandGestureData.argtypes = []
149
+ self.cdll.EveCopyHandGestureData.restype = structs.EveHandGestureData
150
+ self.cdll.EveCopyHandGestureData.argtypes = []
151
+ self.cdll.EveDeleteHandGestureData.restype = structs.EveError
152
+ self.cdll.EveDeleteHandGestureData.argtypes = [structs.EveHandGestureData]
153
+ self.cdll.EveGetStaticGestureDetections.restype = structs.EveStaticGestureData
154
+ self.cdll.EveGetStaticGestureDetections.argtypes = []
155
+ self.cdll.EveGetStaticGestureDefinitions.restype = structs.EveStaticGestureDefinitions
156
+ self.cdll.EveGetStaticGestureDefinitions.argtypes = []
157
+ self.cdll.EveAddStaticGesture.restype = structs.EveError
158
+ self.cdll.EveAddStaticGesture.argtypes = [structs.EveStaticGestureDefinition]
159
+ self.cdll.EveDeleteStaticGesture.restype = structs.EveError
160
+ self.cdll.EveDeleteStaticGesture.argtypes = [structs.EveStaticGestureDefinition]
161
+ # EveAlgorithm.h
162
+ self.cdll.EveGetAlgorithms.restype = structs.EveSupportedAlgorithms
163
+ self.cdll.EveGetAlgorithms.argtypes = []
164
+
165
+ # EveTiming.h
166
+ self.cdll.EveGetTimingInformation.restype = structs.EveTiming
167
+ self.cdll.EveGetTimingInformation.argtypes = []
168
+
169
+
170
+ # EveCamera.h
171
+ def EveGetFormats(self, cameraId: ctypes.c_uint, filter: structs.CCameraFormat) -> structs.EveCameraFormats:
172
+ return self.cdll.EveGetFormats(cameraId, filter)
173
+
174
+ def EveGetCamera(self, cameraId: ctypes.c_uint) -> structs.EveCamera:
175
+ return self.cdll.EveGetCamera(cameraId)
176
+
177
+ def EveSetCamera(self, cameraId: ctypes.c_uint, filter: structs.CCameraFormat) -> structs.EveError:
178
+ return self.cdll.EveSetCamera(cameraId, filter)
179
+
180
+ def EveGetNumberOfCameras(self) -> structs.EveNumberOfCameras:
181
+ return self.cdll.EveGetNumberOfCameras()
182
+
183
+ def EveGetMonitors(self) -> structs.EveMonitors:
184
+ return self.cdll.EveGetMonitors()
185
+
186
+ def EveChangeCameraLocation(self, location: structs.EveCameraLocation) -> structs.EveCameraLocation:
187
+ return self.cdll.EveChangeCameraLocation(location)
188
+
189
+ def EveGetLiveCameraParameters(self) -> structs.EveCameraParameters:
190
+ return self.cdll.EveGetLiveCameraParameters()
191
+
192
+ # EveControlInterface.h
193
+ def CreateEve(self, options: structs.EveStartupParameters) -> structs.EveError:
194
+ return self.cdll.CreateEve(options)
195
+
196
+ def EveRegisterDataCallback(self, callback) -> structs.EveError:
197
+ return self.cdll.EveRegisterDataCallback(callback)
198
+
199
+ def StartEve(self) -> structs.EveError:
200
+ return self.cdll.StartEve()
201
+
202
+ def StartEveWithParameters(self, parameters: structs.EveProcessingParameters) -> structs.EveError:
203
+ return self.cdll.StartEveWithParameters(parameters)
204
+
205
+ def EveSendImageForProcessing(self, image: structs.EveInputImage) -> structs.EveError:
206
+ return self.cdll.EveSendImageForProcessing(image)
207
+
208
+ def EveSendImageForProcessingWithParams(self, image: structs.EveInputImage, params: structs.CCameraParameters) -> structs.EveError:
209
+ return self.cdll.EveSendImageForProcessingWithParams(image, params)
210
+
211
+ def EveSendImageForProcessingWithFpgaData(self, image: structs.EveInputImage, data: structs.EveFpgaManualData) -> structs.EveError:
212
+ return self.cdll.EveSendImageForProcessingWithFpgaData(image, data)
213
+
214
+ def ShutdownEve(self) -> structs.EveError:
215
+ return self.cdll.ShutdownEve()
216
+
217
+ def EveCheckForLicense(self) -> structs.EveLicenseResult:
218
+ return self.cdll.EveCheckForLicense()
219
+
220
+ def EveResetPipeline(self) -> structs.EveError:
221
+ return self.cdll.EveResetPipeline()
222
+
223
+ # EveFaceId.h
224
+ def EveConfigureFaceId(self, options: structs.EveFaceIdOptions) -> structs.EveFaceIdOptions:
225
+ return self.cdll.EveConfigureFaceId(options)
226
+
227
+ def EveFaceIdCalibrateCurrent(self) -> structs.EveError:
228
+ return self.cdll.EveFaceIdCalibrateCurrent()
229
+
230
+ def EveFaceIdCalibrateNew(self) -> structs.EveError:
231
+ return self.cdll.EveFaceIdCalibrateNew()
232
+
233
+ def EveFaceIdForceIdentify(self) -> structs.EveError:
234
+ return self.cdll.EveFaceIdForceIdentify()
235
+
236
+ def EveFaceIdRemoveCurrent(self) -> structs.EveError:
237
+ return self.cdll.EveFaceIdRemoveCurrent()
238
+
239
+ def EveFaceIdRemoveAll(self) -> structs.EveError:
240
+ return self.cdll.EveFaceIdRemoveAll()
241
+
242
+ def EveFaceIdReloadGallery(self) -> structs.EveError:
243
+ return self.cdll.EveFaceIdReloadGallery()
244
+
245
+ def EveFaceIdCommandWaiting(self) -> ctypes.c_uint:
246
+ return self.cdll.EveFaceIdCommandWaiting()
247
+
248
+ def EveGetFaceIdData(self) -> structs.EveFaceIdData:
249
+ return self.cdll.EveGetFaceIdData()
250
+
251
+ def EveSendFaceIdCommand(self, command: structs.EveFaceIdCommandStruct) -> structs.EveFaceIdCommandStruct:
252
+ return self.cdll.EveSendFaceIdCommand(command)
253
+
254
+ # EveFaceTracker.h
255
+ def EveConfigureFaceTracker(self, options: structs.EveFaceTrackerOptions) -> structs.EveFaceTrackerOptions:
256
+ return self.cdll.EveConfigureFaceTracker(options)
257
+
258
+ def EveGetEyesData(self) -> structs.EveEyes:
259
+ return self.cdll.EveGetEyesData()
260
+
261
+ def EveGetPupilsData(self) -> structs.EvePupils:
262
+ return self.cdll.EveGetPupilsData()
263
+
264
+ def EveGetAllFaceData(self) -> structs.EveAllFacesData:
265
+ return self.cdll.EveGetAllFaceData()
266
+
267
+ # EveFpga.h
268
+ def EveGetFpgaData(self) -> structs.EveFpgaData:
269
+ return self.cdll.EveGetFpgaData()
270
+
271
+ def EveConfigureFpga(self, options: structs.EveFpgaOptions) -> structs.EveFpgaOptions:
272
+ return self.cdll.EveConfigureFpga(options)
273
+
274
+ def EveConfigureFpgaDebug(self, options: structs.EveFpgaDebugOptions) -> structs.EveFpgaDebugOptions:
275
+ return self.cdll.EveConfigureFpgaDebug(options)
276
+
277
+ def QueryFpgaSetting(self, command: structs.pipeline_config_t, notify: ctypes.c_bool) -> structs.EveError:
278
+ return self.cdll.QueryFpgaSetting(command, notify)
279
+
280
+ def QueryFpgaSettings(self, typeMask: ctypes.c_uint16, settingsMask: ctypes.c_uint32, notify: ctypes.c_bool) -> structs.EveError:
281
+ return self.cdll.QueryFpgaSettings(typeMask, settingsMask, notify)
282
+
283
+ def SendSetSetting(self, command: structs.pipeline_config_t) -> structs.EveError:
284
+ return self.cdll.SendSetSetting(command)
285
+
286
+ def PopQueuedSetting(self) -> structs.CFpgaGetSetting:
287
+ return self.cdll.PopQueuedSetting()
288
+
289
+ def FpgaReadJson(self) -> structs.EveFpgaJsonMetadata:
290
+ return self.cdll.FpgaReadJson()
291
+
292
+ def FpgaReadData(self) -> structs.EveFpgaData:
293
+ return self.cdll.FpgaReadData()
294
+
295
+ # EveKarolinska.h
296
+ def EveConfigureKarolinska(self, parameters: structs.EveKarolinskaOptions) -> structs.EveKarolinskaOptions:
297
+ return self.cdll.EveConfigureKarolinska(parameters)
298
+
299
+ def EveGetKarolinskaData(self) -> structs.EveKarolinskaData:
300
+ return self.cdll.EveGetKarolinskaData()
301
+
302
+ # EveImageManipulation.h
303
+ def EveConfigureImageManipulation(self, options: structs.EveImageManipulationOptions) -> structs.EveImageManipulationOptions:
304
+ return self.cdll.EveConfigureImageManipulation(options)
305
+
306
+ # EveImage.h
307
+ def EveGetProcessedImage(self) -> structs.EveProcessedImage:
308
+ return self.cdll.EveGetProcessedImage()
309
+
310
+ def EveGetProcessedFrameTime(self) -> structs.EveProcessedFrameTime:
311
+ return self.cdll.EveGetProcessedFrameTime()
312
+
313
+ def EveConfigureProcessedImage(self, fmt: structs.EveImageFormatRequest) -> structs.EveImageFormatRequest:
314
+ return self.cdll.EveConfigureProcessedImage(fmt)
315
+
316
+ def EveConfigureRawImage(self, fmt: structs.EveRawImageRequest) -> structs.EveRawImageRequest:
317
+ return self.cdll.EveConfigureRawImage(fmt)
318
+
319
+ def EveGetRawImage(self) -> structs.EveProcessedImage:
320
+ return self.cdll.EveGetRawImage()
321
+
322
+ def EveGetJsonData(self) -> structs.EveJsonData:
323
+ return self.cdll.EveGetJsonData()
324
+
325
+ # EveObjectDetection.h
326
+ def EveConfigureObjectDetection(self, options: structs.EveObjectDetectionOptions) -> structs.EveObjectDetectionOptions:
327
+ return self.cdll.EveConfigureObjectDetection(options)
328
+
329
+ def EveGetDefaultObjectDetectionOptions(self) -> structs.EveObjectDetectionOptions:
330
+ return self.cdll.EveGetDefaultObjectDetectionOptions()
331
+
332
+ def EveConfigurePersonDetection(self, options: structs.EvePersonDetectionOptions) -> structs.EvePersonDetectionOptions:
333
+ return self.cdll.EveConfigurePersonDetection(options)
334
+
335
+ def EveGetObjectDetectionData(self) -> structs.EveDetectionData:
336
+ return self.cdll.EveGetObjectDetectionData()
337
+
338
+ def EveCopyObjectDetectionData(self) -> structs.EveDetectionData:
339
+ return self.cdll.EveCopyObjectDetectionData()
340
+
341
+ def EveGetPersonDetectionData(self) -> structs.EveDetectionData:
342
+ return self.cdll.EveGetPersonDetectionData()
343
+
344
+ def EveCopyPersonDetectionData(self) -> structs.EveDetectionData:
345
+ return self.cdll.EveCopyPersonDetectionData()
346
+
347
+ def DeleteDetectionData(self, data: structs.EveDetectionData) -> structs.EveError:
348
+ return self.cdll.DeleteDetectionData(data)
349
+
350
+ # EveROI.h
351
+ def EveConfigureROIs(self, options: structs.EveROIOptions) -> structs.EveROIOptions:
352
+ return self.cdll.EveConfigureROIs(options)
353
+
354
+ def EveGetROIScoreData(self) -> structs.EveROIScoreData:
355
+ return self.cdll.EveGetROIScoreData()
356
+
357
+ # EveHandGesture.h
358
+ def EveConfigureHandGesture(self, options: structs.EveHandGestureOptions) -> structs.EveHandGestureOptions:
359
+ return self.cdll.EveConfigureHandGesture(options)
360
+
361
+ def EveGetHandGestureData(self) -> structs.EveHandGestureData:
362
+ return self.cdll.EveGetHandGestureData()
363
+
364
+ def EveCopyHandGestureData(self) -> structs.EveHandGestureData:
365
+ return self.cdll.EveCopyHandGestureData()
366
+
367
+ def EveDeleteHandGestureData(self, data: structs.EveHandGestureData) -> structs.EveError:
368
+ return self.cdll.EveDeleteHandGestureData(data)
369
+
370
+ def EveGetStaticGestureDetections(self) -> structs.EveStaticGestureData:
371
+ return self.cdll.EveGetStaticGestureDetections()
372
+
373
+ def EveGetStaticGestureDefinitions(self) -> structs.EveStaticGestureDefinitions:
374
+ return self.cdll.EveGetStaticGestureDefinitions()
375
+
376
+ def EveAddStaticGesture(self, definition: structs.EveStaticGestureDefinition) -> structs.EveError:
377
+ return self.cdll.EveAddStaticGesture(definition)
378
+
379
+ def EveDeleteStaticGesture(self, definition: structs.EveStaticGestureDefinition) -> structs.EveError:
380
+ return self.cdll.EveDeleteStaticGesture(definition)
381
+
382
+ # EveAlgorithm.h
383
+ def EveGetAlgorithms(self) -> structs.EveSupportedAlgorithms:
384
+ return self.cdll.EveGetAlgorithms()
385
+
386
+ # EveTiming.h
387
+ def EveGetTimingInformation(self) -> structs.EveTiming:
388
+ return self.cdll.EveGetTimingInformation()
shared/eve_python/eve_sdk_structs.py CHANGED
@@ -11,8 +11,9 @@ from .structs.CFpgaData import *
11
  from .structs.CHandGesture import *
12
  from .structs.CImageManipulation import *
13
  from .structs.CKarolinska import *
 
 
14
  from .structs.CROIStructs import *
15
- from .structs.CScreenLocation import *
16
  from .structs.CVisualSpeechStructs import *
17
  from .structs.EveProcessingStatus import *
18
  from .structs.EveAlgorithm import *
@@ -42,7 +43,5 @@ from .structs.EveObjectDetection import *
42
  from .structs.EveObjectDetectionStructs import *
43
  from .structs.EveROI import *
44
  from .structs.EveROIStructs import *
45
- from .structs.EveScreenLocation import *
46
- from .structs.EveScreenLocationStructs import *
47
  from .structs.EveTiming import *
48
  from .structs.EveTimingStructs import *
 
11
  from .structs.CHandGesture import *
12
  from .structs.CImageManipulation import *
13
  from .structs.CKarolinska import *
14
+ from .structs.CLandmarkMaps import *
15
+ from .structs.CLicenseResult import *
16
  from .structs.CROIStructs import *
 
17
  from .structs.CVisualSpeechStructs import *
18
  from .structs.EveProcessingStatus import *
19
  from .structs.EveAlgorithm import *
 
43
  from .structs.EveObjectDetectionStructs import *
44
  from .structs.EveROI import *
45
  from .structs.EveROIStructs import *
 
 
46
  from .structs.EveTiming import *
47
  from .structs.EveTimingStructs import *
shared/eve_python/structs/CAlgorithms.py CHANGED
@@ -1,27 +1,27 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
-
4
-
5
- class EveAlgorithms(CtypesEnum):
6
- EVE_ALGO_NONE = 0
7
- EVE_ALGO_BACKGROUND_SEGMENTATION = 1
8
- EVE_ALGO_OBJECT_DETECTION = 2
9
- EVE_ALGO_PERSON_DETECTION = 3
10
- EVE_ALGO_HEADPOSE_3D = 4
11
- EVE_ALGO_HAND_GESTURE = 5
12
- EVE_ALGO_DEPTH = 6
13
- EVE_ALGO_EYEWEAR_DETECTION = 7
14
- EVE_ALGO_KAROLINSKA = 8
15
- EVE_ALGO_GAZE = 9
16
- EVE_ALGO_GAZE_SINGLE_OUTPUT = 10
17
- EVE_ALGO_FACE_ID = 11
18
- EVE_ALGO_ROI_SELECTION = 12
19
- EVE_ALGO_FACE_ENHANCEMENT = 13
20
- EVE_ALGO_VISUAL_SPEECH_DETECTION = 14
21
- EVE_ALGO_BACKGROUND_BLUR = 15
22
- EVE_ALGO_BACKGROUND_REPLACEMENT = 16
23
- EVE_ALGO_USER_HILIGHT = 17
24
- EVE_ALGO_USER_FRAMING = 18
25
- EVE_ALGO_MIRROR_IMAGE = 19
26
- EVE_ALGO_FPGA_DRAWING = 20
27
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+
4
+
5
+ class EveAlgorithms(CtypesEnum):
6
+ EVE_ALGO_NONE = 0
7
+ EVE_ALGO_BACKGROUND_SEGMENTATION = 1
8
+ EVE_ALGO_OBJECT_DETECTION = 2
9
+ EVE_ALGO_PERSON_DETECTION = 3
10
+ EVE_ALGO_HEADPOSE_3D = 4
11
+ EVE_ALGO_HAND_GESTURE = 5
12
+ EVE_ALGO_DEPTH = 6
13
+ EVE_ALGO_EYEWEAR_DETECTION = 7
14
+ EVE_ALGO_KAROLINSKA = 8
15
+ EVE_ALGO_GAZE = 9
16
+ EVE_ALGO_GAZE_SINGLE_OUTPUT = 10
17
+ EVE_ALGO_FACE_ID = 11
18
+ EVE_ALGO_ROI_SELECTION = 12
19
+ EVE_ALGO_FACE_ENHANCEMENT = 13
20
+ EVE_ALGO_VISUAL_SPEECH_DETECTION = 14
21
+ EVE_ALGO_BACKGROUND_BLUR = 15
22
+ EVE_ALGO_BACKGROUND_REPLACEMENT = 16
23
+ EVE_ALGO_USER_HILIGHT = 17
24
+ EVE_ALGO_USER_FRAMING = 18
25
+ EVE_ALGO_MIRROR_IMAGE = 19
26
+ EVE_ALGO_FPGA_DRAWING = 20
27
+
shared/eve_python/structs/CBasicStructs.py CHANGED
@@ -1,86 +1,92 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
-
4
- EVE_ENCODING_SIZE = 9
5
- EVE_LOCATION_SIZE = 2
6
-
7
- class EveVideoFormat(CtypesEnum):
8
- EVE_NONE = 0
9
- EVE_BGRA = 1
10
- EVE_YUY2 = 2
11
- EVE_NV12 = 3
12
- EVE_MJPG = 4
13
- EVE_BGR = 5
14
- EVE_GRAYSCALE = 6
15
- EVE_RGBA = 7
16
- EVE_RGB = 8
17
- EVE_ENCODING_SIZE = 9
18
-
19
- class EveImageLocation(CtypesEnum):
20
- EVE_CPU = 0
21
- EVE_GPU = 1
22
- EVE_LOCATION_SIZE = 2
23
-
24
- class CPoint2i(ctypes.Structure):
25
- _fields_ = [
26
- ("x", ctypes.c_int),
27
- ("y", ctypes.c_int),
28
- ]
29
-
30
- class CPoint2f(ctypes.Structure):
31
- _fields_ = [
32
- ("x", ctypes.c_float),
33
- ("y", ctypes.c_float),
34
- ]
35
-
36
- class CPoint3i(ctypes.Structure):
37
- _fields_ = [
38
- ("x", ctypes.c_int),
39
- ("y", ctypes.c_int),
40
- ("z", ctypes.c_int),
41
- ]
42
-
43
- class CPoint3f(ctypes.Structure):
44
- _fields_ = [
45
- ("x", ctypes.c_float),
46
- ("y", ctypes.c_float),
47
- ("z", ctypes.c_float),
48
- ]
49
-
50
- class CAngles3f(ctypes.Structure):
51
- _fields_ = [
52
- ("pitch", ctypes.c_float),
53
- ("yaw", ctypes.c_float),
54
- ("roll", ctypes.c_float),
55
- ]
56
-
57
- class CRect2i(ctypes.Structure):
58
- _fields_ = [
59
- ("left", ctypes.c_int),
60
- ("top", ctypes.c_int),
61
- ("right", ctypes.c_int),
62
- ("bottom", ctypes.c_int),
63
- ]
64
-
65
- class CRect2iWH(ctypes.Structure):
66
- _fields_ = [
67
- ("x", ctypes.c_int),
68
- ("y", ctypes.c_int),
69
- ("width", ctypes.c_int),
70
- ("height", ctypes.c_int),
71
- ]
72
-
73
- class CRect2fWH(ctypes.Structure):
74
- _fields_ = [
75
- ("x", ctypes.c_float),
76
- ("y", ctypes.c_float),
77
- ("width", ctypes.c_float),
78
- ("height", ctypes.c_float),
79
- ]
80
-
81
- class CResolution(ctypes.Structure):
82
- _fields_ = [
83
- ("width", ctypes.c_uint),
84
- ("height", ctypes.c_uint),
85
- ]
86
-
 
 
 
 
 
 
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+
4
+ EVE_ENCODING_SIZE = 9
5
+ EVE_LOCATION_SIZE = 2
6
+
7
+ class EveVideoFormat(CtypesEnum):
8
+ EVE_NONE = 0
9
+ EVE_BGRA = 1
10
+ EVE_YUY2 = 2
11
+ EVE_NV12 = 3
12
+ EVE_MJPG = 4
13
+ EVE_BGR = 5
14
+ EVE_GRAYSCALE = 6
15
+ EVE_RGBA = 7
16
+ EVE_RGB = 8
17
+ EVE_ENCODING_SIZE = 9
18
+
19
+ class EveImageLocation(CtypesEnum):
20
+ EVE_CPU = 0
21
+ EVE_GPU = 1
22
+ EVE_LOCATION_SIZE = 2
23
+
24
+ class CPoint2i(ctypes.Structure):
25
+ _fields_ = [
26
+ ("x", ctypes.c_int),
27
+ ("y", ctypes.c_int),
28
+ ]
29
+
30
+ class CPoint2f(ctypes.Structure):
31
+ _fields_ = [
32
+ ("x", ctypes.c_float),
33
+ ("y", ctypes.c_float),
34
+ ]
35
+
36
+ class CPoint3i(ctypes.Structure):
37
+ _fields_ = [
38
+ ("x", ctypes.c_int),
39
+ ("y", ctypes.c_int),
40
+ ("z", ctypes.c_int),
41
+ ]
42
+
43
+ class CPoint3f(ctypes.Structure):
44
+ _fields_ = [
45
+ ("x", ctypes.c_float),
46
+ ("y", ctypes.c_float),
47
+ ("z", ctypes.c_float),
48
+ ]
49
+
50
+ class CAngles3f(ctypes.Structure):
51
+ _fields_ = [
52
+ ("pitch", ctypes.c_float),
53
+ ("yaw", ctypes.c_float),
54
+ ("roll", ctypes.c_float),
55
+ ]
56
+
57
+ class CRect2i(ctypes.Structure):
58
+ _fields_ = [
59
+ ("left", ctypes.c_int),
60
+ ("top", ctypes.c_int),
61
+ ("right", ctypes.c_int),
62
+ ("bottom", ctypes.c_int),
63
+ ]
64
+
65
+ class CRect2iWH(ctypes.Structure):
66
+ _fields_ = [
67
+ ("x", ctypes.c_int),
68
+ ("y", ctypes.c_int),
69
+ ("width", ctypes.c_int),
70
+ ("height", ctypes.c_int),
71
+ ]
72
+
73
+ class CRect2fWH(ctypes.Structure):
74
+ _fields_ = [
75
+ ("x", ctypes.c_float),
76
+ ("y", ctypes.c_float),
77
+ ("width", ctypes.c_float),
78
+ ("height", ctypes.c_float),
79
+ ]
80
+
81
+ class CResolution(ctypes.Structure):
82
+ _fields_ = [
83
+ ("width", ctypes.c_uint),
84
+ ("height", ctypes.c_uint),
85
+ ]
86
+
87
+ class CStringData(ctypes.Structure):
88
+ _fields_ = [
89
+ ("data", ctypes.POINTER(ctypes.c_byte)),
90
+ ("size", ctypes.c_ulonglong),
91
+ ]
92
+
shared/eve_python/structs/CCameraStructs.py CHANGED
@@ -1,48 +1,66 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .CBasicStructs import *
4
-
5
- CAMERA_PID_VID_SIZE = 8
6
- CAMERA_NAME_SIZE = 64
7
-
8
- class EveCompare(CtypesEnum):
9
- EVE_EQUAL = 0
10
- EVE_AT_MOST = 1
11
- EVE_AT_LEAST = 2
12
-
13
- class CCameraFormat(ctypes.Structure):
14
- _fields_ = [
15
- ("resolution", CResolution),
16
- ("format", ctypes.c_int),
17
- ("fps", ctypes.c_float),
18
- ("compareResolution", ctypes.c_int),
19
- ("compareFps", ctypes.c_int),
20
- ]
21
-
22
- class CCamera(ctypes.Structure):
23
- _fields_ = [
24
- ("id", ctypes.c_int),
25
- ("pid", ctypes.c_byte * CAMERA_PID_VID_SIZE),
26
- ("vid", ctypes.c_byte * CAMERA_PID_VID_SIZE),
27
- ("name", ctypes.c_byte * CAMERA_NAME_SIZE),
28
- ("isHardwareCamera", ctypes.c_uint),
29
- ("isFpgaCamera", ctypes.c_uint),
30
- ("isIrCamera", ctypes.c_uint),
31
- ]
32
-
33
- class CCameraParameters(ctypes.Structure):
34
- _fields_ = [
35
- ("width", ctypes.c_int),
36
- ("height", ctypes.c_int),
37
- ("focalLength", ctypes.c_double),
38
- ("pixelSizeX", ctypes.c_double),
39
- ("pixelSizeY", ctypes.c_double),
40
- ("principalPointX", ctypes.c_double),
41
- ("principalPointY", ctypes.c_double),
42
- ("depthMin", ctypes.c_double),
43
- ("depthMax", ctypes.c_double),
44
- ("screenLocationXinMM", ctypes.c_float),
45
- ("screenLocationYinMM", ctypes.c_float),
46
- ("isInfrared", ctypes.c_uint),
47
- ]
48
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .CBasicStructs import *
4
+
5
+ CAMERA_PID_VID_SIZE = 8
6
+ CAMERA_NAME_SIZE = 64
7
+
8
+ class EveCompare(CtypesEnum):
9
+ EVE_EQUAL = 0
10
+ EVE_AT_MOST = 1
11
+ EVE_AT_LEAST = 2
12
+
13
+ class CCameraFormat(ctypes.Structure):
14
+ _fields_ = [
15
+ ("resolution", CResolution),
16
+ ("format", ctypes.c_int),
17
+ ("fps", ctypes.c_float),
18
+ ("compareResolution", ctypes.c_int),
19
+ ("compareFps", ctypes.c_int),
20
+ ]
21
+
22
+ class CCamera(ctypes.Structure):
23
+ _fields_ = [
24
+ ("id", ctypes.c_int),
25
+ ("pid", ctypes.c_byte * CAMERA_PID_VID_SIZE),
26
+ ("vid", ctypes.c_byte * CAMERA_PID_VID_SIZE),
27
+ ("name", ctypes.c_byte * CAMERA_NAME_SIZE),
28
+ ("isHardwareCamera", ctypes.c_uint),
29
+ ("isFpgaCamera", ctypes.c_uint),
30
+ ("isIrCamera", ctypes.c_uint),
31
+ ("screenLocationXinMM", ctypes.c_float),
32
+ ("screenLocationYinMM", ctypes.c_float),
33
+ ]
34
+
35
+ class CCameraParameters(ctypes.Structure):
36
+ _fields_ = [
37
+ ("width", ctypes.c_int),
38
+ ("height", ctypes.c_int),
39
+ ("focalLength", ctypes.c_double),
40
+ ("pixelSizeX", ctypes.c_double),
41
+ ("pixelSizeY", ctypes.c_double),
42
+ ("principalPointX", ctypes.c_double),
43
+ ("principalPointY", ctypes.c_double),
44
+ ("depthMin", ctypes.c_double),
45
+ ("depthMax", ctypes.c_double),
46
+ ("screenLocationXinMM", ctypes.c_float),
47
+ ("screenLocationYinMM", ctypes.c_float),
48
+ ("isInfrared", ctypes.c_uint),
49
+ ]
50
+
51
+ class CMonitor(ctypes.Structure):
52
+ _fields_ = [
53
+ ("rectangle", CRect2iWH),
54
+ ("dpiRatio", ctypes.c_float),
55
+ ("dpiX", ctypes.c_float),
56
+ ("dpiY", ctypes.c_float),
57
+ ("primary", ctypes.c_uint),
58
+ ]
59
+
60
+ class CCameraLocation(ctypes.Structure):
61
+ _fields_ = [
62
+ ("id", ctypes.c_int),
63
+ ("screenLocationXinMM", ctypes.c_float),
64
+ ("screenLocationYinMM", ctypes.c_float),
65
+ ]
66
+
shared/eve_python/structs/CDetectionStructs.py CHANGED
@@ -1,38 +1,44 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .EveProcessingStatus import *
4
-
5
- EVE_DETECTIONS_SIZE = 256
6
- EVE_CLASS_ID_NAME_SIZE = 32
7
-
8
- class EveActionStatus(CtypesEnum):
9
- EVE_IDLE = 0
10
- EVE_INTERPOLATED = 1
11
- EVE_COMPUTED = 2
12
- EVE_NO_OUTPUT = 3
13
-
14
- class FrontalStatus(CtypesEnum):
15
- UNKNOWN = 0
16
- FRONTAL = 1
17
- NON_FRONTAL = 2
18
-
19
- class CSingleDetectionData(ctypes.Structure):
20
- _fields_ = [
21
- ("topLeftX", ctypes.c_int),
22
- ("topLeftY", ctypes.c_int),
23
- ("bottomRightX", ctypes.c_int),
24
- ("bottomRightY", ctypes.c_int),
25
- ("classScore", ctypes.c_float),
26
- ("classId", ctypes.c_int),
27
- ("classIdName", ctypes.c_byte * EVE_CLASS_ID_NAME_SIZE),
28
- ("frontalStatus", ctypes.c_int),
29
- ]
30
-
31
- class CDetectionData(ctypes.Structure):
32
- _fields_ = [
33
- ("processingStatus", ctypes.c_int),
34
- ("actionStatus", ctypes.c_int),
35
- ("numberOfDetections", ctypes.c_int),
36
- ("detections", CSingleDetectionData * EVE_DETECTIONS_SIZE),
37
- ]
38
-
 
 
 
 
 
 
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .EveProcessingStatus import *
4
+
5
+ EVE_DETECTIONS_SIZE = 256
6
+ EVE_CLASS_ID_NAME_SIZE = 32
7
+
8
+ class EveActionStatus(CtypesEnum):
9
+ EVE_IDLE = 0
10
+ EVE_INTERPOLATED = 1
11
+ EVE_COMPUTED = 2
12
+ EVE_NO_OUTPUT = 3
13
+
14
+ class FrontalStatus(CtypesEnum):
15
+ UNKNOWN = 0
16
+ FRONTAL = 1
17
+ NON_FRONTAL = 2
18
+
19
+ class PPEStatus(CtypesEnum):
20
+ PPE_UNKNOWN = 0
21
+ PPE_HARD_HAT = 1
22
+ NO_PPE = 2
23
+
24
+ class CSingleDetectionData(ctypes.Structure):
25
+ _fields_ = [
26
+ ("topLeftX", ctypes.c_int),
27
+ ("topLeftY", ctypes.c_int),
28
+ ("bottomRightX", ctypes.c_int),
29
+ ("bottomRightY", ctypes.c_int),
30
+ ("classScore", ctypes.c_float),
31
+ ("classId", ctypes.c_int),
32
+ ("classIdName", ctypes.c_byte * EVE_CLASS_ID_NAME_SIZE),
33
+ ("frontalStatus", ctypes.c_int),
34
+ ("ppeStatus", ctypes.c_int),
35
+ ]
36
+
37
+ class CDetectionData(ctypes.Structure):
38
+ _fields_ = [
39
+ ("processingStatus", ctypes.c_int),
40
+ ("actionStatus", ctypes.c_int),
41
+ ("numberOfDetections", ctypes.c_int),
42
+ ("detections", CSingleDetectionData * EVE_DETECTIONS_SIZE),
43
+ ]
44
+
shared/eve_python/structs/CFaceData.py CHANGED
@@ -1,55 +1,61 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .CBasicStructs import *
4
- from .CFaceIdStructs import *
5
-
6
- EVE_MAX_FACES = 10
7
- EVE_EYE_LANDMARK_SIZE = 14
8
- EVE_PUPIL_LANDMARK_SIZE = 2
9
-
10
- class EveEyeLandmark(CtypesEnum):
11
- EVE_EYE_RIGHT_CORNER_TEMPORAL = 0
12
- EVE_EYE_RIGHT_EYELID_UPPER_1 = 1
13
- EVE_EYE_RIGHT_EYELID_UPPER_2 = 2
14
- EVE_EYE_RIGHT_CORNER_NASAL = 3
15
- EVE_EYE_RIGHT_EYELID_LOWER_1 = 4
16
- EVE_EYE_RIGHT_EYELID_LOWER_2 = 5
17
- EVE_EYE_LEFT_CORNER_NASAL = 6
18
- EVE_EYE_LEFT_EYELID_UPPER_2 = 7
19
- EVE_EYE_LEFT_EYELID_UPPER_1 = 8
20
- EVE_EYE_LEFT_CORNER_TEMPORAL = 9
21
- EVE_EYE_LEFT_EYELID_LOWER_2 = 10
22
- EVE_EYE_LEFT_EYELID_LOWER_1 = 11
23
- EVE_EYE_RIGHT_PUPIL_CENTER = 12
24
- EVE_EYE_LEFT_PUPIL_CENTER = 13
25
- EVE_EYE_LANDMARK_SIZE = 14
26
-
27
- class EvePupilLandmark(CtypesEnum):
28
- EVE_RIGHT_PUPIL_CENTER = 0
29
- EVE_LEFT_PUPIL_CENTER = 1
30
- EVE_PUPIL_LANDMARK_SIZE = 2
31
-
32
- class CEyeLandmarks(ctypes.Structure):
33
- _fields_ = [
34
- ("landmarks", CPoint3f * EVE_EYE_LANDMARK_SIZE),
35
- ]
36
-
37
- class CPupilLandmarks(ctypes.Structure):
38
- _fields_ = [
39
- ("landmarks", CPoint3f * EVE_PUPIL_LANDMARK_SIZE),
40
- ]
41
-
42
- class CFaceData(ctypes.Structure):
43
- _fields_ = [
44
- ("angles", CAngles3f),
45
- ("faceId", CFaceIdentityData),
46
- ("depth", ctypes.c_float),
47
- ("trackNumber", ctypes.c_int),
48
- ]
49
-
50
- class CAllFaces(ctypes.Structure):
51
- _fields_ = [
52
- ("detectedFacesCount", ctypes.c_uint),
53
- ("faces", CFaceData * EVE_MAX_FACES),
54
- ]
55
-
 
 
 
 
 
 
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .CBasicStructs import *
4
+ from .CFaceIdStructs import *
5
+
6
+ EVE_MAX_FACE_LANDMARKS = 68
7
+ EVE_MAX_FACES = 10
8
+ EVE_EYE_LANDMARK_SIZE = 14
9
+ EVE_PUPIL_LANDMARK_SIZE = 2
10
+
11
+ class EveEyeLandmark(CtypesEnum):
12
+ EVE_EYE_RIGHT_CORNER_TEMPORAL = 0
13
+ EVE_EYE_RIGHT_EYELID_UPPER_1 = 1
14
+ EVE_EYE_RIGHT_EYELID_UPPER_2 = 2
15
+ EVE_EYE_RIGHT_CORNER_NASAL = 3
16
+ EVE_EYE_RIGHT_EYELID_LOWER_1 = 4
17
+ EVE_EYE_RIGHT_EYELID_LOWER_2 = 5
18
+ EVE_EYE_LEFT_CORNER_NASAL = 6
19
+ EVE_EYE_LEFT_EYELID_UPPER_2 = 7
20
+ EVE_EYE_LEFT_EYELID_UPPER_1 = 8
21
+ EVE_EYE_LEFT_CORNER_TEMPORAL = 9
22
+ EVE_EYE_LEFT_EYELID_LOWER_2 = 10
23
+ EVE_EYE_LEFT_EYELID_LOWER_1 = 11
24
+ EVE_EYE_RIGHT_PUPIL_CENTER = 12
25
+ EVE_EYE_LEFT_PUPIL_CENTER = 13
26
+ EVE_EYE_LANDMARK_SIZE = 14
27
+
28
+ class EvePupilLandmark(CtypesEnum):
29
+ EVE_RIGHT_PUPIL_CENTER = 0
30
+ EVE_LEFT_PUPIL_CENTER = 1
31
+ EVE_PUPIL_LANDMARK_SIZE = 2
32
+
33
+ class CEyeLandmarks(ctypes.Structure):
34
+ _fields_ = [
35
+ ("landmarks", CPoint3f * EVE_EYE_LANDMARK_SIZE),
36
+ ]
37
+
38
+ class CPupilLandmarks(ctypes.Structure):
39
+ _fields_ = [
40
+ ("landmarks", CPoint3f * EVE_PUPIL_LANDMARK_SIZE),
41
+ ]
42
+
43
+ class CFaceData(ctypes.Structure):
44
+ _fields_ = [
45
+ ("angles", CAngles3f),
46
+ ("faceId", CFaceIdentityData),
47
+ ("depth", ctypes.c_float),
48
+ ("trackNumber", ctypes.c_int),
49
+ ("box", CRect2iWH),
50
+ ("landmarksCount", ctypes.c_uint),
51
+ ("landmarksICS", CPoint2f * EVE_MAX_FACE_LANDMARKS),
52
+ ("landmarksCCS", CPoint3f * EVE_MAX_FACE_LANDMARKS),
53
+ ("midEyeCCS", CPoint3f),
54
+ ]
55
+
56
+ class CAllFaces(ctypes.Structure):
57
+ _fields_ = [
58
+ ("detectedFacesCount", ctypes.c_uint),
59
+ ("faces", CFaceData * EVE_MAX_FACES),
60
+ ]
61
+
shared/eve_python/structs/CFaceIdStructs.py CHANGED
@@ -1,68 +1,68 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .EveProcessingStatus import *
4
-
5
- EVE_FACE_ID_MAX_MISSING_CALIBRATION_POSES = 5
6
-
7
- class EveFaceIdActionStatus(CtypesEnum):
8
- EVE_FACE_ID_ACTION_IDLE = 0
9
- EVE_FACE_ID_ACTION_CALIBRATING = 1
10
- EVE_FACE_ID_ACTION_CALIBRATED = 2
11
- EVE_FACE_ID_ACTION_IDENTIFIED = 3
12
-
13
- class EveFaceIdCalibrationStatus(CtypesEnum):
14
- EVE_FACE_ID_CALIB_NONE = 0
15
- EVE_FACE_ID_CALIB_RUNNING = 1
16
- EVE_FACE_ID_CALIB_SUCCESS = 2
17
- EVE_FACE_ID_CALIB_FAILURE_LACK_POSE_MOTION = 3
18
- EVE_FACE_ID_CALIB_FAILURE_OTHER = 4
19
-
20
- class EveFaceIdIdentificationStatus(CtypesEnum):
21
- EVE_FACE_ID_NONE = 0
22
- EVE_FACE_ID_SUCCESS = 1
23
- EVE_FACE_ID_FAILURE_VERIFICATION = 2
24
- EVE_FACE_ID_FAILURE_ANGLE_PITCH = 3
25
- EVE_FACE_ID_FAILURE_ANGLE_YAW = 4
26
- EVE_FACE_ID_FAILURE_ANGLE_ROLL = 5
27
- EVE_FACE_ID_FAILURE_ANGLE_BOTH = 6
28
- EVE_FACE_ID_FAILURE_NO_GALLERY = 7
29
- EVE_FACE_ID_FAILURE_EXP_SMILE = 8
30
- EVE_FACE_ID_FAILURE_EXP_SQUINT = 9
31
- EVE_FACE_ID_FAILURE_EXP_EYES_CLOSED = 10
32
- EVE_FACE_ID_FAILURE_DEPTH = 11
33
- EVE_FACE_ID_FAILURE_OTHER = 12
34
-
35
- class EveFaceIdPose(CtypesEnum):
36
- EVE_FACE_ID_POSE_FRONTAL = 0
37
- EVE_FACE_ID_POSE_LEFT = 1
38
- EVE_FACE_ID_POSE_RIGHT = 2
39
- EVE_FACE_ID_POSE_UP = 3
40
- EVE_FACE_ID_POSE_DOWN = 4
41
-
42
- class EveFaceIdCommand(CtypesEnum):
43
- EVE_FACE_ID_COMMAND_NONE = 0
44
- EVE_FACE_ID_COMMAND_ADD_NEW_USER = 1
45
- EVE_FACE_ID_COMMAND_CALIBRATE_CURRENT_USER = 2
46
- EVE_FACE_ID_COMMAND_FORCE_ID = 3
47
- EVE_FACE_ID_COMMAND_REMOVE_CURRENT_USER = 4
48
- EVE_FACE_ID_COMMAND_REMOVE_ALL_USERS = 5
49
- EVE_FACE_ID_COMMAND_RELOAD_GALLERY = 6
50
-
51
- class CFaceIdentity(ctypes.Structure):
52
- _fields_ = [
53
- ("id", ctypes.c_longlong),
54
- ("confidence", ctypes.c_float),
55
- ("similarity", ctypes.c_float),
56
- ]
57
-
58
- class CFaceIdentityData(ctypes.Structure):
59
- _fields_ = [
60
- ("processingStatus", ctypes.c_int),
61
- ("actionStatus", ctypes.c_int),
62
- ("calibrationStatus", ctypes.c_int),
63
- ("identificationStatus", ctypes.c_int),
64
- ("faceIdentity", CFaceIdentity),
65
- ("missingCalibrationPosesCount", ctypes.c_uint),
66
- ("missingCalibrationPoses", ctypes.c_int * EVE_FACE_ID_MAX_MISSING_CALIBRATION_POSES),
67
- ]
68
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .EveProcessingStatus import *
4
+
5
+ EVE_FACE_ID_MAX_MISSING_CALIBRATION_POSES = 5
6
+
7
+ class EveFaceIdActionStatus(CtypesEnum):
8
+ EVE_FACE_ID_ACTION_IDLE = 0
9
+ EVE_FACE_ID_ACTION_CALIBRATING = 1
10
+ EVE_FACE_ID_ACTION_CALIBRATED = 2
11
+ EVE_FACE_ID_ACTION_IDENTIFIED = 3
12
+
13
+ class EveFaceIdCalibrationStatus(CtypesEnum):
14
+ EVE_FACE_ID_CALIB_NONE = 0
15
+ EVE_FACE_ID_CALIB_RUNNING = 1
16
+ EVE_FACE_ID_CALIB_SUCCESS = 2
17
+ EVE_FACE_ID_CALIB_FAILURE_LACK_POSE_MOTION = 3
18
+ EVE_FACE_ID_CALIB_FAILURE_OTHER = 4
19
+
20
+ class EveFaceIdIdentificationStatus(CtypesEnum):
21
+ EVE_FACE_ID_NONE = 0
22
+ EVE_FACE_ID_SUCCESS = 1
23
+ EVE_FACE_ID_FAILURE_VERIFICATION = 2
24
+ EVE_FACE_ID_FAILURE_ANGLE_PITCH = 3
25
+ EVE_FACE_ID_FAILURE_ANGLE_YAW = 4
26
+ EVE_FACE_ID_FAILURE_ANGLE_ROLL = 5
27
+ EVE_FACE_ID_FAILURE_ANGLE_BOTH = 6
28
+ EVE_FACE_ID_FAILURE_NO_GALLERY = 7
29
+ EVE_FACE_ID_FAILURE_EXP_SMILE = 8
30
+ EVE_FACE_ID_FAILURE_EXP_SQUINT = 9
31
+ EVE_FACE_ID_FAILURE_EXP_EYES_CLOSED = 10
32
+ EVE_FACE_ID_FAILURE_DEPTH = 11
33
+ EVE_FACE_ID_FAILURE_OTHER = 12
34
+
35
+ class EveFaceIdPose(CtypesEnum):
36
+ EVE_FACE_ID_POSE_FRONTAL = 0
37
+ EVE_FACE_ID_POSE_LEFT = 1
38
+ EVE_FACE_ID_POSE_RIGHT = 2
39
+ EVE_FACE_ID_POSE_UP = 3
40
+ EVE_FACE_ID_POSE_DOWN = 4
41
+
42
+ class EveFaceIdCommand(CtypesEnum):
43
+ EVE_FACE_ID_COMMAND_NONE = 0
44
+ EVE_FACE_ID_COMMAND_ADD_NEW_USER = 1
45
+ EVE_FACE_ID_COMMAND_CALIBRATE_CURRENT_USER = 2
46
+ EVE_FACE_ID_COMMAND_FORCE_ID = 3
47
+ EVE_FACE_ID_COMMAND_REMOVE_CURRENT_USER = 4
48
+ EVE_FACE_ID_COMMAND_REMOVE_ALL_USERS = 5
49
+ EVE_FACE_ID_COMMAND_RELOAD_GALLERY = 6
50
+
51
+ class CFaceIdentity(ctypes.Structure):
52
+ _fields_ = [
53
+ ("id", ctypes.c_longlong),
54
+ ("confidence", ctypes.c_float),
55
+ ("similarity", ctypes.c_float),
56
+ ]
57
+
58
+ class CFaceIdentityData(ctypes.Structure):
59
+ _fields_ = [
60
+ ("processingStatus", ctypes.c_int),
61
+ ("actionStatus", ctypes.c_int),
62
+ ("calibrationStatus", ctypes.c_int),
63
+ ("identificationStatus", ctypes.c_int),
64
+ ("faceIdentity", CFaceIdentity),
65
+ ("missingCalibrationPosesCount", ctypes.c_uint),
66
+ ("missingCalibrationPoses", ctypes.c_int * EVE_FACE_ID_MAX_MISSING_CALIBRATION_POSES),
67
+ ]
68
+
shared/eve_python/structs/CFpgaData.py CHANGED
@@ -1,350 +1,350 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .CBasicStructs import *
4
-
5
- EVE_FPGA_MAX_USERS = 10
6
- EVE_FPGA_MAX_PERSONS = 5
7
- EVE_FPGA_MAX_HAND_LANDMARKS = 11
8
- EVE_FPGA_HAND_LANDMARKS = 10
9
- EVE_FPGA_MAX_OBJECT_DETECTION = 50
10
- PT_SIZE = 6
11
- MT_SIZE = 4
12
- RT_SIZE = 4
13
-
14
- class EveFpgaConnectionType(CtypesEnum):
15
- EVE_FPGA_AUTO_SELECT = 0
16
- EVE_FPGA_UART = 1
17
- EVE_FPGA_I2C = 2
18
- EVE_FPGA_HUB = 3
19
- EVE_FPGA_MANUAL = 4
20
-
21
- class EveFpgaConnectionRequest(CtypesEnum):
22
- EVE_FPGA_STOP = 0
23
- EVE_FPGA_CONTINUE = 1
24
-
25
- class pipeline_config_type_t(CtypesEnum):
26
- PT_FD = 0
27
- PT_LM_FV = 1
28
- PT_FID = 2
29
- PT_PD = 3
30
- PT_HD = 4
31
- PT_HLMV = 5
32
- PT_SIZE = 6
33
-
34
- class setting_type_t(CtypesEnum):
35
- CS_ENABLED = 0x00
36
- CS_IPS = 0x01
37
- CS_RESERVED_2_7 = 0x02
38
- CS_COMMAND = 0x08
39
- CS_CUSTOM = 0x10
40
- CS_MAX = 0x11
41
-
42
- class message_type_t(CtypesEnum):
43
- MT_NONE = 0
44
- MT_SET = 1
45
- MT_GET = 2
46
- MT_GET_BATCH = 3
47
- MT_SIZE = 4
48
-
49
- class response_type_t(CtypesEnum):
50
- RT_NONE = 0
51
- RT_DATA = 1
52
- RT_GET = 2
53
- RT_ACK = 3
54
- RT_SIZE = 4
55
-
56
- class EveFpgaSerialStatus(CtypesEnum):
57
- EVE_FPGA_SUCCESS = 0
58
- EVE_FPGA_NO_DATA = 1
59
- EVE_FPGA_READ_START_MARKER_FAILED = 2
60
- EVE_FPGA_FIND_START_MARKER_FAILED = 3
61
- EVE_FPGA_READ_DATA_LENGTH_FAILED = 4
62
- EVE_FPGA_READ_DATA_FAILED = 5
63
- EVE_FPGA_CORRUPTED_DATA = 6
64
- EVE_FPGA_UNEXPECTED_RESPONSE_TYPE = 7
65
- EVE_FPGA_API_ERROR_START = 8
66
- EVE_FPGA_NO_CALLBACK = 9
67
- EVE_FPGA_DATA_ACCESSED_OUTSIDE_CALLBACK = 10
68
- EVE_FPGA_INIT_FAILED = 11
69
- EVE_FPGA_NOT_INIT = 12
70
- EVE_FPGA_NOT_IMPLEMENTED = 13
71
- EVE_FPGA_API_ERROR_END = 14
72
-
73
- class EveWakeupDetectionType(CtypesEnum):
74
- EVE_USER_DETECTION = 0
75
- EVE_STRANGER_DETECTION = 1
76
-
77
- class EveFpgaPipelineType(CtypesEnum):
78
- EVE_UNKNOWN_PIPELINE = 0
79
- EVE_HEAD_POSE_PIPELINE = 1
80
- EVE_FACE_ID_PIPELINE = 2
81
- EVE_HAND_GESTURE_PIPELINE = 3
82
- EVE_COMPACT_HEAD_POSE_PIPELINE = 4
83
- EVE_HMI_PIPELINE = 5
84
- EVE_STANDALONE_HAND_GESTURE_PIPELINE = 6
85
-
86
- class EvePersonBodyPose(CtypesEnum):
87
- EVE_FRONT = 0
88
- EVE_NOT_FRONT = 1
89
-
90
- class EveDistanceFromCamera(CtypesEnum):
91
- EVE_DISTANCE_CLOSE = 0
92
- EVE_DISTANCE_MID = 1
93
- EVE_DISTANCE_FAR = 2
94
-
95
- class EvePersonRegistrationStatus(CtypesEnum):
96
- EVE_REGISTERED = 0
97
- EVE_UNREGISTERED = 1
98
- EVE_UNKNOWN = 2
99
- EVE_REQUIREMENTS_UNMET = 3
100
- EVE_DISABLED = 4
101
- EVE_NO_GALLERY = 5
102
-
103
- class EveFpgaHandGesture(CtypesEnum):
104
- EVE_FPGA_HAND_GESTURE_NO_GESTURE = 0
105
- EVE_FPGA_HAND_GESTURE_CLOSE = 1
106
- EVE_FPGA_HAND_GESTURE_OPEN = 2
107
- EVE_FPGA_HAND_GESTURE_OPEN_LEFT = 3
108
- EVE_FPGA_HAND_GESTURE_OPEN_RIGHT = 4
109
- EVE_FPGA_HAND_GESTURE_INDEX_UP = 5
110
- EVE_FPGA_HAND_GESTURE_INDEX_DOWN = 6
111
- EVE_FPGA_HAND_GESTURE_TIP_LEFT = 7
112
- EVE_FPGA_HAND_GESTURE_TIP_RIGHT = 8
113
- EVE_FPGA_HAND_GESTURE_UNKNOWN = 9
114
-
115
- class EveFpgaObjectClass(CtypesEnum):
116
- EVE_FPGA_OBJECT_CLASS_PERSON = 0
117
- EVE_FPGA_OBJECT_CLASS_BICYCLE = 1
118
- EVE_FPGA_OBJECT_CLASS_CAR = 2
119
- EVE_FPGA_OBJECT_CLASS_MOTORCYCLE = 3
120
- EVE_FPGA_OBJECT_CLASS_BUS = 4
121
- EVE_FPGA_OBJECT_CLASS_TRUCK = 5
122
- EVE_FPGA_OBJECT_CLASS_TRAFFIC_LIGHT = 6
123
- EVE_FPGA_OBJECT_CLASS_STOP_SIGN = 7
124
-
125
- class pipeline_setting_t(ctypes.Structure):
126
- _fields_ = [
127
- ("settingType", ctypes.c_int),
128
- ("value", ctypes.c_uint32),
129
- ]
130
-
131
- class pipeline_config_t(ctypes.Structure):
132
- _fields_ = [
133
- ("type", ctypes.c_int),
134
- ("setting", pipeline_setting_t),
135
- ]
136
-
137
- class CFpgaIdealPersonData(ctypes.Structure):
138
- _fields_ = [
139
- ("valid", ctypes.c_uint),
140
- ("index", ctypes.c_uint),
141
- ("status", ctypes.c_int),
142
- ("faceAngles", CAngles3f),
143
- ("faceLandmarksConfidence", ctypes.c_float),
144
- ("isFaceLandmarksConfidenceValid", ctypes.c_bool),
145
- ]
146
-
147
- class CFpgaImageDimensions(ctypes.Structure):
148
- _fields_ = [
149
- ("width", ctypes.c_int),
150
- ("height", ctypes.c_int),
151
- ("cropArea", CRect2i),
152
- ("reserved1", ctypes.c_int),
153
- ("reserved2", ctypes.c_int),
154
- ]
155
-
156
- class CFpgaDataContent(ctypes.Structure):
157
- _fields_ = [
158
- ("numberOfUsers", ctypes.c_int16),
159
- ("idealUserIndex", ctypes.c_int16),
160
- ("numberOfDetectedFaces", ctypes.c_int16),
161
- ("numberOfFacesConfidence", ctypes.c_float),
162
- ("numberOfDetectedPersons", ctypes.c_int16),
163
- ("numberOfPersonsConfidence", ctypes.c_float),
164
- ("isIdealUserDataAvailable", ctypes.c_bool),
165
- ("idealUserDetected", ctypes.c_bool),
166
- ("isIdealUserIndexValid", ctypes.c_bool),
167
- ("isNumberOfDetectedFacesAvailable", ctypes.c_bool),
168
- ("isNumberOfFacesConfidenceAvailable", ctypes.c_bool),
169
- ("isNumberOfDetectedPersonsAvailable", ctypes.c_bool),
170
- ("isNumberOfPersonsConfidenceAvailable", ctypes.c_bool),
171
- ("isUsersDataAvilable", ctypes.c_bool),
172
- ("isFaceIdDataAvailable", ctypes.c_bool),
173
- ("isObjectDetectionAvailable", ctypes.c_bool),
174
- ("isCameraStreaming", ctypes.c_bool),
175
- ("isHandGestureDataAvailable", ctypes.c_bool),
176
- ("isDefectDetectionAvailable", ctypes.c_bool),
177
- ]
178
-
179
- class CFpgaHandData(ctypes.Structure):
180
- _fields_ = [
181
- ("validationScore", ctypes.c_float),
182
- ("handBox", CRect2i),
183
- ("landmarks", CPoint3f * EVE_FPGA_MAX_HAND_LANDMARKS),
184
- ]
185
-
186
- class CFpgaHandsData(ctypes.Structure):
187
- _fields_ = [
188
- ("numberOfHandLandmarkPoints", ctypes.c_int16),
189
- ("handData", CFpgaHandData),
190
- ("gesture", ctypes.c_int),
191
- ("isHandBoxAvailable", ctypes.c_bool),
192
- ("isHandLandmark3D", ctypes.c_bool),
193
- ]
194
-
195
- class CFpgaDefectData(ctypes.Structure):
196
- _fields_ = [
197
- ("defectBox", CRect2i),
198
- ("width", ctypes.c_int),
199
- ("height", ctypes.c_int),
200
- ("similarity", ctypes.c_float),
201
- ("isDefective", ctypes.c_bool),
202
- ]
203
-
204
- class CFpgaFaceData(ctypes.Structure):
205
- _fields_ = [
206
- ("faceConfidence", ctypes.c_float),
207
- ("faceDistance", ctypes.c_int16),
208
- ("faceCenter", CPoint3i),
209
- ("anglesICS", CAngles3f),
210
- ("anglesCCS", CAngles3f),
211
- ("faceLandmarksConfidence", ctypes.c_float),
212
- ("faceBox", CRect2i),
213
- ("faceIDStatus", ctypes.c_int),
214
- ("faceID", ctypes.c_int16),
215
- ("isFaceConfidenceAvailable", ctypes.c_bool),
216
- ("isFaceDistanceAvailable", ctypes.c_bool),
217
- ("isFacePositionAvailable", ctypes.c_bool),
218
- ("isEulerAnglesIcsAvailable", ctypes.c_bool),
219
- ("isEulerAnglesCcsAvailable", ctypes.c_bool),
220
- ("isFaceLandmark3D", ctypes.c_bool),
221
- ("isFaceLandmarksConfidenceAvailable", ctypes.c_bool),
222
- ("isFaceGeometricBoxAvailable", ctypes.c_bool),
223
- ("isStatusAvailable", ctypes.c_bool),
224
- ]
225
-
226
- class CFpgaPersonData(ctypes.Structure):
227
- _fields_ = [
228
- ("personConfidence", ctypes.c_float),
229
- ("personDistance", ctypes.c_int),
230
- ("personPosture", ctypes.c_int),
231
- ("personFrontalPostureConfidence", ctypes.c_float),
232
- ("personNotFrontalPostureConfidence", ctypes.c_float),
233
- ("position", CPoint3i),
234
- ("personBox", CRect2i),
235
- ("isPersonDataAvailable", ctypes.c_bool),
236
- ]
237
-
238
- class CFpgaObjectDetection(ctypes.Structure):
239
- _fields_ = [
240
- ("objectClass", ctypes.c_int),
241
- ("objectConfidence", ctypes.c_float),
242
- ("objectBox", CRect2i),
243
- ]
244
-
245
- class CFpgaObjectData(ctypes.Structure):
246
- _fields_ = [
247
- ("numberOfObjects", ctypes.c_int16),
248
- ("objects", CFpgaObjectDetection * EVE_FPGA_MAX_OBJECT_DETECTION),
249
- ]
250
-
251
- class CFpgaUserData(ctypes.Structure):
252
- _fields_ = [
253
- ("id", ctypes.c_int16),
254
- ("status", ctypes.c_int),
255
- ("scale", ctypes.c_float),
256
- ("faceData", CFpgaFaceData),
257
- ("personData", CFpgaPersonData),
258
- ("isIdealUser", ctypes.c_bool),
259
- ("isIdValid", ctypes.c_bool),
260
- ("isStatusAvailable", ctypes.c_bool),
261
- ("isScaleAvailable", ctypes.c_bool),
262
- ]
263
-
264
- class CFpgaFaceIdData(ctypes.Structure):
265
- _fields_ = [
266
- ("command", ctypes.c_int16),
267
- ("userId", ctypes.c_int16),
268
- ("freeEntry", ctypes.c_int16),
269
- ("statusCode", ctypes.c_int16),
270
- ("faceId", ctypes.c_int16),
271
- ("lastRegisteredFaceID", ctypes.c_int16),
272
- ("usersInGallery", ctypes.c_int16),
273
- ("gallerySize", ctypes.c_int16),
274
- ]
275
-
276
- class CFpgaPipelineData(ctypes.Structure):
277
- _fields_ = [
278
- ("pipelineType", ctypes.c_int),
279
- ("imageDimensions", CFpgaImageDimensions),
280
- ("dataContent", CFpgaDataContent),
281
- ("userData", CFpgaUserData * EVE_FPGA_MAX_USERS),
282
- ("objectData", CFpgaObjectData),
283
- ("faceId", CFpgaFaceIdData),
284
- ("handsData", CFpgaHandsData),
285
- ("defectData", CFpgaDefectData),
286
- ]
287
-
288
- class CFpgaMessage(ctypes.Structure):
289
- _fields_ = [
290
- ("responseType", ctypes.c_int),
291
- ("responseVersion", ctypes.c_uint8),
292
- ("serialStatus", ctypes.c_int),
293
- ("serialReadTimeNano", ctypes.c_longlong),
294
- ]
295
-
296
- class CFpgaData(ctypes.Structure):
297
- _fields_ = [
298
- ("message", CFpgaMessage),
299
- ("pipelineData", CFpgaPipelineData),
300
- ]
301
-
302
- class CFpgaGetSetting(ctypes.Structure):
303
- _fields_ = [
304
- ("message", CFpgaMessage),
305
- ("type", ctypes.c_int),
306
- ("setting", ctypes.c_int),
307
- ("value", ctypes.c_uint32),
308
- ]
309
-
310
- class CFpgaParameters(ctypes.Structure):
311
- _fields_ = [
312
- ("comport", ctypes.c_uint),
313
- ("socWakeupDelay", ctypes.c_uint),
314
- ("wakeupType", ctypes.c_int),
315
- ("forceCameraOn", ctypes.c_ubyte),
316
- ("registerNewFace", ctypes.c_ubyte),
317
- ("clearCurrentFace", ctypes.c_ubyte),
318
- ("enableFaceId", ctypes.c_ubyte),
319
- ("allPipelinesSupported", ctypes.c_ubyte),
320
- ("pipelineVersion", ctypes.c_uint),
321
- ("connection", ctypes.c_int),
322
- ("i2cAdapterNumber", ctypes.c_uint),
323
- ("i2cDeviceNumber", ctypes.c_uint),
324
- ("i2cIRQPin", ctypes.c_uint),
325
- ]
326
-
327
- class CFpgaCallbackControl(ctypes.Structure):
328
- _fields_ = [
329
- ("request", ctypes.c_int),
330
- ]
331
-
332
- class EveFpgaMetadata(ctypes.Structure):
333
- _fields_ = [
334
- ("data", ctypes.POINTER(CFpgaData)),
335
- ("errorCode", ctypes.c_int),
336
- ]
337
-
338
- class EveFpgaManualData(ctypes.Structure):
339
- _fields_ = [
340
- ("data", ctypes.POINTER(ctypes.c_ubyte)),
341
- ("size", ctypes.c_int),
342
- ]
343
-
344
- class EveFpgaJsonMetadata(ctypes.Structure):
345
- _fields_ = [
346
- ("textStart", ctypes.POINTER(ctypes.c_byte)),
347
- ("textSize", ctypes.c_uint),
348
- ("errorCode", ctypes.c_int),
349
- ]
350
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .CBasicStructs import *
4
+
5
+ EVE_FPGA_MAX_USERS = 10
6
+ EVE_FPGA_MAX_PERSONS = 5
7
+ EVE_FPGA_MAX_HAND_LANDMARKS = 11
8
+ EVE_FPGA_HAND_LANDMARKS = 10
9
+ EVE_FPGA_MAX_OBJECT_DETECTION = 50
10
+ PT_SIZE = 6
11
+ MT_SIZE = 4
12
+ RT_SIZE = 4
13
+
14
+ class EveFpgaConnectionType(CtypesEnum):
15
+ EVE_FPGA_AUTO_SELECT = 0
16
+ EVE_FPGA_UART = 1
17
+ EVE_FPGA_I2C = 2
18
+ EVE_FPGA_HUB = 3
19
+ EVE_FPGA_MANUAL = 4
20
+
21
+ class EveFpgaConnectionRequest(CtypesEnum):
22
+ EVE_FPGA_STOP = 0
23
+ EVE_FPGA_CONTINUE = 1
24
+
25
+ class pipeline_config_type_t(CtypesEnum):
26
+ PT_FD = 0
27
+ PT_LM_FV = 1
28
+ PT_FID = 2
29
+ PT_PD = 3
30
+ PT_HD = 4
31
+ PT_HLMV = 5
32
+ PT_SIZE = 6
33
+
34
+ class setting_type_t(CtypesEnum):
35
+ CS_ENABLED = 0x00
36
+ CS_IPS = 0x01
37
+ CS_RESERVED_2_7 = 0x02
38
+ CS_COMMAND = 0x08
39
+ CS_CUSTOM = 0x10
40
+ CS_MAX = 0x11
41
+
42
+ class message_type_t(CtypesEnum):
43
+ MT_NONE = 0
44
+ MT_SET = 1
45
+ MT_GET = 2
46
+ MT_GET_BATCH = 3
47
+ MT_SIZE = 4
48
+
49
+ class response_type_t(CtypesEnum):
50
+ RT_NONE = 0
51
+ RT_DATA = 1
52
+ RT_GET = 2
53
+ RT_ACK = 3
54
+ RT_SIZE = 4
55
+
56
+ class EveFpgaSerialStatus(CtypesEnum):
57
+ EVE_FPGA_SUCCESS = 0
58
+ EVE_FPGA_NO_DATA = 1
59
+ EVE_FPGA_READ_START_MARKER_FAILED = 2
60
+ EVE_FPGA_FIND_START_MARKER_FAILED = 3
61
+ EVE_FPGA_READ_DATA_LENGTH_FAILED = 4
62
+ EVE_FPGA_READ_DATA_FAILED = 5
63
+ EVE_FPGA_CORRUPTED_DATA = 6
64
+ EVE_FPGA_UNEXPECTED_RESPONSE_TYPE = 7
65
+ EVE_FPGA_API_ERROR_START = 8
66
+ EVE_FPGA_NO_CALLBACK = 9
67
+ EVE_FPGA_DATA_ACCESSED_OUTSIDE_CALLBACK = 10
68
+ EVE_FPGA_INIT_FAILED = 11
69
+ EVE_FPGA_NOT_INIT = 12
70
+ EVE_FPGA_NOT_IMPLEMENTED = 13
71
+ EVE_FPGA_API_ERROR_END = 14
72
+
73
+ class EveWakeupDetectionType(CtypesEnum):
74
+ EVE_USER_DETECTION = 0
75
+ EVE_STRANGER_DETECTION = 1
76
+
77
+ class EveFpgaPipelineType(CtypesEnum):
78
+ EVE_UNKNOWN_PIPELINE = 0
79
+ EVE_HEAD_POSE_PIPELINE = 1
80
+ EVE_FACE_ID_PIPELINE = 2
81
+ EVE_HAND_GESTURE_PIPELINE = 3
82
+ EVE_COMPACT_HEAD_POSE_PIPELINE = 4
83
+ EVE_HMI_PIPELINE = 5
84
+ EVE_STANDALONE_HAND_GESTURE_PIPELINE = 6
85
+
86
+ class EvePersonBodyPose(CtypesEnum):
87
+ EVE_FRONT = 0
88
+ EVE_NOT_FRONT = 1
89
+
90
+ class EveDistanceFromCamera(CtypesEnum):
91
+ EVE_DISTANCE_CLOSE = 0
92
+ EVE_DISTANCE_MID = 1
93
+ EVE_DISTANCE_FAR = 2
94
+
95
+ class EvePersonRegistrationStatus(CtypesEnum):
96
+ EVE_REGISTERED = 0
97
+ EVE_UNREGISTERED = 1
98
+ EVE_UNKNOWN = 2
99
+ EVE_REQUIREMENTS_UNMET = 3
100
+ EVE_DISABLED = 4
101
+ EVE_NO_GALLERY = 5
102
+
103
+ class EveFpgaHandGesture(CtypesEnum):
104
+ EVE_FPGA_HAND_GESTURE_NO_GESTURE = 0
105
+ EVE_FPGA_HAND_GESTURE_CLOSE = 1
106
+ EVE_FPGA_HAND_GESTURE_OPEN = 2
107
+ EVE_FPGA_HAND_GESTURE_OPEN_LEFT = 3
108
+ EVE_FPGA_HAND_GESTURE_OPEN_RIGHT = 4
109
+ EVE_FPGA_HAND_GESTURE_INDEX_UP = 5
110
+ EVE_FPGA_HAND_GESTURE_INDEX_DOWN = 6
111
+ EVE_FPGA_HAND_GESTURE_TIP_LEFT = 7
112
+ EVE_FPGA_HAND_GESTURE_TIP_RIGHT = 8
113
+ EVE_FPGA_HAND_GESTURE_UNKNOWN = 9
114
+
115
+ class EveFpgaObjectClass(CtypesEnum):
116
+ EVE_FPGA_OBJECT_CLASS_PERSON = 0
117
+ EVE_FPGA_OBJECT_CLASS_BICYCLE = 1
118
+ EVE_FPGA_OBJECT_CLASS_CAR = 2
119
+ EVE_FPGA_OBJECT_CLASS_MOTORCYCLE = 3
120
+ EVE_FPGA_OBJECT_CLASS_BUS = 4
121
+ EVE_FPGA_OBJECT_CLASS_TRUCK = 5
122
+ EVE_FPGA_OBJECT_CLASS_TRAFFIC_LIGHT = 6
123
+ EVE_FPGA_OBJECT_CLASS_STOP_SIGN = 7
124
+
125
+ class pipeline_setting_t(ctypes.Structure):
126
+ _fields_ = [
127
+ ("settingType", ctypes.c_int),
128
+ ("value", ctypes.c_uint32),
129
+ ]
130
+
131
+ class pipeline_config_t(ctypes.Structure):
132
+ _fields_ = [
133
+ ("type", ctypes.c_int),
134
+ ("setting", pipeline_setting_t),
135
+ ]
136
+
137
+ class CFpgaIdealPersonData(ctypes.Structure):
138
+ _fields_ = [
139
+ ("valid", ctypes.c_uint),
140
+ ("index", ctypes.c_uint),
141
+ ("status", ctypes.c_int),
142
+ ("faceAngles", CAngles3f),
143
+ ("faceLandmarksConfidence", ctypes.c_float),
144
+ ("isFaceLandmarksConfidenceValid", ctypes.c_bool),
145
+ ]
146
+
147
+ class CFpgaImageDimensions(ctypes.Structure):
148
+ _fields_ = [
149
+ ("width", ctypes.c_int),
150
+ ("height", ctypes.c_int),
151
+ ("cropArea", CRect2i),
152
+ ("reserved1", ctypes.c_int),
153
+ ("reserved2", ctypes.c_int),
154
+ ]
155
+
156
+ class CFpgaDataContent(ctypes.Structure):
157
+ _fields_ = [
158
+ ("numberOfUsers", ctypes.c_int16),
159
+ ("idealUserIndex", ctypes.c_int16),
160
+ ("numberOfDetectedFaces", ctypes.c_int16),
161
+ ("numberOfFacesConfidence", ctypes.c_float),
162
+ ("numberOfDetectedPersons", ctypes.c_int16),
163
+ ("numberOfPersonsConfidence", ctypes.c_float),
164
+ ("isIdealUserDataAvailable", ctypes.c_bool),
165
+ ("idealUserDetected", ctypes.c_bool),
166
+ ("isIdealUserIndexValid", ctypes.c_bool),
167
+ ("isNumberOfDetectedFacesAvailable", ctypes.c_bool),
168
+ ("isNumberOfFacesConfidenceAvailable", ctypes.c_bool),
169
+ ("isNumberOfDetectedPersonsAvailable", ctypes.c_bool),
170
+ ("isNumberOfPersonsConfidenceAvailable", ctypes.c_bool),
171
+ ("isUsersDataAvilable", ctypes.c_bool),
172
+ ("isFaceIdDataAvailable", ctypes.c_bool),
173
+ ("isObjectDetectionAvailable", ctypes.c_bool),
174
+ ("isCameraStreaming", ctypes.c_bool),
175
+ ("isHandGestureDataAvailable", ctypes.c_bool),
176
+ ("isDefectDetectionAvailable", ctypes.c_bool),
177
+ ]
178
+
179
+ class CFpgaHandData(ctypes.Structure):
180
+ _fields_ = [
181
+ ("validationScore", ctypes.c_float),
182
+ ("handBox", CRect2i),
183
+ ("landmarks", CPoint3f * EVE_FPGA_MAX_HAND_LANDMARKS),
184
+ ]
185
+
186
+ class CFpgaHandsData(ctypes.Structure):
187
+ _fields_ = [
188
+ ("numberOfHandLandmarkPoints", ctypes.c_int16),
189
+ ("handData", CFpgaHandData),
190
+ ("gesture", ctypes.c_int),
191
+ ("isHandBoxAvailable", ctypes.c_bool),
192
+ ("isHandLandmark3D", ctypes.c_bool),
193
+ ]
194
+
195
+ class CFpgaDefectData(ctypes.Structure):
196
+ _fields_ = [
197
+ ("defectBox", CRect2i),
198
+ ("width", ctypes.c_int),
199
+ ("height", ctypes.c_int),
200
+ ("similarity", ctypes.c_float),
201
+ ("isDefective", ctypes.c_bool),
202
+ ]
203
+
204
+ class CFpgaFaceData(ctypes.Structure):
205
+ _fields_ = [
206
+ ("faceConfidence", ctypes.c_float),
207
+ ("faceDistance", ctypes.c_int16),
208
+ ("faceCenter", CPoint3i),
209
+ ("anglesICS", CAngles3f),
210
+ ("anglesCCS", CAngles3f),
211
+ ("faceLandmarksConfidence", ctypes.c_float),
212
+ ("faceBox", CRect2i),
213
+ ("faceIDStatus", ctypes.c_int),
214
+ ("faceID", ctypes.c_int16),
215
+ ("isFaceConfidenceAvailable", ctypes.c_bool),
216
+ ("isFaceDistanceAvailable", ctypes.c_bool),
217
+ ("isFacePositionAvailable", ctypes.c_bool),
218
+ ("isEulerAnglesIcsAvailable", ctypes.c_bool),
219
+ ("isEulerAnglesCcsAvailable", ctypes.c_bool),
220
+ ("isFaceLandmark3D", ctypes.c_bool),
221
+ ("isFaceLandmarksConfidenceAvailable", ctypes.c_bool),
222
+ ("isFaceGeometricBoxAvailable", ctypes.c_bool),
223
+ ("isStatusAvailable", ctypes.c_bool),
224
+ ]
225
+
226
+ class CFpgaPersonData(ctypes.Structure):
227
+ _fields_ = [
228
+ ("personConfidence", ctypes.c_float),
229
+ ("personDistance", ctypes.c_int),
230
+ ("personPosture", ctypes.c_int),
231
+ ("personFrontalPostureConfidence", ctypes.c_float),
232
+ ("personNotFrontalPostureConfidence", ctypes.c_float),
233
+ ("position", CPoint3i),
234
+ ("personBox", CRect2i),
235
+ ("isPersonDataAvailable", ctypes.c_bool),
236
+ ]
237
+
238
+ class CFpgaObjectDetection(ctypes.Structure):
239
+ _fields_ = [
240
+ ("objectClass", ctypes.c_int),
241
+ ("objectConfidence", ctypes.c_float),
242
+ ("objectBox", CRect2i),
243
+ ]
244
+
245
+ class CFpgaObjectData(ctypes.Structure):
246
+ _fields_ = [
247
+ ("numberOfObjects", ctypes.c_int16),
248
+ ("objects", CFpgaObjectDetection * EVE_FPGA_MAX_OBJECT_DETECTION),
249
+ ]
250
+
251
+ class CFpgaUserData(ctypes.Structure):
252
+ _fields_ = [
253
+ ("id", ctypes.c_int16),
254
+ ("status", ctypes.c_int),
255
+ ("scale", ctypes.c_float),
256
+ ("faceData", CFpgaFaceData),
257
+ ("personData", CFpgaPersonData),
258
+ ("isIdealUser", ctypes.c_bool),
259
+ ("isIdValid", ctypes.c_bool),
260
+ ("isStatusAvailable", ctypes.c_bool),
261
+ ("isScaleAvailable", ctypes.c_bool),
262
+ ]
263
+
264
+ class CFpgaFaceIdData(ctypes.Structure):
265
+ _fields_ = [
266
+ ("command", ctypes.c_int16),
267
+ ("userId", ctypes.c_int16),
268
+ ("freeEntry", ctypes.c_int16),
269
+ ("statusCode", ctypes.c_int16),
270
+ ("faceId", ctypes.c_int16),
271
+ ("lastRegisteredFaceID", ctypes.c_int16),
272
+ ("usersInGallery", ctypes.c_int16),
273
+ ("gallerySize", ctypes.c_int16),
274
+ ]
275
+
276
+ class CFpgaPipelineData(ctypes.Structure):
277
+ _fields_ = [
278
+ ("pipelineType", ctypes.c_int),
279
+ ("imageDimensions", CFpgaImageDimensions),
280
+ ("dataContent", CFpgaDataContent),
281
+ ("userData", CFpgaUserData * EVE_FPGA_MAX_USERS),
282
+ ("objectData", CFpgaObjectData),
283
+ ("faceId", CFpgaFaceIdData),
284
+ ("handsData", CFpgaHandsData),
285
+ ("defectData", CFpgaDefectData),
286
+ ]
287
+
288
+ class CFpgaMessage(ctypes.Structure):
289
+ _fields_ = [
290
+ ("responseType", ctypes.c_int),
291
+ ("responseVersion", ctypes.c_uint8),
292
+ ("serialStatus", ctypes.c_int),
293
+ ("serialReadTimeNano", ctypes.c_longlong),
294
+ ]
295
+
296
+ class CFpgaData(ctypes.Structure):
297
+ _fields_ = [
298
+ ("message", CFpgaMessage),
299
+ ("pipelineData", CFpgaPipelineData),
300
+ ]
301
+
302
+ class CFpgaGetSetting(ctypes.Structure):
303
+ _fields_ = [
304
+ ("message", CFpgaMessage),
305
+ ("type", ctypes.c_int),
306
+ ("setting", ctypes.c_int),
307
+ ("value", ctypes.c_uint32),
308
+ ]
309
+
310
+ class CFpgaParameters(ctypes.Structure):
311
+ _fields_ = [
312
+ ("comport", ctypes.c_uint),
313
+ ("socWakeupDelay", ctypes.c_uint),
314
+ ("wakeupType", ctypes.c_int),
315
+ ("forceCameraOn", ctypes.c_ubyte),
316
+ ("registerNewFace", ctypes.c_ubyte),
317
+ ("clearCurrentFace", ctypes.c_ubyte),
318
+ ("enableFaceId", ctypes.c_ubyte),
319
+ ("allPipelinesSupported", ctypes.c_ubyte),
320
+ ("pipelineVersion", ctypes.c_uint),
321
+ ("connection", ctypes.c_int),
322
+ ("i2cAdapterNumber", ctypes.c_uint),
323
+ ("i2cDeviceNumber", ctypes.c_uint),
324
+ ("i2cIRQPin", ctypes.c_uint),
325
+ ]
326
+
327
+ class CFpgaCallbackControl(ctypes.Structure):
328
+ _fields_ = [
329
+ ("request", ctypes.c_int),
330
+ ]
331
+
332
+ class EveFpgaMetadata(ctypes.Structure):
333
+ _fields_ = [
334
+ ("data", ctypes.POINTER(CFpgaData)),
335
+ ("errorCode", ctypes.c_int),
336
+ ]
337
+
338
+ class EveFpgaManualData(ctypes.Structure):
339
+ _fields_ = [
340
+ ("data", ctypes.POINTER(ctypes.c_ubyte)),
341
+ ("size", ctypes.c_int),
342
+ ]
343
+
344
+ class EveFpgaJsonMetadata(ctypes.Structure):
345
+ _fields_ = [
346
+ ("textStart", ctypes.POINTER(ctypes.c_byte)),
347
+ ("textSize", ctypes.c_uint),
348
+ ("errorCode", ctypes.c_int),
349
+ ]
350
+
shared/eve_python/structs/CHandGesture.py CHANGED
@@ -1,144 +1,105 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .CBasicStructs import *
4
- from .EveProcessingStatus import *
5
-
6
- EVE_MAX_HAND_DETECTIONS = 8
7
- EVE_MAX_DYNAMIC_GESTURE_SEQUENCE = 8
8
- EVE_MAX_CUSTOM_STATIC_GESTURES = 20
9
- EVE_MAX_STATIC_GESTURES = 40
10
- EVE_HAND_LANDMARKS_SIZE = 2
11
- EVE_HAND_LANDMARK_SIZE = 11
12
- EVE_STATIC_GESTURE_SIZE = 22
13
- EVE_DYNAMIC_GESTURE_SIZE = 12
14
-
15
- class EveRunHandLandmarks(CtypesEnum):
16
- EVE_HAND_LANDMARKS_ALL_HANDS = 0
17
- EVE_HAND_LANDMARKS_MAIN_HAND_ONLY = 1
18
- EVE_HAND_LANDMARKS_SIZE = 2
19
-
20
- class EveHandLandmark(CtypesEnum):
21
- EVE_WRIST = 0
22
- EVE_THUMB_IP = 1
23
- EVE_THUMB_TIP = 2
24
- EVE_INDEX_MCP = 3
25
- EVE_INDEX_TIP = 4
26
- EVE_MIDDLE_MCP = 5
27
- EVE_MIDDLE_TIP = 6
28
- EVE_RING_MCP = 7
29
- EVE_RING_TIP = 8
30
- EVE_PINKY_MCP = 9
31
- EVE_PINKY_TIP = 10
32
- EVE_HAND_LANDMARK_SIZE = 11
33
-
34
- class EveGestureQuality(CtypesEnum):
35
- EVE_POOR_QUALITY_LOW_CONFIDENCE = 0
36
- EVE_POOR_QUALITY_HAND_OVER_FACE = 1
37
- EVE_GOOD_QUALITY = 2
38
-
39
- class EveStaticGestureType(CtypesEnum):
40
- EVE_STATIC_GESTURE_NONE = 0
41
- EVE_OPEN_HAND = 1
42
- EVE_OPEN_HAND_LEFT = 2
43
- EVE_OPEN_HAND_RIGHT = 3
44
- EVE_CLOSED_HAND = 4
45
- EVE_THUMBS_LEFT = 5
46
- EVE_THUMBS_RIGHT = 6
47
- EVE_RESERVED_STATIC_GESTURE_1 = 7
48
- EVE_RESERVED_STATIC_GESTURE_2 = 8
49
- EVE_RESERVED_STATIC_GESTURE_3 = 9
50
- EVE_RESERVED_STATIC_GESTURE_4 = 10
51
- EVE_RESERVED_STATIC_GESTURE_5 = 11
52
- EVE_CUSTOM_STATIC_GESTURE_1 = 12
53
- EVE_CUSTOM_STATIC_GESTURE_2 = 13
54
- EVE_CUSTOM_STATIC_GESTURE_3 = 14
55
- EVE_CUSTOM_STATIC_GESTURE_4 = 15
56
- EVE_CUSTOM_STATIC_GESTURE_5 = 16
57
- EVE_CUSTOM_STATIC_GESTURE_6 = 17
58
- EVE_CUSTOM_STATIC_GESTURE_7 = 18
59
- EVE_CUSTOM_STATIC_GESTURE_8 = 19
60
- EVE_CUSTOM_STATIC_GESTURE_9 = 20
61
- EVE_CUSTOM_STATIC_GESTURE_10 = 21
62
- EVE_STATIC_GESTURE_SIZE = 22
63
-
64
- class EveDynamicGestureType(CtypesEnum):
65
- EVE_DYNAMIC_GESTURE_NONE = 0
66
- EVE_GRAB = 1
67
- EVE_RESERVED_DYNAMIC_GESTURE_1 = 2
68
- EVE_RESERVED_DYNAMIC_GESTURE_2 = 3
69
- EVE_RESERVED_DYNAMIC_GESTURE_3 = 4
70
- EVE_RESERVED_DYNAMIC_GESTURE_4 = 5
71
- EVE_RESERVED_DYNAMIC_GESTURE_5 = 6
72
- EVE_CUSTOM_DYNAMIC_GESTURE_1 = 7
73
- EVE_CUSTOM_DYNAMIC_GESTURE_2 = 8
74
- EVE_CUSTOM_DYNAMIC_GESTURE_3 = 9
75
- EVE_CUSTOM_DYNAMIC_GESTURE_4 = 10
76
- EVE_CUSTOM_DYNAMIC_GESTURE_5 = 11
77
- EVE_DYNAMIC_GESTURE_SIZE = 12
78
-
79
- class EveStaticGesture(ctypes.Structure):
80
- _fields_ = [
81
- ("handId", ctypes.c_int),
82
- ("isMainUserHand", ctypes.c_int),
83
- ("type", ctypes.c_int),
84
- ("confidence", ctypes.c_float),
85
- ("quality", ctypes.c_int),
86
- ]
87
-
88
- class EveStaticGestures(ctypes.Structure):
89
- _fields_ = [
90
- ("count", ctypes.c_uint),
91
- ("gestures", EveStaticGesture * EVE_MAX_HAND_DETECTIONS),
92
- ]
93
-
94
- class EveStaticGestureDefinition(ctypes.Structure):
95
- _fields_ = [
96
- ("gestureType", ctypes.c_int),
97
- ("id", ctypes.c_uint),
98
- ("landmarksMap", CPoint2f * EVE_HAND_LANDMARK_SIZE),
99
- ]
100
-
101
- class EveDynamicGesture(ctypes.Structure):
102
- _fields_ = [
103
- ("handId", ctypes.c_int),
104
- ("isMainUserHand", ctypes.c_int),
105
- ("type", ctypes.c_int),
106
- ("quality", ctypes.c_int),
107
- ]
108
-
109
- class EveDynamicGestures(ctypes.Structure):
110
- _fields_ = [
111
- ("count", ctypes.c_uint),
112
- ("gestures", EveDynamicGesture * EVE_MAX_HAND_DETECTIONS),
113
- ]
114
-
115
- class EveDynamicGestureDefinition(ctypes.Structure):
116
- _fields_ = [
117
- ("gestureType", ctypes.c_int),
118
- ("sequenceCount", ctypes.c_uint),
119
- ("gestureSequence", ctypes.c_int * EVE_MAX_DYNAMIC_GESTURE_SEQUENCE),
120
- ]
121
-
122
- class EveSingleHandDetection(ctypes.Structure):
123
- _fields_ = [
124
- ("id", ctypes.c_int),
125
- ("isHandValid", ctypes.c_int),
126
- ("boundingBox", CRect2iWH),
127
- ("boundingBoxScore", ctypes.c_float),
128
- ("landmarksICS", CPoint2f * EVE_HAND_LANDMARK_SIZE),
129
- ("validationScore", ctypes.c_float),
130
- ("inPlaneAngle", ctypes.c_float),
131
- ("depth", ctypes.c_float),
132
- ("isMainUserHand", ctypes.c_int),
133
- ("isInCurrentFrame", ctypes.c_int),
134
- ]
135
-
136
- class EveHandDetections(ctypes.Structure):
137
- _fields_ = [
138
- ("status", ctypes.c_int),
139
- ("hasFaceROI", ctypes.c_int),
140
- ("faceROI", CRect2fWH),
141
- ("detectedHandCount", ctypes.c_uint),
142
- ("hands", EveSingleHandDetection * EVE_MAX_HAND_DETECTIONS),
143
- ]
144
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .CBasicStructs import *
4
+ from .EveProcessingStatus import *
5
+
6
+ EVE_MAX_HAND_DETECTIONS = 8
7
+ EVE_MAX_CUSTOM_STATIC_GESTURES = 20
8
+ EVE_MAX_STATIC_GESTURES = 40
9
+ EVE_HAND_LANDMARKS_SIZE = 2
10
+ EVE_HAND_LANDMARK_SIZE = 11
11
+ EVE_STATIC_GESTURE_SIZE = 22
12
+
13
+ class EveRunHandLandmarks(CtypesEnum):
14
+ EVE_HAND_LANDMARKS_ALL_HANDS = 0
15
+ EVE_HAND_LANDMARKS_MAIN_HAND_ONLY = 1
16
+ EVE_HAND_LANDMARKS_SIZE = 2
17
+
18
+ class EveHandLandmark(CtypesEnum):
19
+ EVE_WRIST = 0
20
+ EVE_THUMB_IP = 1
21
+ EVE_THUMB_TIP = 2
22
+ EVE_INDEX_MCP = 3
23
+ EVE_INDEX_TIP = 4
24
+ EVE_MIDDLE_MCP = 5
25
+ EVE_MIDDLE_TIP = 6
26
+ EVE_RING_MCP = 7
27
+ EVE_RING_TIP = 8
28
+ EVE_PINKY_MCP = 9
29
+ EVE_PINKY_TIP = 10
30
+ EVE_HAND_LANDMARK_SIZE = 11
31
+
32
+ class EveGestureQuality(CtypesEnum):
33
+ EVE_POOR_QUALITY_LOW_CONFIDENCE = 0
34
+ EVE_POOR_QUALITY_HAND_OVER_FACE = 1
35
+ EVE_GOOD_QUALITY = 2
36
+
37
+ class EveStaticGestureType(CtypesEnum):
38
+ EVE_STATIC_GESTURE_NONE = 0
39
+ EVE_OPEN_HAND = 1
40
+ EVE_OPEN_HAND_LEFT = 2
41
+ EVE_OPEN_HAND_RIGHT = 3
42
+ EVE_CLOSED_HAND = 4
43
+ EVE_THUMBS_LEFT = 5
44
+ EVE_THUMBS_RIGHT = 6
45
+ EVE_RESERVED_STATIC_GESTURE_1 = 7
46
+ EVE_RESERVED_STATIC_GESTURE_2 = 8
47
+ EVE_RESERVED_STATIC_GESTURE_3 = 9
48
+ EVE_RESERVED_STATIC_GESTURE_4 = 10
49
+ EVE_RESERVED_STATIC_GESTURE_5 = 11
50
+ EVE_CUSTOM_STATIC_GESTURE_1 = 12
51
+ EVE_CUSTOM_STATIC_GESTURE_2 = 13
52
+ EVE_CUSTOM_STATIC_GESTURE_3 = 14
53
+ EVE_CUSTOM_STATIC_GESTURE_4 = 15
54
+ EVE_CUSTOM_STATIC_GESTURE_5 = 16
55
+ EVE_CUSTOM_STATIC_GESTURE_6 = 17
56
+ EVE_CUSTOM_STATIC_GESTURE_7 = 18
57
+ EVE_CUSTOM_STATIC_GESTURE_8 = 19
58
+ EVE_CUSTOM_STATIC_GESTURE_9 = 20
59
+ EVE_CUSTOM_STATIC_GESTURE_10 = 21
60
+ EVE_STATIC_GESTURE_SIZE = 22
61
+
62
+ class EveStaticGesture(ctypes.Structure):
63
+ _fields_ = [
64
+ ("handId", ctypes.c_int),
65
+ ("isMainUserHand", ctypes.c_int),
66
+ ("type", ctypes.c_int),
67
+ ("confidence", ctypes.c_float),
68
+ ("quality", ctypes.c_int),
69
+ ]
70
+
71
+ class EveStaticGestures(ctypes.Structure):
72
+ _fields_ = [
73
+ ("count", ctypes.c_uint),
74
+ ("gestures", EveStaticGesture * EVE_MAX_HAND_DETECTIONS),
75
+ ]
76
+
77
+ class EveStaticGestureDefinition(ctypes.Structure):
78
+ _fields_ = [
79
+ ("gestureType", ctypes.c_int),
80
+ ("id", ctypes.c_uint),
81
+ ("landmarksMap", CPoint2f * EVE_HAND_LANDMARK_SIZE),
82
+ ]
83
+
84
+ class EveSingleHandDetection(ctypes.Structure):
85
+ _fields_ = [
86
+ ("id", ctypes.c_int),
87
+ ("isHandValid", ctypes.c_int),
88
+ ("boundingBox", CRect2iWH),
89
+ ("boundingBoxScore", ctypes.c_float),
90
+ ("landmarksICS", CPoint2f * EVE_HAND_LANDMARK_SIZE),
91
+ ("validationScore", ctypes.c_float),
92
+ ("inPlaneAngle", ctypes.c_float),
93
+ ("depth", ctypes.c_float),
94
+ ("isMainUserHand", ctypes.c_int),
95
+ ]
96
+
97
+ class EveHandDetections(ctypes.Structure):
98
+ _fields_ = [
99
+ ("status", ctypes.c_int),
100
+ ("hasFaceROI", ctypes.c_int),
101
+ ("faceROI", CRect2fWH),
102
+ ("detectedHandCount", ctypes.c_uint),
103
+ ("hands", EveSingleHandDetection * EVE_MAX_HAND_DETECTIONS),
104
+ ]
105
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
shared/eve_python/structs/CImageManipulation.py CHANGED
@@ -1,12 +1,12 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
-
4
-
5
- class CImageManipulationSettings(ctypes.Structure):
6
- _fields_ = [
7
- ("mirrorImage", ctypes.c_uint),
8
- ("reserved1", ctypes.c_uint),
9
- ("reserved2", ctypes.c_uint),
10
- ("reserved3", ctypes.c_uint),
11
- ]
12
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+
4
+
5
+ class CImageManipulationSettings(ctypes.Structure):
6
+ _fields_ = [
7
+ ("mirrorImage", ctypes.c_uint),
8
+ ("reserved1", ctypes.c_uint),
9
+ ("reserved2", ctypes.c_uint),
10
+ ("reserved3", ctypes.c_uint),
11
+ ]
12
+
shared/eve_python/structs/CKarolinska.py CHANGED
@@ -1,57 +1,57 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
-
4
-
5
- class EveKarolinskaSleepiness(CtypesEnum):
6
- EVE_KAROLINSKA_DISABLED = 0
7
- EVE_KAROLINSKA_1 = 1
8
- EVE_KAROLINSKA_2 = 2
9
- EVE_KAROLINSKA_3 = 3
10
- EVE_KAROLINSKA_4 = 4
11
- EVE_KAROLINSKA_5 = 5
12
- EVE_KAROLINSKA_6 = 6
13
- EVE_KAROLINSKA_7 = 7
14
- EVE_KAROLINSKA_8 = 8
15
- EVE_KAROLINSKA_9 = 9
16
- EVE_KAROLINSKA_MAX = 10
17
-
18
- class EveEyeClosureState(CtypesEnum):
19
- EVE_EYE_STATE_UNKNOWN = 0
20
- EVE_EYE_OPEN = 1
21
- EVE_EYE_CLOSED = 2
22
-
23
- class EveKarolinskaStatus(CtypesEnum):
24
- EVE_KAROLINSKA_OFF = 0
25
- EVE_KAROLINSKA_NO_FACE = 1
26
- EVE_KAROLINSKA_BLINKS_ONLY = 2
27
- EVE_KAROLINSKA_ON = 3
28
-
29
- class CEyeState(ctypes.Structure):
30
- _fields_ = [
31
- ("state", ctypes.c_int),
32
- ("closure", ctypes.c_float),
33
- ("confidence", ctypes.c_float),
34
- ("eyelidDistanceMM", ctypes.c_float),
35
- ]
36
-
37
- class CEyeStates(ctypes.Structure):
38
- _fields_ = [
39
- ("left", CEyeState),
40
- ("right", CEyeState),
41
- ("fused", CEyeState),
42
- ("blinkCount", ctypes.c_uint),
43
- ]
44
-
45
- class CKarolinskaData(ctypes.Structure):
46
- _fields_ = [
47
- ("status", ctypes.c_int),
48
- ("scale", ctypes.c_int),
49
- ("headPitchScale", ctypes.c_int),
50
- ("yawnScale", ctypes.c_int),
51
- ("blinkDurationScale", ctypes.c_int),
52
- ("yawn", ctypes.c_float),
53
- ("yawnConfidence", ctypes.c_float),
54
- ("yawnCount", ctypes.c_uint),
55
- ("eyes", CEyeStates),
56
- ]
57
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+
4
+
5
+ class EveKarolinskaSleepiness(CtypesEnum):
6
+ EVE_KAROLINSKA_DISABLED = 0
7
+ EVE_KAROLINSKA_1 = 1
8
+ EVE_KAROLINSKA_2 = 2
9
+ EVE_KAROLINSKA_3 = 3
10
+ EVE_KAROLINSKA_4 = 4
11
+ EVE_KAROLINSKA_5 = 5
12
+ EVE_KAROLINSKA_6 = 6
13
+ EVE_KAROLINSKA_7 = 7
14
+ EVE_KAROLINSKA_8 = 8
15
+ EVE_KAROLINSKA_9 = 9
16
+ EVE_KAROLINSKA_MAX = 10
17
+
18
+ class EveEyeClosureState(CtypesEnum):
19
+ EVE_EYE_STATE_UNKNOWN = 0
20
+ EVE_EYE_OPEN = 1
21
+ EVE_EYE_CLOSED = 2
22
+
23
+ class EveKarolinskaStatus(CtypesEnum):
24
+ EVE_KAROLINSKA_OFF = 0
25
+ EVE_KAROLINSKA_NO_FACE = 1
26
+ EVE_KAROLINSKA_BLINKS_ONLY = 2
27
+ EVE_KAROLINSKA_ON = 3
28
+
29
+ class CEyeState(ctypes.Structure):
30
+ _fields_ = [
31
+ ("state", ctypes.c_int),
32
+ ("closure", ctypes.c_float),
33
+ ("confidence", ctypes.c_float),
34
+ ("eyelidDistanceMM", ctypes.c_float),
35
+ ]
36
+
37
+ class CEyeStates(ctypes.Structure):
38
+ _fields_ = [
39
+ ("left", CEyeState),
40
+ ("right", CEyeState),
41
+ ("fused", CEyeState),
42
+ ("blinkCount", ctypes.c_uint),
43
+ ]
44
+
45
+ class CKarolinskaData(ctypes.Structure):
46
+ _fields_ = [
47
+ ("status", ctypes.c_int),
48
+ ("scale", ctypes.c_int),
49
+ ("headPitchScale", ctypes.c_int),
50
+ ("yawnScale", ctypes.c_int),
51
+ ("blinkDurationScale", ctypes.c_int),
52
+ ("yawn", ctypes.c_float),
53
+ ("yawnConfidence", ctypes.c_float),
54
+ ("yawnCount", ctypes.c_uint),
55
+ ("eyes", CEyeStates),
56
+ ]
57
+
shared/eve_python/structs/CLandmarkMaps.py CHANGED
@@ -1,40 +1,40 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
-
4
- EVE_HMI_P_L_SIZE = 23
5
- EVE_HMI_S_L_SIZE = 5
6
-
7
- class EveHmiPrimaryLandmarks(CtypesEnum):
8
- EVE_HMI_P_L_RIGHT_TEMPLE = 0
9
- EVE_HMI_P_L_RIGHT_JAW = 1
10
- EVE_HMI_P_L_CENTER_JAW = 2
11
- EVE_HMI_P_L_LEFT_JAW = 3
12
- EVE_HMI_P_L_LEFT_TEMPLE = 4
13
- EVE_HMI_P_L_RIGHT_EYEBROW = 5
14
- EVE_HMI_P_L_LEFT_EYEBROW = 6
15
- EVE_HMI_P_L_NOSE_BRIDGE = 7
16
- EVE_HMI_P_L_NOSE_TIP_HIGH = 8
17
- EVE_HMI_P_L_NOSE_TIP = 9
18
- EVE_HMI_P_L_NOSE_TIP_LOW = 10
19
- EVE_HMI_P_L_RIGHT_EYE_1 = 11
20
- EVE_HMI_P_L_RIGHT_EYE_2 = 12
21
- EVE_HMI_P_L_LEFT_EYE_1 = 13
22
- EVE_HMI_P_L_LEFT_EYE_2 = 14
23
- EVE_HMI_P_L_MOUTH_RIGHT_CORNER = 15
24
- EVE_HMI_P_L_MOUTH_UPPER_LIP = 16
25
- EVE_HMI_P_L_MOUTH_LEFT_CORNER = 17
26
- EVE_HMI_P_L_MOUTH_LOWER_LIP = 18
27
- EVE_HMI_P_L_MOUTH_OPEN_TOP = 19
28
- EVE_HMI_P_L_MOUTH_OPEN_BOTTOM = 20
29
- EVE_HMI_P_L_RIGHT_PUPIL = 21
30
- EVE_HMI_P_L_LEFT_PUPIL = 22
31
- EVE_HMI_P_L_SIZE = 23
32
-
33
- class EveHmiSecondaryLandmarks(CtypesEnum):
34
- EVE_HMI_S_L_RIGHT_PUPIL = 0
35
- EVE_HMI_S_L_LEFT_PUPIL = 1
36
- EVE_HMI_S_L_NOSE_TIP_LOW = 2
37
- EVE_HMI_S_L_RIGHT_MOUTH_CORNER = 3
38
- EVE_HMI_S_L_LEFT_MOUTH_CORNER = 4
39
- EVE_HMI_S_L_SIZE = 5
40
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+
4
+ EVE_HMI_P_L_SIZE = 23
5
+ EVE_HMI_S_L_SIZE = 5
6
+
7
+ class EveHmiPrimaryLandmarks(CtypesEnum):
8
+ EVE_HMI_P_L_RIGHT_TEMPLE = 0
9
+ EVE_HMI_P_L_RIGHT_JAW = 1
10
+ EVE_HMI_P_L_CENTER_JAW = 2
11
+ EVE_HMI_P_L_LEFT_JAW = 3
12
+ EVE_HMI_P_L_LEFT_TEMPLE = 4
13
+ EVE_HMI_P_L_RIGHT_EYEBROW = 5
14
+ EVE_HMI_P_L_LEFT_EYEBROW = 6
15
+ EVE_HMI_P_L_NOSE_BRIDGE = 7
16
+ EVE_HMI_P_L_NOSE_TIP_HIGH = 8
17
+ EVE_HMI_P_L_NOSE_TIP = 9
18
+ EVE_HMI_P_L_NOSE_TIP_LOW = 10
19
+ EVE_HMI_P_L_RIGHT_EYE_1 = 11
20
+ EVE_HMI_P_L_RIGHT_EYE_2 = 12
21
+ EVE_HMI_P_L_LEFT_EYE_1 = 13
22
+ EVE_HMI_P_L_LEFT_EYE_2 = 14
23
+ EVE_HMI_P_L_MOUTH_RIGHT_CORNER = 15
24
+ EVE_HMI_P_L_MOUTH_UPPER_LIP = 16
25
+ EVE_HMI_P_L_MOUTH_LEFT_CORNER = 17
26
+ EVE_HMI_P_L_MOUTH_LOWER_LIP = 18
27
+ EVE_HMI_P_L_MOUTH_OPEN_TOP = 19
28
+ EVE_HMI_P_L_MOUTH_OPEN_BOTTOM = 20
29
+ EVE_HMI_P_L_RIGHT_PUPIL = 21
30
+ EVE_HMI_P_L_LEFT_PUPIL = 22
31
+ EVE_HMI_P_L_SIZE = 23
32
+
33
+ class EveHmiSecondaryLandmarks(CtypesEnum):
34
+ EVE_HMI_S_L_RIGHT_PUPIL = 0
35
+ EVE_HMI_S_L_LEFT_PUPIL = 1
36
+ EVE_HMI_S_L_NOSE_TIP_LOW = 2
37
+ EVE_HMI_S_L_RIGHT_MOUTH_CORNER = 3
38
+ EVE_HMI_S_L_LEFT_MOUTH_CORNER = 4
39
+ EVE_HMI_S_L_SIZE = 5
40
+
shared/eve_python/structs/CLicenseResult.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+
4
+
5
+ class EveLicenseResult(ctypes.Structure):
6
+ _fields_ = [
7
+ ("licenseReturnCode", ctypes.c_uint),
8
+ ("licenseWarnings", ctypes.c_byte * 256),
9
+ ]
10
+
shared/eve_python/structs/CROIStructs.py CHANGED
@@ -1,29 +1,29 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .EveProcessingStatus import *
4
-
5
- EVE_ROI_MAX_SCORE_COUNT = 20
6
-
7
- class EveROIState(CtypesEnum):
8
- EVE_ROI_STATE_INACTIVE = 0
9
- EVE_ROI_STATE_ENTERING = 1
10
- EVE_ROI_STATE_LEAVING = 2
11
- EVE_ROI_STATE_SELECTED = 3
12
-
13
- class CROIScore(ctypes.Structure):
14
- _fields_ = [
15
- ("id", ctypes.c_uint),
16
- ("intersectionScore", ctypes.c_double),
17
- ("filteredScore", ctypes.c_double),
18
- ("state", ctypes.c_int),
19
- ]
20
-
21
- class CROIScoreData(ctypes.Structure):
22
- _fields_ = [
23
- ("processingStatus", ctypes.c_int),
24
- ("fusedRoiScoresCount", ctypes.c_uint),
25
- ("fusedRoiScores", CROIScore * EVE_ROI_MAX_SCORE_COUNT),
26
- ("faceRoiScoresCount", ctypes.c_uint),
27
- ("faceRoiScores", CROIScore * EVE_ROI_MAX_SCORE_COUNT),
28
- ]
29
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .EveProcessingStatus import *
4
+
5
+ EVE_ROI_MAX_SCORE_COUNT = 20
6
+
7
+ class EveROIState(CtypesEnum):
8
+ EVE_ROI_STATE_INACTIVE = 0
9
+ EVE_ROI_STATE_ENTERING = 1
10
+ EVE_ROI_STATE_LEAVING = 2
11
+ EVE_ROI_STATE_SELECTED = 3
12
+
13
+ class CROIScore(ctypes.Structure):
14
+ _fields_ = [
15
+ ("id", ctypes.c_uint),
16
+ ("intersectionScore", ctypes.c_double),
17
+ ("filteredScore", ctypes.c_double),
18
+ ("state", ctypes.c_int),
19
+ ]
20
+
21
+ class CROIScoreData(ctypes.Structure):
22
+ _fields_ = [
23
+ ("processingStatus", ctypes.c_int),
24
+ ("fusedRoiScoresCount", ctypes.c_uint),
25
+ ("fusedRoiScores", CROIScore * EVE_ROI_MAX_SCORE_COUNT),
26
+ ("faceRoiScoresCount", ctypes.c_uint),
27
+ ("faceRoiScores", CROIScore * EVE_ROI_MAX_SCORE_COUNT),
28
+ ]
29
+
shared/eve_python/structs/CVisualSpeechStructs.py CHANGED
@@ -1,18 +1,18 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .EveProcessingStatus import *
4
-
5
-
6
- class EveVisualSpeechState(CtypesEnum):
7
- EVE_NOT_SET = 0
8
- EVE_NOT_SPEAKING = 1
9
- EVE_SPEAKING = 2
10
-
11
- class CVisualSpeechData(ctypes.Structure):
12
- _fields_ = [
13
- ("processingStatus", ctypes.c_int),
14
- ("speechState", ctypes.c_int),
15
- ("notSpeakingProbability", ctypes.c_double),
16
- ("speakingProbability", ctypes.c_double),
17
- ]
18
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .EveProcessingStatus import *
4
+
5
+
6
+ class EveVisualSpeechState(CtypesEnum):
7
+ EVE_NOT_SET = 0
8
+ EVE_NOT_SPEAKING = 1
9
+ EVE_SPEAKING = 2
10
+
11
+ class CVisualSpeechData(ctypes.Structure):
12
+ _fields_ = [
13
+ ("processingStatus", ctypes.c_int),
14
+ ("speechState", ctypes.c_int),
15
+ ("notSpeakingProbability", ctypes.c_double),
16
+ ("speakingProbability", ctypes.c_double),
17
+ ]
18
+
shared/eve_python/structs/EveAlgorithm.py CHANGED
@@ -1,5 +1,5 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .EveAlgorithmStructs import *
4
-
5
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .EveAlgorithmStructs import *
4
+
5
+
shared/eve_python/structs/EveAlgorithmStructs.py CHANGED
@@ -1,14 +1,14 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .CAlgorithms import *
4
- from .EveErrors import *
5
-
6
- EVE_ALGORITHMS_SIZE = 20
7
-
8
- class EveSupportedAlgorithms(ctypes.Structure):
9
- _fields_ = [
10
- ("errorCode", ctypes.c_int),
11
- ("count", ctypes.c_uint),
12
- ("algorithms", ctypes.c_int * EVE_ALGORITHMS_SIZE),
13
- ]
14
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .CAlgorithms import *
4
+ from .EveErrors import *
5
+
6
+ EVE_ALGORITHMS_SIZE = 20
7
+
8
+ class EveSupportedAlgorithms(ctypes.Structure):
9
+ _fields_ = [
10
+ ("errorCode", ctypes.c_int),
11
+ ("count", ctypes.c_uint),
12
+ ("algorithms", ctypes.c_int * EVE_ALGORITHMS_SIZE),
13
+ ]
14
+
shared/eve_python/structs/EveCallbackReturnData.py CHANGED
@@ -1,13 +1,13 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
-
4
-
5
- class EveRequestedProcessingState(CtypesEnum):
6
- EVE_REQUESTED_PROCESSING_STATE_CONTINUE = 0
7
- EVE_REQUESTED_PROCESSING_STATE_STOP = 1
8
-
9
- class EveProcessingCallbackReturnData(ctypes.Structure):
10
- _fields_ = [
11
- ("requestedState", ctypes.c_int),
12
- ]
13
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+
4
+
5
+ class EveRequestedProcessingState(CtypesEnum):
6
+ EVE_REQUESTED_PROCESSING_STATE_CONTINUE = 0
7
+ EVE_REQUESTED_PROCESSING_STATE_STOP = 1
8
+
9
+ class EveProcessingCallbackReturnData(ctypes.Structure):
10
+ _fields_ = [
11
+ ("requestedState", ctypes.c_int),
12
+ ]
13
+
shared/eve_python/structs/EveCamera.py CHANGED
@@ -1,5 +1,5 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .EveCameraStructs import *
4
-
5
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .EveCameraStructs import *
4
+
5
+
shared/eve_python/structs/EveCameraStructs.py CHANGED
@@ -1,27 +1,47 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .CCameraStructs import *
4
- from .EveErrors import *
5
-
6
- EVE_CAMERA_FORMATS_SIZE = 20
7
-
8
- class EveCameraFormats(ctypes.Structure):
9
- _fields_ = [
10
- ("formats", CCameraFormat * EVE_CAMERA_FORMATS_SIZE),
11
- ("formatsCount", ctypes.c_uint),
12
- ("hadMoreFormats", ctypes.c_uint),
13
- ("error", ctypes.c_int),
14
- ]
15
-
16
- class EveCamera(ctypes.Structure):
17
- _fields_ = [
18
- ("data", CCamera),
19
- ("error", ctypes.c_int),
20
- ]
21
-
22
- class EveNumberOfCameras(ctypes.Structure):
23
- _fields_ = [
24
- ("count", ctypes.c_uint),
25
- ("error", ctypes.c_int),
26
- ]
27
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .CCameraStructs import *
4
+ from .EveErrors import *
5
+
6
+ EVE_CAMERA_FORMATS_SIZE = 20
7
+ EVE_MONITOR_SIZE = 4
8
+
9
+ class EveCameraFormats(ctypes.Structure):
10
+ _fields_ = [
11
+ ("formats", CCameraFormat * EVE_CAMERA_FORMATS_SIZE),
12
+ ("formatsCount", ctypes.c_uint),
13
+ ("hadMoreFormats", ctypes.c_uint),
14
+ ("error", ctypes.c_int),
15
+ ]
16
+
17
+ class EveCamera(ctypes.Structure):
18
+ _fields_ = [
19
+ ("data", CCamera),
20
+ ("error", ctypes.c_int),
21
+ ]
22
+
23
+ class EveNumberOfCameras(ctypes.Structure):
24
+ _fields_ = [
25
+ ("count", ctypes.c_uint),
26
+ ("error", ctypes.c_int),
27
+ ]
28
+
29
+ class EveMonitors(ctypes.Structure):
30
+ _fields_ = [
31
+ ("monitorCount", ctypes.c_uint),
32
+ ("error", ctypes.c_int),
33
+ ("monitors", CMonitor * EVE_MONITOR_SIZE),
34
+ ]
35
+
36
+ class EveCameraLocation(ctypes.Structure):
37
+ _fields_ = [
38
+ ("location", CCameraLocation),
39
+ ("error", ctypes.c_int),
40
+ ]
41
+
42
+ class EveCameraParameters(ctypes.Structure):
43
+ _fields_ = [
44
+ ("parameters", CCameraParameters),
45
+ ("error", ctypes.c_int),
46
+ ]
47
+
shared/eve_python/structs/EveConfigurationParameters.py CHANGED
@@ -1,36 +1,45 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
-
4
- EVE_PIPELINE_TYPE_SIZE = 2
5
-
6
- class EveImageProvider(CtypesEnum):
7
- EVE_CAMERA = 0
8
- EVE_CLIENT_PROVIDED = 1
9
-
10
- class EveGpuPreference(CtypesEnum):
11
- EVE_GPU_LOW_POWER = 0
12
- EVE_GPU_HIGH_PERFORMANCE = 1
13
- EVE_NO_GPU = 2
14
-
15
- class EveStartupType(CtypesEnum):
16
- EVE_SYNC = 0
17
- EVE_ASYNC = 1
18
-
19
- class EveProcessingPipelineType(CtypesEnum):
20
- EVE_FULL = 0
21
- EVE_HMI = 1
22
- EVE_PIPELINE_TYPE_SIZE = 2
23
-
24
- class EveStartupParameters(ctypes.Structure):
25
- _fields_ = [
26
- ("gpuPreference", ctypes.c_int),
27
- ("imageProvider", ctypes.c_int),
28
- ("startupType", ctypes.c_int),
29
- ("pathOverride", ctypes.c_byte * 512),
30
- ]
31
-
32
- class EveProcessingParameters(ctypes.Structure):
33
- _fields_ = [
34
- ("type", ctypes.c_int),
35
- ]
36
-
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+
4
+ EVE_PIPELINE_TYPE_SIZE = 2
5
+ EVE_CAMERA_TYPE_SIZE = 3
6
+
7
+ class EveImageProvider(CtypesEnum):
8
+ EVE_CAMERA = 0
9
+ EVE_CLIENT_PROVIDED = 1
10
+
11
+ class EveGpuPreference(CtypesEnum):
12
+ EVE_GPU_LOW_POWER = 0
13
+ EVE_GPU_HIGH_PERFORMANCE = 1
14
+ EVE_NO_GPU = 2
15
+
16
+ class EveStartupType(CtypesEnum):
17
+ EVE_SYNC = 0
18
+ EVE_ASYNC = 1
19
+
20
+ class EveProcessingPipelineType(CtypesEnum):
21
+ EVE_FULL = 0
22
+ EVE_HMI = 1
23
+ EVE_PIPELINE_TYPE_SIZE = 2
24
+
25
+ class EveCameraType(CtypesEnum):
26
+ EVE_CAMERA_AUTO = 0
27
+ EVE_CAMERA_RGB = 1
28
+ EVE_CAMERA_IR = 2
29
+ EVE_CAMERA_TYPE_SIZE = 3
30
+
31
+ class EveStartupParameters(ctypes.Structure):
32
+ _fields_ = [
33
+ ("gpuPreference", ctypes.c_int),
34
+ ("imageProvider", ctypes.c_int),
35
+ ("startupType", ctypes.c_int),
36
+ ("pathOverride", ctypes.c_byte * 512),
37
+ ]
38
+
39
+ class EveProcessingParameters(ctypes.Structure):
40
+ _fields_ = [
41
+ ("type", ctypes.c_int),
42
+ ("cameraType", ctypes.c_int),
43
+ ("imageProvider", ctypes.c_int),
44
+ ]
45
+
shared/eve_python/structs/EveControlInterface.py CHANGED
@@ -1,9 +1,10 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .CCameraStructs import *
4
- from .EveCallbackReturnData import *
5
- from .EveConfigurationParameters import *
6
- from .EveErrors import *
7
- from .EveImageStructs import *
8
-
9
-
 
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .CCameraStructs import *
4
+ from .CLicenseResult import *
5
+ from .EveCallbackReturnData import *
6
+ from .EveConfigurationParameters import *
7
+ from .EveErrors import *
8
+ from .EveImageStructs import *
9
+
10
+
shared/eve_python/structs/EveControlOption.py CHANGED
@@ -1,8 +1,8 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
-
4
-
5
- class EveOptionEnabled(CtypesEnum):
6
- EVE_OPTION_DISABLED = 0
7
- EVE_OPTION_ENABLED = 1
8
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+
4
+
5
+ class EveOptionEnabled(CtypesEnum):
6
+ EVE_OPTION_DISABLED = 0
7
+ EVE_OPTION_ENABLED = 1
8
+
shared/eve_python/structs/EveErrors.py CHANGED
@@ -1,22 +1,26 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
-
4
-
5
- class EveError(CtypesEnum):
6
- EVE_ERROR_NO_ERROR = 0
7
- EVE_ERROR_NOT_CREATED = 1
8
- EVE_ERROR_NOT_STARTED = 2
9
- EVE_ERROR_PIPELINE_NOT_FOUND = 3
10
- EVE_ERROR_CAMERA_MANAGER_NOT_FOUND = 4
11
- EVE_ERROR_NO_CALLBACK = 5
12
- EVE_ERROR_NOT_ACCESSED_FROM_CALLBACK = 6
13
- EVE_INVALID_IMAGE_ENCODING = 7
14
- EVE_CALLBACK_WITHOUT_CONNECTING_TO_CAMERA = 8
15
- EVE_CAMERA_INTERACTION_WITHOUT_CAMERA = 9
16
- EVE_NO_MORE_DATA = 10
17
- EVE_INVALID_CAMERA_ID = 11
18
- EVE_FACE_ID_INVALID_THRESHOLD = 12
19
- EVE_ERROR_NO_CAMERA_INTERACTION_WITH_CAMERA = 13
20
- EVE_ERROR_NOT_IMPLEMENTED = 14
21
- EVE_ERROR_UNSUPPORTED_FORMAT = 15
22
-
 
 
 
 
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+
4
+
5
+ class EveError(CtypesEnum):
6
+ EVE_ERROR_NO_ERROR = 0
7
+ EVE_ERROR_NOT_CREATED = 1
8
+ EVE_ERROR_NOT_STARTED = 2
9
+ EVE_ERROR_PIPELINE_NOT_FOUND = 3
10
+ EVE_ERROR_CAMERA_MANAGER_NOT_FOUND = 4
11
+ EVE_ERROR_NO_CALLBACK = 5
12
+ EVE_ERROR_NOT_ACCESSED_FROM_CALLBACK = 6
13
+ EVE_INVALID_IMAGE_ENCODING = 7
14
+ EVE_CALLBACK_WITHOUT_CONNECTING_TO_CAMERA = 8
15
+ EVE_CAMERA_INTERACTION_WITHOUT_CAMERA = 9
16
+ EVE_NO_MORE_DATA = 10
17
+ EVE_INVALID_CAMERA_ID = 11
18
+ EVE_FACE_ID_INVALID_THRESHOLD = 12
19
+ EVE_ERROR_NO_CAMERA_INTERACTION_WITH_CAMERA = 13
20
+ EVE_ERROR_NOT_IMPLEMENTED = 14
21
+ EVE_ERROR_UNSUPPORTED_FORMAT = 15
22
+ EVE_ERROR_NO_MONITORS = 16
23
+ EVE_OBJECT_DETECTION_INVALID_THRESHOLD = 17
24
+ EVE_OBJECT_DETECTION_INVALID_MODEL_PATH = 18
25
+ EVE_OBJECT_DETECTION_INVALID_CLASS_COUNT = 19
26
+
shared/eve_python/structs/EveFaceId.py CHANGED
@@ -1,5 +1,5 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .EveFaceIdStructs import *
4
-
5
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .EveFaceIdStructs import *
4
+
5
+
shared/eve_python/structs/EveFaceIdStructs.py CHANGED
@@ -1,31 +1,31 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .CFaceIdStructs import *
4
- from .EveControlOption import *
5
- from .EveErrors import *
6
-
7
-
8
- class EveFaceIdCalibrationPoseMode(CtypesEnum):
9
- EVE_FACEID_CALIBRATION_FRONTAL_ONLY = 1
10
-
11
- class EveFaceIdCommandStruct(ctypes.Structure):
12
- _fields_ = [
13
- ("command", ctypes.c_int),
14
- ("errorCode", ctypes.c_int),
15
- ]
16
-
17
- class EveFaceIdOptions(ctypes.Structure):
18
- _fields_ = [
19
- ("enabled", ctypes.c_int),
20
- ("calibrationPoses", ctypes.c_int),
21
- ("galleryPath", ctypes.c_byte * 256),
22
- ("threshold", ctypes.c_float),
23
- ("error", ctypes.c_int),
24
- ]
25
-
26
- class EveFaceIdData(ctypes.Structure):
27
- _fields_ = [
28
- ("data", CFaceIdentityData),
29
- ("error", ctypes.c_int),
30
- ]
31
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .CFaceIdStructs import *
4
+ from .EveControlOption import *
5
+ from .EveErrors import *
6
+
7
+
8
+ class EveFaceIdCalibrationPoseMode(CtypesEnum):
9
+ EVE_FACEID_CALIBRATION_FRONTAL_ONLY = 1
10
+
11
+ class EveFaceIdCommandStruct(ctypes.Structure):
12
+ _fields_ = [
13
+ ("command", ctypes.c_int),
14
+ ("errorCode", ctypes.c_int),
15
+ ]
16
+
17
+ class EveFaceIdOptions(ctypes.Structure):
18
+ _fields_ = [
19
+ ("enabled", ctypes.c_int),
20
+ ("calibrationPoses", ctypes.c_int),
21
+ ("galleryPath", ctypes.c_byte * 256),
22
+ ("threshold", ctypes.c_float),
23
+ ("error", ctypes.c_int),
24
+ ]
25
+
26
+ class EveFaceIdData(ctypes.Structure):
27
+ _fields_ = [
28
+ ("data", CFaceIdentityData),
29
+ ("error", ctypes.c_int),
30
+ ]
31
+
shared/eve_python/structs/EveFaceTracker.py CHANGED
@@ -1,5 +1,5 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .EveFaceTrackerStructs import *
4
-
5
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .EveFaceTrackerStructs import *
4
+
5
+
shared/eve_python/structs/EveFaceTrackerStructs.py CHANGED
@@ -1,40 +1,40 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .CFaceData import *
4
- from .EveErrors import *
5
-
6
-
7
- class EveFaceTrackerMinimumMode(CtypesEnum):
8
- EVE_FACETRACKER_MINIMUM_MODE_OFF = 0
9
- EVE_FACETRACKER_MINIMUM_MODE_MINIMAL = 1
10
- EVE_FACETRACKER_MINIMUM_MODE_AVERAGE = 2
11
- EVE_FACETRACKER_MINIMUM_MODE_MAXIMAL = 3
12
-
13
- class EveFaceTrackerOptions(ctypes.Structure):
14
- _fields_ = [
15
- ("faceTrackerMode", ctypes.c_int),
16
- ("enableEyeLandmarks", ctypes.c_uint),
17
- ("enable3DFaceTracking", ctypes.c_uint),
18
- ("enablePersonDetection", ctypes.c_uint),
19
- ("fitSecondaryUsers", ctypes.c_uint),
20
- ("error", ctypes.c_int),
21
- ]
22
-
23
- class EveEyes(ctypes.Structure):
24
- _fields_ = [
25
- ("data", CEyeLandmarks),
26
- ("errorCode", ctypes.c_int),
27
- ]
28
-
29
- class EvePupils(ctypes.Structure):
30
- _fields_ = [
31
- ("data", CPupilLandmarks),
32
- ("errorCode", ctypes.c_int),
33
- ]
34
-
35
- class EveAllFacesData(ctypes.Structure):
36
- _fields_ = [
37
- ("faceData", ctypes.POINTER(CAllFaces)),
38
- ("errorCode", ctypes.c_int),
39
- ]
40
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .CFaceData import *
4
+ from .EveErrors import *
5
+
6
+
7
+ class EveFaceTrackerMinimumMode(CtypesEnum):
8
+ EVE_FACETRACKER_MINIMUM_MODE_OFF = 0
9
+ EVE_FACETRACKER_MINIMUM_MODE_MINIMAL = 1
10
+ EVE_FACETRACKER_MINIMUM_MODE_AVERAGE = 2
11
+ EVE_FACETRACKER_MINIMUM_MODE_MAXIMAL = 3
12
+
13
+ class EveFaceTrackerOptions(ctypes.Structure):
14
+ _fields_ = [
15
+ ("faceTrackerMode", ctypes.c_int),
16
+ ("enableEyeLandmarks", ctypes.c_uint),
17
+ ("enable3DFaceTracking", ctypes.c_uint),
18
+ ("enablePersonDetection", ctypes.c_uint),
19
+ ("fitSecondaryUsers", ctypes.c_uint),
20
+ ("error", ctypes.c_int),
21
+ ]
22
+
23
+ class EveEyes(ctypes.Structure):
24
+ _fields_ = [
25
+ ("data", CEyeLandmarks),
26
+ ("errorCode", ctypes.c_int),
27
+ ]
28
+
29
+ class EvePupils(ctypes.Structure):
30
+ _fields_ = [
31
+ ("data", CPupilLandmarks),
32
+ ("errorCode", ctypes.c_int),
33
+ ]
34
+
35
+ class EveAllFacesData(ctypes.Structure):
36
+ _fields_ = [
37
+ ("faceData", ctypes.POINTER(CAllFaces)),
38
+ ("errorCode", ctypes.c_int),
39
+ ]
40
+
shared/eve_python/structs/EveFpga.py CHANGED
@@ -1,7 +1,7 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .CFpgaData import *
4
- from .EveFpgaStructs import *
5
- from .EveImageStructs import *
6
-
7
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .CFpgaData import *
4
+ from .EveFpgaStructs import *
5
+ from .EveImageStructs import *
6
+
7
+
shared/eve_python/structs/EveFpgaStructs.py CHANGED
@@ -1,24 +1,24 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .CFpgaData import *
4
- from .EveErrors import *
5
-
6
-
7
- class EveFpgaOptions(ctypes.Structure):
8
- _fields_ = [
9
- ("parameters", CFpgaParameters),
10
- ("error", ctypes.c_int),
11
- ]
12
-
13
- class EveFpgaDebugOptions(ctypes.Structure):
14
- _fields_ = [
15
- ("enableDrawingOnImage", ctypes.c_uint),
16
- ("error", ctypes.c_int),
17
- ]
18
-
19
- class EveFpgaData(ctypes.Structure):
20
- _fields_ = [
21
- ("data", ctypes.POINTER(CFpgaData)),
22
- ("error", ctypes.c_int),
23
- ]
24
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .CFpgaData import *
4
+ from .EveErrors import *
5
+
6
+
7
+ class EveFpgaOptions(ctypes.Structure):
8
+ _fields_ = [
9
+ ("parameters", CFpgaParameters),
10
+ ("error", ctypes.c_int),
11
+ ]
12
+
13
+ class EveFpgaDebugOptions(ctypes.Structure):
14
+ _fields_ = [
15
+ ("enableDrawingOnImage", ctypes.c_uint),
16
+ ("error", ctypes.c_int),
17
+ ]
18
+
19
+ class EveFpgaData(ctypes.Structure):
20
+ _fields_ = [
21
+ ("data", ctypes.POINTER(CFpgaData)),
22
+ ("error", ctypes.c_int),
23
+ ]
24
+
shared/eve_python/structs/EveHandGesture.py CHANGED
@@ -1,5 +1,5 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .EveHandGestureStructs import *
4
-
5
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .EveHandGestureStructs import *
4
+
5
+
shared/eve_python/structs/EveHandGestureStructs.py CHANGED
@@ -1,48 +1,35 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .CHandGesture import *
4
- from .EveControlOption import *
5
- from .EveErrors import *
6
-
7
-
8
- class EveHandGestureOptions(ctypes.Structure):
9
- _fields_ = [
10
- ("enabled", ctypes.c_int),
11
- ("redetectionDelay", ctypes.c_int),
12
- ("async", ctypes.c_int),
13
- ("run", ctypes.c_int),
14
- ("errorCode", ctypes.c_int),
15
- ]
16
-
17
- class EveHandGestureData(ctypes.Structure):
18
- _fields_ = [
19
- ("hands", ctypes.POINTER(EveHandDetections)),
20
- ("errorCode", ctypes.c_int),
21
- ]
22
-
23
- class EveStaticGestureData(ctypes.Structure):
24
- _fields_ = [
25
- ("gestures", EveStaticGestures),
26
- ("errorCode", ctypes.c_int),
27
- ]
28
-
29
- class EveDynamicGestureData(ctypes.Structure):
30
- _fields_ = [
31
- ("gestures", EveDynamicGestures),
32
- ("errorCode", ctypes.c_int),
33
- ]
34
-
35
- class EveStaticGestureDefinitions(ctypes.Structure):
36
- _fields_ = [
37
- ("count", ctypes.c_uint),
38
- ("errorCode", ctypes.c_int),
39
- ("definitions", EveStaticGestureDefinition * EVE_MAX_STATIC_GESTURES),
40
- ]
41
-
42
- class EveDynamicGestureDefinitions(ctypes.Structure):
43
- _fields_ = [
44
- ("count", ctypes.c_uint),
45
- ("errorCode", ctypes.c_int),
46
- ("definitions", EveDynamicGestureDefinition * EVE_DYNAMIC_GESTURE_SIZE),
47
- ]
48
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .CHandGesture import *
4
+ from .EveControlOption import *
5
+ from .EveErrors import *
6
+
7
+
8
+ class EveHandGestureOptions(ctypes.Structure):
9
+ _fields_ = [
10
+ ("enabled", ctypes.c_int),
11
+ ("redetectionDelay", ctypes.c_int),
12
+ ("async", ctypes.c_int),
13
+ ("run", ctypes.c_int),
14
+ ("errorCode", ctypes.c_int),
15
+ ]
16
+
17
+ class EveHandGestureData(ctypes.Structure):
18
+ _fields_ = [
19
+ ("hands", ctypes.POINTER(EveHandDetections)),
20
+ ("errorCode", ctypes.c_int),
21
+ ]
22
+
23
+ class EveStaticGestureData(ctypes.Structure):
24
+ _fields_ = [
25
+ ("gestures", EveStaticGestures),
26
+ ("errorCode", ctypes.c_int),
27
+ ]
28
+
29
+ class EveStaticGestureDefinitions(ctypes.Structure):
30
+ _fields_ = [
31
+ ("count", ctypes.c_uint),
32
+ ("errorCode", ctypes.c_int),
33
+ ("definitions", EveStaticGestureDefinition * EVE_MAX_STATIC_GESTURES),
34
+ ]
35
+
 
 
 
 
 
 
 
 
 
 
 
 
 
shared/eve_python/structs/EveImage.py CHANGED
@@ -1,5 +1,5 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .EveImageStructs import *
4
-
5
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .EveImageStructs import *
4
+
5
+
shared/eve_python/structs/EveImageManipulation.py CHANGED
@@ -1,5 +1,5 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .EveImageManipulationStructs import *
4
-
5
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .EveImageManipulationStructs import *
4
+
5
+
shared/eve_python/structs/EveImageManipulationStructs.py CHANGED
@@ -1,12 +1,12 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .CImageManipulation import *
4
- from .EveErrors import *
5
-
6
-
7
- class EveImageManipulationOptions(ctypes.Structure):
8
- _fields_ = [
9
- ("settings", CImageManipulationSettings),
10
- ("errorCode", ctypes.c_int),
11
- ]
12
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .CImageManipulation import *
4
+ from .EveErrors import *
5
+
6
+
7
+ class EveImageManipulationOptions(ctypes.Structure):
8
+ _fields_ = [
9
+ ("settings", CImageManipulationSettings),
10
+ ("errorCode", ctypes.c_int),
11
+ ]
12
+
shared/eve_python/structs/EveImageStructs.py CHANGED
@@ -1,38 +1,53 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .CBasicStructs import *
4
- from .EveErrors import *
5
-
6
-
7
- class EveInputImage(ctypes.Structure):
8
- _fields_ = [
9
- ("data", ctypes.POINTER(ctypes.c_ubyte)),
10
- ("width", ctypes.c_int),
11
- ("height", ctypes.c_int),
12
- ("encoding", ctypes.c_int),
13
- ]
14
-
15
- class EveProcessedImage(ctypes.Structure):
16
- _fields_ = [
17
- ("data", ctypes.POINTER(ctypes.c_ubyte)),
18
- ("width", ctypes.c_int),
19
- ("height", ctypes.c_int),
20
- ("channels", ctypes.c_int),
21
- ("timestamp", ctypes.c_longlong),
22
- ("error", ctypes.c_int),
23
- ("location", ctypes.c_int),
24
- ]
25
-
26
- class EveProcessedFrameTime(ctypes.Structure):
27
- _fields_ = [
28
- ("frameTime", ctypes.c_double),
29
- ("error", ctypes.c_int),
30
- ]
31
-
32
- class EveImageFormatRequest(ctypes.Structure):
33
- _fields_ = [
34
- ("format", ctypes.c_int),
35
- ("location", ctypes.c_int),
36
- ("error", ctypes.c_int),
37
- ]
38
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .CBasicStructs import *
4
+ from .EveControlOption import *
5
+ from .EveErrors import *
6
+
7
+
8
+ class EveInputImage(ctypes.Structure):
9
+ _fields_ = [
10
+ ("data", ctypes.POINTER(ctypes.c_ubyte)),
11
+ ("width", ctypes.c_int),
12
+ ("height", ctypes.c_int),
13
+ ("encoding", ctypes.c_int),
14
+ ]
15
+
16
+ class EveProcessedImage(ctypes.Structure):
17
+ _fields_ = [
18
+ ("data", ctypes.POINTER(ctypes.c_ubyte)),
19
+ ("width", ctypes.c_int),
20
+ ("height", ctypes.c_int),
21
+ ("channels", ctypes.c_int),
22
+ ("timestamp", ctypes.c_longlong),
23
+ ("error", ctypes.c_int),
24
+ ("location", ctypes.c_int),
25
+ ("format", ctypes.c_int),
26
+ ]
27
+
28
+ class EveProcessedFrameTime(ctypes.Structure):
29
+ _fields_ = [
30
+ ("frameTime", ctypes.c_double),
31
+ ("error", ctypes.c_int),
32
+ ]
33
+
34
+ class EveImageFormatRequest(ctypes.Structure):
35
+ _fields_ = [
36
+ ("format", ctypes.c_int),
37
+ ("location", ctypes.c_int),
38
+ ("error", ctypes.c_int),
39
+ ]
40
+
41
+ class EveRawImageRequest(ctypes.Structure):
42
+ _fields_ = [
43
+ ("enabled", ctypes.c_int),
44
+ ("recordResults", ctypes.c_int),
45
+ ("error", ctypes.c_int),
46
+ ]
47
+
48
+ class EveJsonData(ctypes.Structure):
49
+ _fields_ = [
50
+ ("string", CStringData),
51
+ ("error", ctypes.c_int),
52
+ ]
53
+
shared/eve_python/structs/EveKarolinska.py CHANGED
@@ -1,5 +1,5 @@
1
- import ctypes
2
- from ctypes_enum import CtypesEnum
3
- from .EveKarolinskaStructs import *
4
-
5
-
 
1
+ import ctypes
2
+ from ctypes_enum import CtypesEnum
3
+ from .EveKarolinskaStructs import *
4
+
5
+