diff --git a/docs_v1.0/DESIGN/Appearance_Feature_System_V1.0.md b/docs_v1.0/DESIGN/Appearance_Feature_System_V1.0.md index c65828a..16548cd 100644 --- a/docs_v1.0/DESIGN/Appearance_Feature_System_V1.0.md +++ b/docs_v1.0/DESIGN/Appearance_Feature_System_V1.0.md @@ -114,10 +114,73 @@ Face (identification) → Pose (tracking) → Appearance (tracking) ## Body Proportions Calculation -### Reference Unit +### Reference Units + +Multiple reference units for different shot types: + +| Unit | Real Size | Available In | Notes | +|------|-----------|--------------|-------| +| eye_width | ~6cm | Close-up | Most accurate in close-up | +| head_width | ~16cm | Close-up to Medium | Ear-to-ear distance | +| shoulder_width | ~45cm | Medium to Wide | Most stable reference | + ```python -# Eye distance as reference unit -eye_width = distance(left_eye, right_eye) +# Priority: shoulder_width > head_width > eye_width +# Larger units more stable and available in wider shots +``` + +### Body Proportions Constants + +Standard adult body proportion ratios (used for validation and estimation): + +| Ratio | Value | Description | +|-------|-------|-------------| +| head_to_eye | 2.67 | head_width ≈ 2.67 × eye_width | +| eye_to_shoulder | 7.5 | shoulder_width ≈ 7.5 × eye_width | +| head_to_shoulder | 2.8 | shoulder_width ≈ 2.8 × head_width | +| head_to_height | 7.5 | body_height ≈ 7.5 × head_width | +| shoulder_to_height | 3.8 | body_height ≈ 3.8 × shoulder_width | + +### Shot Type Detection + +Detect shot type based on head position relative to bbox: + +| Shot Type | Head Position | Aspect Ratio | Description | +|-----------|---------------|--------------|-------------| +| full_body | < 15% from top | > 2.0 | Full person visible | +| medium_shot | < 30% from top | > 1.5 | Upper body visible | +| close_up | > 30% or middle | < 1.5 | Head/face dominant | + +```python +# head_position_ratio = (head_y - bbox_top) / bbox_height +# aspect_ratio = bbox_height / bbox_width + +if head_position_ratio < 0.15 and aspect_ratio > 2.0: + shot_type = "full_body" +elif head_position_ratio < 0.30 and aspect_ratio > 1.5: + shot_type = "medium_shot" +else: + shot_type = "close_up" +``` + +**Usage**: Filter frames by shot type (e.g., find all full-body shots in video). + +### Height Estimation + +Height estimation strategy based on shot type: + +| Shot Type | Method | Formula | Result | +|-----------|--------|---------|--------| +| full_body | Direct measurement | body_height / ref_unit × ref_cm | Accurate | +| medium_shot | Torso extrapolate | torso × (1/0.45) | ~170cm | +| close_up | Proportion estimate | shoulder × 3.8 | ~171cm | + +```python +# Close-up: use shoulder_width × 3.8 +estimated_height_cm = 45.0 * 3.8 # ≈ 171cm + +# Or use head_width × 7.5 +estimated_height_cm = 16.0 * 7.5 # ≈ 120cm (lower confidence) ``` ### Body Measurements @@ -137,59 +200,56 @@ leg_height = ankle_y - hip_y # Shoulder width shoulder_width = distance(left_shoulder, right_shoulder) + +# Head width (ear to ear) +head_width = distance(left_ear, right_ear) ``` ### Proportion Ratios ```python proportions = { + 'shot_type': detect_shot_type(keypoints, bbox), 'eye_width': eye_width, + 'head_width': head_width, 'body_height': body_height, 'torso_height': torso_height, 'leg_height': leg_height, 'shoulder_width': shoulder_width, - 'head_ratio': eye_width / body_height, - 'torso_ratio': torso_height / body_height, - 'leg_ratio': leg_height / body_height, + 'head_ratio': eye_width / body_height if body_height > 0 else 0, + 'torso_ratio': torso_height / body_height if body_height > 0 else 0, + 'leg_ratio': leg_height / body_height if body_height > 0 else 0, +} + +# Validation ratios (should match BODY_PROPORTIONS constants) +proportion_ratios = { + 'head_to_eye': head_width / eye_width if eye_width > 0 else 0, # ~2.67 + 'shoulder_to_head': shoulder_width / head_width if head_width > 0 else 0, # ~2.8 + 'shoulder_to_eye': shoulder_width / eye_width if eye_width > 0 else 0, # ~7.5 } ``` -### Body Shape Calculation (三圍) +### Body Shape Classification + +Classification based on chest/waist/hip ratios: + +| Shape | Criteria | Description | +|-------|----------|-------------| +| hourglass | chest_waist < 1.0, waist_hip < 0.9 | Balanced proportions | +| triangle | chest_waist > 1.2 | Upper body dominant | +| inverted_triangle | waist_hip > 1.1 | Lower body dominant | +| rectangle | chest ≈ hip | Uniform width | +| oval | Other | General classification | + ```python -# Chest width (shoulder width approximation) +# Measurements chest_width = distance(left_shoulder, right_shoulder) - -# Waist width (hip width approximation) waist_width = distance(left_hip, right_hip) - -# Hip width hip_width = distance(left_hip, right_hip) -# Body shape classification -if chest_waist_ratio < 1.0 and waist_hip_ratio < 0.9: - shape_type = "hourglass" #葫芦形 -elif chest_waist_ratio > 1.2: - shape_type = "triangle" # 倒三角 -elif waist_hip_ratio > 1.1: - shape_type = "inverted_triangle" # 正三角 -elif abs(chest_width - hip_width) < 0.1 * max(chest_width, hip_width): - shape_type = "rectangle" #矩形 -else: - shape_type = "oval" #椭圆形 +# Ratios +chest_waist_ratio = chest_width / waist_width +waist_hip_ratio = waist_width / hip_width ``` - -### Height Estimation -```python -# Use eye_width as reference (≈6cm) -height_ratio = body_height / eye_width -estimated_height_cm = height_ratio * 6.0 - -# Height category -if estimated_height_cm < 150: - height_category = "short" -elif estimated_height_cm < 170: - height_category = "medium" -elif estimated_height_cm < 180: - height_category = "tall" else: height_category = "very_tall" ```