feat(fam-edge): 赤膊成年人直判爸爸(免费规则) - 用户确认家里只有爸爸会光膀子

用户原话:"赤裸的大人都是爸爸,家里没有其他人会赤裸"——加进闭集识别的免费
规则层(跟汤圆/媳妇同级),命中就不用再调用视觉大模型比对参考图,比 auto_id
更快更准。只对成年人生效(判断顺序上幼儿/儿童年龄档在前面,小孩光膀子玩很
正常,不适用这条规则)。

排查历史数据时用这条规则筛出了一个真实误判:video 1092 的一次赤膊出现被
auto_id(NVIDIA 视觉比对)错误识别成"爷爷",实际是"爸爸"。已用
correct_video_identity 手动纠正(标记 source=manual,受保护不会被以后的自动
识别覆盖回去),描述文字已确认同步更新。

顺带确认了另一批命中同样关键词的历史数据(74 条里有 3 条是"汤圆"光膀子)
是正确的——3 岁小孩光膀子玩正常,是通过幼儿/儿童年龄档规则识别出来的,跟
赤膊无关,不是误判,没有动。

新增 4 个测试:赤膊成年男性直判爸爸且不调用大模型(用会报错的假
person_identifier 验证短路生效)、覆盖各种赤膊近义词表述、赤膊小孩仍然
正确判成汤圆不受影响、没有赤膊关键词时行为不变照常走大模型比对。
This commit is contained in:
ericwyuan
2026-08-23 11:00:43 +08:00
parent 5f7b27bf04
commit 9dff19e6ac
2 changed files with 81 additions and 5 deletions

View File

@@ -514,25 +514,38 @@ class VideoProcessor:
f"events={len(norm_events)}, people={people}, "
f"with_features={len(uid_features)}, 闭集识别={resolved}")
# 家里赤膊/赤裸上身的成年人只有爸爸一个(用户原话:"赤裸的大人都是爸爸,
# 家里没有其他人会赤裸")——命中即免费直判,不用等视觉大模型比对,比
# auto_id 更快更准(实测已经纠正过一条被 auto_id 误判成爷爷的案例)。
# 只匹配成年人(外层已经先过滤掉 age_band 是幼儿/儿童的),小孩光膀子玩
# 很正常,不适用这条规则。
_SHIRTLESS_KEYWORDS = ('赤裸', '光着上身', '赤膊', '裸体', '光膀子',
'上身赤裸', '未穿上衣')
def _resolve_closed_set_identities(self, video_id: int, uid_features: Dict,
norm_events: List[Dict]) -> Dict[str, tuple]:
"""闭集人物识别:返回 {uid: (canonical_name, source)}。
汤圆(幼儿/儿童特征)、媳妇(唯一成年女性)靠 Gemini 已经产出的性别/年龄
字段直接判断source='rule'验证过命中率接近 100%,不需要额外模型调用。
爷爷/爸爸两个成年男性外观规则/人脸向量都区分不开(验证过),改用视觉大模型
比对参考图source='auto_id'),每个 uid 只取本片段内最大 bbox 的一次出现
判断一次,不逐事件重复调用。
汤圆(幼儿/儿童特征)、媳妇(唯一成年女性)、赤膊成年人(家里只有爸爸
会赤膊)靠 Gemini 已经产出的性别/年龄/衣着字段直接判断source='rule'
验证过命中率接近 100%,不需要额外模型调用。爷爷/爸爸两个成年男性穿戴
整齐时外观规则/人脸向量都区分不开(验证过),改用视觉大模型比对参考图
source='auto_id'),每个 uid 只取本片段内最大 bbox 的一次出现判断
一次,不逐事件重复调用。
"""
resolved: Dict[str, tuple] = {}
for uid, feats in uid_features.items():
gender = str(feats.get('gender', '') or '').strip()
age_band = str(feats.get('age_band', '') or '').strip()
clothing = str(feats.get('clothing', '') or '')
if age_band in ('幼儿', '儿童'):
resolved[uid] = ('汤圆', 'rule')
elif gender == '':
resolved[uid] = ('媳妇', 'rule')
elif gender == '':
if any(k in clothing for k in self._SHIRTLESS_KEYWORDS):
resolved[uid] = ('爸爸', 'rule')
continue
crop = self._best_crop_for_uid(video_id, uid, norm_events)
if crop:
person = self.person_identifier.classify_adult_male(crop)