File size: 8,426 Bytes
d2885a7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
# What this file does
# This file turns YAML settings into structured config objects.

# Why this is useful:

# cleaner code
# less bugs
# easier auto-complete
# easier debugging
# easier to explain in FYP presentation


from dataclasses import dataclass
from pathlib import Path
from typing import List


@dataclass(frozen=True)
class ProjectConfig:
    name: str
    version: str
    description: str
    author: str
    random_seed: int


@dataclass(frozen=True)
class SystemConfig:
    device: str
    num_workers: int
    pin_memory: bool
    log_level: str


@dataclass(frozen=True)
class TrackingConfig:
    enable_mlflow: bool
    experiment_name: str
    tracking_uri: str


@dataclass(frozen=True)
class RuntimeConfig:
    use_pretrained_phone_detector_fallback: bool
    save_prediction_images: bool
    save_runtime_hand_crops: bool
    enable_debug_visuals: bool
    allow_multiple_persons: bool


@dataclass(frozen=True)
class LabelConfig:
    posture_classes: List[str]
    phone_classes: List[str]
    final_classes: List[str]


@dataclass(frozen=True)
class PathsConfig:
    artifacts_root: Path
    logs_dir: Path
    data_root: Path
    raw_data_dir: Path
    interim_data_dir: Path
    processed_data_dir: Path
    mmpose_checkpoint_dir: Path
    posture_model_dir: Path
    posture_weights_dir: Path
    posture_archive_dir: Path
    phone_model_dir: Path
    phone_pretrained_dir: Path
    phone_weights_dir: Path
    phone_archive_dir: Path
    metrics_dir: Path
    predictions_dir: Path
    raw_video_dir: Path
    raw_image_dir: Path
    posture_feature_dir: Path
    hand_crop_dir: Path
    phone_dataset_dir: Path
    frontend_upload_dir: Path
    frontend_result_dir: Path
    person_detector_checkpoint: Path
    pose_estimator_checkpoint: Path
    default_posture_model: Path
    archived_posture_model: Path
    default_phone_model: Path
    fallback_phone_model: Path


@dataclass(frozen=True)
class MMPoseDetectorConfig:
    config_file: str
    checkpoint_file: Path
    category_id: int
    bbox_threshold_multi_person: float
    bbox_threshold_single_person: float
    nms_threshold: float


@dataclass(frozen=True)
class MMPoseEstimatorConfig:
    config_file: str
    checkpoint_file: Path


@dataclass(frozen=True)
class MMPoseVisualizerConfig:
    draw_bbox: bool
    draw_heatmap: bool
    keypoint_threshold: float
    radius: int
    alpha: float
    thickness: int
    skeleton_style: str


@dataclass(frozen=True)
class MMPoseKeypointConfig:
    use_first_n_keypoints: int
    left_shoulder_index: int
    right_shoulder_index: int
    left_elbow_index: int
    right_elbow_index: int
    left_wrist_index: int
    right_wrist_index: int
    left_ear_index: int
    right_ear_index: int
    face_center_index: int


@dataclass(frozen=True)
class MMPoseConfig:
    device_preference: str
    detector: MMPoseDetectorConfig
    pose_estimator: MMPoseEstimatorConfig
    visualizer: MMPoseVisualizerConfig
    keypoints: MMPoseKeypointConfig


@dataclass(frozen=True)
class PostureInputShapeConfig:
    channels: int
    depth: int
    height: int
    width: int


@dataclass(frozen=True)
class PostureArchitectureConfig:
    conv_kernel_size: List[int]
    pool_kernel_size: int
    activation: str
    fc_dims: List[int]


@dataclass(frozen=True)
class PostureInferenceConfig:
    confidence_threshold: float
    class_names: List[str]


@dataclass(frozen=True)
class PostureWeightsConfig:
    default_weight_file: Path
    archive_weight_file: Path


@dataclass(frozen=True)
class PostureFeatureEngineeringConfig:
    feature_type: str
    normalize_per_channel: bool
    transpose_to_ncdhw: bool


@dataclass(frozen=True)
class PostureModelConfig:
    model_name: str
    task_type: str
    input_channels: int
    output_classes: int
    input_shape: PostureInputShapeConfig
    architecture: PostureArchitectureConfig
    inference: PostureInferenceConfig
    weights: PostureWeightsConfig
    feature_engineering: PostureFeatureEngineeringConfig


@dataclass(frozen=True)
class PhoneWeightsConfig:
    default_weight_file: Path
    fallback_weight_file: Path


