design batch 代码整理

This commit is contained in:
alab
2024-09-26 06:09:05 +00:00
parent a539923207
commit 04b15aa200
33 changed files with 585 additions and 61 deletions

View File

@@ -6,8 +6,9 @@ from fastapi import APIRouter, HTTPException, UploadFile, File, Form
from app.schemas.design import DesignModel, DesignProgressModel, ModelProgressModel, DBGConfigModel from app.schemas.design import DesignModel, DesignProgressModel, ModelProgressModel, DBGConfigModel
from app.schemas.response_template import ResponseModel from app.schemas.response_template import ResponseModel
from app.service.design.model_process_service import model_transpose from app.service.design_batch.service import start_design_batch_generate
from app.service.design.service_design_batch_generate import start_design_batch_generate # from app.service.design.model_process_service import model_transpose
# from app.service.design.service_design_batch_generate import start_design_batch_generate
from app.service.design_fast.design_generate import design_generate from app.service.design_fast.design_generate import design_generate
from app.service.design_fast.utils.redis_utils import Redis from app.service.design_fast.utils.redis_utils import Redis
@@ -236,7 +237,7 @@ def model_process(request_data: ModelProgressModel):
try: try:
logger.info(f"model_process request item is : @@@@@@:{json.dumps(request_data.dict())}") logger.info(f"model_process request item is : @@@@@@:{json.dumps(request_data.dict())}")
data = model_transpose(image_path=request_data.model_path) # data = model_transpose(image_path=request_data.model_path)
logger.info(f"model_process response @@@@@@:{json.dumps(data)}") logger.info(f"model_process response @@@@@@:{json.dumps(data)}")
except Exception as e: except Exception as e:
logger.warning(f"model_process Run Exception @@@@@@:{e}") logger.warning(f"model_process Run Exception @@@@@@:{e}")
@@ -251,20 +252,18 @@ def model_process(request_data: ModelProgressModel):
async def design(file: UploadFile = File(...), async def design(file: UploadFile = File(...),
tasks_id: str = Form(...), tasks_id: str = Form(...),
user_id: str = Form(...), user_id: str = Form(...),
priority: int = Form(...), file_name: str = Form(...),
total: int = Form(...) total: int = Form(...)
): ):
# file_content = await file.read()
dbg_config = DBGConfigModel( dbg_config = DBGConfigModel(
tasks_id=tasks_id, tasks_id=tasks_id,
user_id=user_id, user_id=user_id,
priority=priority, file_name=file_name,
total=total total=total
) )
contents = await file.read() contents = await file.read()
file_name = file.filename file_name = file.filename
await save_request_file(contents, file_name) await save_request_file(contents, file_name)
return await start_design_batch_generate(dbg_config, contents) return await start_design_batch_generate(dbg_config, contents)

View File

@@ -17,5 +17,5 @@ class ModelProgressModel(BaseModel):
class DBGConfigModel(BaseModel): class DBGConfigModel(BaseModel):
tasks_id: str tasks_id: str
user_id: str user_id: str
priority: int file_name: str
total: int total: int

View File

