feat: 新增design模式 merge,前端CV python 合成
This commit is contained in:
@@ -35,15 +35,9 @@ class LoadImage:
|
||||
return cls.name
|
||||
|
||||
def __call__(self, result):
|
||||
if result.get("merge_image_path"):
|
||||
result['merge_image'], _ = self.read_image(result['merge_image_path'])
|
||||
result['image'], result['pre_mask'] = self.read_image(result['path'])
|
||||
# if 'extract_lines' in result.keys():
|
||||
# if result['extract_lines']:
|
||||
# result['gray'] = self.get_lines(cv2.cvtColor(result['image'], cv2.COLOR_BGR2GRAY), result['path'])
|
||||
# else:
|
||||
# result['gray'] = cv2.cvtColor(result['image'], cv2.COLOR_BGR2GRAY)
|
||||
# else:
|
||||
# result['gray'] = cv2.cvtColor(result['image'], cv2.COLOR_BGR2GRAY)
|
||||
|
||||
result['gray'] = self.get_lines(cv2.cvtColor(result['image'], cv2.COLOR_BGR2GRAY))
|
||||
result['keypoint'] = self.get_keypoint(result['name'])
|
||||
result['img_shape'] = result['image'].shape
|
||||
@@ -61,21 +55,6 @@ class LoadImage:
|
||||
mask = skeleton
|
||||
result = np.ones_like(img) * 255
|
||||
result[mask] = img[mask]
|
||||
|
||||
# 步骤2:细化边缘(可选,让线条更干净)
|
||||
# kernel = np.ones((1, 1), np.uint8)
|
||||
# clean = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
|
||||
|
||||
# thinned = cv2.ximgproc.thinning(binary, thinningType=cv2.ximgproc.THINNING_ZHANGSUEN) # thinning算法细化线条
|
||||
# mask = thinned > 0
|
||||
# result = np.ones_like(img) * 255
|
||||
# result[mask] = img[mask]
|
||||
|
||||
# 步骤3:反转回 白底黑线
|
||||
# lines = cv2.bitwise_not(thinned)
|
||||
# cv2.imwrite(os.path.join('/home/user/PycharmProjects/trinity_client_aida/test/lines_original_result_5', f"Original_{path.replace('/', '-')}.png"), img)
|
||||
# cv2.imwrite(os.path.join('/home/user/PycharmProjects/trinity_client_aida/test/lines_original_result_5', f"Line_{path.replace('/', '-')}.png"), result)
|
||||
|
||||
return result
|
||||
|
||||
def read_image(self, image_path):
|
||||
@@ -96,19 +75,19 @@ class LoadImage:
|
||||
|
||||
@staticmethod
|
||||
def get_keypoint(name):
|
||||
if name == 'blouse' or name == 'outwear' or name == 'dress' or name == 'tops':
|
||||
if name in ['blouse', 'outwear', 'dress', 'tops', 'blouse_merge', 'outwear_merge', 'dress_merge', 'tops_merge']:
|
||||
keypoint = 'shoulder'
|
||||
elif name == 'trousers' or name == 'skirt' or name == 'bottoms':
|
||||
elif name in ['trousers', 'skirt', 'bottoms', 'trousers_merge', 'skirt_merge', 'bottoms_merge']:
|
||||
keypoint = 'waistband'
|
||||
elif name == 'bag':
|
||||
elif name in ['bag', 'bag_merge']:
|
||||
keypoint = 'hand_point'
|
||||
elif name == 'shoes':
|
||||
elif name in ['shoes', 'shoes_merge']:
|
||||
keypoint = 'toe'
|
||||
elif name == 'hairstyle':
|
||||
elif name in ['hairstyle', 'hairstyle_merge']:
|
||||
keypoint = 'head_point'
|
||||
elif name == 'earring':
|
||||
elif name in ['earring', 'earring_merge']:
|
||||
keypoint = 'ear_point'
|
||||
elif name == 'others':
|
||||
elif name in ['others', 'others_merge']:
|
||||
keypoint = "others"
|
||||
else:
|
||||
raise KeyError(f"{name} does not belong to item category list: blouse, outwear, dress, trousers, skirt, "
|
||||
|
||||
@@ -34,15 +34,15 @@ class Segmentation:
|
||||
result['mask'] = result['front_mask'] + result['back_mask']
|
||||
else:
|
||||
# preview 过模型 不缓存
|
||||
if "preview_submit" in result.keys() and result['preview_submit'] == "preview":
|
||||
# 推理获得seg 结果
|
||||
if result.get("design_type", None) == "merge":
|
||||
seg_result = get_seg_result(result['image'])
|
||||
# submit 过模型 缓存
|
||||
elif "preview_submit" in result.keys() and result['preview_submit'] == "submit":
|
||||
# 推理获得seg 结果
|
||||
seg_result = get_seg_result(result['image'])
|
||||
self.save_seg_result(seg_result, result['image_id'])
|
||||
# null 正常流程 加载本地缓存 无缓存则过模型
|
||||
# 默认design 模式 - 过模型 缓存
|
||||
# elif result.get("design_type", None) == "submit":
|
||||
# 推理获得seg 结果
|
||||
# seg_result = get_seg_result(result['image'])
|
||||
# self.save_seg_result(seg_result, result['image_id'])
|
||||
|
||||
# 默认模式- 加载模型,找不到则过模型推理,推理后保存到本地
|
||||
else:
|
||||
# 本地查询seg 缓存是否存在
|
||||
_, seg_result = self.load_seg_result(result["image_id"])
|
||||
|
||||
@@ -4,6 +4,7 @@ import logging
|
||||
import cv2
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
from celery.bin.result import result
|
||||
|
||||
from app.service.design_fast.utils.conversion_image import rgb_to_rgba
|
||||
from app.service.design_fast.utils.transparent import sketch_to_transparent
|
||||
@@ -19,105 +20,106 @@ class Split(object):
|
||||
def __call__(self, result):
|
||||
try:
|
||||
if result['name'] in ('outwear', 'dress', 'blouse', 'skirt', 'trousers', 'tops', 'bottoms', 'others'):
|
||||
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:
|
||||
front_mask = result['front_mask']
|
||||
back_mask = result['back_mask']
|
||||
else:
|
||||
height, width = result['front_mask'].shape[:2]
|
||||
new_width = int(width * result['resize_scale'][0])
|
||||
new_height = int(height * result['resize_scale'][1])
|
||||
|
||||
front_mask = cv2.resize(result['front_mask'], (new_width, new_height), interpolation=cv2.INTER_AREA)
|
||||
back_mask = cv2.resize(result['back_mask'], (new_width, new_height), interpolation=cv2.INTER_AREA)
|
||||
|
||||
rgba_image = rgb_to_rgba(result['final_image'], front_mask + back_mask)
|
||||
new_size = (int(rgba_image.shape[1] * result["scale"]), int(rgba_image.shape[0] * result["scale"]))
|
||||
rgba_image = cv2.resize(rgba_image, new_size, interpolation=cv2.INTER_AREA)
|
||||
result_front_image = np.zeros_like(rgba_image)
|
||||
front_mask = cv2.resize(front_mask, new_size, interpolation=cv2.INTER_AREA)
|
||||
result_front_image[front_mask != 0] = rgba_image[front_mask != 0]
|
||||
result_front_image_pil = Image.fromarray(cv2.cvtColor(result_front_image, cv2.COLOR_BGR2RGBA))
|
||||
if 'transparent' in result.keys():
|
||||
# 用户自选区域transparent
|
||||
transparent = result['transparent']
|
||||
if transparent['mask_url'] is not None and transparent['mask_url'] != "":
|
||||
# 预处理用户自选区mask
|
||||
seg_mask = oss_get_image(oss_client=self.minio_client, bucket=transparent['mask_url'].split('/')[0], object_name=transparent['mask_url'][transparent['mask_url'].find('/') + 1:], data_type="cv2")
|
||||
seg_mask = cv2.resize(seg_mask, new_size, interpolation=cv2.INTER_AREA)
|
||||
# 转换颜色空间为 RGB(OpenCV 默认是 BGR)
|
||||
image_rgb = cv2.cvtColor(seg_mask, cv2.COLOR_BGR2RGB)
|
||||
|
||||
r, g, b = cv2.split(image_rgb)
|
||||
blue_mask = b > r
|
||||
|
||||
# 创建红色和绿色掩码
|
||||
transparent_mask = np.array(blue_mask, dtype=np.uint8) * 255
|
||||
result_front_image_pil = sketch_to_transparent(result_front_image_pil, transparent_mask, transparent["scale"])
|
||||
if result.get('design_type', None) == 'merge':
|
||||
# merge 不需要返回mask (红绿图)
|
||||
if result['resize_scale'][0] == 1.0 and result['resize_scale'][1] == 1.0:
|
||||
front_mask = result['front_mask']
|
||||
back_mask = result['back_mask']
|
||||
else:
|
||||
result_front_image_pil = sketch_to_transparent(result_front_image_pil, front_mask, transparent["scale"])
|
||||
result['front_image'], result["front_image_url"], _ = upload_png_mask(self.minio_client, result_front_image_pil, f'{generate_uuid()}', mask=None)
|
||||
height, width = result['front_mask'].shape[:2]
|
||||
new_width = int(width * result['resize_scale'][0])
|
||||
new_height = int(height * result['resize_scale'][1])
|
||||
|
||||
# 前片部分 (红图部分)
|
||||
# height, width = front_mask.shape
|
||||
# mask_image = np.zeros((height, width, 3))
|
||||
# mask_image[front_mask != 0] = [0, 0, 255]
|
||||
front_mask = cv2.resize(result['front_mask'], (new_width, new_height), interpolation=cv2.INTER_AREA)
|
||||
back_mask = cv2.resize(result['back_mask'], (new_width, new_height), interpolation=cv2.INTER_AREA)
|
||||
result['merge_image'] = cv2.resize(result['merge_image'], (new_width, new_height), interpolation=cv2.INTER_AREA)
|
||||
|
||||
# 切换为原始图片尺寸-------------------------------
|
||||
height, width = ori_front_mask.shape
|
||||
mask_image = np.zeros((height, width, 3))
|
||||
mask_image[ori_front_mask != 0] = [0, 0, 255]
|
||||
# -----------------------------------------------
|
||||
rgba_image = rgb_to_rgba(result['merge_image'], front_mask + back_mask)
|
||||
new_size = (int(rgba_image.shape[1] * result["scale"]), int(rgba_image.shape[0] * result["scale"]))
|
||||
rgba_image = cv2.resize(rgba_image, new_size, interpolation=cv2.INTER_AREA)
|
||||
result_front_image = np.zeros_like(rgba_image)
|
||||
front_mask = cv2.resize(front_mask, new_size, interpolation=cv2.INTER_AREA)
|
||||
result_front_image[front_mask != 0] = rgba_image[front_mask != 0]
|
||||
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)
|
||||
|
||||
# if result["name"] in ('blouse', 'dress', 'outwear', 'tops'):
|
||||
# result_back_image = np.zeros_like(rgba_image)
|
||||
# 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_pil = Image.fromarray(cvtColor(result_back_image, COLOR_BGR2RGBA))
|
||||
# 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]
|
||||
#
|
||||
# rbga_mask = rgb_to_rgba(mask_image, front_mask + back_mask)
|
||||
# mask_pil = Image.fromarray(cvtColor(rbga_mask.astype(np.uint8), 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
|
||||
# else:
|
||||
# rbga_mask = rgb_to_rgba(mask_image, front_mask)
|
||||
# mask_pil = Image.fromarray(cvtColor(rbga_mask.astype(np.uint8), 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'] = None
|
||||
# result["back_image_url"] = None
|
||||
# # result["back_mask_url"] = None
|
||||
# # result['back_mask_image'] = None
|
||||
result_back_image = np.zeros_like(rgba_image)
|
||||
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_pil = Image.fromarray(cv2.cvtColor(result_back_image, cv2.COLOR_BGR2RGBA))
|
||||
result['back_image'], result["back_image_url"], _ = upload_png_mask(self.minio_client, result_back_image_pil, f'{generate_uuid()}', mask=None)
|
||||
return result
|
||||
else:
|
||||
ori_front_mask = result['front_mask'].copy()
|
||||
ori_back_mask = result['back_mask'].copy()
|
||||
|
||||
result_back_image = np.zeros_like(rgba_image)
|
||||
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_pil = Image.fromarray(cv2.cvtColor(result_back_image, cv2.COLOR_BGR2RGBA))
|
||||
result['back_image'], result["back_image_url"], _ = upload_png_mask(self.minio_client, result_back_image_pil, f'{generate_uuid()}', mask=None)
|
||||
if result['resize_scale'][0] == 1.0 and result['resize_scale'][1] == 1.0:
|
||||
front_mask = result['front_mask']
|
||||
back_mask = result['back_mask']
|
||||
else:
|
||||
height, width = result['front_mask'].shape[:2]
|
||||
new_width = int(width * result['resize_scale'][0])
|
||||
new_height = int(height * result['resize_scale'][1])
|
||||
|
||||
# mask_image[back_mask != 0] = [0, 255, 0]
|
||||
mask_image[ori_back_mask != 0] = [0, 255, 0]
|
||||
front_mask = cv2.resize(result['front_mask'], (new_width, new_height), interpolation=cv2.INTER_AREA)
|
||||
back_mask = cv2.resize(result['back_mask'], (new_width, new_height), interpolation=cv2.INTER_AREA)
|
||||
|
||||
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
|
||||
rgba_image = rgb_to_rgba(result['final_image'], front_mask + back_mask)
|
||||
new_size = (int(rgba_image.shape[1] * result["scale"]), int(rgba_image.shape[0] * result["scale"]))
|
||||
rgba_image = cv2.resize(rgba_image, new_size, interpolation=cv2.INTER_AREA)
|
||||
result_front_image = np.zeros_like(rgba_image)
|
||||
front_mask = cv2.resize(front_mask, new_size, interpolation=cv2.INTER_AREA)
|
||||
result_front_image[front_mask != 0] = rgba_image[front_mask != 0]
|
||||
result_front_image_pil = Image.fromarray(cv2.cvtColor(result_front_image, cv2.COLOR_BGR2RGBA))
|
||||
if 'transparent' in result.keys():
|
||||
# 用户自选区域transparent
|
||||
transparent = result['transparent']
|
||||
if transparent['mask_url'] is not None and transparent['mask_url'] != "":
|
||||
# 预处理用户自选区mask
|
||||
seg_mask = oss_get_image(oss_client=self.minio_client, bucket=transparent['mask_url'].split('/')[0], object_name=transparent['mask_url'][transparent['mask_url'].find('/') + 1:], data_type="cv2")
|
||||
seg_mask = cv2.resize(seg_mask, new_size, interpolation=cv2.INTER_AREA)
|
||||
# 转换颜色空间为 RGB(OpenCV 默认是 BGR)
|
||||
image_rgb = cv2.cvtColor(seg_mask, cv2.COLOR_BGR2RGB)
|
||||
|
||||
r, g, b = cv2.split(image_rgb)
|
||||
blue_mask = b > r
|
||||
|
||||
# 创建红色和绿色掩码
|
||||
transparent_mask = np.array(blue_mask, dtype=np.uint8) * 255
|
||||
result_front_image_pil = sketch_to_transparent(result_front_image_pil, transparent_mask, transparent["scale"])
|
||||
else:
|
||||
result_front_image_pil = sketch_to_transparent(result_front_image_pil, front_mask, transparent["scale"])
|
||||
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]
|
||||
|
||||
result_back_image = np.zeros_like(rgba_image)
|
||||
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_pil = Image.fromarray(cv2.cvtColor(result_back_image, cv2.COLOR_BGR2RGBA))
|
||||
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[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
|
||||
|
||||
# 创建中间图层(未分割图层) 1.color + overall_print 2.color + overall_print + print
|
||||
result_pattern_overall_image_pil = Image.fromarray(cv2.cvtColor(rgb_to_rgba(result['no_seg_sketch_overall'], ori_front_mask + ori_back_mask), cv2.COLOR_BGR2RGBA))
|
||||
result['pattern_overall_image'], result['pattern_overall_image_url'], _ = upload_png_mask(self.minio_client, result_pattern_overall_image_pil, f'{generate_uuid()}')
|
||||
|
||||
result_pattern_print_image_pil = Image.fromarray(cv2.cvtColor(rgb_to_rgba(result['no_seg_sketch_print'], ori_front_mask + ori_back_mask), cv2.COLOR_BGR2RGBA))
|
||||
result['pattern_print_image'], result['pattern_print_image_url'], _ = upload_png_mask(self.minio_client, result_pattern_print_image_pil, f'{generate_uuid()}')
|
||||
return result
|
||||
else:
|
||||
ori_front_mask, ori_back_mask = None, None
|
||||
# 创建中间图层(未分割图层) 1.color + overall_print 2.color + overall_print + print
|
||||
@@ -127,5 +129,6 @@ class Split(object):
|
||||
result_pattern_print_image_pil = Image.fromarray(cv2.cvtColor(rgb_to_rgba(result['no_seg_sketch_print'], ori_front_mask + ori_back_mask), cv2.COLOR_BGR2RGBA))
|
||||
result['pattern_print_image'], result['pattern_print_image_url'], _ = upload_png_mask(self.minio_client, result_pattern_print_image_pil, f'{generate_uuid()}')
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logging.warning(f"split runtime exception : {e} image_id : {result['image_id']}")
|
||||
|
||||
Reference in New Issue
Block a user