Files
AiDA_Python/app/api/api_design.py

514 lines
20 KiB
Python
Raw Normal View History

2024-06-13 14:31:14 +08:00
import json
2024-05-28 15:22:11 +08:00
import logging
2026-01-08 17:33:54 +08:00
import requests
from fastapi import APIRouter, HTTPException, BackgroundTasks
2024-05-28 15:22:11 +08:00
2026-01-22 13:41:47 +08:00
from app.core.config import settings
2026-01-08 17:33:54 +08:00
from app.schemas.design import DesignModel, ModelProgressModel, DesignStreamModel, SAMRequestModel
2024-06-13 14:31:14 +08:00
from app.schemas.response_template import ResponseModel
from app.service.design_fast.design_generate import design_generate, design_generate_v2
from app.service.design_fast.model_process_service import model_transpose
2024-05-28 15:22:11 +08:00
router = APIRouter()
logger = logging.getLogger()
@router.post("/design")
def design(request_data: DesignModel):
"""
- **objects.items.transparent**:
```json
"transparent":{
"mask_url":"test/transparent_test/transparent_mask.png",
"scale":0.1
},
```
- **mask_url** 为空"" -> 单件衣服透明
- **mask_url** 非空"mask_url" -> 区域透明
- **transpose** 镜像模式 ,:"top_bottom""left_right"
- **rotate** 45,
- ** design 参数变更:
design detail 请求参数中 basic -> preview_submit 替换为design_type 可选参数 default ,merge (移除preview和submit)
design_type 参数说明:
defuault模式下 请求参数不变
merge模式下 items -> 每个item需要新增 merge_image_path , merge_image_path为前端处理 print color等操作后的单件结果图
**
- 创建一个具有以下参数的请求体:
示例参数
```json
{
"objects": [
{
"basic": {
"body_point_test": {
"waistband_right": [
203,
249
],
"hand_point_right": [
229,
343
],
"waistband_left": [
119,
248
],
"hand_point_left": [
97,
343
],
"shoulder_left": [
108,
107
],
"shoulder_right": [
212,
107
]
2024-08-28 11:47:00 +08:00
},
"layer_order": true,
"design_type": "preview",
"scale_bag": 0.7,
"scale_earrings": 0.16,
"self_template": true,
"single_overall": "overall",
"switch_category": ""
},
"items": [
{
"businessId": 2115382,
"color": "",
"image_id": 61686,
"offset": [
0,
0
],
"path": "aida-sys-image/images/female/dress/0628000564.jpg",
"transpose": [
1,
1
],
2026-01-08 10:29:31 +08:00
"rotate": 45,
"print": {
"element": {
"element_angle_list": [],
"element_path_list": [],
"element_scale_list": [],
"location": []
},
"overall": {
"location": [
[
53.0,
118.5
]
],
"print_angle_list": [
0.0
],
"print_path_list": [
"aida-users/89/print/02d57aa8-f342-4e1d-b02c-b278f94dcfe6-3-89.png"
],
"print_scale_list": [
[
0.5,
0.5
]
],
"gap": [
[
10,
10
]
]
},
"single": {
"location": [],
"print_angle_list": [],
"print_path_list": [],
"print_scale_list": []
}
2024-11-19 10:20:25 +08:00
},
"priority": 10,
"resize_scale": [
1.0,
1.0
],
"seg_mask_url": "aida-clothing/mask/mask_9698b428-eb93-11f0-9327-0242c0a80003.png",
"type": "Dress"
},
{
"body_path": "aida-sys-image/models/female/2e4815b9-1191-419d-94ed-5771239ca4a5.png",
"image_id": 67277,
"type": "Body"
}
]
}
],
"process_id": "89"
}
```
"""
# logger.info(f"design request item is : @@@@@@:{json.dumps(request_data.dict(),indent=4)}")
2024-09-19 14:20:56 +08:00
# data = generate(request_data=request_data)
# logger.info(f"design response @@@@@@:{json.dumps(data, indent=4)}")
2024-09-19 15:10:50 +08:00
#
2024-09-19 14:20:56 +08:00
2024-09-25 11:13:25 +08:00
try:
logger.info(f"design request item is : @@@@@@:{json.dumps(request_data.dict(), indent=4)}")
2024-09-25 11:13:25 +08:00
data = design_generate(request_data=request_data)
logger.info(f"design response @@@@@@:{json.dumps(data, indent=4)}")
2024-09-25 11:13:25 +08:00
except Exception as e:
logger.warning(f"design Run Exception @@@@@@:{e}")
raise HTTPException(status_code=404, detail=str(e))
2024-06-13 14:31:14 +08:00
return ResponseModel(data=data)
2024-06-18 10:50:15 +08:00
@router.post("/design_v2")
async def design_v2(request_data: DesignStreamModel, background_tasks: BackgroundTasks):
"""
创建一个具有以下参数的请求体:
示例参数
{
"objects": [
{
"basic": {
"body_point_test": {
"waistband_right": [
203,
249
],
"hand_point_right": [
229,
343
],
"waistband_left": [
119,
248
],
"hand_point_left": [
97,
343
],
"shoulder_left": [
108,
107
],
"relation_type": "System",
"shoulder_right": [
212,
107
],
"relation_id": 1020356
},
"layer_order": false,
"scale_bag": 0.7,
"scale_earrings": 0.16,
"self_template": false,
"single_overall": "overall",
"switch_category": ""
},
"items": [
{
"color": "209 196 171",
"image_id": 84093,
"offset": [
1,
1
],
"path": "aida-users/89/sketchboard/female/Outwear/0943d209-7ce0-408c-bc61-83f15da94138.png",
"print": {
"element": {
"element_angle_list": [],
"element_path_list": [],
"element_scale_list": [],
"location": []
},
"overall": {
"location": [
[
0.0,
0.0
]
],
"print_angle_list": [
0.0,
0.0
],
"print_path_list": [],
"print_scale_list": [
[
0.0,
0.0
]
]
},
"single": {
"location": [],
"print_angle_list": [],
"print_path_list": [],
"print_scale_list": []
}
},
"resize_scale": [
1.0,
1.0
],
"type": "Outwear"
},
{
"color": "63 71 73",
"image_id": 100496,
"offset": [
1,
1
],
"path": "aida-sys-image/images/female/blouse/0628001684.jpg",
"print": {
"element": {
"element_angle_list": [],
"element_path_list": [],
"element_scale_list": [],
"location": []
},
"overall": {
"location": [
[
0.0,
0.0
]
],
"print_angle_list": [
0.0,
0.0
],
"print_path_list": [],
"print_scale_list": [
[
0.0,
0.0
]
]
},
"single": {
"location": [],
"print_angle_list": [],
"print_path_list": [],
"print_scale_list": []
}
},
"resize_scale": [
1.0,
1.0
],
"type": "Blouse"
},
{
"color": "111 78 63",
"gradient": "aida-gradient/f69b98e8-4248-4f7a-98a2-21bac41bf3e0.png",
"image_id": 92193,
"offset": [
1,
1
],
"path": "aida-sys-image/images/female/trousers/0825001160.jpg",
"print": {
"element": {
"element_angle_list": [],
"element_path_list": [],
"element_scale_list": [],
"location": []
},
"overall": {
"location": [
[
0.0,
0.0
]
],
"print_angle_list": [
0.0,
0.0
],
"print_path_list": [],
"print_scale_list": [
[
0.0,
0.0
]
]
},
"single": {
"location": [],
"print_angle_list": [],
"print_path_list": [],
"print_scale_list": []
}
},
"resize_scale": [
1.0,
1.0
],
"type": "Trousers"
},
{
"body_path": "aida-sys-image/models/female/2e4815b9-1191-419d-94ed-5771239ca4a5.png",
"image_id": 67277,
"offset": [
1,
1
],
"resize_scale": [
1.0,
1.0
],
"type": "Body"
}
],
"objectSign": "65830966"
}
],
"process_id": "4802946666428422",
"requestId": "1d1e7641-0d62-4da2-adc0-b4404910723c",
"callback_url": "https://api.aida.com.hk/api/third/party/receiveDesignResults"
}
"""
try:
# 异步
logger.info(f"generate_image request item is : @@@@@@:{json.dumps(request_data.dict(), indent=4)}")
background_tasks.add_task(design_generate_v2, request_data)
except Exception as e:
logger.warning(f"design Run Exception @@@@@@:{e}")
raise HTTPException(status_code=404, detail=str(e))
return ResponseModel()
2026-01-08 17:33:54 +08:00
@router.post("/seg_anything")
async def seg_anything(request_data: SAMRequestModel):
"""
**Segment Anything 交互式分割接口**
通过传入图片路径和点击的点坐标返回分割后的掩码数据
### 参数说明:
2026-01-13 12:43:30 +08:00
- **user_id**:用户id 用于存储分割图
- **image_path**: 图片在服务器或云端的相对路径
2026-01-13 12:32:18 +08:00
- **type**: 推理类型
- **box**: 框选矩形点位信息
- **points**: 交互点的坐标列表每个点为 [x, y] 像素格式
- **labels**: 坐标点的属性标签必须与 points 长度一致
- 1: **前景点** (代表想要分割出的区域)
- 0: **背景点** (代表想要排除的区域)
### 请求体示例:
```json
2026-01-13 12:32:18 +08:00
point
{
2026-01-13 12:43:30 +08:00
"user_id": 1,
"image_path": "aida-users/89/sketch/4e8fe37d-7068-400a-ac94-c01647fa5f6f.png",
2026-01-13 12:32:18 +08:00
"type":"point",
"points": [[310, 403], [493, 375], [261, 266], [404, 484]],
2026-01-13 12:43:30 +08:00
"labels": [1, 1, 0, 1]
2026-01-13 12:32:18 +08:00
}
box
{
2026-01-13 12:43:30 +08:00
"user_id": 1,
2026-01-13 12:32:18 +08:00
"image_path": "aida-users/89/sketch/4e8fe37d-7068-400a-ac94-c01647fa5f6f.png",
"type":"box",
2026-01-13 12:43:30 +08:00
"box": [350, 286, 544, 520]
}
```
"""
2026-01-08 17:33:54 +08:00
try:
logger.info(f"seg_anything request item is : @@@@@@:{json.dumps(request_data.dict(), indent=4)}")
2026-03-05 15:06:19 +08:00
data = requests.post(f"http://{settings.B_4_X_4090_SERVICE_HOST}:10075/predict", json=request_data.dict())
2026-01-08 17:33:54 +08:00
logger.info(f"seg_anything response @@@@@@:{json.dumps(json.loads(data.content), indent=4)}")
return ResponseModel(data=json.loads(data.content))
except Exception as e:
logger.warning(f"seg_anything Run Exception @@@@@@:{e}")
# @router.post('/get_progress')
# def get_progress(request_data: DesignProgressModel):
# """
# 获取design 进度
# 创建一个具有以下参数的请求体:
# - **process_id**: 进度id
#
# 示例参数:
# {
# "process_id": "6878547032381675"
# }
# """
# try:
# logger.info(f"get_progress request item is : @@@@@@:{json.dumps(request_data.dict(), indent=4)}")
# process_id = request_data.process_id
# r = Redis()
# data = r.read(key=process_id)
# if data is None:
# raise ValueError(f"No progress ID: {process_id}")
# logging.info(f"get_progress process_id @@@@@@ : {process_id} , progress : {json.dumps(data, indent=4)}")
# except Exception as e:
# logger.warning(f"get_progress Run Exception @@@@@@:{e}")
# raise HTTPException(status_code=404, detail=str(e))
# return ResponseModel(data=data)
2024-06-24 16:35:34 +08:00
@router.post('/model_process')
def model_process(request_data: ModelProgressModel):
"""
获取模特图片预处理
创建一个具有以下参数的请求体:
- **model_path**: 模特图片的minio或s3 url地址
示例参数
{
"model_path": "aida-users/10/models/female/9c788f5b-b8c7-424c-b149-025aeb0bda51model.jpg"
}
"""
2024-06-24 16:35:34 +08:00
try:
logger.info(f"model_process request item is : @@@@@@:{json.dumps(request_data.dict(), indent=4)}")
2024-06-24 16:35:34 +08:00
2024-09-26 14:19:32 +08:00
data = model_transpose(image_path=request_data.model_path)
logger.info(f"model_process response @@@@@@:{json.dumps(data, indent=4)}")
2024-06-24 16:35:34 +08:00
except Exception as e:
logger.warning(f"model_process Run Exception @@@@@@:{e}")
raise HTTPException(status_code=404, detail=str(e))
return ResponseModel(data=data)
2024-09-12 10:06:25 +08:00
"""design 批量处理 停用"""
# @router.post("/design_batch_generate")
# async def design_batch(file: UploadFile = File(...),
# tasks_id: str = Form(...),
# user_id: str = Form(...),
# file_name: str = Form(...),
# total: int = Form(...)
# ):
# dbg_config = DBGConfigModel(
# tasks_id=tasks_id,
# user_id=user_id,
# file_name=file_name,
# total=total
# )
# contents = await file.read()
# file_name = file.filename
# await save_request_file(contents, file_name)
# return await start_design_batch_generate(dbg_config, contents)
#
#
# async def save_request_file(contents, file_name):
# # 创建保存文件的目录(如果不存在)
# save_dir = os.path.join(os.getcwd(), "service/design_batch", "request_data")
# if not os.path.exists(save_dir):
# os.makedirs(save_dir)
# # 处理文件
# file_path = os.path.join(save_dir, file_name)
# with open(file_path, "wb") as f:
# f.write(contents)