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
|
## 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
|
```python
|
||||||
# Eye distance as reference unit
|
# Priority: shoulder_width > head_width > eye_width
|
||||||
eye_width = distance(left_eye, right_eye)
|
# 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
|
### Body Measurements
|
||||||
@@ -137,59 +200,56 @@ leg_height = ankle_y - hip_y
|
|||||||
|
|
||||||
# Shoulder width
|
# Shoulder width
|
||||||
shoulder_width = distance(left_shoulder, right_shoulder)
|
shoulder_width = distance(left_shoulder, right_shoulder)
|
||||||
|
|
||||||
|
# Head width (ear to ear)
|
||||||
|
head_width = distance(left_ear, right_ear)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Proportion Ratios
|
### Proportion Ratios
|
||||||
```python
|
```python
|
||||||
proportions = {
|
proportions = {
|
||||||
|
'shot_type': detect_shot_type(keypoints, bbox),
|
||||||
'eye_width': eye_width,
|
'eye_width': eye_width,
|
||||||
|
'head_width': head_width,
|
||||||
'body_height': body_height,
|
'body_height': body_height,
|
||||||
'torso_height': torso_height,
|
'torso_height': torso_height,
|
||||||
'leg_height': leg_height,
|
'leg_height': leg_height,
|
||||||
'shoulder_width': shoulder_width,
|
'shoulder_width': shoulder_width,
|
||||||
'head_ratio': eye_width / body_height,
|
'head_ratio': eye_width / body_height if body_height > 0 else 0,
|
||||||
'torso_ratio': torso_height / body_height,
|
'torso_ratio': torso_height / body_height if body_height > 0 else 0,
|
||||||
'leg_ratio': leg_height / body_height,
|
'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
|
```python
|
||||||
# Chest width (shoulder width approximation)
|
# Measurements
|
||||||
chest_width = distance(left_shoulder, right_shoulder)
|
chest_width = distance(left_shoulder, right_shoulder)
|
||||||
|
|
||||||
# Waist width (hip width approximation)
|
|
||||||
waist_width = distance(left_hip, right_hip)
|
waist_width = distance(left_hip, right_hip)
|
||||||
|
|
||||||
# Hip width
|
|
||||||
hip_width = distance(left_hip, right_hip)
|
hip_width = distance(left_hip, right_hip)
|
||||||
|
|
||||||
# Body shape classification
|
# Ratios
|
||||||
if chest_waist_ratio < 1.0 and waist_hip_ratio < 0.9:
|
chest_waist_ratio = chest_width / waist_width
|
||||||
shape_type = "hourglass" #葫芦形
|
waist_hip_ratio = waist_width / hip_width
|
||||||
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" #椭圆形
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 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:
|
else:
|
||||||
height_category = "very_tall"
|
height_category = "very_tall"
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user