@@ -0,0 +1,126 @@
import logging
import threading
from celery import Celery
from minio import Minio
from app.core.config import *
from app.service.design_batch.item import BodyItem, TopItem, BottomItem
from app.service.design_batch.utils.MQ import publish_status
from app.service.design_batch.utils.organize import organize_body, organize_clothing
from app.service.design_batch.utils.save_json import oss_upload_json
from app.service.design_batch.utils.synthesis_item import update_base_size_priority, synthesis, synthesis_single
id_lock = threading.Lock()
celery_app = Celery('tasks', broker='amqp://guest:guest@10.1.2.213:5672//', backend='rpc://')
celery_app.conf.worker_log_format = '%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s'
celery_app.conf.worker_hijack_root_logger = False
logging.getLogger('pika').setLevel(logging.WARNING)
logger = logging.getLogger()
minio_client = Minio(MINIO_URL, access_key=MINIO_ACCESS, secret_key=MINIO_SECRET, secure=MINIO_SECURE)
def process_item(item, basic):
# 处理project中单个item
if item['type'] == "Body":
body_server = BodyItem(data=item, basic=basic, minio_client=minio_client)
item_data = body_server.process()
elif item['type'].lower() in ['blouse', 'outwear', 'dress', 'tops']:
top_server = TopItem(data=item, basic=basic, minio_client=minio_client)
item_data = top_server.process()
else:
bottom_server = BottomItem(data=item, basic=basic, minio_client=minio_client)
item_data = bottom_server.process()
return item_data
def process_layer(item, layers):
# item处理结束后 对图层数据组装
if item['name'] == "mannequin":
body_layer = organize_body(item)
layers.append(body_layer)
return item['body_image'].size
else:
front_layer, back_layer = organize_clothing(item)
layers.append(front_layer)
layers.append(back_layer)
@celery_app.task
def batch_design(objects_data, tasks_id, json_name):
object_response = []
threads = []
active_threads = 0
lock = threading.Lock()
def process_object(step, object):
nonlocal active_threads
basic = object['basic']
items_response = {'layers': []}
if basic['single_overall'] == "overall":
item_results = []
for item in object['items']:
item_results.append(process_item(item, basic))
layers = []
body_size = None
for item in item_results:
body_size = process_layer(item, layers)
layers = sorted(layers, key=lambda s: s.get("priority", float('inf')))
layers, new_size = update_base_size_priority(layers, body_size)
for lay in layers:
items_response['layers'].append({
'image_category': lay['name'],
'position': lay['position'],
'priority': lay.get("priority", None),
'resize_scale': lay['resize_scale'] if "resize_scale" in lay.keys() else None,
'image_size': lay['image'] if lay['image'] is None else lay['image'].size,
'gradient_string': lay['gradient_string'] if 'gradient_string' in lay.keys() else "",
'mask_url': lay['mask_url'],
'image_url': lay['image_url'] if 'image_url' in lay.keys() else None,
'pattern_image_url': lay['pattern_image_url'] if 'pattern_image_url' in lay.keys() else None,
})
items_response['synthesis_url'] = synthesis(layers, new_size, basic)
else:
item_result = process_item(object['items'][0], basic)
items_response['layers'].append({
'image_category': f"{item_result['name']}_front",
'image_size': item_result['back_image'].size if item_result['back_image'] else None,
'position': None,
'priority': 0,
'image_url': item_result['front_image_url'],
'mask_url': item_result['mask_url'],
"gradient_string": item_result['gradient_string'] if 'gradient_string' in item_result.keys() else "",
'pattern_image_url': item_result['pattern_image_url'] if 'pattern_image_url' in item_result.keys() else None,
})
items_response['layers'].append({
'image_category': f"{item_result['name']}_back",
'image_size': item_result['front_image'].size if item_result['front_image'] else None,
'position': None,
'priority': 0,
'image_url': item_result['back_image_url'],
'mask_url': item_result['mask_url'],
"gradient_string": item_result['gradient_string'] if 'gradient_string' in item_result.keys() else "",
'pattern_image_url': item_result['pattern_image_url'] if 'pattern_image_url' in item_result.keys() else None,
})
items_response['synthesis_url'] = synthesis_single(item_result['front_image'], item_result['back_image'])
with lock:
object_response.append(items_response)
publish_status(tasks_id, step + 1, items_response)
active_threads -= 1
for step, object in enumerate(objects_data):
t = threading.Thread(target=process_object, args=(step, object))
threads.append(t)
t.start()
with lock:
active_threads += 1
for t in threads:
t.join()
oss_upload_json(minio_client, object_response, json_name)
publish_status(tasks_id, "ok", json_name)
return object_response

View File

@@ -0,0 +1,61 @@
from app.service.design_batch.pipeline import *
class BaseItem:
def __init__(self, data, basic):
self.result = data.copy()
self.result['name'] = data['type'].lower()
self.result.pop("type")
self.result.update(basic)
class TopItem(BaseItem):
def __init__(self, data, basic, minio_client):
super().__init__(data, basic)
self.top_pipeline = [
LoadImage(minio_client),
KeyPoint(),
Segmentation(minio_client),
Color(minio_client),
PrintPainting(minio_client),
Scaling(),
Split(minio_client)
]
def process(self):
for item in self.top_pipeline:
self.result = item(self.result)
return self.result
class BottomItem(BaseItem):
def __init__(self, data, basic, minio_client):
super().__init__(data, basic)
self.bottom_pipeline = [
LoadImage(minio_client),
KeyPoint(),
ContourDetection(),
# Segmentation(),
Color(minio_client),
PrintPainting(minio_client),
Scaling(),
Split(minio_client)
]
def process(self):
for item in self.bottom_pipeline:
self.result = item(self.result)
return self.result
class BodyItem(BaseItem):
def __init__(self, data, basic, minio_client):
super().__init__(data, basic)
self.top_pipeline = [
LoadBodyImage(minio_client),
]
def process(self):
for item in self.top_pipeline:
self.result = item(self.result)
return self.result

View File

@@ -3,12 +3,15 @@ import logging
import cv2 import cv2
import numpy as np import numpy as np
from app.service.utils.oss_client import oss_get_image from app.service.utils.new_oss_client import oss_get_image
logger = logging.getLogger() logger = logging.getLogger()
class Color: class Color:
def __init__(self, minio_client):
self.minio_client = minio_client
def __call__(self, result): def __call__(self, result):
dim_image_h, dim_image_w = result['image'].shape[0:2] dim_image_h, dim_image_w = result['image'].shape[0:2]
if "gradient" in result.keys() and result['gradient'] != "": if "gradient" in result.keys() and result['gradient'] != "":
@@ -33,10 +36,9 @@ class Color:
result['alpha'] = 100 / 255.0 result['alpha'] = 100 / 255.0
return result return result
@staticmethod def get_gradient(self, bucket_name, object_name):
def get_gradient(bucket_name, object_name):
# 获取渐变色图案 # 获取渐变色图案
image = oss_get_image(bucket=bucket_name, object_name=object_name, data_type="cv2") image = oss_get_image(oss_client=self.minio_client, bucket=bucket_name, object_name=object_name, data_type="cv2")
if image.shape[2] == 4: if image.shape[2] == 4:
image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR) image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)
return image return image

