接口1: 标注图人头最左/最右竖线改用耳朵分割外缘
- 最左/最右竖线由「头发轮廓」改为同一 BiSeNet 的耳朵类(7/8)外缘, 看不到耳朵(被头发/侧脸遮挡→掩膜空)则该侧不画线 - 外耳轮廓常被误标成头发: 从耳朵外缘沿紧邻前景(耳∪发)按脸宽自适应 外扩回收(上限 face_w*0.045, 遇背景间隙即停) - 先按人脸包围盒裁剪再分割: BiSeNet 在紧裁人脸上训练, 整张全身/街拍图 脸偏小会严重欠分割、丢耳朵; 裁剪后映射回原图, 耳朵稳定可分 - segment_hair_and_ears() 单次推理同出 hair_mask + ear_mask Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -362,17 +362,24 @@ async def _face_measure_impl(image_file, image_url, image_base64, variant="v1"):
|
||||
return None, err(1003, "角度问题,请上传正面照")
|
||||
head_pose = estimate_head_pose(landmarks, w, h)
|
||||
|
||||
# 7. 头发分割(方案 B),失败传 None 由 measure 内部回退方案 A
|
||||
# 7. 头发/耳朵分割(方案 B,单次推理),失败传 None 由 measure 内部回退方案 A。
|
||||
# 传人脸包围盒 → 先按人脸裁剪再分割(全身/街拍等脸偏小的图也能稳出耳朵)。
|
||||
hair_mask = None
|
||||
ear_mask = None
|
||||
try:
|
||||
from face_analysis.hair_segmenter import get_segmenter
|
||||
hair_mask = get_segmenter().segment_hair(image)
|
||||
from face_analysis.calibration import normalized_to_pixel
|
||||
pxs = [normalized_to_pixel(p, w, h) for p in landmarks.landmark]
|
||||
face_box = (min(p[0] for p in pxs), min(p[1] for p in pxs),
|
||||
max(p[0] for p in pxs), max(p[1] for p in pxs))
|
||||
hair_mask, ear_mask = get_segmenter().segment_hair_and_ears(image, face_box=face_box)
|
||||
except Exception as seg_e: # noqa: BLE001
|
||||
logger.warning("头发分割失败,回退方案A:%s", seg_e)
|
||||
logger.warning("头发/耳朵分割失败,回退方案A:%s", seg_e)
|
||||
|
||||
# 8. 测量 + 标注图
|
||||
# 8. 测量 + 标注图(hair_mask 定发际线/头顶;ear_mask 定人头最左/最右竖线)
|
||||
result = measure_face(landmarks, hair_mask, w, h, head_pose=head_pose)
|
||||
annotated = create_annotated_image(image, result, hair_mask=hair_mask, variant=variant)
|
||||
annotated = create_annotated_image(
|
||||
image, result, ear_mask=ear_mask, hair_mask=hair_mask, variant=variant)
|
||||
buf = BytesIO()
|
||||
annotated.save(buf, format="PNG")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user