47 Commits

Author SHA1 Message Date
zcr
d5452098f3 feat:
fix: 移除打印
2026-01-27 13:53:21 +08:00
zcr
315e298ba8 feat:
fix:
2026-01-27 13:53:17 +08:00
zcr
ec26c8b507 feat:
fix:  印花overall 角度异常
2026-01-27 13:53:04 +08:00
zcr
ddef6af1cf fix: 参数对齐 2026-01-26 14:49:57 +08:00
zcr
fdffb1e724 Merge branch 'develop' 2026-01-24 22:05:57 +08:00
zcr
ecf10611c2 fix: merge 模式下 镜像和旋转功能与前端对其
All checks were successful
git commit AiDA python develop 分支构建部署 / scheduled_deploy (push) Has been skipped
2026-01-24 14:43:10 +08:00
zcr
f78809b22a fix: merge 模式下 镜像和旋转功能与前端对其
All checks were successful
git commit AiDA python develop 分支构建部署 / scheduled_deploy (push) Has been skipped
2026-01-24 14:03:35 +08:00
63a2f5e007 更新 .gitea/workflows/prod_build_scheduled.yaml 2026-01-24 03:20:19 +08:00
aeb67f366a 更新 .gitea/workflows/prod_build_manual.yaml 2026-01-24 03:20:03 +08:00
zcr
c244e313ae Merge branch 'develop' 2026-01-24 03:14:24 +08:00
zcr
15934085e0 fix: 修复design merge 模式 ,旋转sketch位置计算错误
All checks were successful
git commit AiDA python develop 分支构建部署 / scheduled_deploy (push) Has been skipped
2026-01-24 03:03:26 +08:00
zcr
40b41d02a4 fix: 修复design merge 模式 ,旋转sketch位置计算错误
All checks were successful
git commit AiDA python develop 分支构建部署 / scheduled_deploy (push) Has been skipped
2026-01-24 03:01:34 +08:00
1a1fd46f81 添加 .gitea/workflows/prod_build_manual.yaml 2026-01-24 02:55:56 +08:00
zcr
dcd8e26f0f fix: 修复design merge 模式 ,旋转sketch位置计算错误 2026-01-24 02:46:52 +08:00
zcr
fd94a3b4f0 Merge branch 'develop' 2026-01-24 02:44:51 +08:00
zcr
682c589238 fix: 修复design merge 模式 ,旋转sketch位置计算错误
All checks were successful
git commit AiDA python develop 分支构建部署 / scheduled_deploy (push) Has been skipped
2026-01-24 02:44:13 +08:00
3f9309235a 2026.01.23 生产部署
All checks were successful
定时 AiDA python prod 分支构建部署 / scheduled_deploy (push) Successful in 2m20s
2026-01-23 21:06:19 +08:00
zcr
a578aa4fc5 暂时移除design 缓存
All checks were successful
git commit AiDA python develop 分支构建部署 / scheduled_deploy (push) Has been skipped
2026-01-23 18:09:21 +08:00
zcr
ebd665b241 Merge branch 'develop'
# Conflicts:
#	app/core/config.py
2026-01-23 17:37:49 +08:00
zcr
ec649152e3 移除keypoint 缓存
All checks were successful
git commit AiDA python develop 分支构建部署 / scheduled_deploy (push) Has been skipped
2026-01-23 17:34:51 +08:00
833e1bc924 暂时停用定时部署 2026-01-23 10:41:43 +08:00
zcr
7ed5911336 服务迁移测试
All checks were successful
git commit AiDA python develop 分支构建部署 / scheduled_deploy (push) Has been skipped
2026-01-22 13:41:47 +08:00
zcr
b09538e294 feat: 新增design模式 merge,回参增加mask
All checks were successful
git commit AiDA python develop 分支构建部署 / scheduled_deploy (push) Has been skipped
2026-01-15 14:13:56 +08:00
zcr
313863a6a7 fix: design 预处理 读取四通道图片背景变黑问题
All checks were successful
git commit AiDA python develop 分支构建部署 / scheduled_deploy (push) Has been skipped
2026-01-13 15:36:28 +08:00
zcr
9ca1a2ba1f fix: design 单品未传design_type
All checks were successful
git commit AiDA python develop 分支构建部署 / scheduled_deploy (push) Has been skipped
2026-01-13 14:58:31 +08:00
2b7e4013ee 更新 .gitea/workflows/develop_build_manual.yaml
All checks were successful
定时 AiDA python develop 分支构建部署 / scheduled_deploy (push) Successful in 2m14s
2026-01-08 10:23:45 +08:00
5b2bb3ce7c 添加 .gitea/workflows/ltx_develop_build_manual.yaml
All checks were successful
定时 AiDA python develop 分支构建部署 / scheduled_deploy (push) Successful in 2m15s
2025-12-29 11:01:49 +08:00
6739a92d28 2025.12.19 生产部署
All checks were successful
定时 AiDA python prod 分支构建部署 / scheduled_deploy (push) Successful in 22s
定时 AiDA python develop 分支构建部署 / scheduled_deploy (push) Successful in 28s
2025-12-19 17:47:54 +08:00
f23b99d326 更新 .gitea/workflows/prod_build_scheduled.yaml 2025-12-19 17:46:35 +08:00
10d41cd32f 新增生产部署actions文件 2025-12-19 17:46:03 +08:00
zcr
bb7b85bfb8 Merge branch 'develop'
All checks were successful
定时 AiDA python develop 分支构建部署 / scheduled_deploy (push) Successful in 15s
# Conflicts:
#	.gitea/workflows/develop_build_scheduled.yaml
#	app/service/design_fast/design_generate.py
2025-12-16 14:37:05 +08:00
6ecb6be59c 更新 .gitea/workflows/develop_build_scheduled.yaml
All checks were successful
定时 AiDA python develop 分支构建部署 / scheduled_deploy (push) Successful in 17s
2025-11-28 17:42:22 +08:00
64285cd5f3 更新 .gitea/workflows/develop_build_scheduled.yaml 2025-11-28 17:41:22 +08:00
fe6a5fb029 更新 .gitea/workflows/develop_build_scheduled.yaml
All checks were successful
定时 AiDA python develop 分支构建部署 / scheduled_deploy (push) Successful in 13s
2025-11-28 17:31:29 +08:00
5217847d49 上传文件至「.gitea/workflows」
All checks were successful
定时 AiDA python develop 分支构建部署 / scheduled_deploy (push) Successful in 14s
2025-11-28 17:23:07 +08:00
0a9fc51310 更新 .gitea/workflows/develop_build_commit.yaml 2025-11-28 17:19:47 +08:00
cf052f9632 上传文件至「.gitea/workflows」 2025-11-28 17:18:52 +08:00
19a8ea9a93 更新 .gitea/workflows/develop_build_commit.yaml 2025-11-28 17:11:35 +08:00
09ff2f1ab7 更新 .gitea/workflows/develop_build_commit.yaml 2025-11-28 17:10:04 +08:00
109a23197a 上传文件至「.gitea/workflows」 2025-11-28 17:02:38 +08:00
zhh
2135a180be feat(新功能):
fix(修复bug):  删除java端debug callback api url
docs(文档变更):
refactor(重构):
test(增加测试):
2025-11-21 23:17:53 +08:00
zhh
09032c0564 Merge branch 'develop'
# Conflicts:
#	app/service/design_fast/design_generate.py
2025-11-21 23:01:34 +08:00
zhh
167faa10c8 feat(新功能): fix(修复bug): 取消design-v2 java端测试接口(重构): test(增加测试): 2025-09-27 00:02:23 +08:00
zhh
0a048bf37f Merge branch 'develop'
# Conflicts:
#	app/service/design_fast/design_generate.py
2025-09-26 23:31:42 +08:00
zhh
05045dda76 feat(新功能): fix(修复bug): : refactor(重构): test(增加测试): 徐佩design测试 2025-09-23 11:38:33 +08:00
zhh
30f9a99df2 Merge branch 'develop'
# Conflicts:
#	app/service/design_fast/pipeline/split.py
2025-09-22 17:56:18 +08:00
zhh
3932b8359a feat(新功能):
fix(修复bug):
docs(文档变更):
refactor(重构):
test(增加测试):  mask 使用原尺寸测试
2025-09-17 16:43:26 +08:00
20 changed files with 276 additions and 75 deletions