View File

@@ -4,7 +4,7 @@ import numpy as np
from pymilvus import MilvusClient from pymilvus import MilvusClient
from app.core.config import * from app.core.config import *
from app.service.design.utils.design_ensemble import get_keypoint_result from app.service.design_batch.utils.design_ensemble import get_keypoint_result
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@@ -1,24 +1,37 @@
import cv2 import io
import logging
from app.service.utils.oss_client import oss_get_image import cv2
import numpy as np
from PIL import Image
from app.service.utils.new_oss_client import oss_get_image
logger = logging.getLogger()
class LoadBodyImage: class LoadBodyImage:
name = "LoadBodyImage" name = "LoadBodyImage"
def __init__(self, minio_client):
self.minio_client = minio_client
@classmethod @classmethod
def get_name(cls): def get_name(cls):
return cls.name return cls.name
def __call__(self, result): def __call__(self, result):
result["name"] = "mannequin" result["name"] = "mannequin"
result['body_image'] = oss_get_image(bucket=result['body_path'].split("/", 1)[0], object_name=result['body_path'].split("/", 1)[1], data_type="PIL") result['body_image'] = oss_get_image(oss_client=self.minio_client, bucket=result['body_path'].split("/", 1)[0], object_name=result['body_path'].split("/", 1)[1], data_type="PIL")
return result return result
class LoadImage: class LoadImage:
name = "LoadImage" name = "LoadImage"
def __init__(self, minio_client):
self.minio_client = minio_client
@classmethod @classmethod
def get_name(cls): def get_name(cls):
return cls.name return cls.name
@@ -31,10 +44,9 @@ class LoadImage:
result['ori_shape'] = result['image'].shape result['ori_shape'] = result['image'].shape
return result return result
@staticmethod def read_image(self, image_path):
def read_image(image_path):
image_mask = None image_mask = None
image = oss_get_image(bucket=image_path.split("/", 1)[0], object_name=image_path.split("/", 1)[1], data_type="cv2") image = oss_get_image(oss_client=self.minio_client, bucket=image_path.split("/", 1)[0], object_name=image_path.split("/", 1)[1], data_type="cv2")
if len(image.shape) == 2: if len(image.shape) == 2:
image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB) image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
if image.shape[2] == 4: # 如果是四通道 mask if image.shape[2] == 4: # 如果是四通道 mask

View File

@@ -4,10 +4,13 @@ import cv2
import numpy as np import numpy as np
from PIL import Image from PIL import Image
from app.service.utils.oss_client import oss_get_image from app.service.utils.new_oss_client import oss_get_image
class PrintPainting: class PrintPainting:
def __init__(self, minio_client):
self.minio_client = minio_client
def __call__(self, result): def __call__(self, result):
single_print = result['print']['single'] single_print = result['print']['single']
overall_print = result['print']['overall'] overall_print = result['print']['overall']
@@ -356,8 +359,7 @@ class PrintPainting:
print_image = cv2.add(img_bg, img_fg) print_image = cv2.add(img_bg, img_fg)
return print_image return print_image
@staticmethod def get_print(self, print_dict):
def get_print(print_dict):
if 'print_scale_list' not in print_dict.keys() or print_dict['print_scale_list'][0] < 0.3: if 'print_scale_list' not in print_dict.keys() or print_dict['print_scale_list'][0] < 0.3:
print_dict['scale'] = 0.3 print_dict['scale'] = 0.3
else: else:
@@ -365,7 +367,7 @@ class PrintPainting:
bucket_name = print_dict['print_path_list'][0].split("/", 1)[0] bucket_name = print_dict['print_path_list'][0].split("/", 1)[0]
object_name = print_dict['print_path_list'][0].split("/", 1)[1] object_name = print_dict['print_path_list'][0].split("/", 1)[1]
image = oss_get_image(bucket=bucket_name, object_name=object_name, data_type="PIL") image = oss_get_image(oss_client=self.minio_client, bucket=bucket_name, object_name=object_name, data_type="PIL")
# 判断图片格式如果是RGBA 则贴在一张纯白图片上 防止透明转黑 # 判断图片格式如果是RGBA 则贴在一张纯白图片上 防止透明转黑
if image.mode == "RGBA": if image.mode == "RGBA":
new_background = Image.new('RGB', image.size, (255, 255, 255)) new_background = Image.new('RGB', image.size, (255, 255, 255))
@@ -480,9 +482,8 @@ class PrintPainting:
return img_rotated return img_rotated
@staticmethod def read_image(self, image_url):
def read_image(image_url): image = oss_get_image(oss_client=self.minio_client, bucket=image_url.split("/", 1)[0], object_name=image_url.split("/", 1)[1], data_type="cv2")
image = oss_get_image(bucket=image_url.split("/", 1)[0], object_name=image_url.split("/", 1)[1], data_type="cv2")
if image.shape[2] == 4: if image.shape[2] == 4:
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGRA2RGBA) image_rgb = cv2.cvtColor(image, cv2.COLOR_BGRA2RGBA)
image = Image.fromarray(image_rgb) image = Image.fromarray(image_rgb)