@dataclass(frozen=True)
class PhoneInferenceConfig:
    image_size: int
    confidence_threshold_trained: float
    confidence_threshold_fallback: float
    use_trained_model_by_default: bool
    trained_model_phone_class_index: int
    fallback_model_phone_class_index: int


@dataclass(frozen=True)
class PhoneHandCropLogicConfig:
    far_body_hand_ratio: float
    near_body_hand_ratio: float
    merge_hand_distance_ratio: float
    hand_extension_ratio: float
    spare_ratio_threshold: float


@dataclass(frozen=True)
class PhoneRuntimeConfig:
    save_runtime_handframes: bool
    runtime_handframe_format: str


@dataclass(frozen=True)
class PhoneDetectorConfig:
    framework: str
    task_type: str
    weights: PhoneWeightsConfig
    inference: PhoneInferenceConfig
    hand_crop_logic: PhoneHandCropLogicConfig
    runtime: PhoneRuntimeConfig


@dataclass(frozen=True)
class GeneralTrainingConfig:
    random_seed: int
    device_preference: str
    num_workers: int
    pin_memory: bool


@dataclass(frozen=True)
class PostureTrainingDataConfig:
    source_feature_dir: Path
    train_split: float
    val_split: float
    test_split: float
    shuffle: bool


@dataclass(frozen=True)
class PostureTrainingHyperConfig:
    epochs: int
    batch_size: int
    learning_rate: float
    weight_decay: float
    early_stopping_patience: int
    min_delta: float


@dataclass(frozen=True)
class PostureTrainingOutputConfig:
    save_best_model_as: str
    save_last_model_as: str
    metrics_file_name: str
    history_file_name: str


@dataclass(frozen=True)
class PostureTrainingConfig:
    enabled: bool
    use_existing_weights: bool
    existing_weights_path: Path
    data: PostureTrainingDataConfig
    hyperparameters: PostureTrainingHyperConfig
    outputs: PostureTrainingOutputConfig


@dataclass(frozen=True)
class PhoneTrainingDataConfig:
    source_dataset_dir: Path


@dataclass(frozen=True)
class PhoneTrainingHyperConfig:
    epochs: int
    batch_size: int
    image_size: int
    learning_rate: float


@dataclass(frozen=True)
class PhoneTrainingOutputConfig:
    save_best_model_as: str
    metrics_file_name: str


@dataclass(frozen=True)
class PhoneTrainingConfig:
    enabled: bool
    use_existing_weights: bool
    existing_weights_path: Path
    data: PhoneTrainingDataConfig
    hyperparameters: PhoneTrainingHyperConfig
    outputs: PhoneTrainingOutputConfig


@dataclass(frozen=True)
class TrainingTrackingConfig:
    enable_mlflow: bool
    experiment_name_posture: str
    experiment_name_phone: str
    tracking_uri: str


@dataclass(frozen=True)
class TrainingConfig:
    general: GeneralTrainingConfig
    posture_training: PostureTrainingConfig
    phone_training: PhoneTrainingConfig
    tracking: TrainingTrackingConfig


@dataclass(frozen=True)
class InferenceGeneralConfig:
    device_preference: str
    allow_multiple_persons: bool
    max_persons_per_frame: int
    save_prediction_images: bool
    save_runtime_hand_crops: bool


@dataclass(frozen=True)
class InferenceVideoConfig:
    default_frame_width: int
    default_frame_height: int
    websocket_frame_width: int
    websocket_frame_height: int


@dataclass(frozen=True)
class InferencePostureConfig:
    confidence_threshold: float
    out_of_frame_missing_keypoints_threshold: int
    keypoint_score_threshold: float
    backside_ratio_threshold: float


@dataclass(frozen=True)
class InferencePhoneConfig:
    trained_model_confidence: float
    fallback_model_confidence: float
    face_announce_interval_seconds: int
    spare_ratio_threshold: float


@dataclass(frozen=True)
class InferenceRenderingConfig:
    show_fps: bool
    show_current_time: bool
    show_last_announce_time: bool
    show_person_bbox: bool
    show_hand_bbox: bool
    show_face_bbox: bool
    window_title: str


@dataclass(frozen=True)
class InferenceAPIConfig:
    host: str
    port: int
    reload: bool


@dataclass(frozen=True)
class InferenceFrontendConfig:
    app_title: str
    upload_folder: Path
    result_folder: Path


@dataclass(frozen=True)
class InferenceConfig:
    general: InferenceGeneralConfig
    video: InferenceVideoConfig
    posture: InferencePostureConfig
    phone: InferencePhoneConfig
    rendering: InferenceRenderingConfig
    api: InferenceAPIConfig
    frontend: InferenceFrontendConfig