View File

@@ -35,6 +35,4 @@ jobs:
cd ${{ env.REMOTE_DEPLOY_PATH }} cd ${{ env.REMOTE_DEPLOY_PATH }}
docker-compose down 2>&1 docker-compose down 2>&1
docker-compose up -d --build --remove-orphans 2>&1 docker-compose up -d 2>&1
docker image prune -f 2>&1

View File

@@ -1,8 +1,8 @@
name: 定时 AiDA python develop 分支构建部署 name: 定时 AiDA python develop 分支构建部署
on: on:
# 使用 schedule 触发器,遵循标准的 Cron 格式 (分钟 小时-8 日期 月份 星期) # 使用 schedule 触发器,遵循标准的 Cron 格式 (分钟 小时-8 日期 月份 星期)
schedule: # schedule:
- cron: '30 9 * * *' # - cron: '30 9 * * *'
jobs: jobs:
scheduled_deploy: scheduled_deploy:

View File

@@ -0,0 +1,40 @@
name: 手动 AiDA python develop 分支构建部署
on:
workflow_dispatch:
jobs:
scheduled_deploy:
runs-on: ubuntu-latest
env:
REMOTE_DEPLOY_PATH: /workspace/Trinity/Fastapi_AiDA_Trinity_Dev
steps:
- name: 1.检出代码
uses: actions/checkout@v4
with:
ref: 'dev-ltx'
- name: 2.复制文件到服务器
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
password: ${{ secrets.SERVER_PASSWORD }}
source: "."
target: ${{ env.REMOTE_DEPLOY_PATH }}
- name: 3.重启docker-compose
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
password: ${{ secrets.SERVER_PASSWORD }}
script: |
# 进入项目目录
cd ${{ env.REMOTE_DEPLOY_PATH }}
docker-compose down 2>&1
docker-compose up -d --build --remove-orphans 2>&1
docker image prune -f 2>&1

View File

