Spaces:
No application file
No application file
import argparse | |
import os | |
os.environ['CUDA_HOME'] = '/usr/local/cuda' | |
os.environ['PATH'] = os.environ['PATH'] + ':/usr/local/cuda/bin' | |
from datetime import datetime | |
import numpy as np | |
import torch | |
from diffusers.image_processor import VaeImageProcessor | |
from huggingface_hub import snapshot_download | |
from PIL import Image | |
torch.jit.script = lambda f: f | |
from model.cloth_masker import AutoMasker, vis_mask | |
from model.pipeline import CatVTONPipeline | |
from utils import init_weight_dtype, resize_and_crop, resize_and_padding | |
# ํจํค์ง ์ถ๊ฐ | |
import cv2 | |
''' | |
def parse_args(): | |
parser = argparse.ArgumentParser(description="Simple example of a training script.") | |
parser.add_argument( | |
"--base_model_path", | |
type=str, | |
default="booksforcharlie/stable-diffusion-inpainting", | |
# default="runwayml/stable-diffusion-inpainting", | |
help=( | |
"The path to the base model to use for evaluation. This can be a local path or a model identifier from the Model Hub." | |
), | |
) | |
parser.add_argument( | |
"--resume_path", | |
type=str, | |
default="zhengchong/CatVTON", | |
help=( | |
"The Path to the checkpoint of trained tryon model." | |
), | |
) | |
parser.add_argument( | |
"--output_dir", | |
type=str, | |
default="resource/demo/output", | |
help="The output directory where the model predictions will be written.", | |
) | |
parser.add_argument( | |
"--width", | |
type=int, | |
default=768, | |
help=( | |
"The resolution for input images, all the images in the train/validation dataset will be resized to this" | |
" resolution" | |
), | |
) | |
parser.add_argument( | |
"--height", | |
type=int, | |
default=1024, | |
help=( | |
"The resolution for input images, all the images in the train/validation dataset will be resized to this" | |
" resolution" | |
), | |
) | |
parser.add_argument( | |
"--repaint", | |
action="store_true", | |
help="Whether to repaint the result image with the original background." | |
) | |
parser.add_argument( | |
"--allow_tf32", | |
action="store_true", | |
default=True, | |
help=( | |
"Whether or not to allow TF32 on Ampere GPUs. Can be used to speed up training. For more information, see" | |
" https://pytorch.org/docs/stable/notes/cuda.html#tensorfloat-32-tf32-on-ampere-devices" | |
), | |
) | |
parser.add_argument( | |
"--mixed_precision", | |
type=str, | |
default="no", | |
choices=["no", "fp16", "bf16"], | |
help=( | |
"Whether to use mixed precision. Choose between fp16 and bf16 (bfloat16). Bf16 requires PyTorch >=" | |
" 1.10.and an Nvidia Ampere GPU. Default to the value of accelerate config of the current system or the" | |
" flag passed with the `accelerate.launch` command. Use this argument to override the accelerate config." | |
), | |
) | |
args = parser.parse_args() | |
env_local_rank = int(os.environ.get("LOCAL_RANK", -1)) | |
if env_local_rank != -1 and env_local_rank != args.local_rank: | |
args.local_rank = env_local_rank | |
return args | |
args = parse_args() | |
''' | |
RESUME_PATH = os.getenv("RESUME_PATH", "zhengchong/CatVTON") | |
repo_path = snapshot_download(repo_id=RESUME_PATH) | |
# AutoMasker | |
mask_processor = VaeImageProcessor(vae_scale_factor=8, do_normalize=False, do_binarize=True, do_convert_grayscale=True) | |
automasker = AutoMasker( | |
densepose_ckpt=os.path.join(repo_path, "DensePose"), | |
schp_ckpt=os.path.join(repo_path, "SCHP"), | |
device='cuda', | |
) | |
person_image = Image.open("./resource/demo/example/person/men/model_7.png").convert("RGB") | |
mask = automasker( | |
person_image, | |
'upper' | |
)['mask'] # ์ฌ๊ธฐ์ ๋ฆฌํด๋๋ mask๋ PIL ์ด๋ฏธ์ง์.(cloth_masker.py ์ฐธ์กฐ) # ์ฐธ๊ณ ๋ก ['densepose']๋ก densepose๋ ํ์ธ๊ฐ๋ฅ. | |
### ์ฌ๊ธฐ์ mask modify์ ์ฌ์ฉ๋ ์ฝ๋๋ฅผ app.py์ ์ฒดํฌํด๋์ ๋ถ๋ถ์ ์ถ๊ฐํ๋ฉด ๋๋ค! | |
def remove_bottom_part(mask: np.ndarray, y_threshold: int): | |
""" | |
์ด๋ฏธ์ง์ y_threshold ์๋์ ์๋ ๋ถ๋ถ์ ์ญ์ . | |
:param mask: ์ ๋ ฅ ๋ง์คํฌ (numpy ๋ฐฐ์ด) | |
:param y_threshold: ์ ๊ฑฐํ Y ์ขํ ๊ฐ | |
:return: ์์ ๋ ๋ง์คํฌ (numpy ๋ฐฐ์ด) | |
""" | |
# y_threshold ์๋์ ๋ชจ๋ ํฝ์ ์ 0์ผ๋ก ์ค์ | |
mask[y_threshold:, :] = 0 | |
return Image.fromarray(mask) | |
# closing ์ฐ์ฐ / fitting_mode๊ฐ standard ๋ loose ์ผ๋๋ง ์ฌ์ฉํ๊ธฐ | |
def morph_close(mask): | |
mask_np = np.array(mask) | |
kernel = np.ones((30, 30), np.uint8) # ์ปค์ง์๋ก ์ ์ฐ๊ฒฐ๋จ | |
closed_mask = cv2.morphologyEx(mask_np, cv2.MORPH_CLOSE, kernel) | |
return Image.fromarray(closed_mask) | |
# opening ์ฐ์ฐ / fitting_mode๊ฐ standard ๋ loose ์ผ๋๋ง ์ฌ์ฉํ๊ธฐ | |
def morph_open(mask): | |
mask_np = np.array(mask) | |
kernel = np.ones((30, 30), np.uint8) # ์ปค์ง์๋ก ์ ์ฌ๋ผ์ง | |
#closed_mask = cv2.morphologyEx(mask_np, cv2.MORPH_CLOSE, kernel) | |
opened_mask = cv2.morphologyEx(mask_np, cv2.MORPH_OPEN, kernel) #opened_mask๋ numpy ์ฐ์ฐ ๊ฒฐ๊ณผ ์ด๋ฏ๋ก PIL ์ด๋ฏธ์ง๋ก ๋ณํ ํ์ | |
return Image.fromarray(opened_mask) | |
def morph_open2(mask): | |
mask_np = np.array(mask) | |
kernel = np.ones((10, 10), np.uint8) # ์ปค์ง์๋ก ์ ์ฌ๋ผ์ง | |
#closed_mask = cv2.morphologyEx(mask_np, cv2.MORPH_CLOSE, kernel) | |
opened_mask = cv2.morphologyEx(mask_np, cv2.MORPH_OPEN, kernel) #opened_mask๋ numpy ์ฐ์ฐ ๊ฒฐ๊ณผ ์ด๋ฏ๋ก PIL ์ด๋ฏธ์ง๋ก ๋ณํ ํ์ | |
return Image.fromarray(opened_mask) | |
## opened_mask = morph_open(mask) | |
## opened_mask.save('./opened_mask.png') #opened_mask๋ PIL ์ด๋ฏธ์ง ํํ๋ก ๋ฐํ๋์์ผ๋ฏ๋ก (Image.fromarray()์ฌ์ฉํด์) .save๋ฅผ ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋ค. | |
#opened_mask2 = morph_open2(mask) | |
#kernel = np.ones((50, 50), np.uint8) | |
#opened_mask2 = cv2.dilate(np.array(opened_mask2), kernel, iterations=1) | |
#opened_mask2 = Image.fromarray(opened_mask2) | |
#opened_mask2 = mask_processor.blur(opened_mask2, blur_factor=9) | |
#opened_mask2.save('./opened_mask2.png') | |
# mask = mask_processor.blur(mask, blur_factor=9) | |
## mask.save("./test_mask.png") # ๋ง์คํฌ๋ฅผ PNG ํ์ผ๋ก ์ ์ฅ | |
## masked_person = vis_mask(person_image, mask) # app.py์์๋ blur ์ฒ๋ฆฌ ํ ๋ค์์ vis_mask ๋ฉ์๋ ํธ์ถํจ. | |
## masked_person.save("./test_masked_person.png") # ๋ง์คํฌ์ target img๊ฐ ํฉ์ณ์ง ์ฌ์ง์ PNG ํ์ผ๋ก ์ ์ฅ | |
# mask์ y์ถ ์์ ๋ฐฉํฅ ์ด๋ | |
def extend_mask_downward(mask_image: np.ndarray, pixels: int) -> np.ndarray: | |
""" | |
y์ถ ์์ ๋ฐฉํฅ์ผ๋ก (์๋๋ก) ๋ง์คํฌ ์ด๋ฏธ์ง๋ฅผ ํ์ฅํ๋ ํจ์. | |
:param mask_image: ๋ง์คํฌ ์ด๋ฏธ์ง (numpy ๋ฐฐ์ด) | |
:param pixels: ํ์ฅํ ํฝ์ ์ | |
:return: ํ์ฅ๋ ๋ง์คํฌ ์ด๋ฏธ์ง (numpy ๋ฐฐ์ด) | |
""" | |
# ์ด์งํ๋ ๋ง์คํฌ๋ฅผ ๋ง๋ฆ | |
mask = cv2.threshold(mask_image, 127, 255, cv2.THRESH_BINARY)[1] | |
# ํ์ฅ์ ์ํ ์ปค๋. y์ถ์ผ๋ก๋ง ํ์ฅํ๊ธฐ ์ํด ์ธ๋ก ๊ธธ์ด๋ฅผ ํฌ๊ฒ ์ค์ ํจ | |
kernel = np.zeros((pixels, 1), np.uint8) # y์ถ์ผ๋ก๋ง ๊ธธ์ด์ง ์ปค๋ | |
# y์ถ ์์ ๋ฐฉํฅ์ผ๋ก๋ง ํ์ฅ (cv2.dilate ์ฌ์ฉ) | |
extended_mask = cv2.dilate(mask, kernel, iterations=1) | |
return Image.fromarray(extended_mask) | |
def image_equal(img1, img2): | |
return np.array_equal(np.array(img1), np.array(img2)) | |
# automasker์ ๋ํ fitting ์ ๋๋ฅผ default ์ฒ๋ฆฌํ๊ธฐ ์ํ ์ฝ๋ ์ถ๊ฐ. | |
def extend_mask_downward2(mask_image: np.ndarray, pixels: int) -> Image.Image: | |
# ์ด์งํ๋ ๋ง์คํฌ๋ฅผ ๋ง๋ฆ | |
mask = cv2.threshold(mask_image, 127, 255, cv2.THRESH_BINARY)[1] | |
height, width = mask.shape[:2] | |
# ๋ง์คํฌ๊ฐ ์์ํ๋ y ์ขํ์ ๋๋๋ y ์ขํ ์ฐพ๊ธฐ | |
non_zero_rows = np.where(mask.any(axis=1))[0] | |
if len(non_zero_rows) == 0: | |
# ๋ง์คํฌ๊ฐ ๋น์ด์๋ ๊ฒฝ์ฐ, ์๋ณธ ์ด๋ฏธ์ง๋ฅผ ๋ฐํ | |
return Image.fromarray(mask.copy()) | |
mask_start_row = non_zero_rows[0] | |
mask_end_row = non_zero_rows[-1] | |
# ๋์ด๋ ๋ง์คํฌ์ ๋ y ์ขํ ๊ณ์ฐ (์ด๋ฏธ์ง ๋์ด๋ฅผ ์ด๊ณผํ์ง ์๋๋ก) | |
new_mask_end_row = min(mask_end_row + pixels, height - 1) | |
# ์๋ณธ ๋ง์คํฌ ์์ญ๊ณผ ๋์ด๋ ๋ง์คํฌ ์์ญ์ ๊ธธ์ด ๊ณ์ฐ | |
original_mask_length = mask_end_row - mask_start_row + 1 | |
stretched_mask_length = new_mask_end_row - mask_start_row + 1 | |
# y ์ขํ ๋งคํ ๋ฐฐ์ด ์์ฑ | |
map_y = np.arange(height, dtype=np.float32) | |
# ๋ง์คํฌ ์์ญ์ ๋ํ y ์ขํ ์ฌ๋งคํ (์ ํ์ ์ผ๋ก ๋๋ฆฌ๊ธฐ) | |
if stretched_mask_length > 1: | |
map_y[mask_start_row:new_mask_end_row + 1] = np.linspace( | |
mask_start_row, | |
mask_end_row, | |
stretched_mask_length | |
) | |
else: | |
map_y[mask_start_row:new_mask_end_row + 1] = mask_start_row | |
# ๋ง์คํฌ ์๋ ์์ญ์ ๋ง์ง๋ง ๋ง์คํฌ ํ์ผ๋ก ๋งคํ | |
if new_mask_end_row + 1 < height: | |
map_y[new_mask_end_row + 1:] = mask_end_row | |
# map_y์ ํฌ๊ธฐ๋ฅผ (height, width)๋ก ํ์ฅ | |
map_y = np.repeat(map_y[:, np.newaxis], width, axis=1) | |
# x ์ขํ๋ ๊ทธ๋๋ก ์ ์ง | |
map_x = np.tile(np.arange(width, dtype=np.float32), (height, 1)) | |
# ์ด๋ฏธ์ง ๋ฆฌ๋งคํ | |
extended_mask = cv2.remap( | |
mask, | |
map_x, | |
map_y, | |
interpolation=cv2.INTER_LINEAR, | |
borderMode=cv2.BORDER_CONSTANT, | |
borderValue=0 | |
) | |
return Image.fromarray(extended_mask) | |
# ๋ง์คํฌ๋ฅผ y์ถ ์์ ๋ฐฉํฅ์ผ๋ก 50ํฝ์ ํ์ฅ | |
## extended_mask = extend_mask_downward(np.array(mask), pixels=100) | |
# ํ์ฅ๋ ๋ง์คํฌ ์ ์ฅ | |
## extended_mask.save('extended_mask_image.png') | |
# ์ต์ข ๋ง์คํฌ ์ ์ฅ | |
# fitting ์ ๋์ ๋ฐ๋ผ, extended_mask ํจ์ ํธ์ถ ๋ณ์์ธ pixels๋ฅผ ์กฐ์ ํ๋ฉด ๋๋ค. | |
# ์ ํ๋๋ฅผ ์ํด ๊ทธ๋ฅ dilation ํ์ง ์๊ณ , y์ขํ๊ฐ ์ฝ๊ฐ ๋ค๋ฅธ ๋ ๋ง์คํฌ๋ฅผ ํฉ์ณค๋ค. | |
## final_mask = Image.fromarray(np.array(opened_mask) | np.array(extended_mask)) | |
## final_mask = morph_close(morph_open(final_mask)) #๋ถํ์ํ ๋๋จ์ด์ง ๋ถ๋ถ ์ญ์ -> ์ฐ๊ฒฐ๋์ง ์์ ๋ถ๋ถ ์ฐ๊ฒฐ | |
## final_mask.save('final_mask_image.png') | |
## masked_person2 = vis_mask(person_image, final_mask) # app.py์์๋ blur ์ฒ๋ฆฌ ํ ๋ค์์ vis_mask ๋ฉ์๋ ํธ์ถํจ. | |
## masked_person2.save("./test_masked_person2.png") # ๋ง์คํฌ์ target img๊ฐ ํฉ์ณ์ง ์ฌ์ง์ PNG ํ์ผ๋ก ์ ์ฅ | |
#person_image = Image.open("path_to_image").convert("RGB") | |
#standard_image = Image.open("./resource/demo/example/person/men/m_lvl3.png").convert("RGB") | |
""" | |
compare_image_mlvl3 = Image.open("./resource/demo/example/person/men/m_lvl3.png").convert("RGB") | |
compare_image_mlvl3 = resize_and_crop(compare_image_mlvl3, (args.width, args.height)) | |
person_image2 = Image.open("./resource/demo/example/person/men/m_lvl0.png").convert("RGB") # ์ด๊ฑธ ์ด๋ bmi ๋ ๋ฒจ์ ๊ธฐ์ค์ผ๋ก ์ธ์ง๋ ๋ญ.. ์คํํด๋ณด๋ฉด์ ์ ์ผ ์ข์ ๊ฑฐ ์ ํ๋ฉด ๋จ. | |
person_image2 = resize_and_crop(person_image2, (args.width, args.height)) | |
mask = automasker( | |
person_image2, | |
"upper" | |
)['mask'] | |
mask.save("./first_mask.png") | |
# ์ดํ ์ฒ๋ฆฌ | |
sam_mask_lower = Image.open("./resource/demo/example/person/sam/m_lvl3_lower_sam.png").convert("L") | |
sam_mask_lower = resize_and_crop(sam_mask_lower, (args.width, args.height)) | |
sam_mask_upper = Image.open("./resource/demo/example/person/sam/m_lvl3_upper_sam.png").convert("L") | |
sam_mask_upper = resize_and_crop(sam_mask_upper, (args.width, args.height)) | |
mask_np = np.array(mask) | |
sam_mask_upper_np = np.array(sam_mask_upper) | |
sam_mask_lower_np = np.array(sam_mask_lower) | |
kernel = np.ones((10, 10), np.uint8) | |
sam_mask_upper_np = cv2.dilate(sam_mask_upper_np, kernel, iterations=1) | |
sam_mask_lower_np = cv2.dilate(sam_mask_lower_np, kernel, iterations=1) | |
result_np = np.where(sam_mask_lower_np== 255, 0, mask_np) | |
result_np = np.where(sam_mask_upper_np== 255, 255, result_np) | |
mask = Image.fromarray(result_np) | |
mask.save("./last_mask2.png") | |
""" |