View File

@@ -5,16 +5,19 @@ import cv2
import numpy as np import numpy as np
from app.core.config import SEG_CACHE_PATH from app.core.config import SEG_CACHE_PATH
from app.service.design.utils.design_ensemble import get_seg_result from app.service.design_batch.utils.design_ensemble import get_seg_result
from app.service.utils.oss_client import oss_get_image from app.service.utils.new_oss_client import oss_get_image
logger = logging.getLogger() logger = logging.getLogger()
class Segmentation: class Segmentation:
def __init__(self, minio_client):
self.minio_client = minio_client
def __call__(self, result): def __call__(self, result):
if "seg_mask_url" in result.keys() and result['seg_mask_url'] != "": if "seg_mask_url" in result.keys() and result['seg_mask_url'] != "":
seg_mask = oss_get_image(bucket=result['seg_mask_url'].split('/')[0], object_name=result['seg_mask_url'][result['seg_mask_url'].find('/') + 1:], data_type="cv2") seg_mask = oss_get_image(oss_client=self.minio_client, bucket=result['seg_mask_url'].split('/')[0], object_name=result['seg_mask_url'][result['seg_mask_url'].find('/') + 1:], data_type="cv2")
seg_mask = cv2.resize(seg_mask, (result['img_shape'][1], result['img_shape'][0]), interpolation=cv2.INTER_NEAREST) seg_mask = cv2.resize(seg_mask, (result['img_shape'][1], result['img_shape'][0]), interpolation=cv2.INTER_NEAREST)
# 转换颜色空间为 RGBOpenCV 默认是 BGR # 转换颜色空间为 RGBOpenCV 默认是 BGR
image_rgb = cv2.cvtColor(seg_mask, cv2.COLOR_BGR2RGB) image_rgb = cv2.cvtColor(seg_mask, cv2.COLOR_BGR2RGB)
@@ -45,7 +48,7 @@ class Segmentation:
@staticmethod @staticmethod
def save_seg_result(seg_result, image_id): def save_seg_result(seg_result, image_id):
file_path = f"{SEG_CACHE_PATH}{image_id}.npy" file_path = f"seg_cache/{image_id}.npy"
try: try:
np.save(file_path, seg_result) np.save(file_path, seg_result)
logger.info(f"保存成功 {os.path.abspath(file_path)}") logger.info(f"保存成功 {os.path.abspath(file_path)}")
@@ -54,7 +57,7 @@ class Segmentation:
@staticmethod @staticmethod
def load_seg_result(image_id): def load_seg_result(image_id):
file_path = f"{SEG_CACHE_PATH}{image_id}.npy" file_path = f"seg_cache/{image_id}.npy"
logger.info(f"load seg file name is :{SEG_CACHE_PATH}{image_id}.npy") logger.info(f"load seg file name is :{SEG_CACHE_PATH}{image_id}.npy")
try: try:
seg_result = np.load(file_path) seg_result = np.load(file_path)

View File