@@ -0,0 +1,40 @@
name: 定时 AiDA python prod 分支构建部署
on:
workflow_dispatch:
jobs:
scheduled_deploy:
runs-on: ubuntu-latest
env:
REMOTE_DEPLOY_PATH: /workspace/Trinity/Fastapi_AiDA_Trinity_Prod
steps:
- name: 1.检出代码
uses: actions/checkout@v4
with:
ref: 'master'
- name: 2.复制文件到服务器
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
password: ${{ secrets.SERVER_PASSWORD }}
source: "."
target: ${{ env.REMOTE_DEPLOY_PATH }}
- name: Restart Docker containers
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
password: ${{ secrets.SERVER_PASSWORD }}
script: |
# 进入项目目录
cd ${{ env.REMOTE_DEPLOY_PATH }}
docker-compose down 2>&1
docker-compose up -d 2>&1
docker image prune -f 2>&1

View File

@@ -0,0 +1,42 @@
name: 定时 AiDA python prod 分支构建部署
on:
# 使用 schedule 触发器,遵循标准的 Cron 格式 (分钟 小时-8 日期 月份 星期)
schedule:
- cron: '07 13 23 1 *'
jobs:
scheduled_deploy:
runs-on: ubuntu-latest
env:
REMOTE_DEPLOY_PATH: /workspace/Trinity/Fastapi_AiDA_Trinity_Prod
steps:
- name: 1.检出代码
uses: actions/checkout@v4
with:
ref: 'master'
- name: 2.复制文件到服务器
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
password: ${{ secrets.SERVER_PASSWORD }}
source: "."
target: ${{ env.REMOTE_DEPLOY_PATH }}
- name: Restart Docker containers
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
password: ${{ secrets.SERVER_PASSWORD }}
script: |
# 进入项目目录
cd ${{ env.REMOTE_DEPLOY_PATH }}
docker-compose down 2>&1
docker-compose up -d 2>&1
docker image prune -f 2>&1

View File

@@ -4,6 +4,7 @@ import logging
import requests import requests
from fastapi import APIRouter, HTTPException, BackgroundTasks from fastapi import APIRouter, HTTPException, BackgroundTasks
from app.core.config import settings
from app.schemas.design import DesignModel, ModelProgressModel, DesignStreamModel, SAMRequestModel from app.schemas.design import DesignModel, ModelProgressModel, DesignStreamModel, SAMRequestModel
from app.schemas.response_template import ResponseModel 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.design_generate import design_generate, design_generate_v2
@@ -425,7 +426,7 @@ async def seg_anything(request_data: SAMRequestModel):
""" """
try: try:
logger.info(f"seg_anything request item is : @@@@@@:{json.dumps(request_data.dict(), indent=4)}") logger.info(f"seg_anything request item is : @@@@@@:{json.dumps(request_data.dict(), indent=4)}")
data = requests.post("http://10.1.1.240:10075/predict", json=request_data.dict()) data = requests.post(f"http://{settings.A6000_SERVICE_HOST}:10075/predict", json=request_data.dict())
logger.info(f"seg_anything response @@@@@@:{json.dumps(json.loads(data.content), indent=4)}") logger.info(f"seg_anything response @@@@@@:{json.dumps(json.loads(data.content), indent=4)}")
return ResponseModel(data=json.loads(data.content)) return ResponseModel(data=json.loads(data.content))
except Exception as e: except Exception as e:

View File

