接口11/12:固定 pushed 遮罩 + multiband 融合,移除其他算法选项

遮罩算法只保留 pushed(发际线外推),融合算法只保留 multiband(多频段金字塔),
eroded/closed/feather/alpha_gradient/seamless 等旧选项从接口参数层移除。

- generate_hairline_grow: 删除 mask_type/blend_method/feather_px/color_match 参数,
  内部固定 mask_type=pushed、blend_method=multiband
- app.py 接口11/12: 删除 mask_type/blend_method/feather_px/color_match Form 参数,
  调用处改关键字传参;grow_v2 只传 image+hairline_id 即默认走最新算法
- 前端两个测试页: 删除遮罩/融合下拉选项及相关联动,固定展示 pushed 步骤
- 文档: 更新为"固定 pushed + multiband,移除其他选项"
This commit is contained in:
xsl
2026-07-11 23:31:19 +08:00
parent 1b9f3fdb6f
commit 1e6c2e54de
5 changed files with 106 additions and 179 deletions
+19 -19
View File
@@ -64,16 +64,14 @@ DEFAULTS = {
"gen_backend": "swaphair", # swaphair(换发型LoRA) | hairgrow(区域生发inpaint)
"is_hr": False,
"seg_model": "segformer", # bisenet | segformer
"mask_type": "eroded", # eroded | closed
"erode_cm": 1.2,
"hairline_push_cm": 1.0, # 发际线径向外推距离(厘米)
"hairline_edge": "column", # column(逐列下沿)
"swap_mode": "ext_mask", # ext_mask | as_is(仅 swaphair
"denoising_strength": 0.6, # 仅 swaphair
"hairgrow_strength": 0.75, # 仅 hairgrow
"blend_method": "feather", # feather | alpha_gradient | seamless | multiband
"feather_px": 15,
"edge_erode_px": 3,
"color_match": False, # True 时对生成图做 Reinhard 颜色校正(seamless 下自动跳过)
"mb_levels": 5, # multiband 金字塔层数(2~6,越大色差抹得越宽)
"erode_cm": 0.6, # 接口12 固定值(pushed 模式下仅用于 baseline 截断参考,影响很小)
}
@@ -662,21 +660,25 @@ def _composite(orig, swap_result, mask_bool, blend_method, feather_px, edge_erod
# ---------------------------------------------------------------------------
def generate_hairline_grow(image_bgr, hairline_id, is_hr=False, seg_model="segformer",
mask_type="eroded", erode_cm=1.2, swap_mode="ext_mask",
blend_method="feather", feather_px=15, edge_erode_px=3,
erode_cm=0.6, swap_mode="ext_mask",
edge_erode_px=3,
denoising_strength=0.6, gen_backend="swaphair",
hairgrow_strength=0.75, color_match=False, mb_levels=5,
hairline_push_cm=0.0, hairline_edge="column", rid=None):
hairgrow_strength=0.75, mb_levels=5,
hairline_push_cm=1.0, hairline_edge="column", rid=None):
"""接口11 完整管线。返回可直接进 ok() 的 data dict。未检出人脸抛 NoFaceError。
rid: 调用方的 request id,用于日志关联。为 None 时自动生成。
遮罩算法固定为 pushed(发际线外推),融合算法固定为 multiband(多频段金字塔),
不再支持其他选项。rid: 调用方的 request id,用于日志关联。为 None 时自动生成。
"""
mask_type = "pushed" # 固定:只支持 pushed 遮罩算法
blend_method = "multiband" # 固定:只支持 multiband 融合
if rid is None:
rid = uuid4().hex[:8]
logger.info("[%s] ===== generate_hairline_grow 开始 =====", rid)
logger.info("[%s] 参数: mask_type=%r erode_cm=%s blend=%s hairline_push_cm=%s hairline_edge=%r "
"seg=%s gen_backend=%s swap_mode=%s", rid, mask_type, erode_cm, blend_method,
hairline_push_cm, hairline_edge, seg_model, gen_backend, swap_mode)
logger.info("[%s] 参数(固定 mask=pushed blend=multiband): erode_cm=%s hairline_push_cm=%s "
"hairline_edge=%r mb_levels=%s seg=%s gen_backend=%s swap_mode=%s",
rid, erode_cm, hairline_push_cm, hairline_edge, mb_levels,
seg_model, gen_backend, swap_mode)
h, w = image_bgr.shape[:2]
landmarks = detector.detect(image_bgr)
if landmarks is None:
@@ -685,7 +687,7 @@ def generate_hairline_grow(image_bgr, hairline_id, is_hr=False, seg_model="segfo
px_per_cm = estimate_scale_factor(landmarks, w, h)
logger.info("[%s] 人脸检出 px_per_cm=%.3f 图尺寸=%dx%d", rid, px_per_cm, w, h)
# 步骤1:接口9 遮罩
# 步骤1:接口9 遮罩(固定 pushed
t0 = time.time()
mask_bool, mask_viz = compute_mask(
image_bgr, landmarks, seg_model, mask_type, erode_cm, px_per_cm,
@@ -706,11 +708,11 @@ def generate_hairline_grow(image_bgr, hairline_id, is_hr=False, seg_model="segfo
hard_paste = image_bgr.copy()
hard_paste[mask_bool] = swap_result[mask_bool]
# 步骤4:接缝融合
# 步骤4:接缝融合(固定 multiband
t0 = time.time()
final, alpha = _composite(
image_bgr, swap_result, mask_bool, blend_method, feather_px, edge_erode_px,
color_match=color_match, mb_levels=mb_levels)
image_bgr, swap_result, mask_bool, blend_method, 0, edge_erode_px,
color_match=False, mb_levels=mb_levels)
t_blend = time.time() - t0
data = {
@@ -723,9 +725,7 @@ def generate_hairline_grow(image_bgr, hairline_id, is_hr=False, seg_model="segfo
"erode_cm": round(float(erode_cm), 2),
"swap_mode": swap_mode,
"blend_method": blend_method,
"feather_px": int(feather_px),
"edge_erode_px": int(edge_erode_px),
"color_match": bool(color_match) and blend_method != "seamless",
"mb_levels": int(mb_levels),
"hairline_push_cm": round(float(hairline_push_cm), 2),
"hairline_edge": hairline_edge,