@@ -7,13 +7,16 @@ from PIL import Image
from cv2 import cvtColor, COLOR_BGR2RGBA from cv2 import cvtColor, COLOR_BGR2RGBA
from app.core.config import AIDA_CLOTHING from app.core.config import AIDA_CLOTHING
from app.service.design.utils.conversion_image import rgb_to_rgba from app.service.design_batch.utils.conversion_image import rgb_to_rgba
from app.service.design.utils.upload_image import upload_png_mask from app.service.design_batch.utils.upload_image import upload_png_mask
from app.service.utils.generate_uuid import generate_uuid from app.service.utils.generate_uuid import generate_uuid
from app.service.utils.oss_client import oss_upload_image from app.service.utils.new_oss_client import oss_upload_image
class Split(object): class Split(object):
def __init__(self, minio_client):
self.minio_client = minio_client
def __call__(self, result): def __call__(self, result):
try: try:
@@ -27,7 +30,7 @@ class Split(object):
front_mask = cv2.resize(front_mask, new_size) front_mask = cv2.resize(front_mask, new_size)
result_front_image[front_mask != 0] = rgba_image[front_mask != 0] result_front_image[front_mask != 0] = rgba_image[front_mask != 0]
result_front_image_pil = Image.fromarray(cvtColor(result_front_image, COLOR_BGR2RGBA)) result_front_image_pil = Image.fromarray(cvtColor(result_front_image, COLOR_BGR2RGBA))
result['front_image'], result["front_image_url"], _ = upload_png_mask(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 = front_mask.shape height, width = front_mask.shape
mask_image = np.zeros((height, width, 3)) mask_image = np.zeros((height, width, 3))
@@ -38,7 +41,7 @@ class Split(object):
back_mask = cv2.resize(back_mask, new_size) back_mask = cv2.resize(back_mask, new_size)
result_back_image[back_mask != 0] = rgba_image[back_mask != 0] result_back_image[back_mask != 0] = rgba_image[back_mask != 0]
result_back_image_pil = Image.fromarray(cvtColor(result_back_image, COLOR_BGR2RGBA)) result_back_image_pil = Image.fromarray(cvtColor(result_back_image, COLOR_BGR2RGBA))
result['back_image'], result["back_image_url"], _ = upload_png_mask(result_back_image_pil, f'{generate_uuid()}', mask=None) result['back_image'], result["back_image_url"], _ = upload_png_mask(self.minio_client, result_back_image_pil, f'{generate_uuid()}', mask=None)
mask_image[back_mask != 0] = [0, 255, 0] mask_image[back_mask != 0] = [0, 255, 0]
rbga_mask = rgb_to_rgba(mask_image, front_mask + back_mask) rbga_mask = rgb_to_rgba(mask_image, front_mask + back_mask)
@@ -47,7 +50,7 @@ class Split(object):
mask_pil.save(image_data, format='PNG') mask_pil.save(image_data, format='PNG')
image_data.seek(0) image_data.seek(0)
image_bytes = image_data.read() image_bytes = image_data.read()
req = oss_upload_image(bucket=AIDA_CLOTHING, object_name=f"mask/mask_{generate_uuid()}.png", image_bytes=image_bytes) 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['mask_url'] = req.bucket_name + "/" + req.object_name
else: else:
rbga_mask = rgb_to_rgba(mask_image, front_mask) rbga_mask = rgb_to_rgba(mask_image, front_mask)
@@ -56,7 +59,7 @@ class Split(object):
mask_pil.save(image_data, format='PNG') mask_pil.save(image_data, format='PNG')
image_data.seek(0) image_data.seek(0)
image_bytes = image_data.read() image_bytes = image_data.read()
req = oss_upload_image(bucket=AIDA_CLOTHING, object_name=f"mask/mask_{generate_uuid()}.png", image_bytes=image_bytes) 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['mask_url'] = req.bucket_name + "/" + req.object_name
result['back_image'] = None result['back_image'] = None
result["back_image_url"] = None result["back_image_url"] = None
@@ -65,7 +68,7 @@ class Split(object):
# 创建中间图层 # 创建中间图层
result_pattern_image_rgba = rgb_to_rgba(result['pattern_image'], result['mask']) result_pattern_image_rgba = rgb_to_rgba(result['pattern_image'], result['mask'])
result_pattern_image_pil = Image.fromarray(cvtColor(result_pattern_image_rgba, COLOR_BGR2RGBA)) result_pattern_image_pil = Image.fromarray(cvtColor(result_pattern_image_rgba, COLOR_BGR2RGBA))
result['pattern_image'], result['pattern_image_url'], _ = upload_png_mask(result_pattern_image_pil, f'{generate_uuid()}') result['pattern_image'], result['pattern_image_url'], _ = upload_png_mask(self.minio_client, result_pattern_image_pil, f'{generate_uuid()}')
return result return result
except Exception as e: except Exception as e:
logging.warning(f"split runtime exception : {e} image_id : {result['image_id']}") logging.warning(f"split runtime exception : {e} image_id : {result['image_id']}")

View File

@@ -0,0 +1,12 @@
import json
import pika
from app.service.design_batch.design_batch_celery import batch_design
from app.service.design_batch.utils.MQ import publish_status
async def start_design_batch_generate(data, file):
generate_clothes_task = batch_design.delay(json.loads(file.decode())['objects'], data.total, data.tasks_id)
print(generate_clothes_task)
publish_status(data.tasks_id, "0/100", "")
return {"task_id": data.tasks_id}

View File

@@ -0,0 +1,162 @@
from app.service.design_batch.design_batch_celery import batch_design
if __name__ == '__main__':
data = {
"objects": [
{
"basic": {
"body_point_test": {
"waistband_right": [
200,
241
],
"hand_point_right": [
223,
297
],
"waistband_left": [
112,
241
],
"hand_point_left": [
92,
305
],
"shoulder_left": [
99,
116
],
"shoulder_right": [
215,
116
]
},
"layer_order": True,
"scale_bag": 0.7,
"scale_earrings": 0.16,
"self_template": True,
"single_overall": "overall",
"switch_category": ""
},
"items": [
{
"businessId": 270372,
"color": "30 28 28",
"image_id": 69780,
"offset": [
0,
0
],
"path": "aida-sys-image/images/female/trousers/0825000630.jpg",
"print": {
"element": {
"element_angle_list": [],
"element_path_list": [],
"element_scale_list": [],
"location": []
},
"overall": {
"location": [],
"print_angle_list": [],
"print_path_list": [],
"print_scale_list": []
},
"single": {
"location": [],
"print_angle_list": [],
"print_path_list": [],
"print_scale_list": []
}
},
"priority": 10,
"resize_scale": [
1.0,
1.0
],
"type": "Trousers"
},
{
"businessId": 270373,
"color": "30 28 28",
"image_id": 98243,
"offset": [
0,
0
],
"path": "aida-sys-image/images/female/blouse/0902003811.jpg",
"print": {
"element": {
"element_angle_list": [],
"element_path_list": [],
"element_scale_list": [],
"location": []
},
"overall": {
"location": [],
"print_angle_list": [],
"print_path_list": [],
"print_scale_list": []
},
"single": {
"location": [],
"print_angle_list": [],
"print_path_list": [],
"print_scale_list": []
}
},
"priority": 11,
"resize_scale": [
1.0,
1.0
],
"type": "Blouse"
},
{
"businessId": 270374,
"color": "172 68 68",
"image_id": 98244,
"offset": [
0,
0
],
"path": "aida-sys-image/images/female/outwear/0825000410.jpg",
"print": {
"element": {
"element_angle_list": [],
"element_path_list": [],
"element_scale_list": [],
"location": []
},
"overall": {
"location": [],
"print_angle_list": [],
"print_path_list": [],
"print_scale_list": []
},
"single": {
"location": [],
"print_angle_list": [],
"print_path_list": [],
"print_scale_list": []
}
},
"priority": 12,
"resize_scale": [
1.0,
1.0
],
"type": "Outwear"
},
{
"body_path": "aida-sys-image/models/female/5bdfe7ca-64eb-44e4-b03d-8e517520c795.png",
"image_id": 96090,
"type": "Body"
}
]
}
],
"process_id": "83"
}
task_id = 1
json_name = "test.json"
batch_design.delay(data['objects'], task_id, json_name)

View File

@@ -0,0 +1,17 @@
import json
import pika
def publish_status(task_id, progress, result):
connection = pika.BlockingConnection(pika.ConnectionParameters('10.1.2.213'))
channel = connection.channel()
channel.queue_declare(queue='DesignBatch', durable=True)
message = {'task_id': task_id, 'progress': progress, "result": result}
channel.basic_publish(exchange='',
routing_key='DesignBatch',
body=json.dumps(message),
properties=pika.BasicProperties(
delivery_mode=2,
))
connection.close()

View File

@@ -0,0 +1,77 @@
import cv2
from app.core.config import PRIORITY_DICT
def organize_body(layer):
body_layer = dict(priority=0,
name=layer["name"].lower(),
image=layer['body_image'],
image_url=layer['body_path'],
mask_image=None,
mask_url=None,
sacle=1,
# mask=layer['body_mask'],
position=(0, 0))
return body_layer
def organize_clothing(layer):
# 起始坐标
start_point = calculate_start_point(layer['keypoint'], layer['scale'], layer['clothes_keypoint'], layer['body_point_test'], layer["offset"], layer["resize_scale"])
# 前片数据
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',
image=layer["front_image"],
# mask_image=layer['front_mask_image'],
image_url=layer['front_image_url'],
mask_url=layer['mask_url'],
sacle=layer['scale'],
clothes_keypoint=layer['clothes_keypoint'],
position=start_point,
resize_scale=layer["resize_scale"],
mask=cv2.resize(layer['mask'], layer["front_image"].size),
gradient_string=layer['gradient_string'] if 'gradient_string' in layer.keys() else "",
pattern_image_url=layer['pattern_image_url'],
pattern_image=layer['pattern_image']
)
# 后片数据
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',
image=layer["back_image"],
# mask_image=layer['back_mask_image'],
image_url=layer['back_image_url'],
mask_url=layer['mask_url'],
sacle=layer['scale'],
clothes_keypoint=layer['clothes_keypoint'],
position=start_point,
resize_scale=layer["resize_scale"],
mask=cv2.resize(layer['mask'], layer["front_image"].size),
gradient_string=layer['gradient_string'] if 'gradient_string' in layer.keys() else "",
pattern_image_url=layer['pattern_image_url'],
)
return front_layer, back_layer
def calculate_start_point(keypoint_type, scale, clothes_point, body_point, offset, resize_scale):
"""
Align left
Args:
keypoint_type: string, "waistband" | "shoulder" | "ear_point"
scale: float
clothes_point: dict{'left': [x1, y1, z1], 'right': [x2, y2, z2]}
body_point: dict, containing keypoint data of body figure
Returns:
start_point: tuple (x', y')
x' = y_body - y1 * scale + offset
y' = x_body - x1 * scale + offset
"""
side_indicator = f'{keypoint_type}_left'
start_point = (
int(body_point[side_indicator][1] + offset[1] - int(clothes_point[side_indicator][0]) * scale), # y
int(body_point[side_indicator][0] + offset[0] - int(clothes_point[side_indicator][1]) * scale) # x
)
return start_point