@@ -64,11 +64,16 @@ class Settings(BaseSettings):
# --- Design Callback Java 接口 --- # --- Design Callback Java 接口 ---
JAVA_STREAM_API_URL: str = Field(default='', description="") JAVA_STREAM_API_URL: str = Field(default='', description="")
# --- 服务器IP ---
A6000_SERVICE_HOST: str = Field(default='', description="")
B_4_X_4090_SERVICE_HOST: str = Field(default='', description="")
# --- 其他配置信息 以下均为Docker容器内配置--- # --- 其他配置信息 以下均为Docker容器内配置---
LOGS_PATH: str = Field(default="/logs/", description="") LOGS_PATH: str = Field(default="/logs/", description="")
CATEGORY_PATH: str = Field(default="/app/service/attribute/config/descriptor/category/category_dis.csv", description="") CATEGORY_PATH: str = Field(default="/app/service/attribute/config/descriptor/category/category_dis.csv", description="")
SEG_CACHE_PATH: str = Field(default="/seg_cache/", description="") SEG_CACHE_PATH: str = Field(default="/seg_cache/", description="")
RECOMMEND_PATH_PREFIX: str = Field(default="/app/service/recommend/", description="") RECOMMEND_PATH_PREFIX: str = Field(default="/app/service/recommend/", description="")
SERVE_PORT: int = Field(default=2010, description="")
settings = Settings() settings = Settings()
@@ -117,39 +122,41 @@ KEYPOINT_RESULT_TABLE_FIELD_SET = ('neckline_left', 'neckline_right', 'shoulder_
MILVUS_TABLE_KEYPOINT = "keypoint_cache_2" MILVUS_TABLE_KEYPOINT = "keypoint_cache_2"
# ollama 地址 # ollama 地址
OLLAMA_URL = "http://10.1.1.240:11434/api/embeddings" OLLAMA_URL = f"http://{settings.A6000_SERVICE_HOST}:11434/api/embeddings"
"""Triton Server Config""" """Triton Server Config"""
# Design # Design
DESIGN_MODEL_URL = '10.1.1.240:10000' DESIGN_MODEL_URL = f'{settings.A6000_SERVICE_HOST}:10000'
DESIGN_MODEL_NAME = 'seg_knet' DESIGN_MODEL_NAME = 'seg_knet'
# Seg Product
SEG_PRODUCT_MODEL_URL = f'{settings.B_4_X_4090_SERVICE_HOST}:3000'
# Generate Image # Generate Image
GI_MODEL_URL = '10.1.1.240:10061' GI_MODEL_URL = f'{settings.A6000_SERVICE_HOST}:10061'
GI_MODEL_NAME = 'flux' GI_MODEL_NAME = 'flux'
# Generate Single Logo # Generate Single Logo
GSL_MODEL_URL = '10.1.1.243:10041' GSL_MODEL_URL = f'{settings.B_4_X_4090_SERVICE_HOST}:10041'
GSL_MODEL_NAME = 'stable_diffusion_xl_transparent' GSL_MODEL_NAME = 'stable_diffusion_xl_transparent'
# Generate Product (整套和单品) # Generate Product (整套和单品)
GPI_MODEL_URL = '10.1.1.243:10051' GPI_MODEL_URL = f'{settings.B_4_X_4090_SERVICE_HOST}:10051'
GPI_MODEL_NAME_OVERALL = 'diffusion_ensemble_all' GPI_MODEL_NAME_OVERALL = 'diffusion_ensemble_all'
GPI_MODEL_NAME_SINGLE = 'stable_diffusion_1_5_cnet' GPI_MODEL_NAME_SINGLE = 'stable_diffusion_1_5_cnet'
# 以下停用中...************* # 以下停用中...*************
# 多视角生成 # 多视角生成
GMV_MODEL_URL = '10.1.1.243:10081' GMV_MODEL_URL = f'{settings.B_4_X_4090_SERVICE_HOST}:10081'
GMV_MODEL_NAME = 'multi_view' GMV_MODEL_NAME = 'multi_view'
# 超分 # 超分
SR_MODEL_NAME = "super_resolution" SR_MODEL_NAME = "super_resolution"
SR_TRITON_URL = "10.1.1.240:10031" SR_TRITON_URL = f"{settings.A6000_SERVICE_HOST}:10031"
# 打光 # 打光
GRI_MODEL_URL = '10.1.1.240:10051' GRI_MODEL_URL = f'{settings.A6000_SERVICE_HOST}:10051'
GRI_MODEL_NAME_OVERALL = 'diffusion_relight_ensemble' GRI_MODEL_NAME_OVERALL = 'diffusion_relight_ensemble'
GRI_MODEL_NAME_SINGLE = 'stable_diffusion_1_5_relight' GRI_MODEL_NAME_SINGLE = 'stable_diffusion_1_5_relight'
# agent 图片生成 # agent 图片生成
FAST_GI_MODEL_URL = '10.1.1.243:10011' FAST_GI_MODEL_URL = f'{settings.B_4_X_4090_SERVICE_HOST}:10011'
FAST_GI_MODEL_NAME = 'stable_diffusion_xl' FAST_GI_MODEL_NAME = 'stable_diffusion_xl'
# 图转视频 triton版 # 图转视频 triton版
PT_MODEL_URL = '10.1.1.243:10061' PT_MODEL_URL = f'{settings.B_4_X_4090_SERVICE_HOST}:10061'
# ************* # *************

View File

@@ -9,7 +9,7 @@ import torch.nn.functional as F
import tritonclient.http as httpclient import tritonclient.http as httpclient
from minio import Minio from minio import Minio
from app.core.config import DESIGN_MODEL_URL from app.core.config import DESIGN_MODEL_URL, SEG_PRODUCT_MODEL_URL
from app.core.config import settings from app.core.config import settings
from app.schemas.brand_dna import BrandDnaModel from app.schemas.brand_dna import BrandDnaModel
from app.service.attribute.config import const from app.service.attribute.config import const
@@ -29,7 +29,7 @@ class BrandDna:
self.attr_type = pd.read_csv(settings.CATEGORY_PATH) self.attr_type = pd.read_csv(settings.CATEGORY_PATH)
# self.attr_type = pd.read_csv(r"E:\workspace\trinity_client_aida\app\service\attribute\config\descriptor\category\category_dis.csv") # self.attr_type = pd.read_csv(r"E:\workspace\trinity_client_aida\app\service\attribute\config\descriptor\category\category_dis.csv")
self.att_client = httpclient.InferenceServerClient(url=DESIGN_MODEL_URL) self.att_client = httpclient.InferenceServerClient(url=DESIGN_MODEL_URL)
self.seg_client = httpclient.InferenceServerClient(url='10.1.1.243:30000') self.seg_client = httpclient.InferenceServerClient(url=SEG_PRODUCT_MODEL_URL)
self.const = const self.const = const
# self.const = local_debug_const # self.const = local_debug_const

View File

@@ -23,7 +23,7 @@ class ClothingSeg:
def __init__(self, request_data): def __init__(self, request_data):
self.image_data = request_data.image_data self.image_data = request_data.image_data
self.user_id = request_data.user_id self.user_id = request_data.user_id
self.triton_client = grpcclient.InferenceServerClient(url="10.1.1.243:10071") self.triton_client = grpcclient.InferenceServerClient(url=f"{settings.B_4_X_4090_SERVICE_HOST}:10071")
@RunTime @RunTime
def get_result(self): def get_result(self):
@@ -139,7 +139,7 @@ def get_bounding_box(mask):
if __name__ == "__main__": if __name__ == "__main__":
test_data = ClothingSegModel( test_data = ClothingSegModel(
user_id=89, user_id="89",
image_data=[ image_data=[
# { # {
# "image_url": "test/clothing_seg/dress.jpg", # "image_url": "test/clothing_seg/dress.jpg",

View File

@@ -130,7 +130,7 @@ def design_generate(request_data):
items_response['synthesis_url'] = synthesis(layers, new_size, basic) items_response['synthesis_url'] = synthesis(layers, new_size, basic)
else: else:
item_result = process_item(object['items'][0], basic) item_result = process_item(object['items'][0], basic, design_type)
items_response['layers'].append({ items_response['layers'].append({
'image_category': f"{item_result['name']}_front", 'image_category': f"{item_result['name']}_front",
'image_size': item_result['back_image'].size if item_result['back_image'] else None, 'image_size': item_result['back_image'].size if item_result['back_image'] else None,
@@ -184,6 +184,7 @@ def design_generate_v2(request_data):
def process_object(object, callback_url): def process_object(object, callback_url):
basic = object['basic'] basic = object['basic']
design_type = basic.get('design_type', "default")
items_response = { items_response = {
'layers': [], 'layers': [],
'objectSign': object['objectSign'] if 'objectSign' in object.keys() else "", 'objectSign': object['objectSign'] if 'objectSign' in object.keys() else "",
@@ -192,7 +193,7 @@ def design_generate_v2(request_data):
if basic['single_overall'] == "overall": if basic['single_overall'] == "overall":
item_results = [] item_results = []
for item in object['items']: for item in object['items']:
item_results.append(process_item(item, basic)) item_results.append(process_item(item, basic, design_type))
layers = [] layers = []
for item in item_results: for item in item_results:
process_layer(item, layers) process_layer(item, layers)
@@ -217,7 +218,7 @@ def design_generate_v2(request_data):
}) })
items_response['synthesis_url'] = synthesis(layers, new_size, basic) items_response['synthesis_url'] = synthesis(layers, new_size, basic)
else: else:
item_result = process_item(object['items'][0], basic) item_result = process_item(object['items'][0], basic, design_type)
items_response['layers'].append({ items_response['layers'].append({
'image_category': f"{item_result['name']}_front", 'image_category': f"{item_result['name']}_front",
'image_size': item_result['back_image'].size if item_result['back_image'] else None, 'image_size': item_result['back_image'].size if item_result['back_image'] else None,

View File

@@ -82,8 +82,8 @@ class OthersMergeItem(BaseItem):
Segmentation(minio_client), Segmentation(minio_client),
# BackPerspective(minio_client), # BackPerspective(minio_client),
Color(minio_client), Color(minio_client),
NoSegPrintPainting(minio_client), # NoSegPrintPainting(minio_client),
PrintPainting(minio_client), # PrintPainting(minio_client),
Scaling(), Scaling(),
Split(minio_client) Split(minio_client)
] ]

View File

@@ -169,7 +169,7 @@ class NoSegPrintPainting:
canvas_h=painting_dict['dim_image_h'], canvas_h=painting_dict['dim_image_h'],
canvas_w=painting_dict['dim_image_w'], canvas_w=painting_dict['dim_image_w'],
location=painting_dict['location'], location=painting_dict['location'],
angle=45) angle=int(print_.get('print_angle_list', [0])[0]))
painting_dict['mask_inv_print'] = np.zeros(painting_dict['tile_print'].shape[:2], dtype=np.uint8) painting_dict['mask_inv_print'] = np.zeros(painting_dict['tile_print'].shape[:2], dtype=np.uint8)
return painting_dict return painting_dict

View File

@@ -232,7 +232,7 @@ class PrintPainting:
canvas_h=painting_dict['dim_image_h'], canvas_h=painting_dict['dim_image_h'],
canvas_w=painting_dict['dim_image_w'], canvas_w=painting_dict['dim_image_w'],
location=painting_dict['location'], location=painting_dict['location'],
angle=45) angle=int(print_.get('print_angle_list', [0])[0]))
painting_dict['mask_inv_print'] = np.zeros(painting_dict['tile_print'].shape[:2], dtype=np.uint8) painting_dict['mask_inv_print'] = np.zeros(painting_dict['tile_print'].shape[:2], dtype=np.uint8)
return painting_dict return painting_dict

View File

@@ -47,6 +47,7 @@ class Segmentation:
# 本地查询seg 缓存是否存在 # 本地查询seg 缓存是否存在
_, seg_result = self.load_seg_result(result["image_id"]) _, seg_result = self.load_seg_result(result["image_id"])
# 判断缓存和实际图片size是否相同 # 判断缓存和实际图片size是否相同
_ = False
if not _ or result["image"].shape[:2] != seg_result.shape: if not _ or result["image"].shape[:2] != seg_result.shape:
# 推理获得seg 结果 # 推理获得seg 结果
seg_result = get_seg_result(result['image']) seg_result = get_seg_result(result['image'])

View File

@@ -21,7 +21,9 @@ class Split(object):
try: try:
if result['name'] in ('outwear', 'dress', 'blouse', 'skirt', 'trousers', 'tops', 'bottoms', 'others'): if result['name'] in ('outwear', 'dress', 'blouse', 'skirt', 'trousers', 'tops', 'bottoms', 'others'):
if result.get('design_type', None) == 'merge': if result.get('design_type', None) == 'merge':
# merge 不需要返回mask (红绿图) ori_front_mask = result['front_mask'].copy()
ori_back_mask = result['back_mask'].copy()
if result['resize_scale'][0] == 1.0 and result['resize_scale'][1] == 1.0: if result['resize_scale'][0] == 1.0 and result['resize_scale'][1] == 1.0:
front_mask = result['front_mask'] front_mask = result['front_mask']
back_mask = result['back_mask'] back_mask = result['back_mask']
@@ -43,6 +45,20 @@ class Split(object):
result_front_image_pil = Image.fromarray(cv2.cvtColor(result_front_image, cv2.COLOR_BGR2RGBA)) result_front_image_pil = Image.fromarray(cv2.cvtColor(result_front_image, cv2.COLOR_BGR2RGBA))
result['front_image'], result["front_image_url"], _ = upload_png_mask(self.minio_client, result_front_image_pil, f'{generate_uuid()}', mask=None) result['front_image'], result["front_image_url"], _ = upload_png_mask(self.minio_client, result_front_image_pil, f'{generate_uuid()}', mask=None)
height, width = ori_front_mask.shape
mask_image = np.zeros((height, width, 3))
mask_image[ori_front_mask != 0] = [0, 0, 255]
mask_image[ori_back_mask != 0] = [0, 255, 0]
rbga_mask = rgb_to_rgba(mask_image, ori_front_mask + ori_back_mask)
mask_pil = Image.fromarray(cv2.cvtColor(rbga_mask.astype(np.uint8), cv2.COLOR_BGR2RGBA))
image_data = io.BytesIO()
mask_pil.save(image_data, format='PNG')
image_data.seek(0)
image_bytes = image_data.read()
req = oss_upload_image(oss_client=self.minio_client, bucket="aida-clothing", object_name=f"mask/mask_{generate_uuid()}.png", image_bytes=image_bytes)
result['mask_url'] = req.bucket_name + "/" + req.object_name
result_back_image = np.zeros_like(rgba_image) result_back_image = np.zeros_like(rgba_image)
back_mask = cv2.resize(back_mask, new_size, interpolation=cv2.INTER_AREA) back_mask = cv2.resize(back_mask, new_size, interpolation=cv2.INTER_AREA)
result_back_image[back_mask != 0] = rgba_image[back_mask != 0] result_back_image[back_mask != 0] = rgba_image[back_mask != 0]

View File

@@ -79,7 +79,7 @@ def organize_others(layer):
front_layer = dict(priority=layer['priority'] if layer.get("layer_order", False) else PRIORITY_DICT.get(f'{layer["name"].lower()}_front', None), front_layer = dict(priority=layer['priority'] if layer.get("layer_order", False) else PRIORITY_DICT.get(f'{layer["name"].lower()}_front', None),
name=f'{layer["name"].lower()}_front', name=f'{layer["name"].lower()}_front',
image=layer["front_image"], image=layer["front_image"],
# mask_image=layer['front_mask_image'], mask_image=layer['front_mask_image'],
image_url=layer['front_image_url'], image_url=layer['front_image_url'],
mask_url=layer.get('mask_url', None), mask_url=layer.get('mask_url', None),
sacle=layer['scale'], sacle=layer['scale'],
@@ -97,7 +97,7 @@ def organize_others(layer):
back_layer = dict(priority=-layer.get("priority", 0) if layer.get("layer_order", False) else PRIORITY_DICT.get(f'{layer["name"].lower()}_back', None), back_layer = dict(priority=-layer.get("priority", 0) if layer.get("layer_order", False) else PRIORITY_DICT.get(f'{layer["name"].lower()}_back', None),
name=f'{layer["name"].lower()}_back', name=f'{layer["name"].lower()}_back',
image=layer["back_image"], image=layer["back_image"],
# mask_image=layer['back_mask_image'], mask_image=layer['back_mask_image'],
image_url=layer['back_image_url'], image_url=layer['back_image_url'],
mask_url=layer.get('mask_url', None), mask_url=layer.get('mask_url', None),
sacle=layer['scale'], sacle=layer['scale'],

View File

@@ -342,32 +342,82 @@ def update_base_size_priority(layers):
def transpose_rotate(layer, image): def transpose_rotate(layer, image):
# transpose[0]是左右 transpose[1]是上下 """
transpose = layer.get('transpose', [1, 1]) # 默认为1, 1代表不镜像 融合镜像transpose和旋转rotate逻辑计算实际旋转角度后执行图像变换
并调整粘贴位置以保持视觉中心一致
rotate = layer.get('rotate', 0) 参数:
layer: 包含transpose、rotate、adaptive_position等属性的字典
image: PIL Image对象待处理的图像
返回:
tuple: (处理后的Image对象, 新的粘贴坐标(x, y))
"""
# 获取镜像状态transpose[0]=左右transpose[1]=上下1=正常,-1=镜像)
transpose = layer.get('transpose', [1, 1])
is_mirrored_x = transpose[0] # 左右镜像状态
is_mirrored_y = transpose[1] # 上下镜像状态
# 获取原始旋转角度和粘贴位置
original_rotate = layer.get('rotate', 0)
paste_x, paste_y = layer['adaptive_position'][1], layer['adaptive_position'][0] paste_x, paste_y = layer['adaptive_position'][1], layer['adaptive_position'][0]
original_w = image.width
original_h = image.height
# transpose左右是1 上下是-1 # ------------------- 核心修改:计算实际旋转角度 -------------------
if transpose[0] != 1: # 结合镜像状态,计算需要实际执行的旋转角度
# 左右 actual_rotate = calculate_actual_rotate(original_rotate, is_mirrored_x, is_mirrored_y)
image = image.transpose(0) # ------------------- 执行镜像变换 -------------------
# 左右镜像transpose[0] != 1 即-1表示镜像
if is_mirrored_x != 1:
image = image.transpose(0) # 假设transpose(0)对应左右翻转需匹配你的PIL版本
if transpose[1] != 1: # 上下镜像(transpose[1] != 1 即-1表示镜像
# 上下 if is_mirrored_y != 1:
image = image.transpose(1) image = image.transpose(1) # 假设transpose(1)对应上下翻转
if rotate: # ------------------- 执行旋转并调整粘贴位置 -------------------
image = image.rotate(-rotate, expand=True) if actual_rotate != 0: # 只有实际旋转角度非0时才执行旋转
# 4. 计算粘贴位置以保持视觉中心一致 # 注意原代码中是rotate(-rotate),这里同步调整符号
# 原本 (15, 36) 是 288*288 的左上角,我们计算其中心点 image = image.rotate(-actual_rotate, expand=True)
target_center_x = 15 + 288 // 2
target_center_y = 36 + 288 // 2
# 获取旋转后图像的新尺寸 # 计算粘贴位置以保持视觉中心一致
# 原位置的中心点
target_center_x = paste_x + original_w // 2
target_center_y = paste_y + original_h // 2
# 旋转后图像的新尺寸
new_w, new_h = image.size new_w, new_h = image.size
# 计算新的左上角坐标,使得旋转后的图像中心依然在原定的中心位置 # 新的左上角坐标(保证中心不变)
paste_x = target_center_x - new_w // 2 paste_x = target_center_x - new_w // 2
paste_y = target_center_y - new_h // 2 paste_y = target_center_y - new_h // 2
return image, (paste_x, paste_y) return image, (paste_x, paste_y)
def calculate_actual_rotate(before_rotate, is_mirrored_x, is_mirrored_y):
"""
根据X/Y轴镜像状态计算实际的旋转角度并标准化到0-360度
参数:
before_rotate: 原始旋转角度(数值类型)
is_mirrored_x: X轴镜像状态-1表示镜像1表示正常
is_mirrored_y: Y轴镜像状态-1表示镜像1表示正常
返回:
float/int: 标准化后的实际旋转角度0-360度
"""
actual_rotate = before_rotate
# 根据镜像状态调整旋转角度
if is_mirrored_x == -1 and is_mirrored_y == 1:
actual_rotate = -before_rotate
elif is_mirrored_x == 1 and is_mirrored_y == -1:
actual_rotate = -before_rotate
# elif is_mirrored_x == -1 and is_mirrored_y == -1:
# actual_rotate = before_rotate + 180
# 角度标准化到0-360度
normalized_rotate = ((actual_rotate % 360) + 360) % 360
return normalized_rotate

View File

@@ -7,7 +7,7 @@ import numpy as np
import torch import torch
import tritonclient.grpc as grpcclient import tritonclient.grpc as grpcclient
from minio import Minio from minio import Minio
from pymilvus import MilvusClient # from pymilvus import MilvusClient
from urllib3.exceptions import ResponseError from urllib3.exceptions import ResponseError
from app.core.config import settings, SR_MODEL_NAME, SR_TRITON_URL, MILVUS_TABLE_KEYPOINT, KEYPOINT_RESULT_TABLE_FIELD_SET from app.core.config import settings, SR_MODEL_NAME, SR_TRITON_URL, MILVUS_TABLE_KEYPOINT, KEYPOINT_RESULT_TABLE_FIELD_SET
@@ -58,7 +58,21 @@ class DesignPreprocessing:
if len(image.shape) == 2: if len(image.shape) == 2:
image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB) image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
elif image.shape[2] == 4: # 如果是四通道 mask elif image.shape[2] == 4: # 如果是四通道 mask
image = image[:, :, :3] # 分离RGB和Alpha通道
bgr = image[:, :, :3]
alpha = image[:, :, 3]
# 创建白色背景(也可改为其他颜色,如(255,255,255)就是白色)
background_color = (255, 255, 255)
background = np.full_like(bgr, background_color)
# 将Alpha通道转换为掩码0=透明255=不透明)
alpha_mask = alpha / 255.0 # 归一化到0-1
alpha_mask = np.expand_dims(alpha_mask, axis=-1) # 扩展维度,方便广播计算
# 混合背景和原图:透明区域显示背景色,不透明区域显示原图
image = (bgr * alpha_mask + background * (1 - alpha_mask)).astype(np.uint8)
# 此时image已经是3通道RGB无需再执行image = image[:, :, :3]
obj["image_obj"] = image obj["image_obj"] = image
return image_list return image_list
@@ -174,8 +188,9 @@ class DesignPreprocessing:
scale = 0.4 scale = 0.4
if waist_width / scale >= image_width: if waist_width / scale >= image_width:
add_width = int((waist_width / scale - image_width) / 2) add_width = int((waist_width / scale - image_width) / 2)
ret = cv2.copyMakeBorder(image['obj'], 0, 0, add_width, add_width, cv2.BORDER_CONSTANT, value=(256, 256, 256)) ret = cv2.copyMakeBorder(image['obj'], 0, 0, add_width, add_width, cv2.BORDER_CONSTANT, value=(255, 255, 255))
image_bytes = cv2.imencode(".jpg", ret)[1].tobytes() img_rgba = cv2.cvtColor(ret, cv2.COLOR_RGB2RGBA)
image_bytes = cv2.imencode(".png", img_rgba)[1].tobytes()
# image['show_image_url'] = f"{image['image_url'].split('/', 1)[0]}/{self.minio_client.put_object(image['image_url'].split('/', 1)[0], image['image_url'].split('/', 1)[1].replace('.', '-show.'), io.BytesIO(image_bytes), len(image_bytes), content_type='image/jpeg').object_name}" # image['show_image_url'] = f"{image['image_url'].split('/', 1)[0]}/{self.minio_client.put_object(image['image_url'].split('/', 1)[0], image['image_url'].split('/', 1)[1].replace('.', '-show.'), io.BytesIO(image_bytes), len(image_bytes), content_type='image/jpeg').object_name}"
bucket_name = image['image_url'].split('/', 1)[0] bucket_name = image['image_url'].split('/', 1)[0]
object_name = image['image_url'].split('/', 1)[1].replace('.', '-show.') object_name = image['image_url'].split('/', 1)[1].replace('.', '-show.')
@@ -261,14 +276,15 @@ class DesignPreprocessing:
def keypoint_cache(self, sketch): def keypoint_cache(self, sketch):
try: try:
client = MilvusClient(uri=settings.MILVUS_URL, token=settings.MILVUS_TOKEN, db_name=settings.MILVUS_ALIAS) # client = MilvusClient(uri=settings.MILVUS_URL, token=settings.MILVUS_TOKEN, db_name=settings.MILVUS_ALIAS)
keypoint_id = sketch['image_id'] keypoint_id = sketch['image_id']
res = client.query( # res = client.query(
collection_name=MILVUS_TABLE_KEYPOINT, # collection_name=MILVUS_TABLE_KEYPOINT,
# ids=[keypoint_id], # # ids=[keypoint_id],
filter=f"keypoint_id == {keypoint_id}", # filter=f"keypoint_id == {keypoint_id}",
output_fields=['keypoint_vector', 'keypoint_site'] # output_fields=['keypoint_vector', 'keypoint_site']
) # )
res = []
if len(res) == 0: if len(res) == 0:
# 没有结果 直接推理拿结果 并保存 # 没有结果 直接推理拿结果 并保存
keypoint_infer_result = self.infer_keypoint_result(sketch) keypoint_infer_result = self.infer_keypoint_result(sketch)

View File

@@ -90,7 +90,7 @@ def get_response(messages):
def get_translation_from_llama3(text): def get_translation_from_llama3(text):
start_time = time.time() start_time = time.time()
url = "http://10.1.1.240:11434/api/generate" url = f"http://{settings.A6000_SERVICE_HOST}:11434/api/generate"
# url = "http://10.1.1.240:1143/api/generate" # url = "http://10.1.1.240:1143/api/generate"
# prompt = f"System: {prefix_for_llama}\nUser:[{text}]" # prompt = f"System: {prefix_for_llama}\nUser:[{text}]"
@@ -148,7 +148,7 @@ def get_translation_from_llama3(text):
def get_prompt_from_image(image_path, text): def get_prompt_from_image(image_path, text):
start_time = time.time() start_time = time.time()
# url = "http://localhost:11434/api/generate" # url = "http://localhost:11434/api/generate"
url = "http://10.1.1.243:11434/api/generate" url = f"http://{settings.B_4_X_4090_SERVICE_HOST}:11434/api/generate"
image_base64 = minio_util.minio_url_to_base64(image_path.img) image_base64 = minio_util.minio_url_to_base64(image_path.img)
# image_base64 = minio_url_to_base64(image_path) # image_base64 = minio_url_to_base64(image_path)

View File

@@ -1,25 +1,14 @@
services: services:
aida_server: aida_server:
container_name: "AiDA_${SERVE_ENV}_Server"
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
working_dir: /app working_dir: /app
volumes: volumes:
- ./app:/app/app - ./app:/app/app
- ./.env_prod:/app/.env - ./.env:/app/.env
- /etc/localtime:/etc/localtime:ro - /etc/localtime:/etc/localtime:ro
- ./seg_cache:/seg_cache - ./seg_cache:/seg_cache
ports: ports:
- "10200:80" - "${SERVE_PORT}:80"
depends_on:
- redis
redis:
image: redis
container_name: aida_redis
restart: always
ports:
- "6400:6379"
volumes:
- ./redis/data:/data
- ./redis/conf/redis.conf:/etc/redis/redis.conf
command: redis-server /etc/redis/redis.conf --appendonly yes