refactor(接口3): 简化为只需划线图一张,去掉 original + best_hairline
按需求方意见——B端只需上传一张已画好发际线的图,用不着原图: - 入参去掉 original_image_*,只保留 marked_image_*(三选一) - 输出去掉 best_hairline_image_url,只返回 hair_growth_image_url + hairline_type - ComfyUI 输入图改用 marked 划线图原样(add_hair.json 本就是"画了线的照片", 提示词清除黑线);检测路径只用于建遮罩,不再重画干净线/不需对齐原图 - service.generate_grow_b 签名改 (marked_bgr) 单参 - 同步文档:接口文档/接口3技术方案/网关映射表(去掉接口3 best_hairline 行) - 测试更新:grow-b 只传 marked,断言无 best_hairline 字段,44全绿 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -538,16 +538,11 @@ async def hair_grow(
|
||||
summary="接口3 B端生发(医生/操作端)",
|
||||
tags=["生发"],
|
||||
description="""
|
||||
医生/操作端在用户原图上**手动划线标注**目标发际线后,上传划线图与原图,返回:
|
||||
- 最合适的发际线图片 URL
|
||||
- 生发后效果图 URL
|
||||
- 发际线形
|
||||
医生/操作端在用户照片上**手动用马克笔划线标注**目标发际线后,**只需上传这一张划线图**,返回:
|
||||
- 生发后效果图(系统检测划线 → 据此生成「植发 3 个月」效果)
|
||||
- 发际线形(手绘为定制,固定 `custom`)
|
||||
|
||||
**划线图片**:字段名前缀为 `marked_image_`,同样支持文件/URL/base64 三选一。
|
||||
|
||||
**原始用户照片**:字段名前缀为 `original_image_`,同样支持文件/URL/base64 三选一,**必填**。
|
||||
|
||||
> 两组图片的传参方式可以不同,例如划线图用 URL,原图用 base64,但各自组内严格互斥。
|
||||
**划线图片**:字段名前缀为 `marked_image_`,支持文件/URL/base64 三选一。**不需要原始照片**。
|
||||
""",
|
||||
responses={
|
||||
200: {
|
||||
@@ -559,7 +554,6 @@ async def hair_grow(
|
||||
"message": "success",
|
||||
"request_id": "mock-request-id",
|
||||
"data": {
|
||||
"best_hairline_image_base64": "iVBORw0KGgo...(原图)",
|
||||
"hair_growth_image_base64": "iVBORw0KGgo...(生发图)",
|
||||
"hairline_type": "custom",
|
||||
},
|
||||
@@ -581,23 +575,16 @@ async def hair_grow_b(
|
||||
marked_image_file: Optional[UploadFile] = File(default=None, description="划线图片文件(JPG/PNG,≤ 1 MB)"),
|
||||
marked_image_url: Optional[str] = Form(default=None, description="划线图片 URL"),
|
||||
marked_image_base64: Optional[str] = Form(default=None, description="划线图片 base64"),
|
||||
original_image_file: Optional[UploadFile] = File(default=None, description="原始用户照片文件(JPG/PNG,≤ 1 MB)"),
|
||||
original_image_url: Optional[str] = Form(default=None, description="原始用户照片 URL"),
|
||||
original_image_base64: Optional[str] = Form(default=None, description="原始用户照片 base64"),
|
||||
):
|
||||
# 1. 两组图各三选一取图
|
||||
# 划线图三选一取图(只需这一张)
|
||||
marked_raw, e = await resolve_image_bytes(marked_image_file, marked_image_url, marked_image_base64)
|
||||
if e is not None:
|
||||
return e
|
||||
orig_raw, e = await resolve_image_bytes(original_image_file, original_image_url, original_image_base64)
|
||||
if e is not None:
|
||||
return e
|
||||
if len(marked_raw) > MAX_FILE_BYTES or len(orig_raw) > MAX_FILE_BYTES:
|
||||
if len(marked_raw) > MAX_FILE_BYTES:
|
||||
return err(1006, "文件超出 1 MB 限制")
|
||||
|
||||
marked = cv2.imdecode(np.frombuffer(marked_raw, np.uint8), cv2.IMREAD_COLOR)
|
||||
original = cv2.imdecode(np.frombuffer(orig_raw, np.uint8), cv2.IMREAD_COLOR)
|
||||
if marked is None or original is None:
|
||||
if marked is None:
|
||||
return err(1008, "图片格式不支持(仅 JPG / PNG)")
|
||||
|
||||
h, w = marked.shape[:2]
|
||||
@@ -609,7 +596,7 @@ async def hair_grow_b(
|
||||
from fastapi.concurrency import run_in_threadpool
|
||||
from hairline.service import generate_grow_b
|
||||
|
||||
res = await run_in_threadpool(generate_grow_b, marked, original)
|
||||
res = await run_in_threadpool(generate_grow_b, marked)
|
||||
if res["status"] == "no_face":
|
||||
return err(1001, "无法识别人像")
|
||||
if res["status"] == "no_line":
|
||||
@@ -617,7 +604,6 @@ async def hair_grow_b(
|
||||
|
||||
grown_b64 = base64.b64encode(res["grown_png"]).decode() if res["grown_png"] else None
|
||||
data = {
|
||||
"best_hairline_image_base64": base64.b64encode(orig_raw).decode(), # 原图原样
|
||||
"hair_growth_image_base64": grown_b64,
|
||||
"hairline_type": "custom",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user