View File

@@ -0,0 +1,30 @@
import logging
from app.service.design_fast.utils.redis_utils import Redis
logger = logging.getLogger(__name__)
def update_progress(process_id, total):
# logger.info(f"{process_id} , {total}")
r = Redis()
progress = r.read(key=process_id)
if progress and total != 1:
if int(progress) <= 100:
r.write(key=process_id, value=int(progress) + int(100 / total))
else:
r.write(key=process_id, value=99)
return progress
elif total == 1:
r.write(key=process_id, value=100)
return progress
else:
r.write(key=process_id, value=int(100 / total))
return progress
def final_progress(process_id):
r = Redis()
progress = r.read(key=process_id)
r.write(key=process_id, value=100)
return progress

View File

@@ -0,0 +1,13 @@
import json
import logging
logger = logging.getLogger()
def oss_upload_json(oss_client, json_data, object_name):
try:
with open(f"app/service/design_batch/response_json/{object_name}", 'w') as file:
json.dump(json_data, file, indent=4)
oss_client.fput_object("test", object_name, f"app/service/design_batch/response_json/{object_name}")
except Exception as e:
logger.warning(str(e))

View File

@@ -179,3 +179,19 @@ def synthesis_single(front_image, back_image):
object_name = f'result_{generate_uuid()}.png' object_name = f'result_{generate_uuid()}.png'
req = oss_upload_image(bucket=bucket_name, object_name=object_name, image_bytes=image_bytes) req = oss_upload_image(bucket=bucket_name, object_name=object_name, image_bytes=image_bytes)
return f"{bucket_name}/{object_name}" return f"{bucket_name}/{object_name}"
def update_base_size_priority(layers, size):
# 计算透明背景图片的宽度
min_x = min(info['position'][1] for info in layers)
x_list = []
for info in layers:
if info['image'] is not None:
x_list.append(info['position'][1] + info['image'].width)
max_x = max(x_list)
new_width = max_x - min_x
new_height = 700
# 更新坐标
for info in layers:
info['adaptive_position'] = (info['position'][0], info['position'][1] - min_x)
return layers, (new_width, new_height)

