perf: 接口2/12 跳过 viz 叠图生成,省 ~80ms
compute_mask 新增 render_viz 开关(默认 True 保持接口11 行为不变)。 接口2/12 路径(generate_hairline_redraw)传 render_viz=False,跳过 6+ 张 overlay JPG 的 _jpg_b64 编码(baseline/upper/hair_seg/mask/hairline/pushed), 只保留必需的数据字段(_inner_pts/_outer_pts/_upper_mask/mask_pixels)。
This commit is contained in:
@@ -357,7 +357,7 @@ def _redraw_band_mask(inner_pts, outer_pts, h, w, rid="", upper=None,
|
|||||||
|
|
||||||
|
|
||||||
def compute_mask(image_bgr, landmarks, seg_model, mask_type, erode_cm, px_per_cm,
|
def compute_mask(image_bgr, landmarks, seg_model, mask_type, erode_cm, px_per_cm,
|
||||||
hairline_push_cm=0.0, hairline_edge="column", rid=""):
|
hairline_push_cm=0.0, hairline_edge="column", rid="", render_viz=True):
|
||||||
"""算出布尔遮罩 + 可视化。
|
"""算出布尔遮罩 + 可视化。
|
||||||
|
|
||||||
seg_model: bisenet | segformer。
|
seg_model: bisenet | segformer。
|
||||||
@@ -365,6 +365,9 @@ def compute_mask(image_bgr, landmarks, seg_model, mask_type, erode_cm, px_per_cm
|
|||||||
hairline_push_cm: 仅 pushed 模式——发际线往头发方向外推的厘米数(进入现有头发)。
|
hairline_push_cm: 仅 pushed 模式——发际线往头发方向外推的厘米数(进入现有头发)。
|
||||||
hairline_edge: 仅 pushed 模式——发际线提取方式 column(逐列最低点) | contour(形态学轮廓)。
|
hairline_edge: 仅 pushed 模式——发际线提取方式 column(逐列最低点) | contour(形态学轮廓)。
|
||||||
rid: 调用方的 request id,用于日志关联。
|
rid: 调用方的 request id,用于日志关联。
|
||||||
|
render_viz: 是否生成各阶段叠图 overlay JPG(接口11 调试页用)。接口2/12 路径传 False
|
||||||
|
可跳过 6+ 张 base64 编码,省 ~80ms;数据字段(_inner_pts/_outer_pts/_upper_mask/
|
||||||
|
mask_pixels 等)始终返回,不受影响。
|
||||||
返回 (mask_bool, viz_dict)。
|
返回 (mask_bool, viz_dict)。
|
||||||
"""
|
"""
|
||||||
lg = lambda msg: logger.info("[%s] %s", rid, msg) if rid else None
|
lg = lambda msg: logger.info("[%s] %s", rid, msg) if rid else None
|
||||||
@@ -425,47 +428,49 @@ def compute_mask(image_bgr, landmarks, seg_model, mask_type, erode_cm, px_per_cm
|
|||||||
# 遮罩计算过程可视化:
|
# 遮罩计算过程可视化:
|
||||||
# eroded/closed 走 top_fill→closed/eroded 流程;
|
# eroded/closed 走 top_fill→closed/eroded 流程;
|
||||||
# pushed 走 baseline→头发分割→发际线→外推 流程,与 top_fill/closed 无关,故置空。
|
# pushed 走 baseline→头发分割→发际线→外推 流程,与 top_fill/closed 无关,故置空。
|
||||||
|
# render_viz=False(接口2/12 路径)时跳过 overlay JPG 编码,只保留数据字段。
|
||||||
viz = {
|
viz = {
|
||||||
"erode_px": r,
|
"erode_px": r,
|
||||||
"hair_pixels": int(hair_mask.sum()),
|
"hair_pixels": int(hair_mask.sum()),
|
||||||
"closed_pixels": int(closed.sum()),
|
"closed_pixels": int(closed.sum()),
|
||||||
"mask_pixels": int(mask_bool.sum()),
|
"mask_pixels": int(mask_bool.sum()),
|
||||||
# 1. 发际线分割线(baseline):151 中心点标红,其余点标绿,黄线含左右延长线
|
# 1. 发际线分割线(baseline):151 中心点标红,其余点标绿,黄线含左右延长线
|
||||||
"baseline_overlay_base64": _jpg_b64(_draw_baseline(image_bgr, baseline_pts, w)),
|
"baseline_overlay_base64": _jpg_b64(_draw_baseline(image_bgr, baseline_pts, w)) if render_viz else "",
|
||||||
# 2. 分割线以上区域(upper 半区):青色叠加
|
# 2. 分割线以上区域(upper 半区):青色叠加
|
||||||
"upper_overlay_base64": _jpg_b64(_overlay(image_bgr, upper, (0, 255, 255))),
|
"upper_overlay_base64": _jpg_b64(_overlay(image_bgr, upper, (0, 255, 255))) if render_viz else "",
|
||||||
# 3. 头发分割原始结果(hair_mask):绿色叠加在原图上
|
# 3. 头发分割原始结果(hair_mask):绿色叠加在原图上
|
||||||
"hair_seg_overlay_base64": _jpg_b64(_overlay(image_bgr, hair_mask, (0, 255, 0))),
|
"hair_seg_overlay_base64": _jpg_b64(_overlay(image_bgr, hair_mask, (0, 255, 0))) if render_viz else "",
|
||||||
# 4. top_fill / closed —— 仅 eroded/closed 流程用;pushed 流程无关,留空
|
# 4. top_fill / closed —— 仅 eroded/closed 流程用;pushed 流程无关,留空
|
||||||
"top_fill_overlay_base64": "" if mask_type == "pushed"
|
"top_fill_overlay_base64": "" if (mask_type == "pushed" or not render_viz)
|
||||||
else _jpg_b64(_overlay(image_bgr, top_fill, (255, 0, 0))),
|
else _jpg_b64(_overlay(image_bgr, top_fill, (255, 0, 0))),
|
||||||
"closed_overlay_base64": "" if mask_type == "pushed"
|
"closed_overlay_base64": "" if (mask_type == "pushed" or not render_viz)
|
||||||
else _jpg_b64(_overlay(image_bgr, closed, (255, 0, 255))),
|
else _jpg_b64(_overlay(image_bgr, closed, (255, 0, 255))),
|
||||||
# 5. pushed 模式专有(发际线提取/外推)—— 非 pushed 留空
|
# 5. pushed 模式专有(发际线提取/外推)—— 非 pushed 留空
|
||||||
"hairline_overlay_base64": "",
|
"hairline_overlay_base64": "",
|
||||||
"pushed_overlay_base64": "",
|
"pushed_overlay_base64": "",
|
||||||
# —— 最终遮罩 ——
|
# —— 最终遮罩 ——
|
||||||
"mask_overlay_base64": _jpg_b64(_overlay(image_bgr, mask_bool, (0, 0, 255))),
|
"mask_overlay_base64": _jpg_b64(_overlay(image_bgr, mask_bool, (0, 0, 255))) if render_viz else "",
|
||||||
"mask_base64": _png_b64((mask_bool.astype(np.uint8)) * 255),
|
"mask_base64": _png_b64((mask_bool.astype(np.uint8)) * 255) if render_viz else "",
|
||||||
}
|
}
|
||||||
# pushed 模式:补充内轮廓提取 + 外推线可视化
|
# pushed 模式:补充内轮廓提取 + 外推线可视化
|
||||||
if pushed_info is not None:
|
if pushed_info is not None:
|
||||||
inner_pts, outer_pts, push_px = pushed_info
|
inner_pts, outer_pts, push_px = pushed_info
|
||||||
# ①-f 提取内轮廓:绿=头发内轮廓线(额头弧+两侧到下颌),黄=baseline 折线
|
if render_viz:
|
||||||
hl_img = _draw_baseline(image_bgr, baseline_pts, w) # 画 baseline(黄线+关键点)
|
# ①-f 提取内轮廓:绿=头发内轮廓线(额头弧+两侧到下颌),黄=baseline 折线
|
||||||
hl_img = _draw_polyline(hl_img, inner_pts, (0, 255, 0), 3)
|
hl_img = _draw_baseline(image_bgr, baseline_pts, w) # 画 baseline(黄线+关键点)
|
||||||
viz["hairline_overlay_base64"] = _jpg_b64(hl_img)
|
hl_img = _draw_polyline(hl_img, inner_pts, (0, 255, 0), 3)
|
||||||
# ①-g 外推:圆心红点(151) + 内轮廓(绿)+ 外推线(青)+ 遮罩(红半透明)
|
viz["hairline_overlay_base64"] = _jpg_b64(hl_img)
|
||||||
ps_img = _draw_polyline(image_bgr.copy(), inner_pts, (0, 255, 0), 2)
|
# ①-g 外推:圆心红点(151) + 内轮廓(绿)+ 外推线(青)+ 遮罩(红半透明)
|
||||||
ps_img = _draw_polyline(ps_img, outer_pts, (0, 255, 255), 3)
|
ps_img = _draw_polyline(image_bgr.copy(), inner_pts, (0, 255, 0), 2)
|
||||||
# 画圆心(151 点)红点,标示径向外推的中心(_idx151 上方已按值查到)
|
ps_img = _draw_polyline(ps_img, outer_pts, (0, 255, 255), 3)
|
||||||
if center is not None:
|
# 画圆心(151 点)红点,标示径向外推的中心(_idx151 上方已按值查到)
|
||||||
cx151, cy151 = center
|
if center is not None:
|
||||||
cv2.circle(ps_img, (cx151, cy151), 6, (0, 0, 255), -1, cv2.LINE_AA)
|
cx151, cy151 = center
|
||||||
cv2.putText(ps_img, "151", (cx151 + 8, cy151 - 8),
|
cv2.circle(ps_img, (cx151, cy151), 6, (0, 0, 255), -1, cv2.LINE_AA)
|
||||||
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 1, cv2.LINE_AA)
|
cv2.putText(ps_img, "151", (cx151 + 8, cy151 - 8),
|
||||||
ps_img = _overlay(ps_img, mask_bool, (0, 0, 255), 0.3)
|
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 1, cv2.LINE_AA)
|
||||||
viz["pushed_overlay_base64"] = _jpg_b64(ps_img)
|
ps_img = _overlay(ps_img, mask_bool, (0, 0, 255), 0.3)
|
||||||
|
viz["pushed_overlay_base64"] = _jpg_b64(ps_img)
|
||||||
viz["push_px"] = push_px
|
viz["push_px"] = push_px
|
||||||
# 重绘带用原始数据:内轮廓点 + 外推点(供 _redraw_band_mask 连端点成带)
|
# 重绘带用原始数据:内轮廓点 + 外推点(供 _redraw_band_mask 连端点成带)
|
||||||
viz["_inner_pts"] = inner_pts
|
viz["_inner_pts"] = inner_pts
|
||||||
@@ -844,7 +849,7 @@ def _grow_core(image_bgr, hairline_id, *, is_hr, seg_model, erode_cm, swap_mode,
|
|||||||
edge_erode_px, denoising_strength, gen_backend, hairgrow_strength,
|
edge_erode_px, denoising_strength, gen_backend, hairgrow_strength,
|
||||||
mb_levels, hairline_push_cm, hairline_edge, blend_method, color_match,
|
mb_levels, hairline_push_cm, hairline_edge, blend_method, color_match,
|
||||||
color_match_strength, mb_feather_px, transition_band_px,
|
color_match_strength, mb_feather_px, transition_band_px,
|
||||||
inpainting_fill, mask_blur, mask_dilate_scale, rid):
|
inpainting_fill, mask_blur, mask_dilate_scale, rid, render_viz=True):
|
||||||
"""接口11 共享核心:遮罩(pushed)→生成→硬贴回→接缝融合,产出 ④ final。
|
"""接口11 共享核心:遮罩(pushed)→生成→硬贴回→接缝融合,产出 ④ final。
|
||||||
|
|
||||||
不做任何重绘。返回中间产物 dict(供接口11 构造响应、接口12 取 final+重绘带用):
|
不做任何重绘。返回中间产物 dict(供接口11 构造响应、接口12 取 final+重绘带用):
|
||||||
@@ -873,7 +878,8 @@ def _grow_core(image_bgr, hairline_id, *, is_hr, seg_model, erode_cm, swap_mode,
|
|||||||
t0 = time.time()
|
t0 = time.time()
|
||||||
mask_bool, mask_viz = compute_mask(
|
mask_bool, mask_viz = compute_mask(
|
||||||
image_bgr, landmarks, seg_model, mask_type, erode_cm, px_per_cm,
|
image_bgr, landmarks, seg_model, mask_type, erode_cm, px_per_cm,
|
||||||
hairline_push_cm=hairline_push_cm, hairline_edge=hairline_edge, rid=rid)
|
hairline_push_cm=hairline_push_cm, hairline_edge=hairline_edge, rid=rid,
|
||||||
|
render_viz=render_viz)
|
||||||
t_mask = time.time() - t0
|
t_mask = time.time() - t0
|
||||||
logger.info("[%s] 步骤1 遮罩完成 耗时=%dms mask_pixels=%d", rid, int(t_mask*1000), int(mask_bool.sum()))
|
logger.info("[%s] 步骤1 遮罩完成 耗时=%dms mask_pixels=%d", rid, int(t_mask*1000), int(mask_bool.sum()))
|
||||||
|
|
||||||
@@ -1050,7 +1056,7 @@ def generate_hairline_redraw(image_bgr, hairline_id, is_hr=False, seg_model="seg
|
|||||||
color_match=color_match, color_match_strength=color_match_strength,
|
color_match=color_match, color_match_strength=color_match_strength,
|
||||||
mb_feather_px=mb_feather_px, transition_band_px=transition_band_px,
|
mb_feather_px=mb_feather_px, transition_band_px=transition_band_px,
|
||||||
inpainting_fill=inpainting_fill, mask_blur=mask_blur,
|
inpainting_fill=inpainting_fill, mask_blur=mask_blur,
|
||||||
mask_dilate_scale=mask_dilate_scale, rid=rid)
|
mask_dilate_scale=mask_dilate_scale, rid=rid, render_viz=False)
|
||||||
final = core["final"]
|
final = core["final"]
|
||||||
mask_viz = core["mask_viz"]
|
mask_viz = core["mask_viz"]
|
||||||
w, h = core["w"], core["h"]
|
w, h = core["w"], core["h"]
|
||||||
|
|||||||
Reference in New Issue
Block a user