Spaces:
Running
on
Zero
Running
on
Zero
# Open Source Model Licensed under the Apache License Version 2.0 and Other Licenses of the Third-Party Components therein: | |
# The below Model in this distribution may have been modified by THL A29 Limited ("Tencent Modifications"). All Tencent Modifications are Copyright (C) 2024 THL A29 Limited. | |
# Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. | |
# The below software and/or models in this distribution may have been | |
# modified by THL A29 Limited ("Tencent Modifications"). | |
# All Tencent Modifications are Copyright (C) THL A29 Limited. | |
# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT | |
# except for the third-party components listed below. | |
# Hunyuan 3D does not impose any additional limitations beyond what is outlined | |
# in the repsective licenses of these third-party components. | |
# Users must comply with all terms and conditions of original licenses of these third-party | |
# components and must ensure that the usage of the third party components adheres to | |
# all relevant laws and regulations. | |
# For avoidance of doubts, Hunyuan 3D means the large language models and | |
# their software and algorithms, including trained model weights, parameters (including | |
# optimizer states), machine-learning model code, inference-enabling code, training-enabling code, | |
# fine-tuning enabling code and other elements of the foregoing made publicly available | |
# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT. | |
import numpy as np | |
from PIL import Image | |
def to_rgb_image(maybe_rgba: Image.Image): | |
''' | |
convert a PIL.Image to rgb mode with white background | |
maybe_rgba: PIL.Image | |
return: PIL.Image | |
''' | |
if maybe_rgba.mode == 'RGB': | |
return maybe_rgba | |
elif maybe_rgba.mode == 'RGBA': | |
rgba = maybe_rgba | |
img = np.random.randint(255, 256, size=[rgba.size[1], rgba.size[0], 3], dtype=np.uint8) | |
img = Image.fromarray(img, 'RGB') | |
img.paste(rgba, mask=rgba.getchannel('A')) | |
return img | |
else: | |
raise ValueError("Unsupported image type.", maybe_rgba.mode) | |
def white_out_background(pil_img, is_gray_fg=True): | |
data = pil_img.getdata() | |
new_data = [] | |
# convert fore-ground white to gray | |
for r, g, b, a in data: | |
if a < 16: | |
new_data.append((255, 255, 255, 0)) # back-ground to be black | |
else: | |
is_white = is_gray_fg and (r>235) and (g>235) and (b>235) | |
new_r = 235 if is_white else r | |
new_g = 235 if is_white else g | |
new_b = 235 if is_white else b | |
new_data.append((new_r, new_g, new_b, a)) | |
pil_img.putdata(new_data) | |
return pil_img | |
def recenter_img(img, size=512, color=(255,255,255)): | |
img = white_out_background(img) | |
mask = np.array(img)[..., 3] | |
image = np.array(img)[..., :3] | |
H, W, C = image.shape | |
coords = np.nonzero(mask) | |
x_min, x_max = coords[0].min(), coords[0].max() | |
y_min, y_max = coords[1].min(), coords[1].max() | |
h = x_max - x_min | |
w = y_max - y_min | |
if h == 0 or w == 0: raise ValueError | |
roi = image[x_min:x_max, y_min:y_max] | |
border_ratio = 0.15 # 0.2 | |
pad_h = int(h * border_ratio) | |
pad_w = int(w * border_ratio) | |
result_tmp = np.full((h + pad_h, w + pad_w, C), color, dtype=np.uint8) | |
result_tmp[pad_h // 2: pad_h // 2 + h, pad_w // 2: pad_w // 2 + w] = roi | |
cur_h, cur_w = result_tmp.shape[:2] | |
side = max(cur_h, cur_w) | |
result = np.full((side, side, C), color, dtype=np.uint8) | |
result[(side-cur_h)//2:(side-cur_h)//2+cur_h, (side-cur_w)//2:(side - cur_w)//2+cur_w,:] = result_tmp | |
result = Image.fromarray(result) | |
return result.resize((size, size), Image.LANCZOS) if size else result |