View File

@@ -13,11 +13,11 @@ import logging
import cv2 import cv2
from app.core.config import * from app.core.config import *
from app.service.utils.oss_client import oss_upload_image from app.service.utils.new_oss_client import oss_upload_image
# @RunTime # @RunTime
def upload_png_mask(front_image, object_name, mask=None): def upload_png_mask(minio_client, front_image, object_name, mask=None):
try: try:
mask_url = None mask_url = None
if mask is not None: if mask is not None:
@@ -25,14 +25,14 @@ def upload_png_mask(front_image, object_name, mask=None):
# 将掩模的3通道转换为4通道白色部分不透明黑色部分透明 # 将掩模的3通道转换为4通道白色部分不透明黑色部分透明
rgba_image = cv2.cvtColor(mask_inverted, cv2.COLOR_BGR2BGRA) rgba_image = cv2.cvtColor(mask_inverted, cv2.COLOR_BGR2BGRA)
rgba_image[rgba_image[:, :, 0] == 0] = [0, 0, 0, 0] rgba_image[rgba_image[:, :, 0] == 0] = [0, 0, 0, 0]
req = oss_upload_image(bucket=AIDA_CLOTHING, object_name=f"mask/mask_{object_name}.png", image_bytes=cv2.imencode('.png', rgba_image)[1]) req = oss_upload_image(oss_client=minio_client, bucket=AIDA_CLOTHING, object_name=f"mask/mask_{object_name}.png", image_bytes=cv2.imencode('.png', rgba_image)[1])
mask_url = f"{AIDA_CLOTHING}/mask/mask_{object_name}.png" mask_url = f"{AIDA_CLOTHING}/mask/mask_{object_name}.png"
image_data = io.BytesIO() image_data = io.BytesIO()
front_image.save(image_data, format='PNG') front_image.save(image_data, format='PNG')
image_data.seek(0) image_data.seek(0)
image_bytes = image_data.read() image_bytes = image_data.read()
req = oss_upload_image(bucket=AIDA_CLOTHING, object_name=f"image/image_{object_name}.png", image_bytes=image_bytes) req = oss_upload_image(oss_client=minio_client, bucket=AIDA_CLOTHING, object_name=f"image/image_{object_name}.png", image_bytes=image_bytes)
image_url = f"{AIDA_CLOTHING}/image/image_{object_name}.png" image_url = f"{AIDA_CLOTHING}/image/image_{object_name}.png"
return front_image, image_url, mask_url return front_image, image_url, mask_url
except Exception as e: except Exception as e:

View File

