570 lines
32 KiB
Python
570 lines
32 KiB
Python
import random
|
||
|
||
import cv2
|
||
import numpy as np
|
||
from PIL import Image
|
||
|
||
from app.service.utils.oss_client import oss_get_image
|
||
from ..builder import PIPELINES
|
||
|
||
|
||
@PIPELINES.register_module()
|
||
class Painting(object):
|
||
def __init__(self, painting_flag=True):
|
||
self.painting_flag = painting_flag
|
||
|
||
# @ RunTime
|
||
def __call__(self, result):
|
||
if result['name'] not in ['hairstyle', 'earring'] and self.painting_flag and result['color'] != 'none':
|
||
dim_image_h, dim_image_w = result['image'].shape[0:2]
|
||
if "gradient" in result.keys() and result['gradient'] != "":
|
||
bucket_name = result['gradient'].split('/')[0]
|
||
object_name = result['gradient'][result['gradient'].find('/') + 1:]
|
||
pattern = self.get_gradient(bucket_name=bucket_name, object_name=object_name)
|
||
resize_pattern = cv2.resize(pattern, (dim_image_w, dim_image_h), interpolation=cv2.INTER_AREA)
|
||
else:
|
||
pattern = self.get_pattern(result['color'])
|
||
resize_pattern = cv2.resize(pattern, (dim_image_w, dim_image_h), interpolation=cv2.INTER_AREA)
|
||
closed_mo = np.expand_dims(result['mask'], axis=2).repeat(3, axis=2)
|
||
gray_mo = np.expand_dims(result['gray'], axis=2).repeat(3, axis=2)
|
||
get_image_fir = resize_pattern * (closed_mo / 255) * (gray_mo / 255)
|
||
result['pattern_image'] = get_image_fir.astype(np.uint8)
|
||
result['final_image'] = result['pattern_image']
|
||
canvas = np.full_like(result['final_image'], 255)
|
||
temp_bg = np.expand_dims(cv2.bitwise_not(result['mask']), axis=2).repeat(3, axis=2)
|
||
tmp1 = (canvas * (temp_bg / 255)).astype(np.uint8)
|
||
temp_fg = np.expand_dims(result['mask'], axis=2).repeat(3, axis=2)
|
||
tmp2 = (result['final_image'] * (temp_fg / 255)).astype(np.uint8)
|
||
result['single_image'] = cv2.add(tmp1, tmp2)
|
||
result['alpha'] = 100 / 255.0
|
||
else:
|
||
closed_mo = np.expand_dims(result['mask'], axis=2).repeat(3, axis=2)
|
||
get_image_fir = result['image'] * (closed_mo / 255)
|
||
result['pattern_image'] = get_image_fir.astype(np.uint8)
|
||
result['final_image'] = result['pattern_image']
|
||
return result
|
||
|
||
@staticmethod
|
||
def get_gradient(bucket_name, object_name):
|
||
# image_data = minio_client.get_object(bucket_name, object_name)
|
||
# image_data = s3.get_object(Bucket=bucket_name, Key=object_name)['Body']
|
||
|
||
# 从数据流中读取图像
|
||
# image_bytes = image_data.read()
|
||
|
||
# 将图像数据转换为numpy数组
|
||
# image_array = np.asarray(bytearray(image_bytes), dtype=np.uint8)
|
||
|
||
# 使用OpenCV解码图像数组
|
||
# image = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
|
||
image = oss_get_image(bucket=bucket_name, object_name=object_name, data_type="cv2")
|
||
return image
|
||
|
||
@staticmethod
|
||
def crop_image(image, image_size_h, image_size_w):
|
||
x_offset = np.random.randint(low=0, high=int(image_size_h / 5) - 6)
|
||
y_offset = np.random.randint(low=0, high=int(image_size_w / 5) - 6)
|
||
image = image[x_offset: x_offset + image_size_h, y_offset: y_offset + image_size_w, :]
|
||
return image
|
||
|
||
@staticmethod
|
||
def get_pattern(single_color):
|
||
if single_color is None:
|
||
raise False
|
||
R, G, B = single_color.split(' ')
|
||
pattern = np.zeros([1, 1, 3], np.uint8)
|
||
pattern[0, 0, 0] = int(B)
|
||
pattern[0, 0, 1] = int(G)
|
||
pattern[0, 0, 2] = int(R)
|
||
return pattern
|
||
|
||
|
||
@PIPELINES.register_module()
|
||
class PrintPainting(object):
|
||
def __init__(self, print_flag=True):
|
||
self.print_flag = print_flag
|
||
|
||
# @ RunTime
|
||
def __call__(self, result):
|
||
|
||
if "location" not in result['print'].keys():
|
||
result['print']["location"] = [[0, 0]]
|
||
elif result['print']["location"] == [] or result['print']["location"] is None:
|
||
result['print']["location"] = [[0, 0]]
|
||
if result['print']['IfSingle']:
|
||
if len(result['print']['print_path_list']) > 0:
|
||
print_background = np.zeros((result['pattern_image'].shape[0], result['pattern_image'].shape[1], 3), dtype=np.uint8)
|
||
mask_background = np.zeros((result['pattern_image'].shape[0], result['pattern_image'].shape[1], 3), dtype=np.uint8)
|
||
# print_background = np.full((result['pattern_image'].shape[0], result['pattern_image'].shape[1], 3), 255, dtype=np.uint8)
|
||
for i in range(len(result['print']['print_path_list'])):
|
||
image, image_mode = self.read_image(result['print']['print_path_list'][i])
|
||
if image_mode == "RGBA":
|
||
new_size = (int(image.width * result['print']['print_scale_list'][i]), int(image.height * result['print']['print_scale_list'][i]))
|
||
|
||
mask = image.split()[3]
|
||
resized_source = image.resize(new_size)
|
||
resized_source_mask = mask.resize(new_size)
|
||
|
||
rotated_resized_source = resized_source.rotate(-result['print']['print_angle_list'][i])
|
||
rotated_resized_source_mask = resized_source_mask.rotate(-result['print']['print_angle_list'][i])
|
||
|
||
source_image_pil = Image.fromarray(cv2.cvtColor(print_background, cv2.COLOR_BGR2RGB))
|
||
source_image_pil_mask = Image.fromarray(cv2.cvtColor(mask_background, cv2.COLOR_BGR2RGB))
|
||
|
||
source_image_pil.paste(rotated_resized_source, (int(result['print']['location'][i][0]), int(result['print']['location'][i][1])), rotated_resized_source)
|
||
source_image_pil_mask.paste(rotated_resized_source_mask, (int(result['print']['location'][i][0]), int(result['print']['location'][i][1])), rotated_resized_source_mask)
|
||
|
||
print_background = cv2.cvtColor(np.array(source_image_pil), cv2.COLOR_RGBA2BGR)
|
||
mask_background = cv2.cvtColor(np.array(source_image_pil_mask), cv2.COLOR_RGBA2BGR)
|
||
else:
|
||
mask = self.get_mask_inv(image)
|
||
mask = np.expand_dims(mask, axis=2)
|
||
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
|
||
mask = cv2.bitwise_not(mask)
|
||
# 旋转后的坐标需要重新算
|
||
rotate_mask, _ = self.img_rotate(mask, result['print']['print_angle_list'][i], result['print']['print_scale_list'][i])
|
||
rotate_image, rotated_new_size = self.img_rotate(image, result['print']['print_angle_list'][i], result['print']['print_scale_list'][i])
|
||
# x, y = int(result['print']['location'][i][0] - rotated_new_size[0] - (rotate_mask.shape[0] - image.shape[0]) / 2), int(result['print']['location'][i][1] - rotated_new_size[1] - (rotate_mask.shape[1] - image.shape[1]) / 2)
|
||
x, y = int(result['print']['location'][i][0] - rotated_new_size[0]), int(result['print']['location'][i][1] - rotated_new_size[1])
|
||
|
||
image_x = print_background.shape[1]
|
||
image_y = print_background.shape[0]
|
||
print_x = rotate_image.shape[1]
|
||
print_y = rotate_image.shape[0]
|
||
|
||
# 有bug
|
||
# if x + print_x > image_x:
|
||
# rotate_image = rotate_image[:, :x + print_x - image_x]
|
||
# rotate_mask = rotate_mask[:, :x + print_x - image_x]
|
||
# #
|
||
# if y + print_y > image_y:
|
||
# rotate_image = rotate_image[:y + print_y - image_y]
|
||
# rotate_mask = rotate_mask[:y + print_y - image_y]
|
||
|
||
# 不能是并行
|
||
# 当前第一轮的if (108以及115)是判断有没有过下界和右界。第二轮的是判断左上有没有超出。 如果这个样子的话,先裁了右边,再左移,region就会有问题
|
||
# 先挪 再判断 最后裁剪
|
||
|
||
# 如果print旋转了 或者 print贴边了 则需要判断 判断左界和上界是否小于0
|
||
if x <= 0:
|
||
rotate_image = rotate_image[:, -x:]
|
||
rotate_mask = rotate_mask[:, -x:]
|
||
start_x = x = 0
|
||
else:
|
||
start_x = x
|
||
|
||
if y <= 0:
|
||
rotate_image = rotate_image[-y:, :]
|
||
rotate_mask = rotate_mask[-y:, :]
|
||
start_y = y = 0
|
||
else:
|
||
start_y = y
|
||
|
||
# ------------------
|
||
# 如果print-size大于image-size 则需要裁剪print
|
||
|
||
if x + print_x > image_x:
|
||
rotate_image = rotate_image[:, :image_x - x]
|
||
rotate_mask = rotate_mask[:, :image_x - x]
|
||
|
||
if y + print_y > image_y:
|
||
rotate_image = rotate_image[:image_y - y, :]
|
||
rotate_mask = rotate_mask[:image_y - y, :]
|
||
|
||
# mask_background[start_y:y + rotate_mask.shape[0], start_x:x + rotate_mask.shape[1]] = cv2.bitwise_xor(mask_background[start_y:y + rotate_mask.shape[0], start_x:x + rotate_mask.shape[1]], rotate_mask)
|
||
# print_background[start_y:y + rotate_image.shape[0], start_x:x + rotate_image.shape[1]] = cv2.add(print_background[start_y:y + rotate_image.shape[0], start_x:x + rotate_image.shape[1]], rotate_image)
|
||
|
||
# mask_background[start_y:y + rotate_mask.shape[0], start_x:x + rotate_mask.shape[1]] = rotate_mask
|
||
# print_background[start_y:y + rotate_image.shape[0], start_x:x + rotate_image.shape[1]] = rotate_image
|
||
mask_background = self.stack_prin(mask_background, result['pattern_image'], rotate_mask, start_y, y, start_x, x)
|
||
print_background = self.stack_prin(print_background, result['pattern_image'], rotate_image, start_y, y, start_x, x)
|
||
|
||
# gray_image = cv2.cvtColor(mask_background, cv2.COLOR_BGR2GRAY)
|
||
# print_background = cv2.bitwise_and(print_background, print_background, mask=gray_image)
|
||
|
||
print_mask = cv2.bitwise_and(result['mask'], cv2.cvtColor(mask_background, cv2.COLOR_BGR2GRAY))
|
||
img_fg = cv2.bitwise_or(print_background, print_background, mask=print_mask)
|
||
img_bg = cv2.bitwise_and(result['pattern_image'], result['pattern_image'], mask=cv2.bitwise_not(print_mask))
|
||
mask_mo = np.expand_dims(print_mask, axis=2).repeat(3, axis=2)
|
||
gray_mo = np.expand_dims(result['gray'], axis=2).repeat(3, axis=2)
|
||
img_fg = (img_fg * (mask_mo / 255) * (gray_mo / 255)).astype(np.uint8)
|
||
result['final_image'] = cv2.add(img_bg, img_fg)
|
||
canvas = np.full_like(result['final_image'], 255)
|
||
temp_bg = np.expand_dims(cv2.bitwise_not(result['mask']), axis=2).repeat(3, axis=2)
|
||
tmp1 = (canvas * (temp_bg / 255)).astype(np.uint8)
|
||
temp_fg = np.expand_dims(result['mask'], axis=2).repeat(3, axis=2)
|
||
tmp2 = (result['final_image'] * (temp_fg / 255)).astype(np.uint8)
|
||
result['single_image'] = cv2.add(tmp1, tmp2)
|
||
else:
|
||
painting_dict = {}
|
||
painting_dict['dim_image_h'], painting_dict['dim_image_w'] = result['pattern_image'].shape[0:2]
|
||
|
||
# no print
|
||
if len(result['print_dict']['print_path_list']) == 0 or not self.print_flag:
|
||
result['print_image'] = result['pattern_image']
|
||
# print
|
||
else:
|
||
painting_dict = self.painting_collection(painting_dict, result, print_trigger=True)
|
||
result['print_image'] = self.printpaint(result, painting_dict, print_=True)
|
||
result['final_image'] = result['print_image']
|
||
canvas = np.full_like(result['final_image'], 255)
|
||
temp_bg = np.expand_dims(cv2.bitwise_not(result['mask']), axis=2).repeat(3, axis=2)
|
||
tmp1 = (canvas * (temp_bg / 255)).astype(np.uint8)
|
||
temp_fg = np.expand_dims(result['mask'], axis=2).repeat(3, axis=2)
|
||
tmp2 = (result['final_image'] * (temp_fg / 255)).astype(np.uint8)
|
||
result['single_image'] = cv2.add(tmp1, tmp2)
|
||
|
||
if "element" in result.keys():
|
||
print_background = np.zeros((result['final_image'].shape[0], result['final_image'].shape[1], 3), dtype=np.uint8)
|
||
mask_background = np.zeros((result['final_image'].shape[0], result['final_image'].shape[1], 3), dtype=np.uint8)
|
||
for i in range(len(result['element']['element_path_list'])):
|
||
image, image_mode = self.read_image(result['element']['element_path_list'][i])
|
||
if image_mode == "RGBA":
|
||
new_size = (int(image.width * result['element']['element_scale_list'][i]), int(image.height * result['element']['element_scale_list'][i]))
|
||
|
||
mask = image.split()[3]
|
||
resized_source = image.resize(new_size)
|
||
resized_source_mask = mask.resize(new_size)
|
||
|
||
rotated_resized_source = resized_source.rotate(-result['element']['element_angle_list'][i])
|
||
rotated_resized_source_mask = resized_source_mask.rotate(-result['element']['element_angle_list'][i])
|
||
|
||
source_image_pil = Image.fromarray(cv2.cvtColor(print_background, cv2.COLOR_BGR2RGB))
|
||
source_image_pil_mask = Image.fromarray(cv2.cvtColor(mask_background, cv2.COLOR_BGR2RGB))
|
||
|
||
source_image_pil.paste(rotated_resized_source, (int(result['element']['location'][i][0]), int(result['element']['location'][i][1])), rotated_resized_source)
|
||
source_image_pil_mask.paste(rotated_resized_source_mask, (int(result['element']['location'][i][0]), int(result['element']['location'][i][1])), rotated_resized_source_mask)
|
||
|
||
print_background = cv2.cvtColor(np.array(source_image_pil), cv2.COLOR_RGBA2BGR)
|
||
mask_background = cv2.cvtColor(np.array(source_image_pil_mask), cv2.COLOR_RGBA2BGR)
|
||
print(1)
|
||
else:
|
||
mask = self.get_mask_inv(image)
|
||
mask = np.expand_dims(mask, axis=2)
|
||
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
|
||
mask = cv2.bitwise_not(mask)
|
||
# 旋转后的坐标需要重新算
|
||
rotate_mask, _ = self.img_rotate(mask, result['element']['element_angle_list'][i], result['element']['element_scale_list'][i])
|
||
rotate_image, rotated_new_size = self.img_rotate(image, result['element']['element_angle_list'][i], result['element']['element_scale_list'][i])
|
||
# x, y = int(result['print']['location'][i][0] - rotated_new_size[0] - (rotate_mask.shape[0] - image.shape[0]) / 2), int(result['print']['location'][i][1] - rotated_new_size[1] - (rotate_mask.shape[1] - image.shape[1]) / 2)
|
||
x, y = int(result['element']['location'][i][0] - rotated_new_size[0]), int(result['element']['location'][i][1] - rotated_new_size[1])
|
||
|
||
image_x = print_background.shape[1]
|
||
image_y = print_background.shape[0]
|
||
print_x = rotate_image.shape[1]
|
||
print_y = rotate_image.shape[0]
|
||
|
||
# 有bug
|
||
# if x + print_x > image_x:
|
||
# rotate_image = rotate_image[:, :x + print_x - image_x]
|
||
# rotate_mask = rotate_mask[:, :x + print_x - image_x]
|
||
# #
|
||
# if y + print_y > image_y:
|
||
# rotate_image = rotate_image[:y + print_y - image_y]
|
||
# rotate_mask = rotate_mask[:y + print_y - image_y]
|
||
|
||
# 不能是并行
|
||
# 当前第一轮的if (108以及115)是判断有没有过下界和右界。第二轮的是判断左上有没有超出。 如果这个样子的话,先裁了右边,再左移,region就会有问题
|
||
# 先挪 再判断 最后裁剪
|
||
|
||
# 如果print旋转了 或者 print贴边了 则需要判断 判断左界和上界是否小于0
|
||
if x <= 0:
|
||
rotate_image = rotate_image[:, -x:]
|
||
rotate_mask = rotate_mask[:, -x:]
|
||
start_x = x = 0
|
||
else:
|
||
start_x = x
|
||
|
||
if y <= 0:
|
||
rotate_image = rotate_image[-y:, :]
|
||
rotate_mask = rotate_mask[-y:, :]
|
||
start_y = y = 0
|
||
else:
|
||
start_y = y
|
||
|
||
# ------------------
|
||
# 如果print-size大于image-size 则需要裁剪print
|
||
|
||
if x + print_x > image_x:
|
||
rotate_image = rotate_image[:, :image_x - x]
|
||
rotate_mask = rotate_mask[:, :image_x - x]
|
||
|
||
if y + print_y > image_y:
|
||
rotate_image = rotate_image[:image_y - y, :]
|
||
rotate_mask = rotate_mask[:image_y - y, :]
|
||
|
||
# mask_background[start_y:y + rotate_mask.shape[0], start_x:x + rotate_mask.shape[1]] = cv2.bitwise_xor(mask_background[start_y:y + rotate_mask.shape[0], start_x:x + rotate_mask.shape[1]], rotate_mask)
|
||
# print_background[start_y:y + rotate_image.shape[0], start_x:x + rotate_image.shape[1]] = cv2.add(print_background[start_y:y + rotate_image.shape[0], start_x:x + rotate_image.shape[1]], rotate_image)
|
||
|
||
# mask_background[start_y:y + rotate_mask.shape[0], start_x:x + rotate_mask.shape[1]] = rotate_mask
|
||
# print_background[start_y:y + rotate_image.shape[0], start_x:x + rotate_image.shape[1]] = rotate_image
|
||
mask_background = self.stack_prin(mask_background, result['pattern_image'], rotate_mask, start_y, y, start_x, x)
|
||
print_background = self.stack_prin(print_background, result['pattern_image'], rotate_image, start_y, y, start_x, x)
|
||
|
||
# gray_image = cv2.cvtColor(mask_background, cv2.COLOR_BGR2GRAY)
|
||
# print_background = cv2.bitwise_and(print_background, print_background, mask=gray_image)
|
||
|
||
print_mask = cv2.bitwise_and(result['mask'], cv2.cvtColor(mask_background, cv2.COLOR_BGR2GRAY))
|
||
img_fg = cv2.bitwise_or(print_background, print_background, mask=print_mask)
|
||
# TODO element 丢失信息
|
||
three_channel_image = cv2.merge([cv2.bitwise_not(print_mask), cv2.bitwise_not(print_mask), cv2.bitwise_not(print_mask)])
|
||
img_bg = cv2.bitwise_and(result['final_image'], three_channel_image)
|
||
# mask_mo = np.expand_dims(print_mask, axis=2).repeat(3, axis=2)
|
||
# gray_mo = np.expand_dims(result['gray'], axis=2).repeat(3, axis=2)
|
||
# img_fg = (img_fg * (mask_mo / 255) * (gray_mo / 255)).astype(np.uint8)
|
||
result['final_image'] = cv2.add(img_bg, img_fg)
|
||
canvas = np.full_like(result['final_image'], 255)
|
||
temp_bg = np.expand_dims(cv2.bitwise_not(result['mask']), axis=2).repeat(3, axis=2)
|
||
tmp1 = (canvas * (temp_bg / 255)).astype(np.uint8)
|
||
temp_fg = np.expand_dims(result['mask'], axis=2).repeat(3, axis=2)
|
||
tmp2 = (result['final_image'] * (temp_fg / 255)).astype(np.uint8)
|
||
result['single_image'] = cv2.add(tmp1, tmp2)
|
||
return result
|
||
|
||
@staticmethod
|
||
def stack_prin(print_background, pattern_image, rotate_image, start_y, y, start_x, x):
|
||
temp_print = np.zeros((pattern_image.shape[0], pattern_image.shape[1], 3), dtype=np.uint8)
|
||
|
||
temp_print[start_y:y + rotate_image.shape[0], start_x:x + rotate_image.shape[1]] = rotate_image
|
||
|
||
img2gray = cv2.cvtColor(print_background, cv2.COLOR_BGR2GRAY)
|
||
|
||
ret, mask_ = cv2.threshold(img2gray, 1, 255, cv2.THRESH_BINARY)
|
||
|
||
mask_inv = cv2.bitwise_not(mask_)
|
||
|
||
img1_bg = cv2.bitwise_and(print_background, print_background, mask=mask_)
|
||
|
||
img2_fg = cv2.bitwise_and(temp_print, temp_print, mask=mask_inv)
|
||
|
||
print_background = img1_bg + img2_fg
|
||
|
||
return print_background
|
||
|
||
def painting_collection(self, painting_dict, result, print_trigger=False):
|
||
if print_trigger:
|
||
print_ = self.get_print(result['print_dict'])
|
||
painting_dict['Trigger'] = not print_['IfSingle']
|
||
painting_dict['location'] = print_['location'] if 'location' in print_.keys() else None
|
||
single_mask_inv_print = self.get_mask_inv(print_['image'])
|
||
dim_max = max(painting_dict['dim_image_h'], painting_dict['dim_image_w'])
|
||
dim_pattern = (int(dim_max * print_['scale'] / 5), int(dim_max * print_['scale'] / 5))
|
||
if not print_['IfSingle']:
|
||
self.random_seed = random.randint(0, 1000)
|
||
painting_dict['mask_inv_print'] = self.tile_image(single_mask_inv_print, dim_pattern, print_['scale'], painting_dict['dim_image_h'], painting_dict['dim_image_w'], painting_dict['location'], trigger=True)
|
||
painting_dict['tile_print'] = self.tile_image(print_['image'], dim_pattern, print_['scale'], painting_dict['dim_image_h'], painting_dict['dim_image_w'], painting_dict['location'], trigger=True)
|
||
else:
|
||
painting_dict['mask_inv_print'] = self.tile_image(single_mask_inv_print, dim_pattern, print_['scale'], painting_dict['dim_image_h'], painting_dict['dim_image_w'], painting_dict['location'])
|
||
painting_dict['tile_print'] = self.tile_image(print_['image'], dim_pattern, print_['scale'], painting_dict['dim_image_h'], painting_dict['dim_image_w'], painting_dict['location'])
|
||
painting_dict['dim_print_h'], painting_dict['dim_print_w'] = dim_pattern
|
||
return painting_dict
|
||
|
||
def tile_image(self, pattern, dim, scale, dim_image_h, dim_image_w, location, trigger=False):
|
||
tile = None
|
||
if not trigger:
|
||
tile = cv2.resize(pattern, dim, interpolation=cv2.INTER_AREA)
|
||
else:
|
||
resize_pattern = cv2.resize(pattern, dim, interpolation=cv2.INTER_AREA)
|
||
if len(pattern.shape) == 2:
|
||
tile = np.tile(resize_pattern, (int((5 + 1) / scale) + 4, int((5 + 1) / scale) + 4))
|
||
if len(pattern.shape) == 3:
|
||
tile = np.tile(resize_pattern, (int((5 + 1) / scale) + 4, int((5 + 1) / scale) + 4, 1))
|
||
tile = self.crop_image(tile, dim_image_h, dim_image_w, location, resize_pattern.shape)
|
||
return tile
|
||
|
||
def get_mask_inv(self, print_):
|
||
if print_[0][0][0] == 255 and print_[0][0][1] == 255 and print_[0][0][2] == 255:
|
||
bg_color = cv2.cvtColor(print_, cv2.COLOR_BGR2LAB)[0][0]
|
||
print_tile = cv2.cvtColor(print_, cv2.COLOR_BGR2LAB)
|
||
bg_l, bg_a, bg_b = bg_color[0], bg_color[1], bg_color[2]
|
||
bg_L_high, bg_L_low = self.get_low_high_lab(bg_l, L=True)
|
||
bg_a_high, bg_a_low = self.get_low_high_lab(bg_a)
|
||
bg_b_high, bg_b_low = self.get_low_high_lab(bg_b)
|
||
lower = np.array([bg_L_low, bg_a_low, bg_b_low])
|
||
upper = np.array([bg_L_high, bg_a_high, bg_b_high])
|
||
mask_inv = cv2.inRange(print_tile, lower, upper)
|
||
return mask_inv
|
||
else:
|
||
# bg_color = cv2.cvtColor(print_, cv2.COLOR_BGR2LAB)[0][0]
|
||
# print_tile = cv2.cvtColor(print_, cv2.COLOR_BGR2LAB)
|
||
# bg_l, bg_a, bg_b = bg_color[0], bg_color[1], bg_color[2]
|
||
# bg_L_high, bg_L_low = self.get_low_high_lab(bg_l, L=True)
|
||
# bg_a_high, bg_a_low = self.get_low_high_lab(bg_a)
|
||
# bg_b_high, bg_b_low = self.get_low_high_lab(bg_b)
|
||
# lower = np.array([bg_L_low, bg_a_low, bg_b_low])
|
||
# upper = np.array([bg_L_high, bg_a_high, bg_b_high])
|
||
|
||
# print_tile = cv2.cvtColor(print_, cv2.COLOR_BGR2LAB)
|
||
# mask_inv = cv2.cvtColor(print_tile, cv2.COLOR_BGR2GRAY)
|
||
|
||
# mask_inv = cv2.cvtColor(print_, cv2.COLOR_BGR2GRAY)
|
||
mask_inv = np.zeros(print_.shape[:2], dtype=np.uint8)
|
||
return mask_inv
|
||
|
||
@staticmethod
|
||
def printpaint(result, painting_dict, print_=False):
|
||
|
||
if print_ and painting_dict['Trigger']:
|
||
print_mask = cv2.bitwise_and(result['mask'], cv2.bitwise_not(painting_dict['mask_inv_print']))
|
||
img_fg = cv2.bitwise_and(painting_dict['tile_print'], painting_dict['tile_print'], mask=print_mask)
|
||
else:
|
||
print_mask = result['mask']
|
||
img_fg = result['final_image']
|
||
if print_ and not painting_dict['Trigger']:
|
||
index_ = None
|
||
try:
|
||
index_ = len(painting_dict['location'])
|
||
except:
|
||
assert f'there must be parameter of location if choose IfSingle'
|
||
|
||
for i in range(index_):
|
||
start_h, start_w = int(painting_dict['location'][i][1]), int(painting_dict['location'][i][0])
|
||
|
||
length_h = min(start_h + painting_dict['dim_print_h'], img_fg.shape[0])
|
||
length_w = min(start_w + painting_dict['dim_print_w'], img_fg.shape[1])
|
||
|
||
change_region = img_fg[start_h: length_h, start_w: length_w, :]
|
||
# problem in change_mask
|
||
change_mask = print_mask[start_h: length_h, start_w: length_w]
|
||
# get real part into change mask
|
||
_, change_mask = cv2.threshold(change_mask, 220, 255, cv2.THRESH_BINARY)
|
||
mask = cv2.bitwise_not(painting_dict['mask_inv_print'])
|
||
img_fg[start_h:start_h + painting_dict['dim_print_h'], start_w:start_w + painting_dict['dim_print_w'], :] = change_region
|
||
|
||
clothes_mask_print = cv2.bitwise_not(print_mask)
|
||
|
||
img_bg = cv2.bitwise_and(result['pattern_image'], result['pattern_image'], mask=clothes_mask_print)
|
||
mask_mo = np.expand_dims(print_mask, axis=2).repeat(3, axis=2)
|
||
gray_mo = np.expand_dims(result['gray'], axis=2).repeat(3, axis=2)
|
||
img_fg = (img_fg * (mask_mo / 255) * (gray_mo / 255)).astype(np.uint8)
|
||
print_image = cv2.add(img_bg, img_fg)
|
||
return print_image
|
||
|
||
@staticmethod
|
||
def get_print(print_dict):
|
||
if not 'print_scale_list' in print_dict.keys() or print_dict['print_scale_list'][0] < 0.3:
|
||
print_dict['scale'] = 0.3
|
||
else:
|
||
print_dict['scale'] = print_dict['print_scale_list'][0]
|
||
|
||
if not 'IfSingle' in print_dict.keys():
|
||
print_dict['IfSingle'] = False
|
||
|
||
# data = minio_client.get_object(print_dict['print_path_list'][0].split("/", 1)[0], print_dict['print_path_list'][0].split("/", 1)[1])
|
||
# data_bytes = BytesIO(data.read())
|
||
# image = Image.open(data_bytes)
|
||
# image_mode = image.mode
|
||
|
||
bucket_name = print_dict['print_path_list'][0].split("/", 1)[0]
|
||
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")
|
||
# 判断图片格式,如果是RGBA 则贴在一张纯白图片上 防止透明转黑
|
||
if image.mode == "RGBA":
|
||
new_background = Image.new('RGB', image.size, (255, 255, 255))
|
||
new_background.paste(image, mask=image.split()[3])
|
||
image = new_background
|
||
print_dict['image'] = cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)
|
||
|
||
# file = minio_client.get_object(print_dict['print_path_list'][0].split("/", 1)[0], print_dict['print_path_list'][0].split("/", 1)[1]).data
|
||
# print_dict['image'] = cv2.imdecode(np.fromstring(file, np.uint8), 1)
|
||
|
||
# image = cv2.imdecode(np.frombuffer(file, np.uint8), 1)
|
||
# return image
|
||
|
||
return print_dict
|
||
|
||
def crop_image(self, image, image_size_h, image_size_w, location, print_shape):
|
||
print_w = print_shape[1]
|
||
print_h = print_shape[0]
|
||
|
||
random.seed(self.random_seed)
|
||
# logging.info(f'overall print location : {location}')
|
||
# x_offset = random.randint(0, image.shape[0] - image_size_h)
|
||
# y_offset = random.randint(0, image.shape[1] - image_size_w)
|
||
|
||
# 1.拿到偏移量后和resize后的print宽高取余 得到真正偏移量
|
||
x_offset = print_w - int(location[0][1] % print_w)
|
||
y_offset = print_w - int(location[0][0] % print_h)
|
||
|
||
# y_offset = int(location[0][0])
|
||
# x_offset = int(location[0][1])
|
||
|
||
if len(image.shape) == 2:
|
||
image = image[x_offset: x_offset + image_size_h, y_offset: y_offset + image_size_w]
|
||
elif len(image.shape) == 3:
|
||
image = image[x_offset: x_offset + image_size_h, y_offset: y_offset + image_size_w, :]
|
||
return image
|
||
|
||
@staticmethod
|
||
def get_low_high_lab(Lab_value, L=False):
|
||
if L:
|
||
high = Lab_value + 30 if Lab_value + 30 < 255 else 255
|
||
low = Lab_value - 30 if Lab_value - 30 > 0 else 0
|
||
else:
|
||
high = Lab_value + 30 if Lab_value + 30 < 255 else 255
|
||
low = Lab_value - 30 if Lab_value - 30 > 0 else 0
|
||
return high, low
|
||
|
||
@staticmethod
|
||
def img_rotate(image, angel, scale):
|
||
"""顺时针旋转图像任意角度
|
||
|
||
Args:
|
||
image (np.array): [原始图像]
|
||
angel (float): [逆时针旋转的角度]
|
||
|
||
Returns:
|
||
[array]: [旋转后的图像]
|
||
"""
|
||
|
||
h, w = image.shape[:2]
|
||
center = (w // 2, h // 2)
|
||
# if type(angel) is not int:
|
||
# angel = 0
|
||
M = cv2.getRotationMatrix2D(center, -angel, scale)
|
||
# 调整旋转后的图像长宽
|
||
rotated_h = int((w * np.abs(M[0, 1]) + (h * np.abs(M[0, 0]))))
|
||
rotated_w = int((h * np.abs(M[0, 1]) + (w * np.abs(M[0, 0]))))
|
||
M[0, 2] += (rotated_w - w) // 2
|
||
M[1, 2] += (rotated_h - h) // 2
|
||
# 旋转图像
|
||
rotated_img = cv2.warpAffine(image, M, (rotated_w, rotated_h))
|
||
|
||
return rotated_img, ((rotated_img.shape[1] - image.shape[1] * scale) // 2, (rotated_img.shape[0] - image.shape[0] * scale) // 2)
|
||
# return rotated_img, (0, 0)
|
||
|
||
@staticmethod
|
||
def read_image(image_url):
|
||
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:
|
||
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGRA2RGBA)
|
||
image = Image.fromarray(image_rgb)
|
||
image_mode = "RGBA"
|
||
else:
|
||
image_mode = "RGB"
|
||
return image, image_mode
|
||
|
||
# data = minio_client.get_object(image_url.split("/", 1)[0], image_url.split("/", 1)[1])
|
||
# # data = s3.get_object(Bucket=image_url.split("/", 1)[0], Key=image_url.split("/", 1)[1])['Body']
|
||
#
|
||
# data_bytes = BytesIO(data.read())
|
||
# image = Image.open(data_bytes)
|
||
# image_mode = image.mode
|
||
# # 判断图片格式,如果是RGBA 则贴在一张纯白图片上 防止透明转黑
|
||
# if image_mode == "RGBA":
|
||
# # new_background = Image.new('RGB', image.size, (255, 255, 255))
|
||
# # new_background.paste(image, mask=image.split()[3])
|
||
# # image = new_background
|
||
# return image, image_mode
|
||
# image = cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)
|
||
# return image, "RGB"
|
||
|
||
# @staticmethod
|
||
# def read_image(image_url):
|
||
# response = requests.get(image_url)
|
||
# image_data = np.frombuffer(response.content, np.uint8)
|
||
#
|
||
# # 解码图像
|
||
# image = cv2.imdecode(image_data, 3)
|
||
# return image
|