Files
momentry_core/scripts/find_kids_refined.py
Warren e75c4d6f07 cleanup: remove dead code and duplicate docs
- Remove session-ses_2f27.md (161KB raw session log)
- Remove 49 ROOT_* duplicate files across REFERENCE/
- Remove 14 duplicate files between REFERENCE/ root and history/
- Remove asr_legacy.rs (dead code, replaced by asr.rs)
- Remove src/core/worker/ (duplicate JobWorker)
- Remove src/core/layers/ (empty directory)
- Remove 4 .bak files in src/
- Remove 7 dead private methods in worker/processor.rs
- Remove backup directory from git tracking
2026-05-04 01:31:21 +08:00

144 lines
4.6 KiB
Python

#!/opt/homebrew/bin/python3.11
"""
Refined Kid Detection with stricter filters.
Filters:
1. Ignore tiny faces (background noise).
2. Ignore sitting/squatting poses (Ankle must be lower than Hip).
"""
import json
import math
import os
POSE_JSON_PATH = "output/384b0ff44aaaa1f1/384b0ff44aaaa1f1.pose.json"
# Heuristic Threshold
RATIO_THRESHOLD = 6.2
# Filter constants
MIN_HEAD_WIDTH_PX = 25.0 # Ignore tiny background blobs
STANDING_TOLERANCE = 50.0 # Allow some wiggle room for ankles/hips overlap
def distance(p1, p2):
return math.sqrt((p1["x"] - p2["x"]) ** 2 + (p1["y"] - p2["y"]) ** 2)
def get_midpoint(p1, p2):
return {"x": (p1["x"] + p2["x"]) / 2, "y": (p1["y"] + p2["y"]) / 2}
def find_kids():
if not os.path.exists(POSE_JSON_PATH):
print(f"Pose JSON not found at {POSE_JSON_PATH}")
return
try:
with open(POSE_JSON_PATH, "r") as f:
data = json.load(f)
except Exception as e:
print(f"Error loading JSON: {e}")
return
frames = data.get("frames", {})
potential_kids = []
analyzed_poses = 0
print("Re-scanning pose data with stricter filters...")
for frame_idx_str, frame_data in frames.items():
timestamp = frame_data.get("timestamp", 0)
people_in_frame = frame_data.get("poses", [])
for person in people_in_frame:
kps_list = person.get("keypoints", [])
kp_dict = {kp["name"]: kp for kp in kps_list}
# Required keypoints for validation
nose = kp_dict.get("nose")
l_shoulder = kp_dict.get("left_shoulder")
r_shoulder = kp_dict.get("right_shoulder")
l_hip = kp_dict.get("left_hip")
r_hip = kp_dict.get("right_hip")
l_ankle = kp_dict.get("left_ankle")
r_ankle = kp_dict.get("right_ankle")
# 1. Basic visibility check
if not nose or not (l_shoulder and r_shoulder):
continue
# For strict standing check, we need reliable ankles/hips
if not (l_ankle and r_ankle):
continue
analyzed_poses += 1
# 2. Check for Sitting/Squatting (Filter 1)
# If Hips are lower (larger Y) than Ankles, or too close to Ankles vertically,
# the person is likely sitting or the detection is bad.
# In Y-down coordinate: Ankle Y should be > Hip Y.
mid_hip_y = (l_hip["y"] + r_hip["y"]) / 2
mid_ankle_y = (l_ankle["y"] + r_ankle["y"]) / 2
if mid_ankle_y < (mid_hip_y + STANDING_TOLERANCE):
# Ankle is above or level with hip -> Sitting/Crouching
continue
# 3. Estimate Head Size
mid_shoulder = get_midpoint(l_shoulder, r_shoulder)
dist_nose_shoulder = distance(nose, mid_shoulder)
# Head Height Estimate
head_height = dist_nose_shoulder * 2.0
# 4. Ignore tiny faces (Filter 2)
# Distance between shoulders (width) is a good proxy for size
shoulder_width = distance(l_shoulder, r_shoulder)
if shoulder_width < MIN_HEAD_WIDTH_PX:
continue
# 5. Calculate Ratio
mid_ankle = get_midpoint(l_ankle, r_ankle)
dist_nose_ankle = distance(nose, mid_ankle)
# Total Height = Nose to Ankle + half head
total_height = dist_nose_ankle + (head_height / 2)
if total_height <= head_height:
continue
ratio = total_height / head_height
if ratio < RATIO_THRESHOLD:
potential_kids.append(
{
"frame": frame_idx_str,
"timestamp": timestamp,
"ratio": round(ratio, 2),
"shoulder_width": round(shoulder_width, 1),
"confidence": "High" if ratio < 5.5 else "Medium",
}
)
print(f"Analyzed {analyzed_poses} valid standing poses.")
print(f"Found {len(potential_kids)} potential kids after filtering.")
# Group by timestamp
unique_kids = {}
for k in potential_kids:
ts = round(k["timestamp"], 1)
if ts not in unique_kids:
unique_kids[ts] = k
sorted_kids = sorted(unique_kids.values(), key=lambda x: x["timestamp"])
print("\nRefined Timestamps:")
for k in sorted_kids:
print(
f" ⏱️ {k['timestamp']:.2f}s | Ratio: {k['ratio']} | Width: {k['shoulder_width']}px | Conf: {k['confidence']}"
)
if __name__ == "__main__":
find_kids()