@@ -4,7 +4,7 @@ import numpy as np
from pymilvus import MilvusClient from pymilvus import MilvusClient
from app.core.config import * from app.core.config import *
from app.service.design.utils.design_ensemble import get_keypoint_result from app.service.design_fast.utils.design_ensemble import get_keypoint_result
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@@ -5,7 +5,7 @@ import cv2
import numpy as np import numpy as np
from app.core.config import SEG_CACHE_PATH from app.core.config import SEG_CACHE_PATH
from app.service.design.utils.design_ensemble import get_seg_result from app.service.design_fast.utils.design_ensemble import get_seg_result
from app.service.utils.new_oss_client import oss_get_image from app.service.utils.new_oss_client import oss_get_image
logger = logging.getLogger() logger = logging.getLogger()

View File

@@ -7,7 +7,7 @@ from PIL import Image
from cv2 import cvtColor, COLOR_BGR2RGBA from cv2 import cvtColor, COLOR_BGR2RGBA
from app.core.config import AIDA_CLOTHING from app.core.config import AIDA_CLOTHING
from app.service.design.utils.conversion_image import rgb_to_rgba from app.service.design_fast.utils.conversion_image import rgb_to_rgba
from app.service.design_fast.utils.upload_image import upload_png_mask from app.service.design_fast.utils.upload_image import upload_png_mask
from app.service.utils.generate_uuid import generate_uuid from app.service.utils.generate_uuid import generate_uuid
from app.service.utils.new_oss_client import oss_upload_image from app.service.utils.new_oss_client import oss_upload_image

View File

@@ -10,7 +10,7 @@ from urllib3.exceptions import ResponseError
from app.core.config import * from app.core.config import *
from app.schemas.pre_processing import DesignPreProcessingModel from app.schemas.pre_processing import DesignPreProcessingModel
from app.service.design.utils.design_ensemble import get_keypoint_result, get_seg_result from app.service.design_fast.utils.design_ensemble import get_seg_result, get_keypoint_result
from app.service.utils.oss_client import oss_get_image, oss_upload_image from app.service.utils.oss_client import oss_get_image, oss_upload_image
logger = logging.getLogger() logger = logging.getLogger()

View File

@@ -1,8 +1,6 @@
import io import io
import logging import logging
from io import BytesIO from io import BytesIO
import boto3
import cv2 import cv2
import numpy as np import numpy as np
import urllib3 import urllib3
@@ -42,12 +40,8 @@ def oss_get_image(bucket, object_name, data_type):
# cv2 默认全通道读取 # cv2 默认全通道读取
image_object = None image_object = None
try: try:
if OSS == "minio": oss_client = Minio(MINIO_URL, access_key=MINIO_ACCESS, secret_key=MINIO_SECRET, secure=MINIO_SECURE, http_client=http_client)
oss_client = Minio(MINIO_URL, access_key=MINIO_ACCESS, secret_key=MINIO_SECRET, secure=MINIO_SECURE, http_client=http_client) image_data = oss_client.get_object(bucket_name=bucket, object_name=object_name)
image_data = oss_client.get_object(bucket_name=bucket, object_name=object_name)
else:
oss_client = boto3.client('s3', aws_access_key_id=S3_ACCESS_KEY, aws_secret_access_key=S3_AWS_SECRET_ACCESS_KEY, region_name=S3_REGION_NAME)
image_data = oss_client.get_object(Bucket=bucket, Key=object_name)['Body']
if data_type == "cv2": if data_type == "cv2":
image_bytes = image_data.read() image_bytes = image_data.read()
image_array = np.frombuffer(image_bytes, np.uint8) # 转成8位无符号整型 image_array = np.frombuffer(image_bytes, np.uint8) # 转成8位无符号整型
@@ -65,12 +59,8 @@ def oss_get_image(bucket, object_name, data_type):
def oss_upload_image(bucket, object_name, image_bytes): def oss_upload_image(bucket, object_name, image_bytes):
req = None req = None
try: try:
if OSS == "minio": oss_client = Minio(MINIO_URL, access_key=MINIO_ACCESS, secret_key=MINIO_SECRET, secure=MINIO_SECURE)
oss_client = Minio(MINIO_URL, access_key=MINIO_ACCESS, secret_key=MINIO_SECRET, secure=MINIO_SECURE) req = oss_client.put_object(bucket_name=bucket, object_name=object_name, data=io.BytesIO(image_bytes), length=len(image_bytes), content_type='image/png')
req = oss_client.put_object(bucket_name=bucket, object_name=object_name, data=io.BytesIO(image_bytes), length=len(image_bytes), content_type='image/png')
else:
oss_client = boto3.client('s3', aws_access_key_id=S3_ACCESS_KEY, aws_secret_access_key=S3_AWS_SECRET_ACCESS_KEY, region_name=S3_REGION_NAME)
req = oss_client.put_object(Bucket=bucket, Key=object_name, Body=io.BytesIO(image_bytes), ContentType='image/png')
except Exception as e: except Exception as e:
logger.warning(f"{OSS} | 上传图片出现异常 ######: {e}") logger.warning(f"{OSS} | 上传图片出现异常 ######: {e}")
return req return req