docs: update Appearance_Feature_System with shot type detection
- Add reference units table (eye/head/shoulder width) - Add BODY_PROPORTIONS constants for validation - Add shot type detection section (full_body/medium_shot/close_up) - Add height estimation strategies per shot type - Update code examples with head_width and proportion_ratios
This commit is contained in:
@@ -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"
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user