Add files using upload-large-folder tool
Browse files- VITON-Extends-Train/data/__init__.py +1 -0
- VITON-Extends-Train/data/__pycache__/aligned_dataset.cpython-36.pyc +0 -0
- VITON-Extends-Train/data/__pycache__/aligned_dataset.cpython-37.pyc +0 -0
- VITON-Extends-Train/data/__pycache__/aligned_dataset_fake.cpython-36.pyc +0 -0
- VITON-Extends-Train/data/__pycache__/aligned_dataset_test.cpython-36.pyc +0 -0
- VITON-Extends-Train/data/__pycache__/base_dataset.cpython-36.pyc +0 -0
- VITON-Extends-Train/data/__pycache__/base_dataset.cpython-37.pyc +0 -0
- VITON-Extends-Train/data/aligned_dataset.py +121 -0
- VITON-Extends-Train/data/base_data_loader.py +13 -0
- VITON-Extends-Train/data/base_dataset.py +116 -0
- VITON-Extends-Train/data/custom_dataset_data_loader.py +31 -0
- VITON-Extends-Train/data/data_loader.py +6 -0
- VITON-Extends-Train/data/image_folder.py +74 -0
- VITON-Extends-Train/models/__init__.py +1 -0
- VITON-Extends-Train/models/afwm.py +273 -0
- VITON-Extends-Train/models/networks.py +202 -0
- VITON-Extends-Train/options/__init__.py +1 -0
- VITON-Extends-Train/options/base_options.py +88 -0
- VITON-Extends-Train/options/train_options.py +40 -0
- VITON-Extends-Train/runs/readme.txt +1 -0
- VITON-Extends-Train/sample/readme.txt +1 -0
- VITON-Extends-Train/scripts/train_VITON-Extends2_e2e.sh +14 -0
- VITON-Extends-Train/scripts/train_VITON-Extends2_stage1.sh +13 -0
- VITON-Extends-Train/scripts/train_VITON-Extends_e2e.sh +12 -0
- VITON-Extends-Train/scripts/train_VITON-Extends_stage1.sh +12 -0
- VITON-Extends-Train/train_VITON-Extends2_e2e.py +306 -0
- VITON-Extends-Train/train_VITON-Extends2_stage1.py +278 -0
- VITON-Extends-Train/train_VITON-Extends_stage1.py +181 -0
- VITON-Extends-Train/train_VITON-Extendse2e.py +242 -0
- VITON-Extends-Train/util/__init__.py +1 -0
- VITON-Extends-Train/util/image_pool.py +31 -0
- VITON-Extends-Train/util/util.py +106 -0
- VITON-Extends_test/.gitignore +27 -0
- VITON-Extends_test/API.py +312 -0
- VITON-Extends_test/components.json +21 -0
- VITON-Extends_test/demo.txt +1 -0
- VITON-Extends_test/demo1.txt +2032 -0
- VITON-Extends_test/next.config.mjs +14 -0
- VITON-Extends_test/output_2.png +0 -0
- VITON-Extends_test/package.json +72 -0
- VITON-Extends_test/pnpm-lock.yaml +5 -0
- VITON-Extends_test/postcss.config.mjs +8 -0
- VITON-Extends_test/tailwind.config.ts +94 -0
- VITON-Extends_test/test.py +84 -0
- VITON-Extends_test/test.sh +1 -0
- VITON-Extends_test/test_1.jpg +0 -0
- VITON-Extends_test/test_2.jpg +0 -0
- VITON-Extends_test/tsconfig.json +27 -0
- VITON-Extends_test/u2net.py +525 -0
- VITON-Extends_test/unet.py +49 -0
VITON-Extends-Train/data/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
# data_init
|
VITON-Extends-Train/data/__pycache__/aligned_dataset.cpython-36.pyc
ADDED
|
Binary file (6.2 kB). View file
|
|
|
VITON-Extends-Train/data/__pycache__/aligned_dataset.cpython-37.pyc
ADDED
|
Binary file (3.78 kB). View file
|
|
|
VITON-Extends-Train/data/__pycache__/aligned_dataset_fake.cpython-36.pyc
ADDED
|
Binary file (6.61 kB). View file
|
|
|
VITON-Extends-Train/data/__pycache__/aligned_dataset_test.cpython-36.pyc
ADDED
|
Binary file (6.95 kB). View file
|
|
|
VITON-Extends-Train/data/__pycache__/base_dataset.cpython-36.pyc
ADDED
|
Binary file (4.56 kB). View file
|
|
|
VITON-Extends-Train/data/__pycache__/base_dataset.cpython-37.pyc
ADDED
|
Binary file (4.49 kB). View file
|
|
|
VITON-Extends-Train/data/aligned_dataset.py
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os.path
|
| 2 |
+
from data.base_dataset import BaseDataset, get_params, get_transform
|
| 3 |
+
from data.image_folder import make_dataset
|
| 4 |
+
from PIL import Image
|
| 5 |
+
import torch
|
| 6 |
+
import json
|
| 7 |
+
import numpy as np
|
| 8 |
+
import os.path as osp
|
| 9 |
+
from PIL import ImageDraw
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
class AlignedDataset(BaseDataset):
|
| 13 |
+
def initialize(self, opt):
|
| 14 |
+
self.opt = opt
|
| 15 |
+
self.root = opt.dataroot
|
| 16 |
+
self.diction={}
|
| 17 |
+
|
| 18 |
+
if opt.isTrain or opt.use_encoded_image:
|
| 19 |
+
dir_A = '_A' if self.opt.label_nc == 0 else '_label'
|
| 20 |
+
self.dir_A = os.path.join(opt.dataroot, opt.phase + dir_A)
|
| 21 |
+
self.A_paths = sorted(make_dataset(self.dir_A))
|
| 22 |
+
|
| 23 |
+
self.fine_height=256
|
| 24 |
+
self.fine_width=192
|
| 25 |
+
self.radius=5
|
| 26 |
+
|
| 27 |
+
dir_B = '_B' if self.opt.label_nc == 0 else '_img'
|
| 28 |
+
self.dir_B = os.path.join(opt.dataroot, opt.phase + dir_B)
|
| 29 |
+
self.B_paths = sorted(make_dataset(self.dir_B))
|
| 30 |
+
|
| 31 |
+
self.dataset_size = len(self.A_paths)
|
| 32 |
+
|
| 33 |
+
if opt.isTrain or opt.use_encoded_image:
|
| 34 |
+
dir_E = '_edge'
|
| 35 |
+
self.dir_E = os.path.join(opt.dataroot, opt.phase + dir_E)
|
| 36 |
+
self.E_paths = sorted(make_dataset(self.dir_E))
|
| 37 |
+
|
| 38 |
+
if opt.isTrain or opt.use_encoded_image:
|
| 39 |
+
dir_C = '_color'
|
| 40 |
+
self.dir_C = os.path.join(opt.dataroot, opt.phase + dir_C)
|
| 41 |
+
self.C_paths = sorted(make_dataset(self.dir_C))
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def __getitem__(self, index):
|
| 45 |
+
|
| 46 |
+
A_path = self.A_paths[index]
|
| 47 |
+
A = Image.open(A_path).convert('L')
|
| 48 |
+
|
| 49 |
+
params = get_params(self.opt, A.size)
|
| 50 |
+
if self.opt.label_nc == 0:
|
| 51 |
+
transform_A = get_transform(self.opt, params)
|
| 52 |
+
A_tensor = transform_A(A.convert('RGB'))
|
| 53 |
+
else:
|
| 54 |
+
transform_A = get_transform(self.opt, params, method=Image.NEAREST, normalize=False)
|
| 55 |
+
A_tensor = transform_A(A) * 255.0
|
| 56 |
+
|
| 57 |
+
B_path = self.B_paths[index]
|
| 58 |
+
B = Image.open(B_path).convert('RGB')
|
| 59 |
+
transform_B = get_transform(self.opt, params)
|
| 60 |
+
B_tensor = transform_B(B)
|
| 61 |
+
|
| 62 |
+
C_path = self.C_paths[index]
|
| 63 |
+
C = Image.open(C_path).convert('RGB')
|
| 64 |
+
C_tensor = transform_B(C)
|
| 65 |
+
|
| 66 |
+
E_path = self.E_paths[index]
|
| 67 |
+
E = Image.open(E_path).convert('L')
|
| 68 |
+
E_tensor = transform_A(E)
|
| 69 |
+
|
| 70 |
+
index_un = np.random.randint(14221)
|
| 71 |
+
C_un_path = self.C_paths[index_un]
|
| 72 |
+
C_un = Image.open(C_un_path).convert('RGB')
|
| 73 |
+
C_un_tensor = transform_B(C_un)
|
| 74 |
+
|
| 75 |
+
E_un_path = self.E_paths[index_un]
|
| 76 |
+
E_un = Image.open(E_un_path).convert('L')
|
| 77 |
+
E_un_tensor = transform_A(E_un)
|
| 78 |
+
|
| 79 |
+
pose_name =B_path.replace('.png', '_keypoints.json').replace('.jpg','_keypoints.json').replace('train_img','train_pose')
|
| 80 |
+
with open(osp.join(pose_name), 'r') as f:
|
| 81 |
+
pose_label = json.load(f)
|
| 82 |
+
try:
|
| 83 |
+
pose_data = pose_label['people'][0]['pose_keypoints']
|
| 84 |
+
except IndexError:
|
| 85 |
+
pose_data = [0 for i in range(54)]
|
| 86 |
+
pose_data = np.array(pose_data)
|
| 87 |
+
pose_data = pose_data.reshape((-1,3))
|
| 88 |
+
|
| 89 |
+
point_num = pose_data.shape[0]
|
| 90 |
+
pose_map = torch.zeros(point_num, self.fine_height, self.fine_width)
|
| 91 |
+
r = self.radius
|
| 92 |
+
im_pose = Image.new('L', (self.fine_width, self.fine_height))
|
| 93 |
+
pose_draw = ImageDraw.Draw(im_pose)
|
| 94 |
+
for i in range(point_num):
|
| 95 |
+
one_map = Image.new('L', (self.fine_width, self.fine_height))
|
| 96 |
+
draw = ImageDraw.Draw(one_map)
|
| 97 |
+
pointx = pose_data[i,0]
|
| 98 |
+
pointy = pose_data[i,1]
|
| 99 |
+
if pointx > 1 and pointy > 1:
|
| 100 |
+
draw.rectangle((pointx-r, pointy-r, pointx+r, pointy+r), 'white', 'white')
|
| 101 |
+
pose_draw.rectangle((pointx-r, pointy-r, pointx+r, pointy+r), 'white', 'white')
|
| 102 |
+
one_map = transform_B(one_map.convert('RGB'))
|
| 103 |
+
pose_map[i] = one_map[0]
|
| 104 |
+
P_tensor=pose_map
|
| 105 |
+
|
| 106 |
+
densepose_name = B_path.replace('.png', '.npy').replace('.jpg','.npy').replace('train_img','train_densepose')
|
| 107 |
+
dense_mask = np.load(densepose_name).astype(np.float32)
|
| 108 |
+
dense_mask = transform_A(dense_mask)
|
| 109 |
+
|
| 110 |
+
if self.opt.isTrain:
|
| 111 |
+
input_dict = { 'label': A_tensor, 'image': B_tensor, 'path': A_path, 'img_path': B_path ,'color_path': C_path,'color_un_path': C_un_path,
|
| 112 |
+
'edge': E_tensor, 'color': C_tensor, 'edge_un': E_un_tensor, 'color_un': C_un_tensor, 'pose':P_tensor, 'densepose':dense_mask
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
return input_dict
|
| 116 |
+
|
| 117 |
+
def __len__(self):
|
| 118 |
+
return len(self.A_paths) // (self.opt.batchSize * self.opt.num_gpus) * (self.opt.batchSize * self.opt.num_gpus)
|
| 119 |
+
|
| 120 |
+
def name(self):
|
| 121 |
+
return 'AlignedDataset'
|
VITON-Extends-Train/data/base_data_loader.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class BaseDataLoader():
|
| 2 |
+
def __init__(self):
|
| 3 |
+
pass
|
| 4 |
+
|
| 5 |
+
def initialize(self, opt):
|
| 6 |
+
self.opt = opt
|
| 7 |
+
pass
|
| 8 |
+
|
| 9 |
+
def load_data():
|
| 10 |
+
return None
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
|
VITON-Extends-Train/data/base_dataset.py
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch.utils.data as data
|
| 2 |
+
from PIL import Image
|
| 3 |
+
import torchvision.transforms as transforms
|
| 4 |
+
import numpy as np
|
| 5 |
+
import random
|
| 6 |
+
|
| 7 |
+
class BaseDataset(data.Dataset):
|
| 8 |
+
def __init__(self):
|
| 9 |
+
super(BaseDataset, self).__init__()
|
| 10 |
+
|
| 11 |
+
def name(self):
|
| 12 |
+
return 'BaseDataset'
|
| 13 |
+
|
| 14 |
+
def initialize(self, opt):
|
| 15 |
+
pass
|
| 16 |
+
|
| 17 |
+
def get_params(opt, size):
|
| 18 |
+
w, h = size
|
| 19 |
+
new_h = h
|
| 20 |
+
new_w = w
|
| 21 |
+
if opt.resize_or_crop == 'resize_and_crop':
|
| 22 |
+
new_h = new_w = opt.loadSize
|
| 23 |
+
elif opt.resize_or_crop == 'scale_width_and_crop':
|
| 24 |
+
new_w = opt.loadSize
|
| 25 |
+
new_h = opt.loadSize * h // w
|
| 26 |
+
|
| 27 |
+
x = random.randint(0, np.maximum(0, new_w - opt.fineSize))
|
| 28 |
+
y = random.randint(0, np.maximum(0, new_h - opt.fineSize))
|
| 29 |
+
|
| 30 |
+
#flip = random.random() > 0.5
|
| 31 |
+
flip = 0
|
| 32 |
+
return {'crop_pos': (x, y), 'flip': flip}
|
| 33 |
+
|
| 34 |
+
def get_transform_resize(opt, params, method=Image.BICUBIC, normalize=True):
|
| 35 |
+
transform_list = []
|
| 36 |
+
transform_list.append(transforms.Lambda(lambda img: __scale_width(img, opt.loadSize, method)))
|
| 37 |
+
osize = [256,192]
|
| 38 |
+
transform_list.append(transforms.Scale(osize, method))
|
| 39 |
+
if 'crop' in opt.resize_or_crop:
|
| 40 |
+
transform_list.append(transforms.Lambda(lambda img: __crop(img, params['crop_pos'], opt.fineSize)))
|
| 41 |
+
|
| 42 |
+
if opt.resize_or_crop == 'none':
|
| 43 |
+
base = float(2 ** opt.n_downsample_global)
|
| 44 |
+
if opt.netG == 'local':
|
| 45 |
+
base *= (2 ** opt.n_local_enhancers)
|
| 46 |
+
transform_list.append(transforms.Lambda(lambda img: __make_power_2(img, base, method)))
|
| 47 |
+
|
| 48 |
+
if opt.isTrain and not opt.no_flip:
|
| 49 |
+
transform_list.append(transforms.Lambda(lambda img: __flip(img, params['flip'])))
|
| 50 |
+
|
| 51 |
+
transform_list += [transforms.ToTensor()]
|
| 52 |
+
|
| 53 |
+
if normalize:
|
| 54 |
+
transform_list += [transforms.Normalize((0.5, 0.5, 0.5),
|
| 55 |
+
(0.5, 0.5, 0.5))]
|
| 56 |
+
return transforms.Compose(transform_list)
|
| 57 |
+
|
| 58 |
+
def get_transform(opt, params, method=Image.BICUBIC, normalize=True):
|
| 59 |
+
transform_list = []
|
| 60 |
+
if 'resize' in opt.resize_or_crop:
|
| 61 |
+
osize = [opt.loadSize, opt.loadSize]
|
| 62 |
+
transform_list.append(transforms.Scale(osize, method))
|
| 63 |
+
elif 'scale_width' in opt.resize_or_crop:
|
| 64 |
+
transform_list.append(transforms.Lambda(lambda img: __scale_width(img, opt.loadSize, method)))
|
| 65 |
+
osize = [256,192]
|
| 66 |
+
transform_list.append(transforms.Scale(osize, method))
|
| 67 |
+
if 'crop' in opt.resize_or_crop:
|
| 68 |
+
transform_list.append(transforms.Lambda(lambda img: __crop(img, params['crop_pos'], opt.fineSize)))
|
| 69 |
+
|
| 70 |
+
if opt.resize_or_crop == 'none':
|
| 71 |
+
base = float(2 ** opt.n_downsample_global)
|
| 72 |
+
if opt.netG == 'local':
|
| 73 |
+
base *= (2 ** opt.n_local_enhancers)
|
| 74 |
+
transform_list.append(transforms.Lambda(lambda img: __make_power_2(img, base, method)))
|
| 75 |
+
|
| 76 |
+
if opt.isTrain and not opt.no_flip:
|
| 77 |
+
transform_list.append(transforms.Lambda(lambda img: __flip(img, params['flip'])))
|
| 78 |
+
|
| 79 |
+
transform_list += [transforms.ToTensor()]
|
| 80 |
+
|
| 81 |
+
if normalize:
|
| 82 |
+
transform_list += [transforms.Normalize((0.5, 0.5, 0.5),
|
| 83 |
+
(0.5, 0.5, 0.5))]
|
| 84 |
+
return transforms.Compose(transform_list)
|
| 85 |
+
|
| 86 |
+
def normalize():
|
| 87 |
+
return transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
|
| 88 |
+
|
| 89 |
+
def __make_power_2(img, base, method=Image.BICUBIC):
|
| 90 |
+
ow, oh = img.size
|
| 91 |
+
h = int(round(oh / base) * base)
|
| 92 |
+
w = int(round(ow / base) * base)
|
| 93 |
+
if (h == oh) and (w == ow):
|
| 94 |
+
return img
|
| 95 |
+
return img.resize((w, h), method)
|
| 96 |
+
|
| 97 |
+
def __scale_width(img, target_width, method=Image.BICUBIC):
|
| 98 |
+
ow, oh = img.size
|
| 99 |
+
if (ow == target_width):
|
| 100 |
+
return img
|
| 101 |
+
w = target_width
|
| 102 |
+
h = int(target_width * oh / ow)
|
| 103 |
+
return img.resize((w, h), method)
|
| 104 |
+
|
| 105 |
+
def __crop(img, pos, size):
|
| 106 |
+
ow, oh = img.size
|
| 107 |
+
x1, y1 = pos
|
| 108 |
+
tw = th = size
|
| 109 |
+
if (ow > tw or oh > th):
|
| 110 |
+
return img.crop((x1, y1, x1 + tw, y1 + th))
|
| 111 |
+
return img
|
| 112 |
+
|
| 113 |
+
def __flip(img, flip):
|
| 114 |
+
if flip:
|
| 115 |
+
return img.transpose(Image.FLIP_LEFT_RIGHT)
|
| 116 |
+
return img
|
VITON-Extends-Train/data/custom_dataset_data_loader.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch.utils.data
|
| 2 |
+
from data.base_data_loader import BaseDataLoader
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
def CreateDataset(opt):
|
| 6 |
+
dataset = None
|
| 7 |
+
from data.aligned_dataset import AlignedDataset
|
| 8 |
+
dataset = AlignedDataset()
|
| 9 |
+
|
| 10 |
+
print("dataset [%s] was created" % (dataset.name()))
|
| 11 |
+
dataset.initialize(opt)
|
| 12 |
+
return dataset
|
| 13 |
+
|
| 14 |
+
class CustomDatasetDataLoader(BaseDataLoader):
|
| 15 |
+
def name(self):
|
| 16 |
+
return 'CustomDatasetDataLoader'
|
| 17 |
+
|
| 18 |
+
def initialize(self, opt):
|
| 19 |
+
BaseDataLoader.initialize(self, opt)
|
| 20 |
+
self.dataset = CreateDataset(opt)
|
| 21 |
+
self.dataloader = torch.utils.data.DataLoader(
|
| 22 |
+
self.dataset,
|
| 23 |
+
batch_size=opt.batchSize,
|
| 24 |
+
shuffle=not opt.serial_batches,
|
| 25 |
+
num_workers=int(opt.nThreads))
|
| 26 |
+
|
| 27 |
+
def load_data(self):
|
| 28 |
+
return self.dataloader
|
| 29 |
+
|
| 30 |
+
def __len__(self):
|
| 31 |
+
return min(len(self.dataset), self.opt.max_dataset_size)
|
VITON-Extends-Train/data/data_loader.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
def CreateDataLoader(opt):
|
| 2 |
+
from data.custom_dataset_data_loader import CustomDatasetDataLoader
|
| 3 |
+
data_loader = CustomDatasetDataLoader()
|
| 4 |
+
print(data_loader.name())
|
| 5 |
+
data_loader.initialize(opt)
|
| 6 |
+
return data_loader
|
VITON-Extends-Train/data/image_folder.py
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch.utils.data as data
|
| 2 |
+
from PIL import Image
|
| 3 |
+
import os
|
| 4 |
+
|
| 5 |
+
IMG_EXTENSIONS = [
|
| 6 |
+
'.jpg', '.JPG', '.jpeg', '.JPEG',
|
| 7 |
+
'.png', '.PNG', '.ppm', '.PPM', '.bmp', '.BMP', '.tiff'
|
| 8 |
+
]
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def is_image_file(filename):
|
| 12 |
+
return any(filename.endswith(extension) for extension in IMG_EXTENSIONS)
|
| 13 |
+
|
| 14 |
+
def make_dataset(dir):
|
| 15 |
+
images = []
|
| 16 |
+
assert os.path.isdir(dir), '%s is not a valid directory' % dir
|
| 17 |
+
|
| 18 |
+
f = dir.split('/')[-1].split('_')[-1]
|
| 19 |
+
print (dir, f)
|
| 20 |
+
dirs= os.listdir(dir)
|
| 21 |
+
for img in dirs:
|
| 22 |
+
|
| 23 |
+
path = os.path.join(dir, img)
|
| 24 |
+
#print(path)
|
| 25 |
+
images.append(path)
|
| 26 |
+
return images
|
| 27 |
+
|
| 28 |
+
def make_dataset_test(dir):
|
| 29 |
+
images = []
|
| 30 |
+
assert os.path.isdir(dir), '%s is not a valid directory' % dir
|
| 31 |
+
|
| 32 |
+
f = dir.split('/')[-1].split('_')[-1]
|
| 33 |
+
for i in range(len([name for name in os.listdir(dir) if os.path.isfile(os.path.join(dir, name))])):
|
| 34 |
+
if f == 'label' or f == 'labelref':
|
| 35 |
+
img = str(i) + '.png'
|
| 36 |
+
else:
|
| 37 |
+
img = str(i) + '.jpg'
|
| 38 |
+
path = os.path.join(dir, img)
|
| 39 |
+
#print(path)
|
| 40 |
+
images.append(path)
|
| 41 |
+
return images
|
| 42 |
+
|
| 43 |
+
def default_loader(path):
|
| 44 |
+
return Image.open(path).convert('RGB')
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
class ImageFolder(data.Dataset):
|
| 48 |
+
|
| 49 |
+
def __init__(self, root, transform=None, return_paths=False,
|
| 50 |
+
loader=default_loader):
|
| 51 |
+
imgs = make_dataset(root)
|
| 52 |
+
if len(imgs) == 0:
|
| 53 |
+
raise(RuntimeError("Found 0 images in: " + root + "\n"
|
| 54 |
+
"Supported image extensions are: " +
|
| 55 |
+
",".join(IMG_EXTENSIONS)))
|
| 56 |
+
|
| 57 |
+
self.root = root
|
| 58 |
+
self.imgs = imgs
|
| 59 |
+
self.transform = transform
|
| 60 |
+
self.return_paths = return_paths
|
| 61 |
+
self.loader = loader
|
| 62 |
+
|
| 63 |
+
def __getitem__(self, index):
|
| 64 |
+
path = self.imgs[index]
|
| 65 |
+
img = self.loader(path)
|
| 66 |
+
if self.transform is not None:
|
| 67 |
+
img = self.transform(img)
|
| 68 |
+
if self.return_paths:
|
| 69 |
+
return img, path
|
| 70 |
+
else:
|
| 71 |
+
return img
|
| 72 |
+
|
| 73 |
+
def __len__(self):
|
| 74 |
+
return len(self.imgs)
|
VITON-Extends-Train/models/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
# model_init
|
VITON-Extends-Train/models/afwm.py
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
import torch.nn as nn
|
| 3 |
+
import torch.nn.functional as F
|
| 4 |
+
import numpy as np
|
| 5 |
+
from options.train_options import TrainOptions
|
| 6 |
+
from .correlation import correlation # the custom cost volume layer
|
| 7 |
+
opt = TrainOptions().parse()
|
| 8 |
+
|
| 9 |
+
def apply_offset(offset):
|
| 10 |
+
sizes = list(offset.size()[2:])
|
| 11 |
+
grid_list = torch.meshgrid([torch.arange(size, device=offset.device) for size in sizes])
|
| 12 |
+
grid_list = reversed(grid_list)
|
| 13 |
+
# apply offset
|
| 14 |
+
grid_list = [grid.float().unsqueeze(0) + offset[:, dim, ...]
|
| 15 |
+
for dim, grid in enumerate(grid_list)]
|
| 16 |
+
# normalize
|
| 17 |
+
grid_list = [grid / ((size - 1.0) / 2.0) - 1.0
|
| 18 |
+
for grid, size in zip(grid_list, reversed(sizes))]
|
| 19 |
+
|
| 20 |
+
return torch.stack(grid_list, dim=-1)
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def TVLoss(x):
|
| 24 |
+
tv_h = x[:, :, 1:, :] - x[:, :, :-1, :]
|
| 25 |
+
tv_w = x[:, :, :, 1:] - x[:, :, :, :-1]
|
| 26 |
+
|
| 27 |
+
return torch.mean(torch.abs(tv_h)) + torch.mean(torch.abs(tv_w))
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
# backbone
|
| 31 |
+
class ResBlock(nn.Module):
|
| 32 |
+
def __init__(self, in_channels):
|
| 33 |
+
super(ResBlock, self).__init__()
|
| 34 |
+
self.block = nn.Sequential(
|
| 35 |
+
nn.BatchNorm2d(in_channels),
|
| 36 |
+
nn.ReLU(inplace=True),
|
| 37 |
+
nn.Conv2d(in_channels, in_channels, kernel_size=3, padding=1, bias=False),
|
| 38 |
+
nn.BatchNorm2d(in_channels),
|
| 39 |
+
nn.ReLU(inplace=True),
|
| 40 |
+
nn.Conv2d(in_channels, in_channels, kernel_size=3, padding=1, bias=False)
|
| 41 |
+
)
|
| 42 |
+
|
| 43 |
+
def forward(self, x):
|
| 44 |
+
return self.block(x) + x
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
class DownSample(nn.Module):
|
| 48 |
+
def __init__(self, in_channels, out_channels):
|
| 49 |
+
super(DownSample, self).__init__()
|
| 50 |
+
self.block= nn.Sequential(
|
| 51 |
+
nn.BatchNorm2d(in_channels),
|
| 52 |
+
nn.ReLU(inplace=True),
|
| 53 |
+
nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=2, padding=1, bias=False)
|
| 54 |
+
)
|
| 55 |
+
|
| 56 |
+
def forward(self, x):
|
| 57 |
+
return self.block(x)
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
class FeatureEncoder(nn.Module):
|
| 62 |
+
def __init__(self, in_channels, chns=[64,128,256,256,256]):
|
| 63 |
+
# in_channels = 3 for images, and is larger (e.g., 17+1+1) for agnositc representation
|
| 64 |
+
super(FeatureEncoder, self).__init__()
|
| 65 |
+
self.encoders = []
|
| 66 |
+
for i, out_chns in enumerate(chns):
|
| 67 |
+
if i == 0:
|
| 68 |
+
encoder = nn.Sequential(DownSample(in_channels, out_chns),
|
| 69 |
+
ResBlock(out_chns),
|
| 70 |
+
ResBlock(out_chns))
|
| 71 |
+
else:
|
| 72 |
+
encoder = nn.Sequential(DownSample(chns[i-1], out_chns),
|
| 73 |
+
ResBlock(out_chns),
|
| 74 |
+
ResBlock(out_chns))
|
| 75 |
+
|
| 76 |
+
self.encoders.append(encoder)
|
| 77 |
+
|
| 78 |
+
self.encoders = nn.ModuleList(self.encoders)
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def forward(self, x):
|
| 82 |
+
encoder_features = []
|
| 83 |
+
for encoder in self.encoders:
|
| 84 |
+
x = encoder(x)
|
| 85 |
+
encoder_features.append(x)
|
| 86 |
+
return encoder_features
|
| 87 |
+
|
| 88 |
+
class RefinePyramid(nn.Module):
|
| 89 |
+
def __init__(self, chns=[64,128,256,256,256], fpn_dim=256):
|
| 90 |
+
super(RefinePyramid, self).__init__()
|
| 91 |
+
self.chns = chns
|
| 92 |
+
|
| 93 |
+
# adaptive
|
| 94 |
+
self.adaptive = []
|
| 95 |
+
for in_chns in list(reversed(chns)):
|
| 96 |
+
adaptive_layer = nn.Conv2d(in_chns, fpn_dim, kernel_size=1)
|
| 97 |
+
self.adaptive.append(adaptive_layer)
|
| 98 |
+
self.adaptive = nn.ModuleList(self.adaptive)
|
| 99 |
+
# output conv
|
| 100 |
+
self.smooth = []
|
| 101 |
+
for i in range(len(chns)):
|
| 102 |
+
smooth_layer = nn.Conv2d(fpn_dim, fpn_dim, kernel_size=3, padding=1)
|
| 103 |
+
self.smooth.append(smooth_layer)
|
| 104 |
+
self.smooth = nn.ModuleList(self.smooth)
|
| 105 |
+
|
| 106 |
+
def forward(self, x):
|
| 107 |
+
conv_ftr_list = x
|
| 108 |
+
|
| 109 |
+
feature_list = []
|
| 110 |
+
last_feature = None
|
| 111 |
+
for i, conv_ftr in enumerate(list(reversed(conv_ftr_list))):
|
| 112 |
+
# adaptive
|
| 113 |
+
feature = self.adaptive[i](conv_ftr)
|
| 114 |
+
# fuse
|
| 115 |
+
if last_feature is not None:
|
| 116 |
+
feature = feature + F.interpolate(last_feature, scale_factor=2, mode='nearest')
|
| 117 |
+
# smooth
|
| 118 |
+
feature = self.smooth[i](feature)
|
| 119 |
+
last_feature = feature
|
| 120 |
+
feature_list.append(feature)
|
| 121 |
+
|
| 122 |
+
return tuple(reversed(feature_list))
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
class AFlowNet(nn.Module):
|
| 126 |
+
def __init__(self, num_pyramid, fpn_dim=256):
|
| 127 |
+
super(AFlowNet, self).__init__()
|
| 128 |
+
self.netMain = []
|
| 129 |
+
self.netRefine = []
|
| 130 |
+
for i in range(num_pyramid):
|
| 131 |
+
netMain_layer = torch.nn.Sequential(
|
| 132 |
+
torch.nn.Conv2d(in_channels=49, out_channels=128, kernel_size=3, stride=1, padding=1),
|
| 133 |
+
torch.nn.LeakyReLU(inplace=False, negative_slope=0.1),
|
| 134 |
+
torch.nn.Conv2d(in_channels=128, out_channels=64, kernel_size=3, stride=1, padding=1),
|
| 135 |
+
torch.nn.LeakyReLU(inplace=False, negative_slope=0.1),
|
| 136 |
+
torch.nn.Conv2d(in_channels=64, out_channels=32, kernel_size=3, stride=1, padding=1),
|
| 137 |
+
torch.nn.LeakyReLU(inplace=False, negative_slope=0.1),
|
| 138 |
+
torch.nn.Conv2d(in_channels=32, out_channels=2, kernel_size=3, stride=1, padding=1)
|
| 139 |
+
)
|
| 140 |
+
|
| 141 |
+
netRefine_layer = torch.nn.Sequential(
|
| 142 |
+
torch.nn.Conv2d(2 * fpn_dim, out_channels=128, kernel_size=3, stride=1, padding=1),
|
| 143 |
+
torch.nn.LeakyReLU(inplace=False, negative_slope=0.1),
|
| 144 |
+
torch.nn.Conv2d(in_channels=128, out_channels=64, kernel_size=3, stride=1, padding=1),
|
| 145 |
+
torch.nn.LeakyReLU(inplace=False, negative_slope=0.1),
|
| 146 |
+
torch.nn.Conv2d(in_channels=64, out_channels=32, kernel_size=3, stride=1, padding=1),
|
| 147 |
+
torch.nn.LeakyReLU(inplace=False, negative_slope=0.1),
|
| 148 |
+
torch.nn.Conv2d(in_channels=32, out_channels=2, kernel_size=3, stride=1, padding=1)
|
| 149 |
+
)
|
| 150 |
+
self.netMain.append(netMain_layer)
|
| 151 |
+
self.netRefine.append(netRefine_layer)
|
| 152 |
+
|
| 153 |
+
self.netMain = nn.ModuleList(self.netMain)
|
| 154 |
+
self.netRefine = nn.ModuleList(self.netRefine)
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
def forward(self, x, x_edge, x_warps, x_conds, warp_feature=True):
|
| 158 |
+
last_flow = None
|
| 159 |
+
last_flow_all = []
|
| 160 |
+
delta_list = []
|
| 161 |
+
x_all = []
|
| 162 |
+
x_edge_all = []
|
| 163 |
+
cond_fea_all = []
|
| 164 |
+
delta_x_all = []
|
| 165 |
+
delta_y_all = []
|
| 166 |
+
filter_x = [[0, 0, 0],
|
| 167 |
+
[1, -2, 1],
|
| 168 |
+
[0, 0, 0]]
|
| 169 |
+
filter_y = [[0, 1, 0],
|
| 170 |
+
[0, -2, 0],
|
| 171 |
+
[0, 1, 0]]
|
| 172 |
+
filter_diag1 = [[1, 0, 0],
|
| 173 |
+
[0, -2, 0],
|
| 174 |
+
[0, 0, 1]]
|
| 175 |
+
filter_diag2 = [[0, 0, 1],
|
| 176 |
+
[0, -2, 0],
|
| 177 |
+
[1, 0, 0]]
|
| 178 |
+
weight_array = np.ones([3, 3, 1, 4])
|
| 179 |
+
weight_array[:, :, 0, 0] = filter_x
|
| 180 |
+
weight_array[:, :, 0, 1] = filter_y
|
| 181 |
+
weight_array[:, :, 0, 2] = filter_diag1
|
| 182 |
+
weight_array[:, :, 0, 3] = filter_diag2
|
| 183 |
+
|
| 184 |
+
weight_array = torch.cuda.FloatTensor(weight_array).permute(3,2,0,1)
|
| 185 |
+
self.weight = nn.Parameter(data=weight_array, requires_grad=False)
|
| 186 |
+
|
| 187 |
+
for i in range(len(x_warps)):
|
| 188 |
+
x_warp = x_warps[len(x_warps) - 1 - i]
|
| 189 |
+
x_cond = x_conds[len(x_warps) - 1 - i]
|
| 190 |
+
cond_fea_all.append(x_cond)
|
| 191 |
+
|
| 192 |
+
if last_flow is not None and warp_feature:
|
| 193 |
+
x_warp_after = F.grid_sample(x_warp, last_flow.detach().permute(0, 2, 3, 1),
|
| 194 |
+
mode='bilinear', padding_mode='border')
|
| 195 |
+
else:
|
| 196 |
+
x_warp_after = x_warp
|
| 197 |
+
|
| 198 |
+
tenCorrelation = F.leaky_relu(input=correlation.FunctionCorrelation(tenFirst=x_warp_after, tenSecond=x_cond, intStride=1), negative_slope=0.1, inplace=False)
|
| 199 |
+
flow = self.netMain[i](tenCorrelation)
|
| 200 |
+
delta_list.append(flow)
|
| 201 |
+
flow = apply_offset(flow)
|
| 202 |
+
if last_flow is not None:
|
| 203 |
+
flow = F.grid_sample(last_flow, flow, mode='bilinear', padding_mode='border')
|
| 204 |
+
else:
|
| 205 |
+
flow = flow.permute(0, 3, 1, 2)
|
| 206 |
+
|
| 207 |
+
last_flow = flow
|
| 208 |
+
x_warp = F.grid_sample(x_warp, flow.permute(0, 2, 3, 1),mode='bilinear', padding_mode='border')
|
| 209 |
+
concat = torch.cat([x_warp,x_cond],1)
|
| 210 |
+
flow = self.netRefine[i](concat)
|
| 211 |
+
delta_list.append(flow)
|
| 212 |
+
flow = apply_offset(flow)
|
| 213 |
+
flow = F.grid_sample(last_flow, flow, mode='bilinear', padding_mode='border')
|
| 214 |
+
|
| 215 |
+
last_flow = F.interpolate(flow, scale_factor=2, mode='bilinear')
|
| 216 |
+
last_flow_all.append(last_flow)
|
| 217 |
+
cur_x = F.interpolate(x, scale_factor=0.5**(len(x_warps)-1-i), mode='bilinear')
|
| 218 |
+
cur_x_warp = F.grid_sample(cur_x, last_flow.permute(0, 2, 3, 1),mode='bilinear', padding_mode='border')
|
| 219 |
+
x_all.append(cur_x_warp)
|
| 220 |
+
cur_x_edge = F.interpolate(x_edge, scale_factor=0.5**(len(x_warps)-1-i), mode='bilinear')
|
| 221 |
+
cur_x_warp_edge = F.grid_sample(cur_x_edge, last_flow.permute(0, 2, 3, 1),mode='bilinear', padding_mode='zeros')
|
| 222 |
+
x_edge_all.append(cur_x_warp_edge)
|
| 223 |
+
flow_x,flow_y = torch.split(last_flow,1,dim=1)
|
| 224 |
+
delta_x = F.conv2d(flow_x, self.weight)
|
| 225 |
+
delta_y = F.conv2d(flow_y,self.weight)
|
| 226 |
+
delta_x_all.append(delta_x)
|
| 227 |
+
delta_y_all.append(delta_y)
|
| 228 |
+
|
| 229 |
+
x_warp = F.grid_sample(x, last_flow.permute(0, 2, 3, 1),
|
| 230 |
+
mode='bilinear', padding_mode='border')
|
| 231 |
+
return x_warp, last_flow, cond_fea_all, last_flow_all, delta_list, x_all, x_edge_all, delta_x_all, delta_y_all
|
| 232 |
+
|
| 233 |
+
|
| 234 |
+
class AFWM(nn.Module):
|
| 235 |
+
|
| 236 |
+
def __init__(self, opt, input_nc):
|
| 237 |
+
super(AFWM, self).__init__()
|
| 238 |
+
num_filters = [64,128,256,256,256]
|
| 239 |
+
self.image_features = FeatureEncoder(3, num_filters)
|
| 240 |
+
self.cond_features = FeatureEncoder(input_nc, num_filters)
|
| 241 |
+
self.image_FPN = RefinePyramid(num_filters)
|
| 242 |
+
self.cond_FPN = RefinePyramid(num_filters)
|
| 243 |
+
self.aflow_net = AFlowNet(len(num_filters))
|
| 244 |
+
self.old_lr = opt.lr
|
| 245 |
+
self.old_lr_warp = opt.lr*0.2
|
| 246 |
+
|
| 247 |
+
def forward(self, cond_input, image_input, image_edge):
|
| 248 |
+
cond_pyramids = self.cond_FPN(self.cond_features(cond_input)) # maybe use nn.Sequential
|
| 249 |
+
image_pyramids = self.image_FPN(self.image_features(image_input))
|
| 250 |
+
|
| 251 |
+
x_warp, last_flow, last_flow_all, flow_all, delta_list, x_all, x_edge_all, delta_x_all, delta_y_all = self.aflow_net(image_input, image_edge, image_pyramids, cond_pyramids)
|
| 252 |
+
|
| 253 |
+
return x_warp, last_flow, last_flow_all, flow_all, delta_list, x_all, x_edge_all, delta_x_all, delta_y_all
|
| 254 |
+
|
| 255 |
+
|
| 256 |
+
def update_learning_rate(self,optimizer):
|
| 257 |
+
lrd = opt.lr / opt.niter_decay
|
| 258 |
+
lr = self.old_lr - lrd
|
| 259 |
+
for param_group in optimizer.param_groups:
|
| 260 |
+
param_group['lr'] = lr
|
| 261 |
+
if opt.verbose:
|
| 262 |
+
print('update learning rate: %f -> %f' % (self.old_lr, lr))
|
| 263 |
+
self.old_lr = lr
|
| 264 |
+
|
| 265 |
+
def update_learning_rate_warp(self,optimizer):
|
| 266 |
+
lrd = 0.2 * opt.lr / opt.niter_decay
|
| 267 |
+
lr = self.old_lr_warp - lrd
|
| 268 |
+
for param_group in optimizer.param_groups:
|
| 269 |
+
param_group['lr'] = lr
|
| 270 |
+
if opt.verbose:
|
| 271 |
+
print('update learning rate: %f -> %f' % (self.old_lr_warp, lr))
|
| 272 |
+
self.old_lr_warp = lr
|
| 273 |
+
|
VITON-Extends-Train/models/networks.py
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
import torch.nn as nn
|
| 3 |
+
import torch.nn.parallel
|
| 4 |
+
from torchvision import models
|
| 5 |
+
from options.train_options import TrainOptions
|
| 6 |
+
import os
|
| 7 |
+
|
| 8 |
+
opt = TrainOptions().parse()
|
| 9 |
+
|
| 10 |
+
class ResidualBlock(nn.Module):
|
| 11 |
+
def __init__(self, in_features=64, norm_layer=nn.BatchNorm2d):
|
| 12 |
+
super(ResidualBlock, self).__init__()
|
| 13 |
+
self.relu = nn.ReLU(True)
|
| 14 |
+
if norm_layer == None:
|
| 15 |
+
self.block = nn.Sequential(
|
| 16 |
+
nn.Conv2d(in_features, in_features, 3, 1, 1, bias=False),
|
| 17 |
+
nn.ReLU(inplace=True),
|
| 18 |
+
nn.Conv2d(in_features, in_features, 3, 1, 1, bias=False),
|
| 19 |
+
)
|
| 20 |
+
else:
|
| 21 |
+
self.block = nn.Sequential(
|
| 22 |
+
nn.Conv2d(in_features, in_features, 3, 1, 1, bias=False),
|
| 23 |
+
norm_layer(in_features),
|
| 24 |
+
nn.ReLU(inplace=True),
|
| 25 |
+
nn.Conv2d(in_features, in_features, 3, 1, 1, bias=False),
|
| 26 |
+
norm_layer(in_features)
|
| 27 |
+
)
|
| 28 |
+
|
| 29 |
+
def forward(self, x):
|
| 30 |
+
residual = x
|
| 31 |
+
out = self.block(x)
|
| 32 |
+
out += residual
|
| 33 |
+
out = self.relu(out)
|
| 34 |
+
return out
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
class ResUnetGenerator(nn.Module):
|
| 38 |
+
def __init__(self, input_nc, output_nc, num_downs, ngf=64,
|
| 39 |
+
norm_layer=nn.BatchNorm2d, use_dropout=False):
|
| 40 |
+
super(ResUnetGenerator, self).__init__()
|
| 41 |
+
# construct unet structure
|
| 42 |
+
unet_block = ResUnetSkipConnectionBlock(ngf * 8, ngf * 8, input_nc=None, submodule=None, norm_layer=norm_layer, innermost=True)
|
| 43 |
+
|
| 44 |
+
for i in range(num_downs - 5):
|
| 45 |
+
unet_block = ResUnetSkipConnectionBlock(ngf * 8, ngf * 8, input_nc=None, submodule=unet_block, norm_layer=norm_layer, use_dropout=use_dropout)
|
| 46 |
+
unet_block = ResUnetSkipConnectionBlock(ngf * 4, ngf * 8, input_nc=None, submodule=unet_block, norm_layer=norm_layer)
|
| 47 |
+
unet_block = ResUnetSkipConnectionBlock(ngf * 2, ngf * 4, input_nc=None, submodule=unet_block, norm_layer=norm_layer)
|
| 48 |
+
unet_block = ResUnetSkipConnectionBlock(ngf, ngf * 2, input_nc=None, submodule=unet_block, norm_layer=norm_layer)
|
| 49 |
+
unet_block = ResUnetSkipConnectionBlock(output_nc, ngf, input_nc=input_nc, submodule=unet_block, outermost=True, norm_layer=norm_layer)
|
| 50 |
+
|
| 51 |
+
self.model = unet_block
|
| 52 |
+
self.old_lr = opt.lr
|
| 53 |
+
self.old_lr_gmm = 0.1*opt.lr
|
| 54 |
+
|
| 55 |
+
def forward(self, input):
|
| 56 |
+
return self.model(input)
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
# Defines the submodule with skip connection.
|
| 60 |
+
# X -------------------identity---------------------- X
|
| 61 |
+
# |-- downsampling -- |submodule| -- upsampling --|
|
| 62 |
+
class ResUnetSkipConnectionBlock(nn.Module):
|
| 63 |
+
def __init__(self, outer_nc, inner_nc, input_nc=None,
|
| 64 |
+
submodule=None, outermost=False, innermost=False, norm_layer=nn.BatchNorm2d, use_dropout=False):
|
| 65 |
+
super(ResUnetSkipConnectionBlock, self).__init__()
|
| 66 |
+
self.outermost = outermost
|
| 67 |
+
use_bias = norm_layer == nn.InstanceNorm2d
|
| 68 |
+
|
| 69 |
+
if input_nc is None:
|
| 70 |
+
input_nc = outer_nc
|
| 71 |
+
downconv = nn.Conv2d(input_nc, inner_nc, kernel_size=3,
|
| 72 |
+
stride=2, padding=1, bias=use_bias)
|
| 73 |
+
# add two resblock
|
| 74 |
+
res_downconv = [ResidualBlock(inner_nc, norm_layer), ResidualBlock(inner_nc, norm_layer)]
|
| 75 |
+
res_upconv = [ResidualBlock(outer_nc, norm_layer), ResidualBlock(outer_nc, norm_layer)]
|
| 76 |
+
|
| 77 |
+
downrelu = nn.ReLU(True)
|
| 78 |
+
uprelu = nn.ReLU(True)
|
| 79 |
+
if norm_layer != None:
|
| 80 |
+
downnorm = norm_layer(inner_nc)
|
| 81 |
+
upnorm = norm_layer(outer_nc)
|
| 82 |
+
|
| 83 |
+
if outermost:
|
| 84 |
+
upsample = nn.Upsample(scale_factor=2, mode='nearest')
|
| 85 |
+
upconv = nn.Conv2d(inner_nc * 2, outer_nc, kernel_size=3, stride=1, padding=1, bias=use_bias)
|
| 86 |
+
down = [downconv, downrelu] + res_downconv
|
| 87 |
+
up = [upsample, upconv]
|
| 88 |
+
model = down + [submodule] + up
|
| 89 |
+
elif innermost:
|
| 90 |
+
upsample = nn.Upsample(scale_factor=2, mode='nearest')
|
| 91 |
+
upconv = nn.Conv2d(inner_nc, outer_nc, kernel_size=3, stride=1, padding=1, bias=use_bias)
|
| 92 |
+
down = [downconv, downrelu] + res_downconv
|
| 93 |
+
if norm_layer == None:
|
| 94 |
+
up = [upsample, upconv, uprelu] + res_upconv
|
| 95 |
+
else:
|
| 96 |
+
up = [upsample, upconv, upnorm, uprelu] + res_upconv
|
| 97 |
+
model = down + up
|
| 98 |
+
else:
|
| 99 |
+
upsample = nn.Upsample(scale_factor=2, mode='nearest')
|
| 100 |
+
upconv = nn.Conv2d(inner_nc*2, outer_nc, kernel_size=3, stride=1, padding=1, bias=use_bias)
|
| 101 |
+
if norm_layer == None:
|
| 102 |
+
down = [downconv, downrelu] + res_downconv
|
| 103 |
+
up = [upsample, upconv, uprelu] + res_upconv
|
| 104 |
+
else:
|
| 105 |
+
down = [downconv, downnorm, downrelu] + res_downconv
|
| 106 |
+
up = [upsample, upconv, upnorm, uprelu] + res_upconv
|
| 107 |
+
|
| 108 |
+
if use_dropout:
|
| 109 |
+
model = down + [submodule] + up + [nn.Dropout(0.5)]
|
| 110 |
+
else:
|
| 111 |
+
model = down + [submodule] + up
|
| 112 |
+
|
| 113 |
+
self.model = nn.Sequential(*model)
|
| 114 |
+
|
| 115 |
+
def forward(self, x):
|
| 116 |
+
if self.outermost:
|
| 117 |
+
return self.model(x)
|
| 118 |
+
else:
|
| 119 |
+
return torch.cat([x, self.model(x)], 1)
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
class Vgg19(nn.Module):
|
| 123 |
+
def __init__(self, requires_grad=False):
|
| 124 |
+
super(Vgg19, self).__init__()
|
| 125 |
+
vgg_pretrained_features = models.vgg19(pretrained=True).features
|
| 126 |
+
self.slice1 = nn.Sequential()
|
| 127 |
+
self.slice2 = nn.Sequential()
|
| 128 |
+
self.slice3 = nn.Sequential()
|
| 129 |
+
self.slice4 = nn.Sequential()
|
| 130 |
+
self.slice5 = nn.Sequential()
|
| 131 |
+
for x in range(2):
|
| 132 |
+
self.slice1.add_module(str(x), vgg_pretrained_features[x])
|
| 133 |
+
for x in range(2, 7):
|
| 134 |
+
self.slice2.add_module(str(x), vgg_pretrained_features[x])
|
| 135 |
+
for x in range(7, 12):
|
| 136 |
+
self.slice3.add_module(str(x), vgg_pretrained_features[x])
|
| 137 |
+
for x in range(12, 21):
|
| 138 |
+
self.slice4.add_module(str(x), vgg_pretrained_features[x])
|
| 139 |
+
for x in range(21, 30):
|
| 140 |
+
self.slice5.add_module(str(x), vgg_pretrained_features[x])
|
| 141 |
+
if not requires_grad:
|
| 142 |
+
for param in self.parameters():
|
| 143 |
+
param.requires_grad = False
|
| 144 |
+
|
| 145 |
+
def forward(self, X):
|
| 146 |
+
h_relu1 = self.slice1(X)
|
| 147 |
+
h_relu2 = self.slice2(h_relu1)
|
| 148 |
+
h_relu3 = self.slice3(h_relu2)
|
| 149 |
+
h_relu4 = self.slice4(h_relu3)
|
| 150 |
+
h_relu5 = self.slice5(h_relu4)
|
| 151 |
+
out = [h_relu1, h_relu2, h_relu3, h_relu4, h_relu5]
|
| 152 |
+
return out
|
| 153 |
+
|
| 154 |
+
class VGGLoss(nn.Module):
|
| 155 |
+
def __init__(self, layids = None):
|
| 156 |
+
super(VGGLoss, self).__init__()
|
| 157 |
+
self.vgg = Vgg19()
|
| 158 |
+
self.vgg.cuda()
|
| 159 |
+
self.criterion = nn.L1Loss()
|
| 160 |
+
self.weights = [1.0/32, 1.0/16, 1.0/8, 1.0/4, 1.0]
|
| 161 |
+
self.layids = layids
|
| 162 |
+
|
| 163 |
+
def forward(self, x, y):
|
| 164 |
+
x_vgg, y_vgg = self.vgg(x), self.vgg(y)
|
| 165 |
+
loss = 0
|
| 166 |
+
if self.layids is None:
|
| 167 |
+
self.layids = list(range(len(x_vgg)))
|
| 168 |
+
for i in self.layids:
|
| 169 |
+
loss += self.weights[i] * self.criterion(x_vgg[i], y_vgg[i].detach())
|
| 170 |
+
return loss
|
| 171 |
+
|
| 172 |
+
def save_checkpoint(model, save_path):
|
| 173 |
+
if not os.path.exists(os.path.dirname(save_path)):
|
| 174 |
+
os.makedirs(os.path.dirname(save_path))
|
| 175 |
+
torch.save(model.state_dict(), save_path)
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
def load_checkpoint_parallel(model, checkpoint_path):
|
| 179 |
+
|
| 180 |
+
if not os.path.exists(checkpoint_path):
|
| 181 |
+
print('No checkpoint!')
|
| 182 |
+
return
|
| 183 |
+
|
| 184 |
+
checkpoint = torch.load(checkpoint_path, map_location='cuda:{}'.format(opt.local_rank))
|
| 185 |
+
checkpoint_new = model.state_dict()
|
| 186 |
+
for param in checkpoint_new:
|
| 187 |
+
checkpoint_new[param] = checkpoint[param]
|
| 188 |
+
model.load_state_dict(checkpoint_new)
|
| 189 |
+
|
| 190 |
+
def load_checkpoint_part_parallel(model, checkpoint_path):
|
| 191 |
+
|
| 192 |
+
if not os.path.exists(checkpoint_path):
|
| 193 |
+
print('No checkpoint!')
|
| 194 |
+
return
|
| 195 |
+
checkpoint = torch.load(checkpoint_path,map_location='cuda:{}'.format(opt.local_rank))
|
| 196 |
+
checkpoint_new = model.state_dict()
|
| 197 |
+
for param in checkpoint_new:
|
| 198 |
+
if 'cond_' not in param and 'aflow_net.netRefine' not in param:
|
| 199 |
+
checkpoint_new[param] = checkpoint[param]
|
| 200 |
+
model.load_state_dict(checkpoint_new)
|
| 201 |
+
|
| 202 |
+
|
VITON-Extends-Train/options/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
# options_init
|
VITON-Extends-Train/options/base_options.py
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import os
|
| 3 |
+
from util import util
|
| 4 |
+
import torch
|
| 5 |
+
|
| 6 |
+
class BaseOptions():
|
| 7 |
+
def __init__(self):
|
| 8 |
+
self.parser = argparse.ArgumentParser()
|
| 9 |
+
self.initialized = False
|
| 10 |
+
|
| 11 |
+
def initialize(self):
|
| 12 |
+
# experiment specifics
|
| 13 |
+
self.parser.add_argument('--name', type=str, default='flow', help='name of the experiment. It decides where to store samples and models')
|
| 14 |
+
self.parser.add_argument('--gpu_ids', type=str, default='0', help='gpu ids: e.g. 0 0,1,2, 0,2. use -1 for CPU')
|
| 15 |
+
self.parser.add_argument('--num_gpus', type=int, default=1, help='the number of gpus')
|
| 16 |
+
self.parser.add_argument('--checkpoints_dir', type=str, default='./checkpoints', help='models are saved here')
|
| 17 |
+
self.parser.add_argument('--norm', type=str, default='instance', help='instance normalization or batch normalization')
|
| 18 |
+
self.parser.add_argument('--use_dropout', action='store_true', help='use dropout for the generator')
|
| 19 |
+
self.parser.add_argument('--data_type', default=32, type=int, choices=[8, 16, 32], help="Supported data type i.e. 8, 16, 32 bit")
|
| 20 |
+
self.parser.add_argument('--verbose', action='store_true', default=False, help='toggles verbose')
|
| 21 |
+
|
| 22 |
+
# input/output sizes
|
| 23 |
+
self.parser.add_argument('--batchSize', type=int, default=32, help='input batch size')
|
| 24 |
+
self.parser.add_argument('--loadSize', type=int, default=512, help='scale images to this size')
|
| 25 |
+
self.parser.add_argument('--fineSize', type=int, default=512, help='then crop to this size')
|
| 26 |
+
self.parser.add_argument('--label_nc', type=int, default=20, help='# of input label channels')
|
| 27 |
+
self.parser.add_argument('--input_nc', type=int, default=3, help='# of input image channels')
|
| 28 |
+
self.parser.add_argument('--output_nc', type=int, default=3, help='# of output image channels')
|
| 29 |
+
|
| 30 |
+
# for setting inputs
|
| 31 |
+
self.parser.add_argument('--dataroot', type=str,default='dataset/VITON_traindata/')
|
| 32 |
+
self.parser.add_argument('--resize_or_crop', type=str, default='scale_width', help='scaling and cropping of images at load time [resize_and_crop|crop|scale_width|scale_width_and_crop]')
|
| 33 |
+
self.parser.add_argument('--serial_batches', action='store_true', help='if true, takes images in order to make batches, otherwise takes them randomly')
|
| 34 |
+
self.parser.add_argument('--no_flip', action='store_true', help='if specified, do not flip the images for data argumentation')
|
| 35 |
+
self.parser.add_argument('--nThreads', default=1, type=int, help='# threads for loading data')
|
| 36 |
+
self.parser.add_argument('--max_dataset_size', type=int, default=float("inf"), help='Maximum number of samples allowed per dataset. If the dataset directory contains more than max_dataset_size, only a subset is loaded.')
|
| 37 |
+
|
| 38 |
+
# for displays
|
| 39 |
+
self.parser.add_argument('--display_winsize', type=int, default=512, help='display window size')
|
| 40 |
+
self.parser.add_argument('--tf_log', action='store_true', help='if specified, use tensorboard logging. Requires tensorflow installed')
|
| 41 |
+
|
| 42 |
+
# for generator
|
| 43 |
+
self.parser.add_argument('--netG', type=str, default='global', help='selects model to use for netG')
|
| 44 |
+
self.parser.add_argument('--ngf', type=int, default=64, help='# of gen filters in first conv layer')
|
| 45 |
+
self.parser.add_argument('--n_downsample_global', type=int, default=4, help='number of downsampling layers in netG')
|
| 46 |
+
self.parser.add_argument('--n_blocks_global', type=int, default=4, help='number of residual blocks in the global generator network')
|
| 47 |
+
self.parser.add_argument('--n_blocks_local', type=int, default=3, help='number of residual blocks in the local enhancer network')
|
| 48 |
+
self.parser.add_argument('--n_local_enhancers', type=int, default=1, help='number of local enhancers to use')
|
| 49 |
+
self.parser.add_argument('--niter_fix_global', type=int, default=0, help='number of epochs that we only train the outmost local enhancer')
|
| 50 |
+
self.parser.add_argument('--tv_weight', type=float, default=0.1, help='weight for TV loss')
|
| 51 |
+
|
| 52 |
+
self.initialized = True
|
| 53 |
+
|
| 54 |
+
def parse(self, save=True):
|
| 55 |
+
if not self.initialized:
|
| 56 |
+
self.initialize()
|
| 57 |
+
self.opt = self.parser.parse_args()
|
| 58 |
+
self.opt.isTrain = self.isTrain # train or test
|
| 59 |
+
|
| 60 |
+
str_ids = self.opt.gpu_ids.split(',')
|
| 61 |
+
self.opt.gpu_ids = []
|
| 62 |
+
for str_id in str_ids:
|
| 63 |
+
id = int(str_id)
|
| 64 |
+
if id >= 0:
|
| 65 |
+
self.opt.gpu_ids.append(id)
|
| 66 |
+
|
| 67 |
+
# set gpu ids
|
| 68 |
+
if len(self.opt.gpu_ids) > 0:
|
| 69 |
+
torch.cuda.set_device(self.opt.gpu_ids[0])
|
| 70 |
+
|
| 71 |
+
args = vars(self.opt)
|
| 72 |
+
|
| 73 |
+
print('------------ Options -------------')
|
| 74 |
+
for k, v in sorted(args.items()):
|
| 75 |
+
print('%s: %s' % (str(k), str(v)))
|
| 76 |
+
print('-------------- End ----------------')
|
| 77 |
+
|
| 78 |
+
# save to the disk
|
| 79 |
+
expr_dir = os.path.join(self.opt.checkpoints_dir, self.opt.name)
|
| 80 |
+
util.mkdirs(expr_dir)
|
| 81 |
+
if save and not self.opt.continue_train:
|
| 82 |
+
file_name = os.path.join(expr_dir, 'opt.txt')
|
| 83 |
+
with open(file_name, 'wt') as opt_file:
|
| 84 |
+
opt_file.write('------------ Options -------------\n')
|
| 85 |
+
for k, v in sorted(args.items()):
|
| 86 |
+
opt_file.write('%s: %s\n' % (str(k), str(v)))
|
| 87 |
+
opt_file.write('-------------- End ----------------\n')
|
| 88 |
+
return self.opt
|
VITON-Extends-Train/options/train_options.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from .base_options import BaseOptions
|
| 2 |
+
|
| 3 |
+
class TrainOptions(BaseOptions):
|
| 4 |
+
def initialize(self):
|
| 5 |
+
BaseOptions.initialize(self)
|
| 6 |
+
# for displays
|
| 7 |
+
self.parser.add_argument('--launcher', choices=['none', 'pytorch'], default='none',help='job launcher')
|
| 8 |
+
self.parser.add_argument('--local_rank', type=int, default=0)
|
| 9 |
+
|
| 10 |
+
self.parser.add_argument('--display_freq', type=int, default=100, help='frequency of showing training results on screen')
|
| 11 |
+
self.parser.add_argument('--print_freq', type=int, default=100, help='frequency of showing training results on console')
|
| 12 |
+
self.parser.add_argument('--save_latest_freq', type=int, default=1000, help='frequency of saving the latest results')
|
| 13 |
+
self.parser.add_argument('--save_epoch_freq', type=int, default=20, help='frequency of saving checkpoints at the end of epochs')
|
| 14 |
+
self.parser.add_argument('--no_html', action='store_true', help='do not save intermediate training results to [opt.checkpoints_dir]/[opt.name]/web/')
|
| 15 |
+
self.parser.add_argument('--debug', action='store_true', help='only do one epoch and displays at each iteration')
|
| 16 |
+
|
| 17 |
+
# for training
|
| 18 |
+
self.parser.add_argument('--continue_train', action='store_true', help='continue training: load the latest model')
|
| 19 |
+
self.parser.add_argument('--load_pretrain', type=str, default='', help='load the pretrained model from the specified location')
|
| 20 |
+
self.parser.add_argument('--which_epoch', type=str, default='latest', help='which epoch to load? set to latest to use latest cached model')
|
| 21 |
+
self.parser.add_argument('--phase', type=str, default='train', help='train, val, test, etc')
|
| 22 |
+
self.parser.add_argument('--niter', type=int, default=50, help='# of iter at starting learning rate')
|
| 23 |
+
self.parser.add_argument('--niter_decay', type=int, default=50, help='# of iter to linearly decay learning rate to zero')
|
| 24 |
+
self.parser.add_argument('--beta1', type=float, default=0.5, help='momentum term of adam')
|
| 25 |
+
self.parser.add_argument('--lr', type=float, default=0.00005, help='initial learning rate for adam')
|
| 26 |
+
self.parser.add_argument('--PFAFN_warp_checkpoint', type=str, help='load the pretrained model from the specified location')
|
| 27 |
+
self.parser.add_argument('--PFAFN_gen_checkpoint', type=str, help='load the pretrained model from the specified location')
|
| 28 |
+
self.parser.add_argument('--PBAFN_warp_checkpoint', type=str, help='load the pretrained model from the specified location')
|
| 29 |
+
self.parser.add_argument('--PBAFN_gen_checkpoint', type=str, help='load the pretrained model from the specified location')
|
| 30 |
+
# for discriminators
|
| 31 |
+
self.parser.add_argument('--num_D', type=int, default=2, help='number of discriminators to use')
|
| 32 |
+
self.parser.add_argument('--n_layers_D', type=int, default=3, help='only used if which_model_netD==n_layers')
|
| 33 |
+
self.parser.add_argument('--ndf', type=int, default=64, help='# of discrim filters in first conv layer')
|
| 34 |
+
self.parser.add_argument('--lambda_feat', type=float, default=10.0, help='weight for feature matching loss')
|
| 35 |
+
self.parser.add_argument('--no_ganFeat_loss', action='store_true', help='if specified, do *not* use discriminator feature matching loss')
|
| 36 |
+
self.parser.add_argument('--no_vgg_loss', action='store_true', help='if specified, do *not* use VGG feature matching loss')
|
| 37 |
+
self.parser.add_argument('--no_lsgan', action='store_true', help='do *not* use least square GAN, if false, use vanilla GAN')
|
| 38 |
+
self.parser.add_argument('--pool_size', type=int, default=0, help='the size of image buffer that stores previously generated images')
|
| 39 |
+
|
| 40 |
+
self.isTrain = True
|
VITON-Extends-Train/runs/readme.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
The tensorboard logs will be saved here.
|
VITON-Extends-Train/sample/readme.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
The images during training will be saved here.
|
VITON-Extends-Train/scripts/train_VITON-Extends2_e2e.sh
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
python -m torch.distributed.launch --nproc_per_node=8 --master_port=7129 train_VITON-Extends2_e2e.py --name VITON-Extends2_e2e \
|
| 2 |
+
--VITON-Extends2_warp_checkpoint 'checkpoints/VITON-Extends2_stage1/VITON-Extends2_warp_epoch_201.pth' \
|
| 3 |
+
--VITON-Extends_warp_checkpoint 'checkpoints/VITON-Extends_e2e/VITON-Extends_warp_epoch_101.pth' --VITON-Extends_gen_checkpoint 'checkpoints/VITON-Extends_e2e/VITON-Extends_gen_epoch_101.pth' \
|
| 4 |
+
--resize_or_crop None --verbose --tf_log --batchSize 4 --num_gpus 8 --label_nc 14 --launcher pytorch
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
|
VITON-Extends-Train/scripts/train_VITON-Extends2_stage1.sh
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
python -m torch.distributed.launch --nproc_per_node=8 --master_port=4703 train_VITON-Extends2_stage1.py --name VITON-Extends2_stage1 \
|
| 2 |
+
--PBAFN_warp_checkpoint 'checkpoints/VITON-Extends_e2e/VITON-Extends_warp_epoch_101.pth' --PBAFN_gen_checkpoint 'checkpoints/VITON-Extends_e2e/VITON-Extends_gen_epoch_101.pth' \
|
| 3 |
+
--lr 0.00003 --niter 100 --niter_decay 100 --resize_or_crop None --verbose --tf_log --batchSize 4 --num_gpus 8 --label_nc 14 --launcher pytorch
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
|
VITON-Extends-Train/scripts/train_VITON-Extends_e2e.sh
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
python -m torch.distributed.launch --nproc_per_node=8 --master_port=4736 train_VITON-Extends_e2e.py --name VITON-Extends_e2e \
|
| 2 |
+
--VITON-Extends_warp_checkpoint 'checkpoints/VITON-Extends_stage1/VITON-Extends_warp_epoch_101.pth' --resize_or_crop None --verbose --tf_log --batchSize 4 --num_gpus 8 --label_nc 14 --launcher pytorch
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
|
VITON-Extends-Train/scripts/train_VITON-Extends_stage1.sh
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
python -m torch.distributed.launch --nproc_per_node=8 --master_port=7129 train_VITON-Extends_stage1.py --name VITON-Extends_stage1 \
|
| 2 |
+
--resize_or_crop None --verbose --tf_log --batchSize 4 --num_gpus 8 --label_nc 14 --launcher pytorch
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
|
VITON-Extends-Train/train_VITON-Extends2_e2e.py
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import time
|
| 2 |
+
from options.train_options import TrainOptions
|
| 3 |
+
from models.networks import ResUnetGenerator, VGGLoss, save_checkpoint, load_checkpoint_parallel
|
| 4 |
+
from models.afwm import TVLoss, AFWM
|
| 5 |
+
import torch.nn as nn
|
| 6 |
+
import torch.nn.functional as F
|
| 7 |
+
import os
|
| 8 |
+
import numpy as np
|
| 9 |
+
import torch
|
| 10 |
+
from torch.utils.data import DataLoader
|
| 11 |
+
from torch.utils.data.distributed import DistributedSampler
|
| 12 |
+
from tensorboardX import SummaryWriter
|
| 13 |
+
import datetime
|
| 14 |
+
import cv2
|
| 15 |
+
|
| 16 |
+
opt = TrainOptions().parse()
|
| 17 |
+
path = 'runs/' + opt.name
|
| 18 |
+
os.makedirs(path, exist_ok=True)
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def CreateDataset(opt):
|
| 22 |
+
from data.aligned_dataset import AlignedDataset
|
| 23 |
+
dataset = AlignedDataset()
|
| 24 |
+
print("dataset [%s] was created" % (dataset.name()))
|
| 25 |
+
dataset.initialize(opt)
|
| 26 |
+
return dataset
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
os.makedirs('sample', exist_ok=True)
|
| 30 |
+
opt = TrainOptions().parse()
|
| 31 |
+
iter_path = os.path.join(opt.checkpoints_dir, opt.name, 'iter.txt')
|
| 32 |
+
|
| 33 |
+
torch.cuda.set_device(opt.local_rank)
|
| 34 |
+
torch.distributed.init_process_group(
|
| 35 |
+
'nccl',
|
| 36 |
+
init_method='env://'
|
| 37 |
+
)
|
| 38 |
+
device = torch.device(f'cuda:{opt.local_rank}')
|
| 39 |
+
|
| 40 |
+
start_epoch, epoch_iter = 1, 0
|
| 41 |
+
|
| 42 |
+
train_data = CreateDataset(opt)
|
| 43 |
+
train_sampler = DistributedSampler(train_data)
|
| 44 |
+
train_loader = DataLoader(train_data, batch_size=opt.batchSize, shuffle=False,
|
| 45 |
+
num_workers=4, pin_memory=True, sampler=train_sampler)
|
| 46 |
+
dataset_size = len(train_loader)
|
| 47 |
+
|
| 48 |
+
PF_warp_model = AFWM(opt, 3)
|
| 49 |
+
print(PF_warp_model)
|
| 50 |
+
PF_warp_model.train()
|
| 51 |
+
PF_warp_model.cuda()
|
| 52 |
+
load_checkpoint_parallel(PF_warp_model, opt.PFAFN_warp_checkpoint)
|
| 53 |
+
|
| 54 |
+
PF_gen_model = ResUnetGenerator(7, 4, 5, ngf=64, norm_layer=nn.BatchNorm2d)
|
| 55 |
+
print(PF_gen_model)
|
| 56 |
+
PF_gen_model.train()
|
| 57 |
+
PF_gen_model.cuda()
|
| 58 |
+
|
| 59 |
+
PB_warp_model = AFWM(opt, 45)
|
| 60 |
+
print(PB_warp_model)
|
| 61 |
+
PB_warp_model.eval()
|
| 62 |
+
PB_warp_model.cuda()
|
| 63 |
+
load_checkpoint_parallel(PB_warp_model, opt.PBAFN_warp_checkpoint)
|
| 64 |
+
|
| 65 |
+
PB_gen_model = ResUnetGenerator(8, 4, 5, ngf=64, norm_layer=nn.BatchNorm2d)
|
| 66 |
+
print(PB_gen_model)
|
| 67 |
+
PB_gen_model.eval()
|
| 68 |
+
PB_gen_model.cuda()
|
| 69 |
+
load_checkpoint_parallel(PB_gen_model, opt.PBAFN_gen_checkpoint)
|
| 70 |
+
|
| 71 |
+
PF_warp_model = torch.nn.SyncBatchNorm.convert_sync_batchnorm(PF_warp_model).to(device)
|
| 72 |
+
PF_gen_model = torch.nn.SyncBatchNorm.convert_sync_batchnorm(PF_gen_model).to(device)
|
| 73 |
+
|
| 74 |
+
if opt.isTrain and len(opt.gpu_ids):
|
| 75 |
+
PF_warp_model = torch.nn.parallel.DistributedDataParallel(PF_warp_model, device_ids=[opt.local_rank])
|
| 76 |
+
PF_gen_model = torch.nn.parallel.DistributedDataParallel(PF_gen_model, device_ids=[opt.local_rank])
|
| 77 |
+
PB_warp_model = torch.nn.parallel.DistributedDataParallel(PB_warp_model, device_ids=[opt.local_rank])
|
| 78 |
+
PB_gen_model = torch.nn.parallel.DistributedDataParallel(PB_gen_model, device_ids=[opt.local_rank])
|
| 79 |
+
|
| 80 |
+
criterionL1 = nn.L1Loss()
|
| 81 |
+
criterionVGG = VGGLoss()
|
| 82 |
+
criterionL2 = nn.MSELoss('sum')
|
| 83 |
+
|
| 84 |
+
params_warp = [p for p in PF_warp_model.parameters()]
|
| 85 |
+
params_gen = [p for p in PF_gen_model.parameters()]
|
| 86 |
+
optimizer_warp = torch.optim.Adam(params_warp, lr=0.2 * opt.lr, betas=(opt.beta1, 0.999))
|
| 87 |
+
optimizer_gen = torch.optim.Adam(params_gen, lr=opt.lr, betas=(opt.beta1, 0.999))
|
| 88 |
+
|
| 89 |
+
total_steps = (start_epoch - 1) * dataset_size + epoch_iter
|
| 90 |
+
|
| 91 |
+
if opt.local_rank == 0:
|
| 92 |
+
writer = SummaryWriter(path)
|
| 93 |
+
|
| 94 |
+
step = 0
|
| 95 |
+
step_per_batch = dataset_size
|
| 96 |
+
|
| 97 |
+
for epoch in range(start_epoch, opt.niter + opt.niter_decay + 1):
|
| 98 |
+
epoch_start_time = time.time()
|
| 99 |
+
if epoch != start_epoch:
|
| 100 |
+
epoch_iter = epoch_iter % dataset_size
|
| 101 |
+
|
| 102 |
+
train_sampler.set_epoch(epoch)
|
| 103 |
+
|
| 104 |
+
for i, data in enumerate(train_loader):
|
| 105 |
+
|
| 106 |
+
iter_start_time = time.time()
|
| 107 |
+
|
| 108 |
+
total_steps += 1
|
| 109 |
+
epoch_iter += 1
|
| 110 |
+
save_fake = True
|
| 111 |
+
|
| 112 |
+
t_mask = torch.FloatTensor((data['label'].cpu().numpy() == 7).astype(np.float))
|
| 113 |
+
data['label'] = data['label'] * (1 - t_mask) + t_mask * 4
|
| 114 |
+
edge = data['edge']
|
| 115 |
+
pre_clothes_edge = torch.FloatTensor((edge.detach().numpy() > 0.5).astype(np.int))
|
| 116 |
+
clothes = data['color']
|
| 117 |
+
clothes = clothes * pre_clothes_edge
|
| 118 |
+
edge_un = data['edge_un']
|
| 119 |
+
pre_clothes_edge_un = torch.FloatTensor((edge_un.detach().numpy() > 0.5).astype(np.int))
|
| 120 |
+
clothes_un = data['color_un']
|
| 121 |
+
clothes_un = clothes_un * pre_clothes_edge_un
|
| 122 |
+
person_clothes_edge = torch.FloatTensor((data['label'].cpu().numpy() == 4).astype(np.int))
|
| 123 |
+
real_image = data['image']
|
| 124 |
+
person_clothes = real_image * person_clothes_edge
|
| 125 |
+
pose = data['pose']
|
| 126 |
+
size = data['label'].size()
|
| 127 |
+
oneHot_size1 = (size[0], 25, size[2], size[3])
|
| 128 |
+
densepose = torch.cuda.FloatTensor(torch.Size(oneHot_size1)).zero_()
|
| 129 |
+
densepose = densepose.scatter_(1, data['densepose'].data.long().cuda(), 1.0)
|
| 130 |
+
densepose_fore = data['densepose'] / 24
|
| 131 |
+
face_mask = torch.FloatTensor((data['label'].cpu().numpy() == 1).astype(np.int)) + torch.FloatTensor((data['label'].cpu().numpy() == 12).astype(np.int))
|
| 132 |
+
other_clothes_mask = torch.FloatTensor((data['label'].cpu().numpy() == 5).astype(np.int)) + torch.FloatTensor((data['label'].cpu().numpy() == 6).astype(np.int)) \
|
| 133 |
+
+ torch.FloatTensor((data['label'].cpu().numpy() == 8).astype(np.int)) + torch.FloatTensor((data['label'].cpu().numpy() == 9).astype(np.int)) \
|
| 134 |
+
+ torch.FloatTensor((data['label'].cpu().numpy() == 10).astype(np.int))
|
| 135 |
+
face_img = face_mask * real_image
|
| 136 |
+
other_clothes_img = other_clothes_mask * real_image
|
| 137 |
+
preserve_mask = torch.cat([face_mask, other_clothes_mask], 1)
|
| 138 |
+
|
| 139 |
+
concat_un = torch.cat([preserve_mask.cuda(), densepose, pose.cuda()], 1)
|
| 140 |
+
flow_out_un = PB_warp_model(concat_un.cuda(), clothes_un.cuda(), pre_clothes_edge_un.cuda())
|
| 141 |
+
warped_cloth_un, last_flow_un, cond_un_all, flow_un_all, delta_list_un, x_all_un, x_edge_all_un, delta_x_all_un, delta_y_all_un = flow_out_un
|
| 142 |
+
warped_prod_edge_un = F.grid_sample(pre_clothes_edge_un.cuda(), last_flow_un.permute(0, 2, 3, 1),
|
| 143 |
+
mode='bilinear', padding_mode='zeros')
|
| 144 |
+
|
| 145 |
+
flow_out_sup = PB_warp_model(concat_un.cuda(), clothes.cuda(), pre_clothes_edge.cuda())
|
| 146 |
+
warped_cloth_sup, last_flow_sup, cond_sup_all, flow_sup_all, delta_list_sup, x_all_sup, x_edge_all_sup, delta_x_all_sup, delta_y_all_sup = flow_out_sup
|
| 147 |
+
|
| 148 |
+
arm_mask = torch.FloatTensor((data['label'].cpu().numpy() == 11).astype(np.float)) + torch.FloatTensor((data['label'].cpu().numpy() == 13).astype(np.float))
|
| 149 |
+
hand_mask = torch.FloatTensor((data['densepose'].cpu().numpy() == 3).astype(np.int)) + torch.FloatTensor((data['densepose'].cpu().numpy() == 4).astype(np.int))
|
| 150 |
+
dense_preserve_mask = torch.FloatTensor((data['densepose'].cpu().numpy() == 15).astype(np.int)) + torch.FloatTensor((data['densepose'].cpu().numpy() == 16).astype(np.int)) \
|
| 151 |
+
+ torch.FloatTensor((data['densepose'].cpu().numpy() == 17).astype(np.int)) + torch.FloatTensor((data['densepose'].cpu().numpy() == 18).astype(np.int)) \
|
| 152 |
+
+ torch.FloatTensor((data['densepose'].cpu().numpy() == 19).astype(np.int)) + torch.FloatTensor((data['densepose'].cpu().numpy() == 20).astype(np.int)) \
|
| 153 |
+
+ torch.FloatTensor((data['densepose'].cpu().numpy() == 21).astype(np.int)) + torch.FloatTensor((data['densepose'].cpu().numpy() == 22))
|
| 154 |
+
hand_img = (arm_mask * hand_mask) * real_image
|
| 155 |
+
dense_preserve_mask = dense_preserve_mask.cuda() * (1 - warped_prod_edge_un)
|
| 156 |
+
preserve_region = face_img + other_clothes_img + hand_img
|
| 157 |
+
|
| 158 |
+
gen_inputs_un = torch.cat([preserve_region.cuda(), warped_cloth_un, warped_prod_edge_un, dense_preserve_mask], 1)
|
| 159 |
+
gen_outputs_un = PB_gen_model(gen_inputs_un)
|
| 160 |
+
p_rendered_un, m_composite_un = torch.split(gen_outputs_un, [3, 1], 1)
|
| 161 |
+
p_rendered_un = torch.tanh(p_rendered_un)
|
| 162 |
+
m_composite_un = torch.sigmoid(m_composite_un)
|
| 163 |
+
m_composite_un = m_composite_un * warped_prod_edge_un
|
| 164 |
+
p_tryon_un = warped_cloth_un * m_composite_un + p_rendered_un * (1 - m_composite_un)
|
| 165 |
+
|
| 166 |
+
flow_out = PF_warp_model(p_tryon_un.detach(), clothes.cuda(), pre_clothes_edge.cuda())
|
| 167 |
+
warped_cloth, last_flow, cond_all, flow_all, delta_list, x_all, x_edge_all, delta_x_all, delta_y_all = flow_out
|
| 168 |
+
warped_prod_edge = x_edge_all[4]
|
| 169 |
+
|
| 170 |
+
epsilon = 0.001
|
| 171 |
+
loss_smooth = sum([TVLoss(x) for x in delta_list])
|
| 172 |
+
loss_warp = 0
|
| 173 |
+
loss_fea_sup_all = 0
|
| 174 |
+
loss_flow_sup_all = 0
|
| 175 |
+
|
| 176 |
+
l1_loss_batch = torch.abs(warped_cloth_sup.detach() - person_clothes.cuda())
|
| 177 |
+
l1_loss_batch = l1_loss_batch.reshape(opt.batchSize, 3 * 256 * 192)
|
| 178 |
+
l1_loss_batch = l1_loss_batch.sum(dim=1) / (3 * 256 * 192)
|
| 179 |
+
l1_loss_batch_pred = torch.abs(warped_cloth.detach() - person_clothes.cuda())
|
| 180 |
+
l1_loss_batch_pred = l1_loss_batch_pred.reshape(opt.batchSize, 3 * 256 * 192)
|
| 181 |
+
l1_loss_batch_pred = l1_loss_batch_pred.sum(dim=1) / (3 * 256 * 192)
|
| 182 |
+
weight = (l1_loss_batch < l1_loss_batch_pred).float()
|
| 183 |
+
num_all = len(np.where(weight.cpu().numpy() > 0)[0])
|
| 184 |
+
if num_all == 0:
|
| 185 |
+
num_all = 1
|
| 186 |
+
|
| 187 |
+
for num in range(5):
|
| 188 |
+
cur_person_clothes = F.interpolate(person_clothes, scale_factor=0.5 ** (4 - num), mode='bilinear')
|
| 189 |
+
cur_person_clothes_edge = F.interpolate(person_clothes_edge, scale_factor=0.5 ** (4 - num), mode='bilinear')
|
| 190 |
+
loss_l1 = criterionL1(x_all[num], cur_person_clothes.cuda())
|
| 191 |
+
loss_vgg = criterionVGG(x_all[num], cur_person_clothes.cuda())
|
| 192 |
+
loss_edge = criterionL1(x_edge_all[num], cur_person_clothes_edge.cuda())
|
| 193 |
+
b, c, h, w = delta_x_all[num].shape
|
| 194 |
+
loss_flow_x = (delta_x_all[num].pow(2) + epsilon * epsilon).pow(0.45)
|
| 195 |
+
loss_flow_x = torch.sum(loss_flow_x) / (b * c * h * w)
|
| 196 |
+
loss_flow_y = (delta_y_all[num].pow(2) + epsilon * epsilon).pow(0.45)
|
| 197 |
+
loss_flow_y = torch.sum(loss_flow_y) / (b * c * h * w)
|
| 198 |
+
loss_second_smooth = loss_flow_x + loss_flow_y
|
| 199 |
+
b1, c1, h1, w1 = cond_all[num].shape
|
| 200 |
+
weight_all = weight.reshape(-1, 1, 1, 1).repeat(1, 256, h1, w1)
|
| 201 |
+
cond_sup_loss = ((cond_sup_all[num].detach() - cond_all[num]) ** 2 * weight_all).sum() / (256 * h1 * w1 * num_all)
|
| 202 |
+
loss_fea_sup_all = loss_fea_sup_all + (5 - num) * 0.04 * cond_sup_loss
|
| 203 |
+
loss_warp = loss_warp + (num + 1) * loss_l1 + (num + 1) * 0.2 * loss_vgg + (num + 1) * 2 * loss_edge + (num + 1) * 6 * loss_second_smooth + (5 - num) * 0.04 * cond_sup_loss
|
| 204 |
+
if num >= 2:
|
| 205 |
+
b1, c1, h1, w1 = flow_all[num].shape
|
| 206 |
+
weight_all = weight.reshape(-1, 1, 1).repeat(1, h1, w1)
|
| 207 |
+
flow_sup_loss = (torch.norm(flow_sup_all[num].detach() - flow_all[num], p=2, dim=1) * weight_all).sum() / (h1 * w1 * num_all)
|
| 208 |
+
loss_flow_sup_all = loss_flow_sup_all + (num + 1) * 1 * flow_sup_loss
|
| 209 |
+
loss_warp = loss_warp + (num + 1) * 1 * flow_sup_loss
|
| 210 |
+
|
| 211 |
+
loss_warp = 0.01 * loss_smooth + loss_warp
|
| 212 |
+
|
| 213 |
+
if opt.local_rank == 0:
|
| 214 |
+
writer.add_scalar('loss_warp', loss_warp, step)
|
| 215 |
+
writer.add_scalar('loss_fea_sup_all', loss_fea_sup_all, step)
|
| 216 |
+
writer.add_scalar('loss_flow_sup_all', loss_flow_sup_all, step)
|
| 217 |
+
|
| 218 |
+
skin_mask = warped_prod_edge_un.detach() * (1 - person_clothes_edge.cuda())
|
| 219 |
+
gen_inputs = torch.cat([p_tryon_un.detach(), warped_cloth, warped_prod_edge], 1)
|
| 220 |
+
gen_outputs = PF_gen_model(gen_inputs)
|
| 221 |
+
p_rendered, m_composite = torch.split(gen_outputs, [3, 1], 1)
|
| 222 |
+
p_rendered = torch.tanh(p_rendered)
|
| 223 |
+
m_composite = torch.sigmoid(m_composite)
|
| 224 |
+
m_composite1 = m_composite * warped_prod_edge
|
| 225 |
+
m_composite = person_clothes_edge.cuda() * m_composite1
|
| 226 |
+
p_tryon = warped_cloth * m_composite + p_rendered * (1 - m_composite)
|
| 227 |
+
|
| 228 |
+
loss_mask_l1 = torch.mean(torch.abs(1 - m_composite))
|
| 229 |
+
loss_l1_skin = criterionL1(p_rendered * skin_mask, skin_mask * real_image.cuda())
|
| 230 |
+
loss_vgg_skin = criterionVGG(p_rendered * skin_mask, skin_mask * real_image.cuda())
|
| 231 |
+
loss_l1 = criterionL1(p_tryon, real_image.cuda())
|
| 232 |
+
loss_vgg = criterionVGG(p_tryon, real_image.cuda())
|
| 233 |
+
bg_loss_l1 = criterionL1(p_rendered, real_image.cuda())
|
| 234 |
+
bg_loss_vgg = criterionVGG(p_rendered, real_image.cuda())
|
| 235 |
+
|
| 236 |
+
if epoch < opt.niter:
|
| 237 |
+
loss_gen = (loss_l1 * 5 + loss_l1_skin * 30 + loss_vgg + loss_vgg_skin * 2 + bg_loss_l1 * 5 + bg_loss_vgg + 1 * loss_mask_l1)
|
| 238 |
+
else:
|
| 239 |
+
loss_gen = (loss_l1 * 5 + loss_l1_skin * 60 + loss_vgg + loss_vgg_skin * 4 + bg_loss_l1 * 5 + bg_loss_vgg + 1 * loss_mask_l1)
|
| 240 |
+
|
| 241 |
+
loss_all = 0.25 * loss_warp + loss_gen
|
| 242 |
+
|
| 243 |
+
if opt.local_rank == 0:
|
| 244 |
+
writer.add_scalar('loss_gen', loss_gen, step)
|
| 245 |
+
|
| 246 |
+
optimizer_warp.zero_grad()
|
| 247 |
+
optimizer_gen.zero_grad()
|
| 248 |
+
loss_all.backward()
|
| 249 |
+
optimizer_warp.step()
|
| 250 |
+
optimizer_gen.step()
|
| 251 |
+
|
| 252 |
+
############## Display results and errors ##########
|
| 253 |
+
path = 'sample/' + opt.name
|
| 254 |
+
os.makedirs(path, exist_ok=True)
|
| 255 |
+
### display output images
|
| 256 |
+
if step % 1000 == 0:
|
| 257 |
+
if opt.local_rank == 0:
|
| 258 |
+
a = real_image.float().cuda()
|
| 259 |
+
b = p_tryon_un.detach()
|
| 260 |
+
c = clothes.cuda()
|
| 261 |
+
d = person_clothes.cuda()
|
| 262 |
+
e = torch.cat([skin_mask.cuda(), skin_mask.cuda(), skin_mask.cuda()], 1)
|
| 263 |
+
f = warped_cloth
|
| 264 |
+
g = p_rendered
|
| 265 |
+
h = torch.cat([m_composite1, m_composite1, m_composite1], 1)
|
| 266 |
+
i = p_tryon
|
| 267 |
+
combine = torch.cat([a[0], b[0], c[0], d[0], e[0], f[0], g[0], h[0], i[0]], 2).squeeze()
|
| 268 |
+
cv_img = (combine.permute(1, 2, 0).detach().cpu().numpy() + 1) / 2
|
| 269 |
+
writer.add_image('combine', (combine.data + 1) / 2.0, step)
|
| 270 |
+
rgb = (cv_img * 255).astype(np.uint8)
|
| 271 |
+
bgr = cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR)
|
| 272 |
+
cv2.imwrite('sample/' + opt.name + '/' + str(step) + '.jpg', bgr)
|
| 273 |
+
|
| 274 |
+
step += 1
|
| 275 |
+
iter_end_time = time.time()
|
| 276 |
+
iter_delta_time = iter_end_time - iter_start_time
|
| 277 |
+
step_delta = (step_per_batch - step % step_per_batch) + step_per_batch * (opt.niter + opt.niter_decay - epoch)
|
| 278 |
+
eta = iter_delta_time * step_delta
|
| 279 |
+
eta = str(datetime.timedelta(seconds=int(eta)))
|
| 280 |
+
time_stamp = datetime.datetime.now()
|
| 281 |
+
now = time_stamp.strftime('%Y.%m.%d-%H:%M:%S')
|
| 282 |
+
|
| 283 |
+
if step % 100 == 0:
|
| 284 |
+
if opt.local_rank == 0:
|
| 285 |
+
print('{}:{}:[step-{}]--[loss-{:.6f}]--[loss-{:.6f}]--[ETA-{}]'.format(now, epoch_iter, step, loss_gen, loss_warp, eta))
|
| 286 |
+
|
| 287 |
+
if epoch_iter >= dataset_size:
|
| 288 |
+
break
|
| 289 |
+
|
| 290 |
+
# end of epoch
|
| 291 |
+
iter_end_time = time.time()
|
| 292 |
+
if opt.local_rank == 0:
|
| 293 |
+
print('End of epoch %d / %d \t Time Taken: %d sec' %
|
| 294 |
+
(epoch, opt.niter + opt.niter_decay, time.time() - epoch_start_time))
|
| 295 |
+
|
| 296 |
+
if epoch % opt.save_epoch_freq == 0:
|
| 297 |
+
if opt.local_rank == 0:
|
| 298 |
+
print('saving the model at the end of epoch %d, iters %d' % (epoch, total_steps))
|
| 299 |
+
save_checkpoint(PF_warp_model.module,
|
| 300 |
+
os.path.join(opt.checkpoints_dir, opt.name, 'PFAFN_warp_epoch_%03d.pth' % (epoch + 1)))
|
| 301 |
+
save_checkpoint(PF_gen_model.module,
|
| 302 |
+
os.path.join(opt.checkpoints_dir, opt.name, 'PFAFN_gen_epoch_%03d.pth' % (epoch + 1)))
|
| 303 |
+
|
| 304 |
+
if epoch > opt.niter:
|
| 305 |
+
PF_warp_model.module.update_learning_rate_warp(optimizer_warp)
|
| 306 |
+
PF_warp_model.module.update_learning_rate(optimizer_gen)
|
VITON-Extends-Train/train_VITON-Extends2_stage1.py
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import time
|
| 2 |
+
from options.train_options import TrainOptions
|
| 3 |
+
from models.networks import ResUnetGenerator, VGGLoss, save_checkpoint, load_checkpoint_part_parallel, \
|
| 4 |
+
load_checkpoint_parallel
|
| 5 |
+
from models.afwm import TVLoss, AFWM
|
| 6 |
+
import torch.nn as nn
|
| 7 |
+
import torch.nn.functional as F
|
| 8 |
+
import os
|
| 9 |
+
import numpy as np
|
| 10 |
+
import torch
|
| 11 |
+
from torch.utils.data import DataLoader
|
| 12 |
+
from torch.utils.data.distributed import DistributedSampler
|
| 13 |
+
from tensorboardX import SummaryWriter
|
| 14 |
+
import cv2
|
| 15 |
+
import datetime
|
| 16 |
+
|
| 17 |
+
opt = TrainOptions().parse()
|
| 18 |
+
path = 'runs/' + opt.name
|
| 19 |
+
os.makedirs(path, exist_ok=True)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def CreateDataset(opt):
|
| 23 |
+
from data.aligned_dataset import AlignedDataset
|
| 24 |
+
dataset = AlignedDataset()
|
| 25 |
+
print("dataset [%s] was created" % (dataset.name()))
|
| 26 |
+
dataset.initialize(opt)
|
| 27 |
+
return dataset
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
os.makedirs('sample', exist_ok=True)
|
| 31 |
+
opt = TrainOptions().parse()
|
| 32 |
+
iter_path = os.path.join(opt.checkpoints_dir, opt.name, 'iter.txt')
|
| 33 |
+
|
| 34 |
+
torch.cuda.set_device(opt.local_rank)
|
| 35 |
+
torch.distributed.init_process_group(
|
| 36 |
+
'nccl',
|
| 37 |
+
init_method='env://'
|
| 38 |
+
)
|
| 39 |
+
device = torch.device(f'cuda:{opt.local_rank}')
|
| 40 |
+
|
| 41 |
+
start_epoch, epoch_iter = 1, 0
|
| 42 |
+
|
| 43 |
+
train_data = CreateDataset(opt)
|
| 44 |
+
train_sampler = DistributedSampler(train_data)
|
| 45 |
+
train_loader = DataLoader(train_data, batch_size=opt.batchSize, shuffle=False,
|
| 46 |
+
num_workers=4, pin_memory=True, sampler=train_sampler)
|
| 47 |
+
dataset_size = len(train_loader)
|
| 48 |
+
print('#training images = %d' % dataset_size)
|
| 49 |
+
|
| 50 |
+
PF_warp_model = AFWM(opt, 3)
|
| 51 |
+
print(PF_warp_model)
|
| 52 |
+
PF_warp_model.train()
|
| 53 |
+
PF_warp_model.cuda()
|
| 54 |
+
load_checkpoint_part_parallel(PF_warp_model, opt.PBAFN_warp_checkpoint)
|
| 55 |
+
|
| 56 |
+
PB_warp_model = AFWM(opt, 45)
|
| 57 |
+
print(PB_warp_model)
|
| 58 |
+
PB_warp_model.eval()
|
| 59 |
+
PB_warp_model.cuda()
|
| 60 |
+
load_checkpoint_parallel(PB_warp_model, opt.PBAFN_warp_checkpoint)
|
| 61 |
+
|
| 62 |
+
PB_gen_model = ResUnetGenerator(8, 4, 5, ngf=64, norm_layer=nn.BatchNorm2d)
|
| 63 |
+
print(PB_gen_model)
|
| 64 |
+
PB_gen_model.eval()
|
| 65 |
+
PB_gen_model.cuda()
|
| 66 |
+
load_checkpoint_parallel(PB_gen_model, opt.PBAFN_gen_checkpoint)
|
| 67 |
+
|
| 68 |
+
PF_warp_model = torch.nn.SyncBatchNorm.convert_sync_batchnorm(PF_warp_model).to(device)
|
| 69 |
+
|
| 70 |
+
if opt.isTrain and len(opt.gpu_ids):
|
| 71 |
+
PF_warp_model = torch.nn.parallel.DistributedDataParallel(PF_warp_model, device_ids=[opt.local_rank])
|
| 72 |
+
PB_warp_model = torch.nn.parallel.DistributedDataParallel(PB_warp_model, device_ids=[opt.local_rank])
|
| 73 |
+
PB_gen_model = torch.nn.parallel.DistributedDataParallel(PB_gen_model, device_ids=[opt.local_rank])
|
| 74 |
+
|
| 75 |
+
criterionL1 = nn.L1Loss()
|
| 76 |
+
criterionVGG = VGGLoss()
|
| 77 |
+
criterionL2 = nn.MSELoss('sum')
|
| 78 |
+
|
| 79 |
+
# optimizer
|
| 80 |
+
params = [p for p in PF_warp_model.parameters()]
|
| 81 |
+
optimizer = torch.optim.Adam(params, lr=opt.lr, betas=(opt.beta1, 0.999))
|
| 82 |
+
|
| 83 |
+
params_part = []
|
| 84 |
+
for name, param in PF_warp_model.named_parameters():
|
| 85 |
+
if 'cond_' in name or 'aflow_net.netRefine' in name:
|
| 86 |
+
params_part.append(param)
|
| 87 |
+
optimizer_part = torch.optim.Adam(params_part, lr=opt.lr, betas=(opt.beta1, 0.999))
|
| 88 |
+
|
| 89 |
+
total_steps = (start_epoch - 1) * dataset_size + epoch_iter
|
| 90 |
+
|
| 91 |
+
if opt.local_rank == 0:
|
| 92 |
+
writer = SummaryWriter(path)
|
| 93 |
+
|
| 94 |
+
step = 0
|
| 95 |
+
step_per_batch = dataset_size
|
| 96 |
+
|
| 97 |
+
for epoch in range(start_epoch, opt.niter + opt.niter_decay + 1):
|
| 98 |
+
epoch_start_time = time.time()
|
| 99 |
+
if epoch != start_epoch:
|
| 100 |
+
epoch_iter = epoch_iter % dataset_size
|
| 101 |
+
|
| 102 |
+
train_sampler.set_epoch(epoch)
|
| 103 |
+
|
| 104 |
+
for i, data in enumerate(train_loader):
|
| 105 |
+
|
| 106 |
+
iter_start_time = time.time()
|
| 107 |
+
|
| 108 |
+
total_steps += 1
|
| 109 |
+
epoch_iter += 1
|
| 110 |
+
save_fake = True
|
| 111 |
+
|
| 112 |
+
t_mask = torch.FloatTensor((data['label'].cpu().numpy() == 7).astype(np.float))
|
| 113 |
+
data['label'] = data['label'] * (1 - t_mask) + t_mask * 4
|
| 114 |
+
edge = data['edge']
|
| 115 |
+
pre_clothes_edge = torch.FloatTensor((edge.detach().numpy() > 0.5).astype(np.int))
|
| 116 |
+
clothes = data['color']
|
| 117 |
+
clothes = clothes * pre_clothes_edge
|
| 118 |
+
edge_un = data['edge_un']
|
| 119 |
+
pre_clothes_edge_un = torch.FloatTensor((edge_un.detach().numpy() > 0.5).astype(np.int))
|
| 120 |
+
clothes_un = data['color_un']
|
| 121 |
+
clothes_un = clothes_un * pre_clothes_edge_un
|
| 122 |
+
person_clothes_edge = torch.FloatTensor((data['label'].cpu().numpy() == 4).astype(np.int))
|
| 123 |
+
real_image = data['image']
|
| 124 |
+
person_clothes = real_image * person_clothes_edge
|
| 125 |
+
pose = data['pose']
|
| 126 |
+
size = data['label'].size()
|
| 127 |
+
oneHot_size1 = (size[0], 25, size[2], size[3])
|
| 128 |
+
densepose = torch.cuda.FloatTensor(torch.Size(oneHot_size1)).zero_()
|
| 129 |
+
densepose = densepose.scatter_(1, data['densepose'].data.long().cuda(), 1.0)
|
| 130 |
+
densepose_fore = data['densepose'] / 24
|
| 131 |
+
face_mask = torch.FloatTensor((data['label'].cpu().numpy() == 1).astype(np.int)) + torch.FloatTensor((data['label'].cpu().numpy() == 12).astype(np.int))
|
| 132 |
+
other_clothes_mask = torch.FloatTensor((data['label'].cpu().numpy() == 5).astype(np.int)) + torch.FloatTensor((data['label'].cpu().numpy() == 6).astype(np.int)) \
|
| 133 |
+
+ torch.FloatTensor((data['label'].cpu().numpy() == 8).astype(np.int)) + torch.FloatTensor((data['label'].cpu().numpy() == 9).astype(np.int)) \
|
| 134 |
+
+ torch.FloatTensor((data['label'].cpu().numpy() == 10).astype(np.int))
|
| 135 |
+
face_img = face_mask * real_image
|
| 136 |
+
other_clothes_img = other_clothes_mask * real_image
|
| 137 |
+
preserve_mask = torch.cat([face_mask, other_clothes_mask], 1)
|
| 138 |
+
|
| 139 |
+
concat_un = torch.cat([preserve_mask.cuda(), densepose, pose.cuda()], 1)
|
| 140 |
+
flow_out_un = PB_warp_model(concat_un.cuda(), clothes_un.cuda(), pre_clothes_edge_un.cuda())
|
| 141 |
+
warped_cloth_un, last_flow_un, cond_un_all, flow_un_all, delta_list_un, x_all_un, x_edge_all_un, delta_x_all_un, delta_y_all_un = flow_out_un
|
| 142 |
+
warped_prod_edge_un = F.grid_sample(pre_clothes_edge_un.cuda(), last_flow_un.permute(0, 2, 3, 1),
|
| 143 |
+
mode='bilinear', padding_mode='zeros')
|
| 144 |
+
|
| 145 |
+
flow_out_sup = PB_warp_model(concat_un.cuda(), clothes.cuda(), pre_clothes_edge.cuda())
|
| 146 |
+
warped_cloth_sup, last_flow_sup, cond_sup_all, flow_sup_all, delta_list_sup, x_all_sup, x_edge_all_sup, delta_x_all_sup, delta_y_all_sup = flow_out_sup
|
| 147 |
+
|
| 148 |
+
arm_mask = torch.FloatTensor((data['label'].cpu().numpy() == 11).astype(np.float)) + torch.FloatTensor((data['label'].cpu().numpy() == 13).astype(np.float))
|
| 149 |
+
hand_mask = torch.FloatTensor((data['densepose'].cpu().numpy() == 3).astype(np.int)) + torch.FloatTensor((data['densepose'].cpu().numpy() == 4).astype(np.int))
|
| 150 |
+
dense_preserve_mask = torch.FloatTensor((data['densepose'].cpu().numpy() == 15).astype(np.int)) + torch.FloatTensor((data['densepose'].cpu().numpy() == 16).astype(np.int)) \
|
| 151 |
+
+ torch.FloatTensor((data['densepose'].cpu().numpy() == 17).astype(np.int)) + torch.FloatTensor((data['densepose'].cpu().numpy() == 18).astype(np.int)) \
|
| 152 |
+
+ torch.FloatTensor((data['densepose'].cpu().numpy() == 19).astype(np.int)) + torch.FloatTensor((data['densepose'].cpu().numpy() == 20).astype(np.int)) \
|
| 153 |
+
+ torch.FloatTensor((data['densepose'].cpu().numpy() == 21).astype(np.int)) + torch.FloatTensor((data['densepose'].cpu().numpy() == 22))
|
| 154 |
+
hand_img = (arm_mask * hand_mask) * real_image
|
| 155 |
+
dense_preserve_mask = dense_preserve_mask.cuda() * (1 - warped_prod_edge_un)
|
| 156 |
+
preserve_region = face_img + other_clothes_img + hand_img
|
| 157 |
+
|
| 158 |
+
gen_inputs_un = torch.cat([preserve_region.cuda(), warped_cloth_un, warped_prod_edge_un, dense_preserve_mask], 1)
|
| 159 |
+
gen_outputs_un = PB_gen_model(gen_inputs_un)
|
| 160 |
+
p_rendered_un, m_composite_un = torch.split(gen_outputs_un, [3, 1], 1)
|
| 161 |
+
p_rendered_un = torch.tanh(p_rendered_un)
|
| 162 |
+
m_composite_un = torch.sigmoid(m_composite_un)
|
| 163 |
+
m_composite_un = m_composite_un * warped_prod_edge_un
|
| 164 |
+
p_tryon_un = warped_cloth_un * m_composite_un + p_rendered_un * (1 - m_composite_un)
|
| 165 |
+
|
| 166 |
+
flow_out = PF_warp_model(p_tryon_un.detach(), clothes.cuda(), pre_clothes_edge.cuda())
|
| 167 |
+
warped_cloth, last_flow, cond_all, flow_all, delta_list, x_all, x_edge_all, delta_x_all, delta_y_all = flow_out
|
| 168 |
+
warped_prod_edge = x_edge_all[4]
|
| 169 |
+
|
| 170 |
+
epsilon = 0.001
|
| 171 |
+
loss_smooth = sum([TVLoss(x) for x in delta_list])
|
| 172 |
+
loss_all = 0
|
| 173 |
+
loss_fea_sup_all = 0
|
| 174 |
+
loss_flow_sup_all = 0
|
| 175 |
+
|
| 176 |
+
l1_loss_batch = torch.abs(warped_cloth_sup.detach() - person_clothes.cuda())
|
| 177 |
+
l1_loss_batch = l1_loss_batch.reshape(opt.batchSize, 3 * 256 * 192)
|
| 178 |
+
l1_loss_batch = l1_loss_batch.sum(dim=1) / (3 * 256 * 192)
|
| 179 |
+
l1_loss_batch_pred = torch.abs(warped_cloth.detach() - person_clothes.cuda())
|
| 180 |
+
l1_loss_batch_pred = l1_loss_batch_pred.reshape(opt.batchSize, 3 * 256 * 192)
|
| 181 |
+
l1_loss_batch_pred = l1_loss_batch_pred.sum(dim=1) / (3 * 256 * 192)
|
| 182 |
+
weight = (l1_loss_batch < l1_loss_batch_pred).float()
|
| 183 |
+
num_all = len(np.where(weight.cpu().numpy() > 0)[0])
|
| 184 |
+
if num_all == 0:
|
| 185 |
+
num_all = 1
|
| 186 |
+
|
| 187 |
+
for num in range(5):
|
| 188 |
+
cur_person_clothes = F.interpolate(person_clothes, scale_factor=0.5 ** (4 - num), mode='bilinear')
|
| 189 |
+
cur_person_clothes_edge = F.interpolate(person_clothes_edge, scale_factor=0.5 ** (4 - num), mode='bilinear')
|
| 190 |
+
loss_l1 = criterionL1(x_all[num], cur_person_clothes.cuda())
|
| 191 |
+
loss_vgg = criterionVGG(x_all[num], cur_person_clothes.cuda())
|
| 192 |
+
loss_edge = criterionL1(x_edge_all[num], cur_person_clothes_edge.cuda())
|
| 193 |
+
b, c, h, w = delta_x_all[num].shape
|
| 194 |
+
loss_flow_x = (delta_x_all[num].pow(2) + epsilon * epsilon).pow(0.45)
|
| 195 |
+
loss_flow_x = torch.sum(loss_flow_x) / (b * c * h * w)
|
| 196 |
+
loss_flow_y = (delta_y_all[num].pow(2) + epsilon * epsilon).pow(0.45)
|
| 197 |
+
loss_flow_y = torch.sum(loss_flow_y) / (b * c * h * w)
|
| 198 |
+
loss_second_smooth = loss_flow_x + loss_flow_y
|
| 199 |
+
b1, c1, h1, w1 = cond_all[num].shape
|
| 200 |
+
weight_all = weight.reshape(-1, 1, 1, 1).repeat(1, 256, h1, w1)
|
| 201 |
+
cond_sup_loss = ((cond_sup_all[num].detach() - cond_all[num]) ** 2 * weight_all).sum() / (256 * h1 * w1 * num_all)
|
| 202 |
+
loss_fea_sup_all = loss_fea_sup_all + (5 - num) * 0.04 * cond_sup_loss
|
| 203 |
+
loss_all = loss_all + (num + 1) * loss_l1 + (num + 1) * 0.2 * loss_vgg + (num + 1) * 2 * loss_edge + (num + 1) * 6 * loss_second_smooth + (5 - num) * 0.04 * cond_sup_loss
|
| 204 |
+
if num >= 2:
|
| 205 |
+
b1, c1, h1, w1 = flow_all[num].shape
|
| 206 |
+
weight_all = weight.reshape(-1, 1, 1).repeat(1, h1, w1)
|
| 207 |
+
flow_sup_loss = (torch.norm(flow_sup_all[num].detach() - flow_all[num], p=2, dim=1) * weight_all).sum() / (h1 * w1 * num_all)
|
| 208 |
+
loss_flow_sup_all = loss_flow_sup_all + (num + 1) * 1 * flow_sup_loss
|
| 209 |
+
loss_all = loss_all + (num + 1) * 1 * flow_sup_loss
|
| 210 |
+
|
| 211 |
+
loss_all = 0.01 * loss_smooth + loss_all
|
| 212 |
+
|
| 213 |
+
# sum per device losses
|
| 214 |
+
if opt.local_rank == 0:
|
| 215 |
+
writer.add_scalar('loss_all', loss_all, step)
|
| 216 |
+
writer.add_scalar('loss_fea_sup_all', loss_fea_sup_all, step)
|
| 217 |
+
writer.add_scalar('loss_flow_sup_all', loss_flow_sup_all, step)
|
| 218 |
+
|
| 219 |
+
if epoch < opt.niter:
|
| 220 |
+
optimizer_part.zero_grad()
|
| 221 |
+
loss_all.backward()
|
| 222 |
+
optimizer_part.step()
|
| 223 |
+
else:
|
| 224 |
+
optimizer.zero_grad()
|
| 225 |
+
loss_all.backward()
|
| 226 |
+
optimizer.step()
|
| 227 |
+
|
| 228 |
+
############## Display results and errors ##########
|
| 229 |
+
path = 'sample/' + opt.name
|
| 230 |
+
os.makedirs(path, exist_ok=True)
|
| 231 |
+
### display output images
|
| 232 |
+
if step % 1000 == 0:
|
| 233 |
+
if opt.local_rank == 0:
|
| 234 |
+
a = real_image.float().cuda()
|
| 235 |
+
b = p_tryon_un.detach()
|
| 236 |
+
c = clothes.cuda()
|
| 237 |
+
d = person_clothes.cuda()
|
| 238 |
+
e = torch.cat([person_clothes_edge.cuda(), person_clothes_edge.cuda(), person_clothes_edge.cuda()], 1)
|
| 239 |
+
f = torch.cat([densepose_fore.cuda(), densepose_fore.cuda(), densepose_fore.cuda()], 1)
|
| 240 |
+
g = warped_cloth
|
| 241 |
+
h = torch.cat([warped_prod_edge, warped_prod_edge, warped_prod_edge], 1)
|
| 242 |
+
combine = torch.cat([a[0], b[0], c[0], d[0], e[0], f[0], g[0], h[0]], 2).squeeze()
|
| 243 |
+
cv_img = (combine.permute(1, 2, 0).detach().cpu().numpy() + 1) / 2
|
| 244 |
+
writer.add_image('combine', (combine.data + 1) / 2.0, step)
|
| 245 |
+
rgb = (cv_img * 255).astype(np.uint8)
|
| 246 |
+
bgr = cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR)
|
| 247 |
+
cv2.imwrite('sample/' + opt.name + '/' + str(step) + '.jpg', bgr)
|
| 248 |
+
|
| 249 |
+
step += 1
|
| 250 |
+
iter_end_time = time.time()
|
| 251 |
+
iter_delta_time = iter_end_time - iter_start_time
|
| 252 |
+
step_delta = (step_per_batch - step % step_per_batch) + step_per_batch * (opt.niter + opt.niter_decay - epoch)
|
| 253 |
+
eta = iter_delta_time * step_delta
|
| 254 |
+
eta = str(datetime.timedelta(seconds=int(eta)))
|
| 255 |
+
time_stamp = datetime.datetime.now()
|
| 256 |
+
now = time_stamp.strftime('%Y.%m.%d-%H:%M:%S')
|
| 257 |
+
if step % 100 == 0:
|
| 258 |
+
if opt.local_rank == 0:
|
| 259 |
+
print('{}:{}:[step-{}]--[loss-{:.6f}]--[loss-{:.6f}]--[loss-{:.6f}]--[ETA-{}]'.format(now, epoch_iter, step, loss_all, loss_fea_sup_all, loss_flow_sup_all, eta))
|
| 260 |
+
|
| 261 |
+
if epoch_iter >= dataset_size:
|
| 262 |
+
break
|
| 263 |
+
|
| 264 |
+
# end of epoch
|
| 265 |
+
iter_end_time = time.time()
|
| 266 |
+
if opt.local_rank == 0:
|
| 267 |
+
print('End of epoch %d / %d \t Time Taken: %d sec' %
|
| 268 |
+
(epoch, opt.niter + opt.niter_decay, time.time() - epoch_start_time))
|
| 269 |
+
|
| 270 |
+
### save model for this epoch
|
| 271 |
+
if epoch % opt.save_epoch_freq == 0:
|
| 272 |
+
if opt.local_rank == 0:
|
| 273 |
+
print('saving the model at the end of epoch %d, iters %d' % (epoch, total_steps))
|
| 274 |
+
save_checkpoint(PF_warp_model.module,
|
| 275 |
+
os.path.join(opt.checkpoints_dir, opt.name, 'PFAFN_warp_epoch_%03d.pth' % (epoch + 1)))
|
| 276 |
+
|
| 277 |
+
if epoch > opt.niter:
|
| 278 |
+
PF_warp_model.module.update_learning_rate(optimizer)
|
VITON-Extends-Train/train_VITON-Extends_stage1.py
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import time
|
| 2 |
+
from options.train_options import TrainOptions
|
| 3 |
+
from models.networks import VGGLoss,save_checkpoint
|
| 4 |
+
from models.afwm import TVLoss,AFWM
|
| 5 |
+
import torch.nn as nn
|
| 6 |
+
import torch.nn.functional as F
|
| 7 |
+
import os
|
| 8 |
+
import numpy as np
|
| 9 |
+
import torch
|
| 10 |
+
from torch.utils.data import DataLoader
|
| 11 |
+
from torch.utils.data.distributed import DistributedSampler
|
| 12 |
+
from tensorboardX import SummaryWriter
|
| 13 |
+
import cv2
|
| 14 |
+
import datetime
|
| 15 |
+
|
| 16 |
+
opt = TrainOptions().parse()
|
| 17 |
+
path = 'runs/'+opt.name
|
| 18 |
+
os.makedirs(path,exist_ok=True)
|
| 19 |
+
|
| 20 |
+
def CreateDataset(opt):
|
| 21 |
+
from data.aligned_dataset import AlignedDataset
|
| 22 |
+
dataset = AlignedDataset()
|
| 23 |
+
print("dataset [%s] was created" % (dataset.name()))
|
| 24 |
+
dataset.initialize(opt)
|
| 25 |
+
return dataset
|
| 26 |
+
|
| 27 |
+
os.makedirs('sample',exist_ok=True)
|
| 28 |
+
iter_path = os.path.join(opt.checkpoints_dir, opt.name, 'iter.txt')
|
| 29 |
+
|
| 30 |
+
torch.cuda.set_device(opt.local_rank)
|
| 31 |
+
torch.distributed.init_process_group(
|
| 32 |
+
'nccl',
|
| 33 |
+
init_method='env://'
|
| 34 |
+
)
|
| 35 |
+
device = torch.device(f'cuda:{opt.local_rank}')
|
| 36 |
+
|
| 37 |
+
start_epoch, epoch_iter = 1, 0
|
| 38 |
+
|
| 39 |
+
train_data = CreateDataset(opt)
|
| 40 |
+
train_sampler = DistributedSampler(train_data)
|
| 41 |
+
train_loader = DataLoader(train_data, batch_size=opt.batchSize, shuffle=False,
|
| 42 |
+
num_workers=4, pin_memory=True, sampler=train_sampler)
|
| 43 |
+
dataset_size = len(train_loader)
|
| 44 |
+
print('#training images = %d' % dataset_size)
|
| 45 |
+
|
| 46 |
+
warp_model = AFWM(opt, 45)
|
| 47 |
+
print(warp_model)
|
| 48 |
+
warp_model.train()
|
| 49 |
+
warp_model.cuda()
|
| 50 |
+
warp_model = torch.nn.SyncBatchNorm.convert_sync_batchnorm(warp_model).to(device)
|
| 51 |
+
|
| 52 |
+
if opt.isTrain and len(opt.gpu_ids):
|
| 53 |
+
model = torch.nn.parallel.DistributedDataParallel(warp_model, device_ids=[opt.local_rank])
|
| 54 |
+
|
| 55 |
+
criterionL1 = nn.L1Loss()
|
| 56 |
+
criterionVGG = VGGLoss()
|
| 57 |
+
|
| 58 |
+
params_warp = [p for p in model.parameters()]
|
| 59 |
+
optimizer_warp = torch.optim.Adam(params_warp, lr=opt.lr, betas=(opt.beta1, 0.999))
|
| 60 |
+
|
| 61 |
+
total_steps = (start_epoch-1) * dataset_size + epoch_iter
|
| 62 |
+
step = 0
|
| 63 |
+
step_per_batch = dataset_size
|
| 64 |
+
|
| 65 |
+
if opt.local_rank == 0:
|
| 66 |
+
writer = SummaryWriter(path)
|
| 67 |
+
|
| 68 |
+
for epoch in range(start_epoch, opt.niter + opt.niter_decay + 1):
|
| 69 |
+
epoch_start_time = time.time()
|
| 70 |
+
if epoch != start_epoch:
|
| 71 |
+
epoch_iter = epoch_iter % dataset_size
|
| 72 |
+
|
| 73 |
+
train_sampler.set_epoch(epoch)
|
| 74 |
+
|
| 75 |
+
for i, data in enumerate(train_loader):
|
| 76 |
+
iter_start_time = time.time()
|
| 77 |
+
|
| 78 |
+
total_steps += 1
|
| 79 |
+
epoch_iter += 1
|
| 80 |
+
save_fake = True
|
| 81 |
+
|
| 82 |
+
t_mask = torch.FloatTensor((data['label'].cpu().numpy()==7).astype(np.float))
|
| 83 |
+
data['label'] = data['label']*(1-t_mask)+t_mask*4
|
| 84 |
+
edge = data['edge']
|
| 85 |
+
pre_clothes_edge = torch.FloatTensor((edge.detach().numpy() > 0.5).astype(np.int))
|
| 86 |
+
clothes = data['color']
|
| 87 |
+
clothes = clothes * pre_clothes_edge
|
| 88 |
+
person_clothes_edge = torch.FloatTensor((data['label'].cpu().numpy()==4).astype(np.int))
|
| 89 |
+
real_image = data['image']
|
| 90 |
+
person_clothes = real_image * person_clothes_edge
|
| 91 |
+
pose = data['pose']
|
| 92 |
+
size = data['label'].size()
|
| 93 |
+
oneHot_size1 = (size[0], 25, size[2], size[3])
|
| 94 |
+
densepose = torch.cuda.FloatTensor(torch.Size(oneHot_size1)).zero_()
|
| 95 |
+
densepose = densepose.scatter_(1,data['densepose'].data.long().cuda(),1.0)
|
| 96 |
+
densepose_fore = data['densepose']/24.0
|
| 97 |
+
face_mask = torch.FloatTensor((data['label'].cpu().numpy()==1).astype(np.int)) + torch.FloatTensor((data['label'].cpu().numpy()==12).astype(np.int))
|
| 98 |
+
other_clothes_mask = torch.FloatTensor((data['label'].cpu().numpy()==5).astype(np.int)) + torch.FloatTensor((data['label'].cpu().numpy()==6).astype(np.int)) + \
|
| 99 |
+
torch.FloatTensor((data['label'].cpu().numpy()==8).astype(np.int)) + torch.FloatTensor((data['label'].cpu().numpy()==9).astype(np.int)) + \
|
| 100 |
+
torch.FloatTensor((data['label'].cpu().numpy()==10).astype(np.int))
|
| 101 |
+
preserve_mask = torch.cat([face_mask,other_clothes_mask],1)
|
| 102 |
+
concat = torch.cat([preserve_mask.cuda(),densepose,pose.cuda()],1)
|
| 103 |
+
|
| 104 |
+
flow_out = model(concat.cuda(), clothes.cuda(), pre_clothes_edge.cuda())
|
| 105 |
+
warped_cloth, last_flow, _1, _2, delta_list, x_all, x_edge_all, delta_x_all, delta_y_all = flow_out
|
| 106 |
+
warped_prod_edge = x_edge_all[4]
|
| 107 |
+
|
| 108 |
+
epsilon = 0.001
|
| 109 |
+
loss_smooth = sum([TVLoss(x) for x in delta_list])
|
| 110 |
+
loss_all = 0
|
| 111 |
+
|
| 112 |
+
for num in range(5):
|
| 113 |
+
cur_person_clothes = F.interpolate(person_clothes, scale_factor=0.5**(4-num), mode='bilinear')
|
| 114 |
+
cur_person_clothes_edge = F.interpolate(person_clothes_edge, scale_factor=0.5**(4-num), mode='bilinear')
|
| 115 |
+
loss_l1 = criterionL1(x_all[num], cur_person_clothes.cuda())
|
| 116 |
+
loss_vgg = criterionVGG(x_all[num], cur_person_clothes.cuda())
|
| 117 |
+
loss_edge = criterionL1(x_edge_all[num], cur_person_clothes_edge.cuda())
|
| 118 |
+
b,c,h,w = delta_x_all[num].shape
|
| 119 |
+
loss_flow_x = (delta_x_all[num].pow(2)+ epsilon*epsilon).pow(0.45)
|
| 120 |
+
loss_flow_x = torch.sum(loss_flow_x)/(b*c*h*w)
|
| 121 |
+
loss_flow_y = (delta_y_all[num].pow(2)+ epsilon*epsilon).pow(0.45)
|
| 122 |
+
loss_flow_y = torch.sum(loss_flow_y)/(b*c*h*w)
|
| 123 |
+
loss_second_smooth = loss_flow_x + loss_flow_y
|
| 124 |
+
loss_all = loss_all + (num+1) * loss_l1 + (num + 1) * 0.2 * loss_vgg + (num+1) * 2 * loss_edge + (num + 1) * 6 * loss_second_smooth
|
| 125 |
+
|
| 126 |
+
loss_all = 0.01 * loss_smooth + loss_all
|
| 127 |
+
|
| 128 |
+
if opt.local_rank == 0:
|
| 129 |
+
writer.add_scalar('loss_all', loss_all, step)
|
| 130 |
+
|
| 131 |
+
optimizer_warp.zero_grad()
|
| 132 |
+
loss_all.backward()
|
| 133 |
+
optimizer_warp.step()
|
| 134 |
+
############## Display results and errors ##########
|
| 135 |
+
|
| 136 |
+
path = 'sample/'+opt.name
|
| 137 |
+
os.makedirs(path,exist_ok=True)
|
| 138 |
+
if step % 1000 == 0:
|
| 139 |
+
if opt.local_rank == 0:
|
| 140 |
+
a = real_image.float().cuda()
|
| 141 |
+
b = person_clothes.cuda()
|
| 142 |
+
c = clothes.cuda()
|
| 143 |
+
d = torch.cat([densepose_fore.cuda(),densepose_fore.cuda(),densepose_fore.cuda()],1)
|
| 144 |
+
e = warped_cloth
|
| 145 |
+
f = torch.cat([warped_prod_edge,warped_prod_edge,warped_prod_edge],1)
|
| 146 |
+
combine = torch.cat([a[0],b[0],c[0],d[0],e[0],f[0]], 2).squeeze()
|
| 147 |
+
cv_img=(combine.permute(1,2,0).detach().cpu().numpy()+1)/2
|
| 148 |
+
writer.add_image('combine', (combine.data + 1) / 2.0, step)
|
| 149 |
+
rgb=(cv_img*255).astype(np.uint8)
|
| 150 |
+
bgr=cv2.cvtColor(rgb,cv2.COLOR_RGB2BGR)
|
| 151 |
+
cv2.imwrite('sample/'+opt.name+'/'+str(step)+'.jpg',bgr)
|
| 152 |
+
|
| 153 |
+
step += 1
|
| 154 |
+
iter_end_time = time.time()
|
| 155 |
+
iter_delta_time = iter_end_time - iter_start_time
|
| 156 |
+
step_delta = (step_per_batch-step%step_per_batch) + step_per_batch*(opt.niter + opt.niter_decay-epoch)
|
| 157 |
+
eta = iter_delta_time*step_delta
|
| 158 |
+
eta = str(datetime.timedelta(seconds=int(eta)))
|
| 159 |
+
time_stamp = datetime.datetime.now()
|
| 160 |
+
now = time_stamp.strftime('%Y.%m.%d-%H:%M:%S')
|
| 161 |
+
if step % 100 == 0:
|
| 162 |
+
if opt.local_rank == 0:
|
| 163 |
+
print('{}:{}:[step-{}]--[loss-{:.6f}]--[ETA-{}]'.format(now, epoch_iter,step, loss_all,eta))
|
| 164 |
+
|
| 165 |
+
if epoch_iter >= dataset_size:
|
| 166 |
+
break
|
| 167 |
+
|
| 168 |
+
# end of epoch
|
| 169 |
+
iter_end_time = time.time()
|
| 170 |
+
if opt.local_rank == 0:
|
| 171 |
+
print('End of epoch %d / %d \t Time Taken: %d sec' %
|
| 172 |
+
(epoch, opt.niter + opt.niter_decay, time.time() - epoch_start_time))
|
| 173 |
+
|
| 174 |
+
### save model for this epoch
|
| 175 |
+
if epoch % opt.save_epoch_freq == 0:
|
| 176 |
+
if opt.local_rank == 0:
|
| 177 |
+
print('saving the model at the end of epoch %d, iters %d' % (epoch, total_steps))
|
| 178 |
+
save_checkpoint(model.module, os.path.join(opt.checkpoints_dir, opt.name, 'PBAFN_warp_epoch_%03d.pth' % (epoch+1)))
|
| 179 |
+
|
| 180 |
+
if epoch > opt.niter:
|
| 181 |
+
model.module.update_learning_rate(optimizer_warp)
|
VITON-Extends-Train/train_VITON-Extendse2e.py
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import time
|
| 2 |
+
from options.train_options import TrainOptions
|
| 3 |
+
from models.networks import ResUnetGenerator, VGGLoss, save_checkpoint, load_checkpoint_parallel
|
| 4 |
+
from models.afwm import TVLoss, AFWM
|
| 5 |
+
import torch.nn as nn
|
| 6 |
+
import torch.nn.functional as F
|
| 7 |
+
import os
|
| 8 |
+
import numpy as np
|
| 9 |
+
import torch
|
| 10 |
+
from torch.utils.data import DataLoader
|
| 11 |
+
from torch.utils.data.distributed import DistributedSampler
|
| 12 |
+
from tensorboardX import SummaryWriter
|
| 13 |
+
import cv2
|
| 14 |
+
import datetime
|
| 15 |
+
|
| 16 |
+
opt = TrainOptions().parse()
|
| 17 |
+
path = 'runs/'+opt.name
|
| 18 |
+
os.makedirs(path,exist_ok=True)
|
| 19 |
+
|
| 20 |
+
def CreateDataset(opt):
|
| 21 |
+
from data.aligned_dataset import AlignedDataset
|
| 22 |
+
dataset = AlignedDataset()
|
| 23 |
+
print("dataset [%s] was created" % (dataset.name()))
|
| 24 |
+
dataset.initialize(opt)
|
| 25 |
+
return dataset
|
| 26 |
+
|
| 27 |
+
os.makedirs('sample',exist_ok=True)
|
| 28 |
+
opt = TrainOptions().parse()
|
| 29 |
+
iter_path = os.path.join(opt.checkpoints_dir, opt.name, 'iter.txt')
|
| 30 |
+
|
| 31 |
+
torch.cuda.set_device(opt.local_rank)
|
| 32 |
+
torch.distributed.init_process_group(
|
| 33 |
+
'nccl',
|
| 34 |
+
init_method='env://'
|
| 35 |
+
)
|
| 36 |
+
device = torch.device(f'cuda:{opt.local_rank}')
|
| 37 |
+
|
| 38 |
+
start_epoch, epoch_iter = 1, 0
|
| 39 |
+
|
| 40 |
+
train_data = CreateDataset(opt)
|
| 41 |
+
train_sampler = DistributedSampler(train_data)
|
| 42 |
+
train_loader = DataLoader(train_data, batch_size=opt.batchSize, shuffle=False,
|
| 43 |
+
num_workers=4, pin_memory=True, sampler=train_sampler)
|
| 44 |
+
dataset_size = len(train_loader)
|
| 45 |
+
|
| 46 |
+
warp_model = AFWM(opt, 45)
|
| 47 |
+
print(warp_model)
|
| 48 |
+
warp_model.train()
|
| 49 |
+
warp_model.cuda()
|
| 50 |
+
load_checkpoint_parallel(warp_model, opt.PBAFN_warp_checkpoint)
|
| 51 |
+
|
| 52 |
+
gen_model = ResUnetGenerator(8, 4, 5, ngf=64, norm_layer=nn.BatchNorm2d)
|
| 53 |
+
print(gen_model)
|
| 54 |
+
gen_model.train()
|
| 55 |
+
gen_model.cuda()
|
| 56 |
+
|
| 57 |
+
warp_model = torch.nn.SyncBatchNorm.convert_sync_batchnorm(warp_model).to(device)
|
| 58 |
+
gen_model = torch.nn.SyncBatchNorm.convert_sync_batchnorm(gen_model).to(device)
|
| 59 |
+
|
| 60 |
+
if opt.isTrain and len(opt.gpu_ids):
|
| 61 |
+
model = torch.nn.parallel.DistributedDataParallel(warp_model, device_ids=[opt.local_rank])
|
| 62 |
+
model_gen = torch.nn.parallel.DistributedDataParallel(gen_model, device_ids=[opt.local_rank])
|
| 63 |
+
|
| 64 |
+
criterionL1 = nn.L1Loss()
|
| 65 |
+
criterionVGG = VGGLoss()
|
| 66 |
+
# optimizer
|
| 67 |
+
params_warp = [p for p in model.parameters()]
|
| 68 |
+
params_gen = [p for p in model_gen.parameters()]
|
| 69 |
+
optimizer_warp = torch.optim.Adam(params_warp, lr=0.2*opt.lr, betas=(opt.beta1, 0.999))
|
| 70 |
+
optimizer_gen = torch.optim.Adam(params_gen, lr=opt.lr, betas=(opt.beta1, 0.999))
|
| 71 |
+
|
| 72 |
+
total_steps = (start_epoch-1) * dataset_size + epoch_iter
|
| 73 |
+
|
| 74 |
+
step = 0
|
| 75 |
+
step_per_batch = dataset_size
|
| 76 |
+
|
| 77 |
+
if opt.local_rank == 0:
|
| 78 |
+
writer = SummaryWriter(path)
|
| 79 |
+
|
| 80 |
+
for epoch in range(start_epoch, opt.niter + opt.niter_decay + 1):
|
| 81 |
+
epoch_start_time = time.time()
|
| 82 |
+
if epoch != start_epoch:
|
| 83 |
+
epoch_iter = epoch_iter % dataset_size
|
| 84 |
+
|
| 85 |
+
train_sampler.set_epoch(epoch)
|
| 86 |
+
|
| 87 |
+
for i, data in enumerate(train_loader):
|
| 88 |
+
|
| 89 |
+
iter_start_time = time.time()
|
| 90 |
+
|
| 91 |
+
total_steps += 1
|
| 92 |
+
epoch_iter += 1
|
| 93 |
+
save_fake = True
|
| 94 |
+
|
| 95 |
+
t_mask = torch.FloatTensor((data['label'].cpu().numpy()==7).astype(np.float))
|
| 96 |
+
data['label'] = data['label']*(1-t_mask)+t_mask*4
|
| 97 |
+
edge = data['edge']
|
| 98 |
+
pre_clothes_edge = torch.FloatTensor((edge.detach().numpy() > 0.5).astype(np.int))
|
| 99 |
+
clothes = data['color']
|
| 100 |
+
clothes = clothes * pre_clothes_edge
|
| 101 |
+
person_clothes_edge = torch.FloatTensor((data['label'].cpu().numpy()==4).astype(np.int))
|
| 102 |
+
real_image = data['image']
|
| 103 |
+
person_clothes = real_image*person_clothes_edge
|
| 104 |
+
pose = data['pose']
|
| 105 |
+
size = data['label'].size()
|
| 106 |
+
oneHot_size1 = (size[0], 25, size[2], size[3])
|
| 107 |
+
densepose = torch.cuda.FloatTensor(torch.Size(oneHot_size1)).zero_()
|
| 108 |
+
densepose = densepose.scatter_(1,data['densepose'].data.long().cuda(),1.0)
|
| 109 |
+
densepose_fore = data['densepose']/24.0
|
| 110 |
+
face_mask = torch.FloatTensor((data['label'].cpu().numpy()==1).astype(np.int))+torch.FloatTensor((data['label'].cpu().numpy()==12).astype(np.int))
|
| 111 |
+
other_clothes_mask = torch.FloatTensor((data['label'].cpu().numpy()==5).astype(np.int)) + torch.FloatTensor((data['label'].cpu().numpy()==6).astype(np.int))\
|
| 112 |
+
+ torch.FloatTensor((data['label'].cpu().numpy()==8).astype(np.int)) + torch.FloatTensor((data['label'].cpu().numpy()==9).astype(np.int))\
|
| 113 |
+
+ torch.FloatTensor((data['label'].cpu().numpy()==10).astype(np.int))
|
| 114 |
+
face_img = face_mask * real_image
|
| 115 |
+
other_clothes_img = other_clothes_mask * real_image
|
| 116 |
+
preserve_region = face_img + other_clothes_img
|
| 117 |
+
preserve_mask = torch.cat([face_mask, other_clothes_mask],1)
|
| 118 |
+
concat = torch.cat([preserve_mask.cuda(), densepose, pose.cuda()],1)
|
| 119 |
+
arm_mask = torch.FloatTensor((data['label'].cpu().numpy()==11).astype(np.float)) + torch.FloatTensor((data['label'].cpu().numpy()==13).astype(np.float))
|
| 120 |
+
hand_mask = torch.FloatTensor((data['densepose'].cpu().numpy()==3).astype(np.int)) + torch.FloatTensor((data['densepose'].cpu().numpy()==4).astype(np.int))
|
| 121 |
+
hand_mask = arm_mask*hand_mask
|
| 122 |
+
hand_img = hand_mask*real_image
|
| 123 |
+
dense_preserve_mask = torch.FloatTensor((data['densepose'].cpu().numpy()==15).astype(np.int))+torch.FloatTensor((data['densepose'].cpu().numpy()==16).astype(np.int))\
|
| 124 |
+
+torch.FloatTensor((data['densepose'].cpu().numpy()==17).astype(np.int))+torch.FloatTensor((data['densepose'].cpu().numpy()==18).astype(np.int))\
|
| 125 |
+
+torch.FloatTensor((data['densepose'].cpu().numpy()==19).astype(np.int))+torch.FloatTensor((data['densepose'].cpu().numpy()==20).astype(np.int))\
|
| 126 |
+
+torch.FloatTensor((data['densepose'].cpu().numpy()==21).astype(np.int))+torch.FloatTensor((data['densepose'].cpu().numpy()==22))
|
| 127 |
+
dense_preserve_mask = dense_preserve_mask.cuda()*(1-person_clothes_edge.cuda())
|
| 128 |
+
preserve_region = face_img + other_clothes_img +hand_img
|
| 129 |
+
|
| 130 |
+
flow_out = model(concat.cuda(), clothes.cuda(), pre_clothes_edge.cuda())
|
| 131 |
+
warped_cloth, last_flow, _1, _2, delta_list, x_all, x_edge_all, delta_x_all, delta_y_all = flow_out
|
| 132 |
+
|
| 133 |
+
epsilon = 0.001
|
| 134 |
+
loss_smooth = sum([TVLoss(x) for x in delta_list])
|
| 135 |
+
warp_loss = 0
|
| 136 |
+
|
| 137 |
+
for num in range(5):
|
| 138 |
+
cur_person_clothes = F.interpolate(person_clothes, scale_factor=0.5**(4-num), mode='bilinear')
|
| 139 |
+
cur_person_clothes_edge = F.interpolate(person_clothes_edge, scale_factor=0.5**(4-num), mode='bilinear')
|
| 140 |
+
loss_l1 = criterionL1(x_all[num], cur_person_clothes.cuda())
|
| 141 |
+
loss_vgg = criterionVGG(x_all[num], cur_person_clothes.cuda())
|
| 142 |
+
loss_edge = criterionL1(x_edge_all[num], cur_person_clothes_edge.cuda())
|
| 143 |
+
b,c,h,w = delta_x_all[num].shape
|
| 144 |
+
loss_flow_x = (delta_x_all[num].pow(2) + epsilon*epsilon).pow(0.45)
|
| 145 |
+
loss_flow_x = torch.sum(loss_flow_x) / (b*c*h*w)
|
| 146 |
+
loss_flow_y = (delta_y_all[num].pow(2) + epsilon*epsilon).pow(0.45)
|
| 147 |
+
loss_flow_y = torch.sum(loss_flow_y) / (b*c*h*w)
|
| 148 |
+
loss_second_smooth = loss_flow_x + loss_flow_y
|
| 149 |
+
warp_loss = warp_loss + (num+1) * loss_l1 + (num+1) * 0.2 * loss_vgg + (num+1) * 2 * loss_edge + (num+1) * 6 * loss_second_smooth
|
| 150 |
+
|
| 151 |
+
warp_loss = 0.01 * loss_smooth + warp_loss
|
| 152 |
+
|
| 153 |
+
if opt.local_rank == 0:
|
| 154 |
+
writer.add_scalar('warp_loss', warp_loss, step)
|
| 155 |
+
|
| 156 |
+
warped_prod_edge = x_edge_all[4]
|
| 157 |
+
gen_inputs = torch.cat([preserve_region.cuda(), warped_cloth, warped_prod_edge, dense_preserve_mask], 1)
|
| 158 |
+
|
| 159 |
+
gen_outputs = model_gen(gen_inputs)
|
| 160 |
+
p_rendered, m_composite = torch.split(gen_outputs, [3, 1], 1)
|
| 161 |
+
p_rendered = torch.tanh(p_rendered)
|
| 162 |
+
m_composite = torch.sigmoid(m_composite)
|
| 163 |
+
m_composite1 = m_composite * warped_prod_edge
|
| 164 |
+
m_composite = person_clothes_edge.cuda()*m_composite1
|
| 165 |
+
p_tryon = warped_cloth * m_composite + p_rendered * (1 - m_composite)
|
| 166 |
+
|
| 167 |
+
loss_mask_l1 = torch.mean(torch.abs(1 - m_composite))
|
| 168 |
+
loss_l1 = criterionL1(p_tryon, real_image.cuda())
|
| 169 |
+
loss_vgg = criterionVGG(p_tryon,real_image.cuda())
|
| 170 |
+
bg_loss_l1 = criterionL1(p_rendered, real_image.cuda())
|
| 171 |
+
bg_loss_vgg = criterionVGG(p_rendered, real_image.cuda())
|
| 172 |
+
gen_loss = (loss_l1 * 5 + loss_vgg + bg_loss_l1 * 5 + bg_loss_vgg + loss_mask_l1)
|
| 173 |
+
|
| 174 |
+
|
| 175 |
+
if opt.local_rank == 0:
|
| 176 |
+
writer.add_scalar('gen_loss', gen_loss, step)
|
| 177 |
+
|
| 178 |
+
loss_all = 0.5 * warp_loss + 1.0 * gen_loss
|
| 179 |
+
|
| 180 |
+
if opt.local_rank == 0:
|
| 181 |
+
writer.add_scalar('loss_all', loss_all, step)
|
| 182 |
+
|
| 183 |
+
optimizer_warp.zero_grad()
|
| 184 |
+
optimizer_gen.zero_grad()
|
| 185 |
+
loss_all.backward()
|
| 186 |
+
optimizer_warp.step()
|
| 187 |
+
optimizer_gen.step()
|
| 188 |
+
|
| 189 |
+
############## Display results and errors ##########
|
| 190 |
+
path = 'sample/'+opt.name
|
| 191 |
+
os.makedirs(path,exist_ok=True)
|
| 192 |
+
if step % 1000 == 0:
|
| 193 |
+
if opt.local_rank == 0:
|
| 194 |
+
a = real_image.float().cuda()
|
| 195 |
+
b = person_clothes.cuda()
|
| 196 |
+
c = clothes.cuda()
|
| 197 |
+
d = torch.cat([densepose_fore.cuda(),densepose_fore.cuda(),densepose_fore.cuda()],1)
|
| 198 |
+
e = warped_cloth
|
| 199 |
+
f = torch.cat([warped_prod_edge,warped_prod_edge,warped_prod_edge],1)
|
| 200 |
+
g = preserve_region.cuda()
|
| 201 |
+
h = torch.cat([dense_preserve_mask,dense_preserve_mask,dense_preserve_mask],1)
|
| 202 |
+
i = p_rendered
|
| 203 |
+
j = torch.cat([m_composite1,m_composite1,m_composite1],1)
|
| 204 |
+
k = p_tryon
|
| 205 |
+
combine = torch.cat([a[0],b[0],c[0],d[0],e[0],f[0],g[0],h[0],i[0],j[0],k[0]], 2).squeeze()
|
| 206 |
+
cv_img = (combine.permute(1,2,0).detach().cpu().numpy()+1)/2
|
| 207 |
+
writer.add_image('combine', (combine.data + 1) / 2.0, step)
|
| 208 |
+
rgb = (cv_img*255).astype(np.uint8)
|
| 209 |
+
bgr = cv2.cvtColor(rgb,cv2.COLOR_RGB2BGR)
|
| 210 |
+
cv2.imwrite('sample/'+opt.name+'/'+str(step)+'.jpg',bgr)
|
| 211 |
+
|
| 212 |
+
step += 1
|
| 213 |
+
iter_end_time = time.time()
|
| 214 |
+
iter_delta_time = iter_end_time - iter_start_time
|
| 215 |
+
step_delta = (step_per_batch-step%step_per_batch) + step_per_batch*(opt.niter + opt.niter_decay-epoch)
|
| 216 |
+
eta = iter_delta_time*step_delta
|
| 217 |
+
eta = str(datetime.timedelta(seconds=int(eta)))
|
| 218 |
+
time_stamp = datetime.datetime.now()
|
| 219 |
+
now = time_stamp.strftime('%Y.%m.%d-%H:%M:%S')
|
| 220 |
+
|
| 221 |
+
if step % 100 == 0:
|
| 222 |
+
if opt.local_rank == 0:
|
| 223 |
+
print('{}:{}:[step-{}]--[loss-{:.6f}]--[loss-{:.6f}]--[ETA-{}]'.format(now, epoch_iter, step, warp_loss, gen_loss, eta))
|
| 224 |
+
|
| 225 |
+
if epoch_iter >= dataset_size:
|
| 226 |
+
break
|
| 227 |
+
|
| 228 |
+
iter_end_time = time.time()
|
| 229 |
+
if opt.local_rank == 0:
|
| 230 |
+
print('End of epoch %d / %d \t Time Taken: %d sec' %
|
| 231 |
+
(epoch, opt.niter + opt.niter_decay, time.time() - epoch_start_time))
|
| 232 |
+
|
| 233 |
+
### save model for this epoch
|
| 234 |
+
if epoch % opt.save_epoch_freq == 0:
|
| 235 |
+
if opt.local_rank == 0:
|
| 236 |
+
print('saving the model at the end of epoch %d, iters %d' % (epoch, total_steps))
|
| 237 |
+
save_checkpoint(model.module, os.path.join(opt.checkpoints_dir, opt.name, 'PBAFN_warp_epoch_%03d.pth' % (epoch+1)))
|
| 238 |
+
save_checkpoint(model_gen.module, os.path.join(opt.checkpoints_dir, opt.name, 'PBAFN_gen_epoch_%03d.pth' % (epoch+1)))
|
| 239 |
+
|
| 240 |
+
if epoch > opt.niter:
|
| 241 |
+
model.module.update_learning_rate_warp(optimizer_warp)
|
| 242 |
+
model.module.update_learning_rate(optimizer_gen)
|
VITON-Extends-Train/util/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
# util_init
|
VITON-Extends-Train/util/image_pool.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import random
|
| 2 |
+
import torch
|
| 3 |
+
from torch.autograd import Variable
|
| 4 |
+
class ImagePool():
|
| 5 |
+
def __init__(self, pool_size):
|
| 6 |
+
self.pool_size = pool_size
|
| 7 |
+
if self.pool_size > 0:
|
| 8 |
+
self.num_imgs = 0
|
| 9 |
+
self.images = []
|
| 10 |
+
|
| 11 |
+
def query(self, images):
|
| 12 |
+
if self.pool_size == 0:
|
| 13 |
+
return images
|
| 14 |
+
return_images = []
|
| 15 |
+
for image in images.data:
|
| 16 |
+
image = torch.unsqueeze(image, 0)
|
| 17 |
+
if self.num_imgs < self.pool_size:
|
| 18 |
+
self.num_imgs = self.num_imgs + 1
|
| 19 |
+
self.images.append(image)
|
| 20 |
+
return_images.append(image)
|
| 21 |
+
else:
|
| 22 |
+
p = random.uniform(0, 1)
|
| 23 |
+
if p > 0.5:
|
| 24 |
+
random_id = random.randint(0, self.pool_size-1)
|
| 25 |
+
tmp = self.images[random_id].clone()
|
| 26 |
+
self.images[random_id] = image
|
| 27 |
+
return_images.append(tmp)
|
| 28 |
+
else:
|
| 29 |
+
return_images.append(image)
|
| 30 |
+
return_images = Variable(torch.cat(return_images, 0))
|
| 31 |
+
return return_images
|
VITON-Extends-Train/util/util.py
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import print_function
|
| 2 |
+
|
| 3 |
+
import torch
|
| 4 |
+
import numpy as np
|
| 5 |
+
from PIL import Image
|
| 6 |
+
import numpy as np
|
| 7 |
+
import os
|
| 8 |
+
|
| 9 |
+
# Converts a Tensor into a Numpy array
|
| 10 |
+
# |imtype|: the desired type of the converted numpy array
|
| 11 |
+
def tensor2im(image_tensor, imtype=np.uint8, normalize=True):
|
| 12 |
+
if isinstance(image_tensor, list):
|
| 13 |
+
image_numpy = []
|
| 14 |
+
for i in range(len(image_tensor)):
|
| 15 |
+
image_numpy.append(tensor2im(image_tensor[i], imtype, normalize))
|
| 16 |
+
return image_numpy
|
| 17 |
+
image_numpy = image_tensor.cpu().float().numpy()
|
| 18 |
+
#if normalize:
|
| 19 |
+
# image_numpy = (np.transpose(image_numpy, (1, 2, 0)) + 1) / 2.0 * 255.0
|
| 20 |
+
#else:
|
| 21 |
+
# image_numpy = np.transpose(image_numpy, (1, 2, 0)) * 255.0
|
| 22 |
+
image_numpy = (image_numpy + 1) / 2.0
|
| 23 |
+
image_numpy = np.clip(image_numpy, 0, 1)
|
| 24 |
+
if image_numpy.shape[2] == 1 or image_numpy.shape[2] > 3:
|
| 25 |
+
image_numpy = image_numpy[:,:,0]
|
| 26 |
+
|
| 27 |
+
return image_numpy
|
| 28 |
+
|
| 29 |
+
# Converts a one-hot tensor into a colorful label map
|
| 30 |
+
def tensor2label(label_tensor, n_label, imtype=np.uint8):
|
| 31 |
+
if n_label == 0:
|
| 32 |
+
return tensor2im(label_tensor, imtype)
|
| 33 |
+
label_tensor = label_tensor.cpu().float()
|
| 34 |
+
if label_tensor.size()[0] > 1:
|
| 35 |
+
label_tensor = label_tensor.max(0, keepdim=True)[1]
|
| 36 |
+
label_tensor = Colorize(n_label)(label_tensor)
|
| 37 |
+
#label_numpy = np.transpose(label_tensor.numpy(), (1, 2, 0))
|
| 38 |
+
label_numpy = label_tensor.numpy()
|
| 39 |
+
label_numpy = label_numpy / 255.0
|
| 40 |
+
|
| 41 |
+
return label_numpy
|
| 42 |
+
|
| 43 |
+
def save_image(image_numpy, image_path):
|
| 44 |
+
image_pil = Image.fromarray(image_numpy)
|
| 45 |
+
image_pil.save(image_path)
|
| 46 |
+
|
| 47 |
+
def mkdirs(paths):
|
| 48 |
+
if isinstance(paths, list) and not isinstance(paths, str):
|
| 49 |
+
for path in paths:
|
| 50 |
+
mkdir(path)
|
| 51 |
+
else:
|
| 52 |
+
mkdir(paths)
|
| 53 |
+
|
| 54 |
+
def mkdir(path):
|
| 55 |
+
if not os.path.exists(path):
|
| 56 |
+
os.makedirs(path)
|
| 57 |
+
|
| 58 |
+
###############################################################################
|
| 59 |
+
# Code from
|
| 60 |
+
# https://github.com/ycszen/pytorch-seg/blob/master/transform.py
|
| 61 |
+
# Modified so it complies with the Citscape label map colors
|
| 62 |
+
###############################################################################
|
| 63 |
+
def uint82bin(n, count=8):
|
| 64 |
+
"""returns the binary of integer n, count refers to amount of bits"""
|
| 65 |
+
return ''.join([str((n >> y) & 1) for y in range(count-1, -1, -1)])
|
| 66 |
+
|
| 67 |
+
def labelcolormap(N):
|
| 68 |
+
if N == 35: # cityscape
|
| 69 |
+
cmap = np.array([( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0), (111, 74, 0), ( 81, 0, 81),
|
| 70 |
+
(128, 64,128), (244, 35,232), (250,170,160), (230,150,140), ( 70, 70, 70), (102,102,156), (190,153,153),
|
| 71 |
+
(180,165,180), (150,100,100), (150,120, 90), (153,153,153), (153,153,153), (250,170, 30), (220,220, 0),
|
| 72 |
+
(107,142, 35), (152,251,152), ( 70,130,180), (220, 20, 60), (255, 0, 0), ( 0, 0,142), ( 0, 0, 70),
|
| 73 |
+
( 0, 60,100), ( 0, 0, 90), ( 0, 0,110), ( 0, 80,100), ( 0, 0,230), (119, 11, 32), ( 0, 0,142)],
|
| 74 |
+
dtype=np.uint8)
|
| 75 |
+
else:
|
| 76 |
+
cmap = np.zeros((N, 3), dtype=np.uint8)
|
| 77 |
+
for i in range(N):
|
| 78 |
+
r, g, b = 0, 0, 0
|
| 79 |
+
id = i
|
| 80 |
+
for j in range(7):
|
| 81 |
+
str_id = uint82bin(id)
|
| 82 |
+
r = r ^ (np.uint8(str_id[-1]) << (7-j))
|
| 83 |
+
g = g ^ (np.uint8(str_id[-2]) << (7-j))
|
| 84 |
+
b = b ^ (np.uint8(str_id[-3]) << (7-j))
|
| 85 |
+
id = id >> 3
|
| 86 |
+
cmap[i, 0] = r
|
| 87 |
+
cmap[i, 1] = g
|
| 88 |
+
cmap[i, 2] = b
|
| 89 |
+
return cmap
|
| 90 |
+
|
| 91 |
+
class Colorize(object):
|
| 92 |
+
def __init__(self, n=35):
|
| 93 |
+
self.cmap = labelcolormap(n)
|
| 94 |
+
self.cmap = torch.from_numpy(self.cmap[:n])
|
| 95 |
+
|
| 96 |
+
def __call__(self, gray_image):
|
| 97 |
+
size = gray_image.size()
|
| 98 |
+
color_image = torch.ByteTensor(3, size[1], size[2]).fill_(0)
|
| 99 |
+
|
| 100 |
+
for label in range(0, len(self.cmap)):
|
| 101 |
+
mask = (label == gray_image[0]).cpu()
|
| 102 |
+
color_image[0][mask] = self.cmap[label][0]
|
| 103 |
+
color_image[1][mask] = self.cmap[label][1]
|
| 104 |
+
color_image[2][mask] = self.cmap[label][2]
|
| 105 |
+
|
| 106 |
+
return color_image
|
VITON-Extends_test/.gitignore
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
| 2 |
+
|
| 3 |
+
# dependencies
|
| 4 |
+
/node_modules
|
| 5 |
+
|
| 6 |
+
# next.js
|
| 7 |
+
/.next/
|
| 8 |
+
/out/
|
| 9 |
+
|
| 10 |
+
# production
|
| 11 |
+
/build
|
| 12 |
+
|
| 13 |
+
# debug
|
| 14 |
+
npm-debug.log*
|
| 15 |
+
yarn-debug.log*
|
| 16 |
+
yarn-error.log*
|
| 17 |
+
.pnpm-debug.log*
|
| 18 |
+
|
| 19 |
+
# env files
|
| 20 |
+
.env*
|
| 21 |
+
|
| 22 |
+
# vercel
|
| 23 |
+
.vercel
|
| 24 |
+
|
| 25 |
+
# typescript
|
| 26 |
+
*.tsbuildinfo
|
| 27 |
+
next-env.d.ts
|
VITON-Extends_test/API.py
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import cv2
|
| 2 |
+
import torch
|
| 3 |
+
import numpy as np
|
| 4 |
+
from torchvision import transforms
|
| 5 |
+
from PIL import Image
|
| 6 |
+
import shutil
|
| 7 |
+
import os
|
| 8 |
+
import uuid
|
| 9 |
+
from fastapi import FastAPI, File, UploadFile
|
| 10 |
+
from fastapi.responses import FileResponse
|
| 11 |
+
|
| 12 |
+
# Giả định rằng file u2net.py chứa class U2NET và file u2net.pth
|
| 13 |
+
# nằm cùng thư mục với main.py hoặc trong PYTHONPATH.
|
| 14 |
+
# Ví dụ: from your_project.u2net import U2NET
|
| 15 |
+
# Nếu u2net.py là file định nghĩa class, bạn có thể import trực tiếp:
|
| 16 |
+
try:
|
| 17 |
+
from u2net import U2NET # Model definition
|
| 18 |
+
except ImportError:
|
| 19 |
+
print("Lỗi: Không tìm thấy file u2net.py định nghĩa class U2NET.")
|
| 20 |
+
print("Hãy đảm bảo file u2net.py (chứa class U2NET) nằm trong cùng thư mục hoặc PYTHONPATH.")
|
| 21 |
+
exit()
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
# --- Khởi tạo FastAPI app ---
|
| 25 |
+
app = FastAPI(title="VITON-Extends API")
|
| 26 |
+
|
| 27 |
+
# --- Cấu hình và tải mô hình U2NET ---
|
| 28 |
+
# Thực hiện một lần khi ứng dụng khởi động
|
| 29 |
+
U2NET_MODEL = None
|
| 30 |
+
_API_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 31 |
+
U2NET_MODEL_PATH = os.path.join(_API_SCRIPT_DIR, 'checkpoints', 'u2net.pth')
|
| 32 |
+
|
| 33 |
+
def load_u2net_model():
|
| 34 |
+
global U2NET_MODEL
|
| 35 |
+
if not os.path.exists(U2NET_MODEL_PATH):
|
| 36 |
+
print(f"Lỗi: Không tìm thấy file trọng số U2NET tại '{U2NET_MODEL_PATH}'.")
|
| 37 |
+
print("Hãy đảm bảo file u2net.pth nằm đúng vị trí.")
|
| 38 |
+
# Không exit() ở đây để FastAPI vẫn có thể khởi động và báo lỗi qua API nếu cần
|
| 39 |
+
# Hoặc bạn có thể quyết định exit() nếu U2NET là bắt buộc.
|
| 40 |
+
return False
|
| 41 |
+
|
| 42 |
+
try:
|
| 43 |
+
U2NET_MODEL = U2NET(3, 1) # 3 kênh đầu vào (RGB), 1 kênh đầu ra (mask)
|
| 44 |
+
# Sử dụng torch.device để đảm bảo tương thích CPU/GPU
|
| 45 |
+
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
|
| 46 |
+
U2NET_MODEL.load_state_dict(torch.load(U2NET_MODEL_PATH, map_location=device))
|
| 47 |
+
U2NET_MODEL.to(device)
|
| 48 |
+
U2NET_MODEL.eval()
|
| 49 |
+
print(f"Đã tải thành công mô hình U2NET lên {device}.")
|
| 50 |
+
return True
|
| 51 |
+
except Exception as e:
|
| 52 |
+
print(f"Lỗi khi tải mô hình U2NET: {e}")
|
| 53 |
+
U2NET_MODEL = None # Đảm bảo model là None nếu tải lỗi
|
| 54 |
+
return False
|
| 55 |
+
|
| 56 |
+
# Gọi hàm tải model khi ứng dụng khởi động
|
| 57 |
+
# FastAPI sẽ chạy hàm này trong sự kiện startup nếu bạn dùng @app.on_event("startup")
|
| 58 |
+
# Tuy nhiên, để đơn giản, ta gọi trực tiếp. Nếu có lỗi, các endpoint sẽ kiểm tra U2NET_MODEL.
|
| 59 |
+
MODEL_LOADED_SUCCESSFULLY = load_u2net_model()
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
# --- Các hàm xử lý ảnh với U2NET (tương tự unet.py) ---
|
| 63 |
+
def _preprocess_for_u2net(pil_image: Image.Image) -> torch.Tensor:
|
| 64 |
+
"""Tiền xử lý ảnh PIL cho đầu vào U2NET."""
|
| 65 |
+
transform = transforms.Compose([
|
| 66 |
+
transforms.Resize((256, 192)), # (H, W) theo convention của U2NET trong unet.py
|
| 67 |
+
transforms.ToTensor(),
|
| 68 |
+
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
|
| 69 |
+
])
|
| 70 |
+
return transform(pil_image).unsqueeze(0)
|
| 71 |
+
|
| 72 |
+
def generate_person_mask_from_image(
|
| 73 |
+
image_path: str,
|
| 74 |
+
output_mask_path: str,
|
| 75 |
+
device: torch.device
|
| 76 |
+
) -> str:
|
| 77 |
+
"""
|
| 78 |
+
Tạo mặt nạ cho người từ ảnh đầu vào bằng U2NET.
|
| 79 |
+
Mặt nạ được resize về kích thước ảnh gốc và lưu dưới dạng ảnh grayscale.
|
| 80 |
+
"""
|
| 81 |
+
if U2NET_MODEL is None:
|
| 82 |
+
raise RuntimeError("Mô hình U2NET chưa được tải thành công.")
|
| 83 |
+
|
| 84 |
+
pil_image = Image.open(image_path).convert('RGB')
|
| 85 |
+
original_w, original_h = pil_image.size
|
| 86 |
+
|
| 87 |
+
input_tensor = _preprocess_for_u2net(pil_image)
|
| 88 |
+
input_tensor = input_tensor.to(device) # Chuyển tensor sang device của model
|
| 89 |
+
|
| 90 |
+
with torch.no_grad():
|
| 91 |
+
# U2NET thường trả về nhiều output ở các scale khác nhau, d1 là output chính
|
| 92 |
+
d1, *_ = U2NET_MODEL(input_tensor)
|
| 93 |
+
|
| 94 |
+
pred = d1[:,0,:,:] # Lấy mask từ output, shape: (1, H_u2net, W_u2net)
|
| 95 |
+
pred = pred.squeeze().cpu().numpy() # Chuyển về numpy array trên CPU, shape: (H_u2net, W_u2net)
|
| 96 |
+
|
| 97 |
+
# Chuẩn hóa giá trị của mask về khoảng [0, 1]
|
| 98 |
+
pred_min = pred.min()
|
| 99 |
+
pred_max = pred.max()
|
| 100 |
+
if pred_max - pred_min > 1e-8: # Tránh chia cho 0
|
| 101 |
+
pred = (pred - pred_min) / (pred_max - pred_min)
|
| 102 |
+
else:
|
| 103 |
+
pred = np.zeros_like(pred) # Nếu ảnh đầu vào đồng màu, mask có thể là 0
|
| 104 |
+
|
| 105 |
+
# Resize mask về kích thước ảnh gốc
|
| 106 |
+
# cv2.resize yêu cầu dsize là (width, height)
|
| 107 |
+
mask_resized = cv2.resize(pred, (original_w, original_h), interpolation=cv2.INTER_LINEAR)
|
| 108 |
+
|
| 109 |
+
# Lưu mask dưới dạng ảnh grayscale (giá trị 0-255)
|
| 110 |
+
cv2.imwrite(output_mask_path, (mask_resized * 255).astype(np.uint8))
|
| 111 |
+
return output_mask_path
|
| 112 |
+
|
| 113 |
+
def apply_mask_and_prepare_person_image(
|
| 114 |
+
original_image_path: str,
|
| 115 |
+
person_mask_path: str, # Đường dẫn đến file mask grayscale (0-255)
|
| 116 |
+
output_image_path: str,
|
| 117 |
+
target_size: tuple = (192, 256) # (W, H) cho ảnh output cuối cùng của người
|
| 118 |
+
) -> str:
|
| 119 |
+
"""
|
| 120 |
+
Áp dụng mặt nạ lên ảnh gốc (nền trắng) và resize về kích thước mục tiêu.
|
| 121 |
+
"""
|
| 122 |
+
original_bgr = cv2.imread(original_image_path)
|
| 123 |
+
if original_bgr is None:
|
| 124 |
+
raise FileNotFoundError(f"Không tìm thấy ảnh gốc: {original_image_path}")
|
| 125 |
+
original_rgb = cv2.cvtColor(original_bgr, cv2.COLOR_BGR2RGB)
|
| 126 |
+
|
| 127 |
+
mask_gray = cv2.imread(person_mask_path, cv2.IMREAD_GRAYSCALE)
|
| 128 |
+
if mask_gray is None:
|
| 129 |
+
raise FileNotFoundError(f"Không tìm thấy ảnh mặt nạ: {person_mask_path}")
|
| 130 |
+
|
| 131 |
+
# Đảm bảo mask có cùng kích thước với ảnh gốc
|
| 132 |
+
if mask_gray.shape[:2] != original_rgb.shape[:2]:
|
| 133 |
+
mask_gray = cv2.resize(mask_gray, (original_rgb.shape[1], original_rgb.shape[0]),
|
| 134 |
+
interpolation=cv2.INTER_LINEAR)
|
| 135 |
+
|
| 136 |
+
# Chuẩn hóa mask về khoảng [0, 1]
|
| 137 |
+
mask_float = mask_gray / 255.0
|
| 138 |
+
# Mở rộng mask thành 3 kênh để áp dụng cho ảnh RGB
|
| 139 |
+
mask_3channel = np.repeat(np.expand_dims(mask_float, axis=2), 3, axis=2)
|
| 140 |
+
|
| 141 |
+
# Tạo ảnh nền trắng
|
| 142 |
+
white_background_rgb = np.full_like(original_rgb, 255, dtype=np.uint8)
|
| 143 |
+
|
| 144 |
+
# Áp dụng công thức: result = foreground * mask + background * (1 - mask)
|
| 145 |
+
composited_rgb = (original_rgb.astype(float) * mask_3channel + \
|
| 146 |
+
white_background_rgb.astype(float) * (1 - mask_3channel))
|
| 147 |
+
composited_uint8 = np.clip(composited_rgb, 0, 255).astype(np.uint8)
|
| 148 |
+
|
| 149 |
+
# Resize ảnh đã xử lý về kích thước mục tiêu (W, H)
|
| 150 |
+
# cv2.resize yêu cầu dsize là (width, height)
|
| 151 |
+
resized_image_rgb = cv2.resize(composited_uint8, target_size, interpolation=cv2.INTER_AREA)
|
| 152 |
+
|
| 153 |
+
# Chuyển lại BGR để lưu bằng OpenCV
|
| 154 |
+
output_bgr = cv2.cvtColor(resized_image_rgb, cv2.COLOR_RGB2BGR)
|
| 155 |
+
cv2.imwrite(output_image_path, output_bgr)
|
| 156 |
+
return output_image_path
|
| 157 |
+
|
| 158 |
+
# --- Placeholder cho mô hình VITON-Extends ---
|
| 159 |
+
def run_viton_try_on_model(
|
| 160 |
+
person_image_path: str, # Ảnh người đã xử lý (nền trắng, resized)
|
| 161 |
+
clothing_image_path: str, # Ảnh trang phục
|
| 162 |
+
person_mask_path: str, # Mặt nạ người (có thể dùng làm "edge")
|
| 163 |
+
output_dir: str
|
| 164 |
+
) -> str:
|
| 165 |
+
"""
|
| 166 |
+
Hàm giả lập việc gọi mô hình VITON-Extends.
|
| 167 |
+
Trong thực tế, bạn sẽ thay thế phần này bằng code gọi mô hình của bạn.
|
| 168 |
+
"""
|
| 169 |
+
print(f"Gọi mô hình VITON (giả lập) với:")
|
| 170 |
+
print(f" - Ảnh người: {person_image_path}")
|
| 171 |
+
print(f" - Ảnh trang phục: {clothing_image_path}")
|
| 172 |
+
print(f" - Mặt nạ người ('edge'): {person_mask_path}")
|
| 173 |
+
|
| 174 |
+
# Tạo một file output giả lập
|
| 175 |
+
dummy_output_name = f"viton_result_{uuid.uuid4().hex}.png"
|
| 176 |
+
dummy_output_path = os.path.join(output_dir, dummy_output_name)
|
| 177 |
+
|
| 178 |
+
# Ví dụ: copy ảnh người làm kết quả giả lập
|
| 179 |
+
if os.path.exists(person_image_path):
|
| 180 |
+
shutil.copy(person_image_path, dummy_output_path)
|
| 181 |
+
print(f"Mô hình VITON (giả lập) đã lưu kết quả tại: {dummy_output_path}")
|
| 182 |
+
return dummy_output_path
|
| 183 |
+
else:
|
| 184 |
+
# Tạo ảnh trống nếu không có ảnh người
|
| 185 |
+
error_img = np.zeros((256, 192, 3), dtype=np.uint8)
|
| 186 |
+
cv2.putText(error_img, "VITON Error", (10,128), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,255),1)
|
| 187 |
+
cv2.imwrite(dummy_output_path, error_img)
|
| 188 |
+
print(f"Lỗi: Không tìm thấy ảnh người để tạo output giả lập. Đã tạo ảnh lỗi.")
|
| 189 |
+
return dummy_output_path
|
| 190 |
+
|
| 191 |
+
|
| 192 |
+
# --- Thiết lập thư mục tạm ---
|
| 193 |
+
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 194 |
+
TEMP_DIR = os.path.join(BASE_DIR, "temp_files_viton_api")
|
| 195 |
+
os.makedirs(TEMP_DIR, exist_ok=True)
|
| 196 |
+
|
| 197 |
+
# Thư mục cho các file input gốc
|
| 198 |
+
UPLOADED_FILES_DIR = os.path.join(TEMP_DIR, "uploads")
|
| 199 |
+
os.makedirs(UPLOADED_FILES_DIR, exist_ok=True)
|
| 200 |
+
|
| 201 |
+
# Thư mục cho output của U2NET (ảnh người đã xử lý, mặt nạ người)
|
| 202 |
+
UNET_OUTPUT_DIR = os.path.join(TEMP_DIR, "unet_outputs")
|
| 203 |
+
os.makedirs(UNET_OUTPUT_DIR, exist_ok=True)
|
| 204 |
+
|
| 205 |
+
# Thư mục cho output cuối cùng của VITON
|
| 206 |
+
VITON_OUTPUT_DIR = os.path.join(TEMP_DIR, "viton_results")
|
| 207 |
+
os.makedirs(VITON_OUTPUT_DIR, exist_ok=True)
|
| 208 |
+
|
| 209 |
+
|
| 210 |
+
# --- API Endpoint ---
|
| 211 |
+
@app.post("/virtual-try-on/",
|
| 212 |
+
summary="Thực hiện thử đồ ảo",
|
| 213 |
+
description="Tải lên ảnh người và ảnh trang phục. API sẽ trả về ảnh người mặc trang phục đó.")
|
| 214 |
+
async def virtual_try_on_endpoint(
|
| 215 |
+
person_image: UploadFile = File(..., description="Ảnh người dùng (định dạng JPG, PNG)."),
|
| 216 |
+
clothing_image: UploadFile = File(..., description="Ảnh trang phục (định dạng JPG, PNG).")
|
| 217 |
+
):
|
| 218 |
+
if not MODEL_LOADED_SUCCESSFULLY or U2NET_MODEL is None:
|
| 219 |
+
return {"error": "Mô hình U2NET chưa sẵn sàng hoặc tải lỗi. Vui lòng kiểm tra console server."}
|
| 220 |
+
|
| 221 |
+
request_id = uuid.uuid4().hex
|
| 222 |
+
|
| 223 |
+
# --- 1. Lưu ảnh tải lên ---
|
| 224 |
+
person_image_name = f"{request_id}_person{os.path.splitext(person_image.filename)[1]}"
|
| 225 |
+
clothing_image_name = f"{request_id}_clothing{os.path.splitext(clothing_image.filename)[1]}"
|
| 226 |
+
|
| 227 |
+
original_person_image_path = os.path.join(UPLOADED_FILES_DIR, person_image_name)
|
| 228 |
+
original_clothing_image_path = os.path.join(UPLOADED_FILES_DIR, clothing_image_name)
|
| 229 |
+
|
| 230 |
+
try:
|
| 231 |
+
with open(original_person_image_path, "wb") as buffer:
|
| 232 |
+
shutil.copyfileobj(person_image.file, buffer)
|
| 233 |
+
with open(original_clothing_image_path, "wb") as buffer:
|
| 234 |
+
shutil.copyfileobj(clothing_image.file, buffer)
|
| 235 |
+
except Exception as e:
|
| 236 |
+
return {"error": f"Lỗi khi lưu file tải lên: {e}"}
|
| 237 |
+
finally:
|
| 238 |
+
person_image.file.close()
|
| 239 |
+
clothing_image.file.close()
|
| 240 |
+
|
| 241 |
+
# --- 2. Xử lý ảnh người bằng U2NET ---
|
| 242 |
+
# Đường dẫn cho mặt nạ người (person mask)
|
| 243 |
+
person_mask_filename = f"{request_id}_person_mask.png"
|
| 244 |
+
generated_person_mask_path = os.path.join(UNET_OUTPUT_DIR, person_mask_filename)
|
| 245 |
+
|
| 246 |
+
# Đường dẫn cho ảnh người đã xử lý (nền trắng, resized) - đây sẽ là "img" cho VITON
|
| 247 |
+
# Kích thước (192, 256) WxH như trong unet.py gốc
|
| 248 |
+
processed_person_image_filename = f"{request_id}_person_processed.png"
|
| 249 |
+
processed_person_image_path = os.path.join(UNET_OUTPUT_DIR, processed_person_image_filename)
|
| 250 |
+
|
| 251 |
+
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
|
| 252 |
+
|
| 253 |
+
try:
|
| 254 |
+
print(f"[{request_id}] Bắt đầu tạo mặt nạ cho: {original_person_image_path}")
|
| 255 |
+
actual_person_mask_path = generate_person_mask_from_image(
|
| 256 |
+
original_person_image_path,
|
| 257 |
+
generated_person_mask_path,
|
| 258 |
+
device
|
| 259 |
+
)
|
| 260 |
+
print(f"[{request_id}] Đã tạo mặt nạ người tại: {actual_person_mask_path}")
|
| 261 |
+
|
| 262 |
+
print(f"[{request_id}] Bắt đầu xử lý ảnh người: {original_person_image_path}")
|
| 263 |
+
# "img" cho VITON (192W x 256H, nền trắng)
|
| 264 |
+
actual_processed_person_image_path = apply_mask_and_prepare_person_image(
|
| 265 |
+
original_image_path=original_person_image_path,
|
| 266 |
+
person_mask_path=actual_person_mask_path,
|
| 267 |
+
output_image_path=processed_person_image_path,
|
| 268 |
+
target_size=(192, 256) # (W, H)
|
| 269 |
+
)
|
| 270 |
+
print(f"[{request_id}] Đã xử lý ảnh người tại: {actual_processed_person_image_path}")
|
| 271 |
+
|
| 272 |
+
except FileNotFoundError as e:
|
| 273 |
+
return {"error": f"Lỗi file trong quá trình xử lý U2NET: {e}"}
|
| 274 |
+
except RuntimeError as e: # Bắt lỗi Runtime từ U2NET (ví dụ model chưa tải)
|
| 275 |
+
return {"error": f"Lỗi Runtime U2NET: {e}"}
|
| 276 |
+
except Exception as e:
|
| 277 |
+
return {"error": f"Lỗi không xác định trong quá trình xử lý U2NET: {e}"}
|
| 278 |
+
|
| 279 |
+
# --- 3. Gọi mô hình VITON-Extends (Placeholder) ---
|
| 280 |
+
# Đầu vào cho mô hình VITON:
|
| 281 |
+
# - img: actual_processed_person_image_path (ảnh người 192x256, nền trắng)
|
| 282 |
+
# - clothes: original_clothing_image_path (ảnh trang phục gốc)
|
| 283 |
+
# - edge: actual_person_mask_path (mặt nạ người, kích thước gốc)
|
| 284 |
+
try:
|
| 285 |
+
print(f"[{request_id}] Bắt đầu gọi mô hình VITON (giả lập)...")
|
| 286 |
+
final_try_on_image_path = run_viton_try_on_model(
|
| 287 |
+
person_image_path=actual_processed_person_image_path,
|
| 288 |
+
clothing_image_path=original_clothing_image_path,
|
| 289 |
+
person_mask_path=actual_person_mask_path, # "edge" là mặt nạ người
|
| 290 |
+
output_dir=VITON_OUTPUT_DIR
|
| 291 |
+
)
|
| 292 |
+
print(f"[{request_id}] Mô hình VITON (giả lập) hoàn tất. Kết quả: {final_try_on_image_path}")
|
| 293 |
+
|
| 294 |
+
if not os.path.exists(final_try_on_image_path):
|
| 295 |
+
return {"error": "Mô hình VITON không tạo ra file output."}
|
| 296 |
+
|
| 297 |
+
# Trả về file ảnh kết quả
|
| 298 |
+
return FileResponse(final_try_on_image_path, media_type="image/png")
|
| 299 |
+
|
| 300 |
+
except Exception as e:
|
| 301 |
+
# Cân nhắc dọn dẹp file tạm ở đây nếu cần
|
| 302 |
+
return {"error": f"Lỗi trong quá trình chạy mô hình VITON: {e}"}
|
| 303 |
+
|
| 304 |
+
# --- Chạy FastAPI app (ví dụ với uvicorn) ---
|
| 305 |
+
# Để chạy: mở terminal, cd vào thư mục chứa file này và chạy:
|
| 306 |
+
# uvicorn main:app --reload
|
| 307 |
+
# (main là tên file .py, app là tên biến FastAPI instance)
|
| 308 |
+
|
| 309 |
+
if __name__ == "__main__":
|
| 310 |
+
import uvicorn
|
| 311 |
+
print("Để chạy API, sử dụng lệnh: uvicorn main:app --reload --host 0.0.0.0 --port 8000")
|
| 312 |
+
uvicorn.run(app, host="0.0.0.0", port=8000) # B�� comment để chạy trực tiếp khi thực thi file
|
VITON-Extends_test/components.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"$schema": "https://ui.shadcn.com/schema.json",
|
| 3 |
+
"style": "default",
|
| 4 |
+
"rsc": true,
|
| 5 |
+
"tsx": true,
|
| 6 |
+
"tailwind": {
|
| 7 |
+
"config": "tailwind.config.ts",
|
| 8 |
+
"css": "app/globals.css",
|
| 9 |
+
"baseColor": "neutral",
|
| 10 |
+
"cssVariables": true,
|
| 11 |
+
"prefix": ""
|
| 12 |
+
},
|
| 13 |
+
"aliases": {
|
| 14 |
+
"components": "@/components",
|
| 15 |
+
"utils": "@/lib/utils",
|
| 16 |
+
"ui": "@/components/ui",
|
| 17 |
+
"lib": "@/lib",
|
| 18 |
+
"hooks": "@/hooks"
|
| 19 |
+
},
|
| 20 |
+
"iconLibrary": "lucide"
|
| 21 |
+
}
|
VITON-Extends_test/demo.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
000129_0.jpg 007365_1.jpg
|
VITON-Extends_test/demo1.txt
ADDED
|
@@ -0,0 +1,2032 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
000001_0.jpg 001744_1.jpg
|
| 2 |
+
000010_0.jpg 004325_1.jpg
|
| 3 |
+
000020_0.jpg 002022_1.jpg
|
| 4 |
+
000028_0.jpg 014652_1.jpg
|
| 5 |
+
000038_0.jpg 010143_1.jpg
|
| 6 |
+
000048_0.jpg 010608_1.jpg
|
| 7 |
+
000057_0.jpg 012578_1.jpg
|
| 8 |
+
000066_0.jpg 009595_1.jpg
|
| 9 |
+
000074_0.jpg 015392_1.jpg
|
| 10 |
+
000082_0.jpg 003291_1.jpg
|
| 11 |
+
000097_0.jpg 019522_1.jpg
|
| 12 |
+
000109_0.jpg 018778_1.jpg
|
| 13 |
+
000118_0.jpg 005533_1.jpg
|
| 14 |
+
000129_0.jpg 007365_1.jpg
|
| 15 |
+
000143_0.jpg 016246_1.jpg
|
| 16 |
+
000154_0.jpg 003898_1.jpg
|
| 17 |
+
000164_0.jpg 003514_1.jpg
|
| 18 |
+
000174_0.jpg 016866_1.jpg
|
| 19 |
+
000183_0.jpg 019332_1.jpg
|
| 20 |
+
000192_0.jpg 007692_1.jpg
|
| 21 |
+
000200_0.jpg 015272_1.jpg
|
| 22 |
+
000209_0.jpg 013780_1.jpg
|
| 23 |
+
000220_0.jpg 001360_1.jpg
|
| 24 |
+
000228_0.jpg 019540_1.jpg
|
| 25 |
+
000240_0.jpg 018746_1.jpg
|
| 26 |
+
000248_0.jpg 001583_1.jpg
|
| 27 |
+
000258_0.jpg 019037_1.jpg
|
| 28 |
+
000266_0.jpg 015836_1.jpg
|
| 29 |
+
000274_0.jpg 008560_1.jpg
|
| 30 |
+
000284_0.jpg 019552_1.jpg
|
| 31 |
+
000293_0.jpg 007415_1.jpg
|
| 32 |
+
000303_0.jpg 013245_1.jpg
|
| 33 |
+
000312_0.jpg 007484_1.jpg
|
| 34 |
+
000320_0.jpg 019029_1.jpg
|
| 35 |
+
000330_0.jpg 005053_1.jpg
|
| 36 |
+
000339_0.jpg 001879_1.jpg
|
| 37 |
+
000347_0.jpg 016367_1.jpg
|
| 38 |
+
000356_0.jpg 014701_1.jpg
|
| 39 |
+
000370_0.jpg 002397_1.jpg
|
| 40 |
+
000378_0.jpg 005666_1.jpg
|
| 41 |
+
000386_0.jpg 015308_1.jpg
|
| 42 |
+
000395_0.jpg 011689_1.jpg
|
| 43 |
+
000404_0.jpg 004922_1.jpg
|
| 44 |
+
000417_0.jpg 008406_1.jpg
|
| 45 |
+
000426_0.jpg 014794_1.jpg
|
| 46 |
+
000437_0.jpg 000846_1.jpg
|
| 47 |
+
000445_0.jpg 008645_1.jpg
|
| 48 |
+
000456_0.jpg 015759_1.jpg
|
| 49 |
+
000466_0.jpg 000514_1.jpg
|
| 50 |
+
000477_0.jpg 006976_1.jpg
|
| 51 |
+
000488_0.jpg 007986_1.jpg
|
| 52 |
+
000501_0.jpg 016300_1.jpg
|
| 53 |
+
000514_0.jpg 012652_1.jpg
|
| 54 |
+
000523_0.jpg 017868_1.jpg
|
| 55 |
+
000532_0.jpg 013214_1.jpg
|
| 56 |
+
000542_0.jpg 014149_1.jpg
|
| 57 |
+
000560_0.jpg 006640_1.jpg
|
| 58 |
+
000568_0.jpg 004342_1.jpg
|
| 59 |
+
000576_0.jpg 001192_1.jpg
|
| 60 |
+
000585_0.jpg 008471_1.jpg
|
| 61 |
+
000593_0.jpg 003998_1.jpg
|
| 62 |
+
000602_0.jpg 012860_1.jpg
|
| 63 |
+
000610_0.jpg 014979_1.jpg
|
| 64 |
+
000619_0.jpg 008744_1.jpg
|
| 65 |
+
000629_0.jpg 001144_1.jpg
|
| 66 |
+
000639_0.jpg 008420_1.jpg
|
| 67 |
+
000651_0.jpg 003422_1.jpg
|
| 68 |
+
000659_0.jpg 015362_1.jpg
|
| 69 |
+
000668_0.jpg 008959_1.jpg
|
| 70 |
+
000676_0.jpg 010105_1.jpg
|
| 71 |
+
000685_0.jpg 011944_1.jpg
|
| 72 |
+
000696_0.jpg 012605_1.jpg
|
| 73 |
+
000706_0.jpg 016474_1.jpg
|
| 74 |
+
000716_0.jpg 006808_1.jpg
|
| 75 |
+
000724_0.jpg 007243_1.jpg
|
| 76 |
+
000734_0.jpg 014888_1.jpg
|
| 77 |
+
000742_0.jpg 009390_1.jpg
|
| 78 |
+
000750_0.jpg 013654_1.jpg
|
| 79 |
+
000760_0.jpg 005368_1.jpg
|
| 80 |
+
000768_0.jpg 017886_1.jpg
|
| 81 |
+
000776_0.jpg 008506_1.jpg
|
| 82 |
+
000786_0.jpg 007957_1.jpg
|
| 83 |
+
000795_0.jpg 006859_1.jpg
|
| 84 |
+
000803_0.jpg 005203_1.jpg
|
| 85 |
+
000812_0.jpg 003821_1.jpg
|
| 86 |
+
000827_0.jpg 002297_1.jpg
|
| 87 |
+
000837_0.jpg 004710_1.jpg
|
| 88 |
+
000846_0.jpg 001606_1.jpg
|
| 89 |
+
000855_0.jpg 011816_1.jpg
|
| 90 |
+
000867_0.jpg 002111_1.jpg
|
| 91 |
+
000877_0.jpg 010543_1.jpg
|
| 92 |
+
000889_0.jpg 004080_1.jpg
|
| 93 |
+
000898_0.jpg 011173_1.jpg
|
| 94 |
+
000907_0.jpg 004123_1.jpg
|
| 95 |
+
000915_0.jpg 016049_1.jpg
|
| 96 |
+
000924_0.jpg 007286_1.jpg
|
| 97 |
+
000934_0.jpg 017466_1.jpg
|
| 98 |
+
000943_0.jpg 010463_1.jpg
|
| 99 |
+
000957_0.jpg 012322_1.jpg
|
| 100 |
+
000968_0.jpg 005328_1.jpg
|
| 101 |
+
000979_0.jpg 014765_1.jpg
|
| 102 |
+
000988_0.jpg 016059_1.jpg
|
| 103 |
+
000997_0.jpg 019224_1.jpg
|
| 104 |
+
001009_0.jpg 000889_1.jpg
|
| 105 |
+
001017_0.jpg 010744_1.jpg
|
| 106 |
+
001028_0.jpg 004844_1.jpg
|
| 107 |
+
001038_0.jpg 003721_1.jpg
|
| 108 |
+
001048_0.jpg 002076_1.jpg
|
| 109 |
+
001056_0.jpg 005396_1.jpg
|
| 110 |
+
001064_0.jpg 017438_1.jpg
|
| 111 |
+
001073_0.jpg 000724_1.jpg
|
| 112 |
+
001083_0.jpg 007609_1.jpg
|
| 113 |
+
001092_0.jpg 000154_1.jpg
|
| 114 |
+
001101_0.jpg 018962_1.jpg
|
| 115 |
+
001109_0.jpg 016951_1.jpg
|
| 116 |
+
001118_0.jpg 002874_1.jpg
|
| 117 |
+
001126_0.jpg 011042_1.jpg
|
| 118 |
+
001136_0.jpg 019045_1.jpg
|
| 119 |
+
001144_0.jpg 016172_1.jpg
|
| 120 |
+
001153_0.jpg 018210_1.jpg
|
| 121 |
+
001162_0.jpg 019009_1.jpg
|
| 122 |
+
001173_0.jpg 007505_1.jpg
|
| 123 |
+
001181_0.jpg 002103_1.jpg
|
| 124 |
+
001192_0.jpg 017002_1.jpg
|
| 125 |
+
001203_0.jpg 009236_1.jpg
|
| 126 |
+
001211_0.jpg 014192_1.jpg
|
| 127 |
+
001219_0.jpg 009995_1.jpg
|
| 128 |
+
001228_0.jpg 003731_1.jpg
|
| 129 |
+
001236_0.jpg 007149_1.jpg
|
| 130 |
+
001245_0.jpg 010891_1.jpg
|
| 131 |
+
001255_0.jpg 017091_1.jpg
|
| 132 |
+
001269_0.jpg 014262_1.jpg
|
| 133 |
+
001283_0.jpg 002137_1.jpg
|
| 134 |
+
001292_0.jpg 013047_1.jpg
|
| 135 |
+
001301_0.jpg 003813_1.jpg
|
| 136 |
+
001310_0.jpg 014854_1.jpg
|
| 137 |
+
001320_0.jpg 003208_1.jpg
|
| 138 |
+
001328_0.jpg 011615_1.jpg
|
| 139 |
+
001337_0.jpg 012174_1.jpg
|
| 140 |
+
001349_0.jpg 008241_1.jpg
|
| 141 |
+
001360_0.jpg 008451_1.jpg
|
| 142 |
+
001369_0.jpg 019279_1.jpg
|
| 143 |
+
001378_0.jpg 000466_1.jpg
|
| 144 |
+
001387_0.jpg 015325_1.jpg
|
| 145 |
+
001399_0.jpg 005711_1.jpg
|
| 146 |
+
001408_0.jpg 002980_1.jpg
|
| 147 |
+
001419_0.jpg 010337_1.jpg
|
| 148 |
+
001428_0.jpg 007617_1.jpg
|
| 149 |
+
001437_0.jpg 001476_1.jpg
|
| 150 |
+
001448_0.jpg 016067_1.jpg
|
| 151 |
+
001457_0.jpg 008804_1.jpg
|
| 152 |
+
001467_0.jpg 017235_1.jpg
|
| 153 |
+
001476_0.jpg 010281_1.jpg
|
| 154 |
+
001485_0.jpg 018420_1.jpg
|
| 155 |
+
001494_0.jpg 008928_1.jpg
|
| 156 |
+
001502_0.jpg 015150_1.jpg
|
| 157 |
+
001512_0.jpg 018031_1.jpg
|
| 158 |
+
001520_0.jpg 012395_1.jpg
|
| 159 |
+
001528_0.jpg 015688_1.jpg
|
| 160 |
+
001537_0.jpg 001825_1.jpg
|
| 161 |
+
001547_0.jpg 003357_1.jpg
|
| 162 |
+
001559_0.jpg 011190_1.jpg
|
| 163 |
+
001567_0.jpg 001567_1.jpg
|
| 164 |
+
001575_0.jpg 018544_1.jpg
|
| 165 |
+
001583_0.jpg 019087_1.jpg
|
| 166 |
+
001594_0.jpg 013527_1.jpg
|
| 167 |
+
001606_0.jpg 010115_1.jpg
|
| 168 |
+
001614_0.jpg 005975_1.jpg
|
| 169 |
+
001623_0.jpg 010300_1.jpg
|
| 170 |
+
001635_0.jpg 019573_1.jpg
|
| 171 |
+
001645_0.jpg 009342_1.jpg
|
| 172 |
+
001655_0.jpg 000576_1.jpg
|
| 173 |
+
001664_0.jpg 004061_1.jpg
|
| 174 |
+
001673_0.jpg 008863_1.jpg
|
| 175 |
+
001683_0.jpg 008206_1.jpg
|
| 176 |
+
001695_0.jpg 017175_1.jpg
|
| 177 |
+
001706_0.jpg 010735_1.jpg
|
| 178 |
+
001715_0.jpg 006581_1.jpg
|
| 179 |
+
001725_0.jpg 002892_1.jpg
|
| 180 |
+
001735_0.jpg 001645_1.jpg
|
| 181 |
+
001744_0.jpg 001328_1.jpg
|
| 182 |
+
001756_0.jpg 002999_1.jpg
|
| 183 |
+
001765_0.jpg 006834_1.jpg
|
| 184 |
+
001776_0.jpg 007899_1.jpg
|
| 185 |
+
001789_0.jpg 011288_1.jpg
|
| 186 |
+
001798_0.jpg 001735_1.jpg
|
| 187 |
+
001809_0.jpg 010995_1.jpg
|
| 188 |
+
001817_0.jpg 003777_1.jpg
|
| 189 |
+
001825_0.jpg 017945_1.jpg
|
| 190 |
+
001834_0.jpg 005044_1.jpg
|
| 191 |
+
001845_0.jpg 000395_1.jpg
|
| 192 |
+
001858_0.jpg 019402_1.jpg
|
| 193 |
+
001868_0.jpg 011270_1.jpg
|
| 194 |
+
001879_0.jpg 004727_1.jpg
|
| 195 |
+
001891_0.jpg 018348_1.jpg
|
| 196 |
+
001900_0.jpg 011544_1.jpg
|
| 197 |
+
001908_0.jpg 011515_1.jpg
|
| 198 |
+
001919_0.jpg 001211_1.jpg
|
| 199 |
+
001928_0.jpg 013155_1.jpg
|
| 200 |
+
001937_0.jpg 005887_1.jpg
|
| 201 |
+
001947_0.jpg 002990_1.jpg
|
| 202 |
+
001957_0.jpg 002749_1.jpg
|
| 203 |
+
001966_0.jpg 007932_1.jpg
|
| 204 |
+
001974_0.jpg 008101_1.jpg
|
| 205 |
+
001983_0.jpg 004423_1.jpg
|
| 206 |
+
001991_0.jpg 004981_1.jpg
|
| 207 |
+
002000_0.jpg 016628_1.jpg
|
| 208 |
+
002011_0.jpg 005440_1.jpg
|
| 209 |
+
002022_0.jpg 017204_1.jpg
|
| 210 |
+
002031_0.jpg 008967_1.jpg
|
| 211 |
+
002039_0.jpg 018769_1.jpg
|
| 212 |
+
002049_0.jpg 003124_1.jpg
|
| 213 |
+
002059_0.jpg 008092_1.jpg
|
| 214 |
+
002068_0.jpg 010415_1.jpg
|
| 215 |
+
002076_0.jpg 000716_1.jpg
|
| 216 |
+
002085_0.jpg 001236_1.jpg
|
| 217 |
+
002093_0.jpg 018971_1.jpg
|
| 218 |
+
002103_0.jpg 017070_1.jpg
|
| 219 |
+
002111_0.jpg 017012_1.jpg
|
| 220 |
+
002119_0.jpg 016445_1.jpg
|
| 221 |
+
002128_0.jpg 005360_1.jpg
|
| 222 |
+
002137_0.jpg 015579_1.jpg
|
| 223 |
+
002147_0.jpg 005603_1.jpg
|
| 224 |
+
002156_0.jpg 018431_1.jpg
|
| 225 |
+
002169_0.jpg 009094_1.jpg
|
| 226 |
+
002180_0.jpg 019066_1.jpg
|
| 227 |
+
002191_0.jpg 009215_1.jpg
|
| 228 |
+
002200_0.jpg 008632_1.jpg
|
| 229 |
+
002208_0.jpg 009435_1.jpg
|
| 230 |
+
002217_0.jpg 002119_1.jpg
|
| 231 |
+
002226_0.jpg 016145_1.jpg
|
| 232 |
+
002236_0.jpg 006213_1.jpg
|
| 233 |
+
002248_0.jpg 012338_1.jpg
|
| 234 |
+
002259_0.jpg 013391_1.jpg
|
| 235 |
+
002268_0.jpg 000760_1.jpg
|
| 236 |
+
002276_0.jpg 003338_1.jpg
|
| 237 |
+
002287_0.jpg 018569_1.jpg
|
| 238 |
+
002297_0.jpg 013883_1.jpg
|
| 239 |
+
002307_0.jpg 014416_1.jpg
|
| 240 |
+
002317_0.jpg 017243_1.jpg
|
| 241 |
+
002327_0.jpg 015724_1.jpg
|
| 242 |
+
002337_0.jpg 002439_1.jpg
|
| 243 |
+
002345_0.jpg 015607_1.jpg
|
| 244 |
+
002353_0.jpg 016653_1.jpg
|
| 245 |
+
002362_0.jpg 018401_1.jpg
|
| 246 |
+
002371_0.jpg 005877_1.jpg
|
| 247 |
+
002379_0.jpg 011240_1.jpg
|
| 248 |
+
002388_0.jpg 005081_1.jpg
|
| 249 |
+
002397_0.jpg 009496_1.jpg
|
| 250 |
+
002405_0.jpg 018496_1.jpg
|
| 251 |
+
002413_0.jpg 008023_1.jpg
|
| 252 |
+
002422_0.jpg 015125_1.jpg
|
| 253 |
+
002431_0.jpg 007797_1.jpg
|
| 254 |
+
002439_0.jpg 004185_1.jpg
|
| 255 |
+
002447_0.jpg 000240_1.jpg
|
| 256 |
+
002455_0.jpg 011891_1.jpg
|
| 257 |
+
002464_0.jpg 010851_1.jpg
|
| 258 |
+
002474_0.jpg 004268_1.jpg
|
| 259 |
+
002486_0.jpg 017348_1.jpg
|
| 260 |
+
002494_0.jpg 013836_1.jpg
|
| 261 |
+
002502_0.jpg 004333_1.jpg
|
| 262 |
+
002511_0.jpg 000020_1.jpg
|
| 263 |
+
002523_0.jpg 009114_1.jpg
|
| 264 |
+
002533_0.jpg 019340_1.jpg
|
| 265 |
+
002545_0.jpg 004006_1.jpg
|
| 266 |
+
002553_0.jpg 012763_1.jpg
|
| 267 |
+
002561_0.jpg 012644_1.jpg
|
| 268 |
+
002575_0.jpg 012996_1.jpg
|
| 269 |
+
002589_0.jpg 013891_1.jpg
|
| 270 |
+
002599_0.jpg 005648_1.jpg
|
| 271 |
+
002610_0.jpg 015465_1.jpg
|
| 272 |
+
002620_0.jpg 003749_1.jpg
|
| 273 |
+
002628_0.jpg 016739_1.jpg
|
| 274 |
+
002639_0.jpg 000143_1.jpg
|
| 275 |
+
002651_0.jpg 016636_1.jpg
|
| 276 |
+
002659_0.jpg 003935_1.jpg
|
| 277 |
+
002670_0.jpg 010710_1.jpg
|
| 278 |
+
002681_0.jpg 000312_1.jpg
|
| 279 |
+
002691_0.jpg 015256_1.jpg
|
| 280 |
+
002699_0.jpg 001118_1.jpg
|
| 281 |
+
002712_0.jpg 013583_1.jpg
|
| 282 |
+
002720_0.jpg 019514_1.jpg
|
| 283 |
+
002728_0.jpg 001991_1.jpg
|
| 284 |
+
002739_0.jpg 005952_1.jpg
|
| 285 |
+
002749_0.jpg 011523_1.jpg
|
| 286 |
+
002758_0.jpg 012256_1.jpg
|
| 287 |
+
002769_0.jpg 010806_1.jpg
|
| 288 |
+
002778_0.jpg 001512_1.jpg
|
| 289 |
+
002787_0.jpg 002787_1.jpg
|
| 290 |
+
002795_0.jpg 018138_1.jpg
|
| 291 |
+
002803_0.jpg 016238_1.jpg
|
| 292 |
+
002812_0.jpg 004497_1.jpg
|
| 293 |
+
002820_0.jpg 011761_1.jpg
|
| 294 |
+
002828_0.jpg 000968_1.jpg
|
| 295 |
+
002839_0.jpg 009178_1.jpg
|
| 296 |
+
002852_0.jpg 007261_1.jpg
|
| 297 |
+
002865_0.jpg 004167_1.jpg
|
| 298 |
+
002874_0.jpg 008429_1.jpg
|
| 299 |
+
002883_0.jpg 009141_1.jpg
|
| 300 |
+
002892_0.jpg 016290_1.jpg
|
| 301 |
+
002901_0.jpg 015627_1.jpg
|
| 302 |
+
002911_0.jpg 013355_1.jpg
|
| 303 |
+
002922_0.jpg 012975_1.jpg
|
| 304 |
+
002930_0.jpg 016002_1.jpg
|
| 305 |
+
002942_0.jpg 015371_1.jpg
|
| 306 |
+
002952_0.jpg 011381_1.jpg
|
| 307 |
+
002962_0.jpg 012553_1.jpg
|
| 308 |
+
002970_0.jpg 016593_1.jpg
|
| 309 |
+
002980_0.jpg 004366_1.jpg
|
| 310 |
+
002990_0.jpg 003684_1.jpg
|
| 311 |
+
002999_0.jpg 018393_1.jpg
|
| 312 |
+
003008_0.jpg 007455_1.jpg
|
| 313 |
+
003016_0.jpg 012811_1.jpg
|
| 314 |
+
003024_0.jpg 001245_1.jpg
|
| 315 |
+
003032_0.jpg 005797_1.jpg
|
| 316 |
+
003041_0.jpg 001673_1.jpg
|
| 317 |
+
003049_0.jpg 008822_1.jpg
|
| 318 |
+
003060_0.jpg 002720_1.jpg
|
| 319 |
+
003069_0.jpg 013680_1.jpg
|
| 320 |
+
003077_0.jpg 000639_1.jpg
|
| 321 |
+
003086_0.jpg 006057_1.jpg
|
| 322 |
+
003094_0.jpg 018452_1.jpg
|
| 323 |
+
003107_0.jpg 002795_1.jpg
|
| 324 |
+
003115_0.jpg 007772_1.jpg
|
| 325 |
+
003124_0.jpg 010591_1.jpg
|
| 326 |
+
003133_0.jpg 010125_1.jpg
|
| 327 |
+
003142_0.jpg 011068_1.jpg
|
| 328 |
+
003150_0.jpg 011736_1.jpg
|
| 329 |
+
003158_0.jpg 012350_1.jpg
|
| 330 |
+
003167_0.jpg 006606_1.jpg
|
| 331 |
+
003179_0.jpg 010937_1.jpg
|
| 332 |
+
003187_0.jpg 011212_1.jpg
|
| 333 |
+
003195_0.jpg 009282_1.jpg
|
| 334 |
+
003208_0.jpg 001255_1.jpg
|
| 335 |
+
003218_0.jpg 016541_1.jpg
|
| 336 |
+
003226_0.jpg 010177_1.jpg
|
| 337 |
+
003236_0.jpg 005251_1.jpg
|
| 338 |
+
003250_0.jpg 017410_1.jpg
|
| 339 |
+
003259_0.jpg 002639_1.jpg
|
| 340 |
+
003270_0.jpg 017796_1.jpg
|
| 341 |
+
003280_0.jpg 017526_1.jpg
|
| 342 |
+
003291_0.jpg 011708_1.jpg
|
| 343 |
+
003303_0.jpg 003491_1.jpg
|
| 344 |
+
003311_0.jpg 013827_1.jpg
|
| 345 |
+
003319_0.jpg 015192_1.jpg
|
| 346 |
+
003328_0.jpg 012273_1.jpg
|
| 347 |
+
003338_0.jpg 010567_1.jpg
|
| 348 |
+
003349_0.jpg 001101_1.jpg
|
| 349 |
+
003357_0.jpg 013374_1.jpg
|
| 350 |
+
003367_0.jpg 002353_1.jpg
|
| 351 |
+
003376_0.jpg 014006_1.jpg
|
| 352 |
+
003386_0.jpg 018479_1.jpg
|
| 353 |
+
003395_0.jpg 010726_1.jpg
|
| 354 |
+
003404_0.jpg 015844_1.jpg
|
| 355 |
+
003414_0.jpg 000855_1.jpg
|
| 356 |
+
003422_0.jpg 000456_1.jpg
|
| 357 |
+
003434_0.jpg 010718_1.jpg
|
| 358 |
+
003443_0.jpg 003945_1.jpg
|
| 359 |
+
003451_0.jpg 011336_1.jpg
|
| 360 |
+
003461_0.jpg 004814_1.jpg
|
| 361 |
+
003472_0.jpg 006470_1.jpg
|
| 362 |
+
003481_0.jpg 016726_1.jpg
|
| 363 |
+
003491_0.jpg 017298_1.jpg
|
| 364 |
+
003501_0.jpg 010270_1.jpg
|
| 365 |
+
003514_0.jpg 018608_1.jpg
|
| 366 |
+
003526_0.jpg 001858_1.jpg
|
| 367 |
+
003535_0.jpg 009852_1.jpg
|
| 368 |
+
003545_0.jpg 002085_1.jpg
|
| 369 |
+
003555_0.jpg 013564_1.jpg
|
| 370 |
+
003565_0.jpg 005525_1.jpg
|
| 371 |
+
003578_0.jpg 013007_1.jpg
|
| 372 |
+
003591_0.jpg 005720_1.jpg
|
| 373 |
+
003600_0.jpg 015938_1.jpg
|
| 374 |
+
003611_0.jpg 013715_1.jpg
|
| 375 |
+
003621_0.jpg 000274_1.jpg
|
| 376 |
+
003632_0.jpg 000585_1.jpg
|
| 377 |
+
003641_0.jpg 014876_1.jpg
|
| 378 |
+
003649_0.jpg 019140_1.jpg
|
| 379 |
+
003658_0.jpg 016465_1.jpg
|
| 380 |
+
003668_0.jpg 010234_1.jpg
|
| 381 |
+
003676_0.jpg 007601_1.jpg
|
| 382 |
+
003684_0.jpg 006381_1.jpg
|
| 383 |
+
003693_0.jpg 015590_1.jpg
|
| 384 |
+
003703_0.jpg 011883_1.jpg
|
| 385 |
+
003712_0.jpg 014621_1.jpg
|
| 386 |
+
003721_0.jpg 001126_1.jpg
|
| 387 |
+
003731_0.jpg 015715_1.jpg
|
| 388 |
+
003739_0.jpg 004804_1.jpg
|
| 389 |
+
003749_0.jpg 014140_1.jpg
|
| 390 |
+
003760_0.jpg 008397_1.jpg
|
| 391 |
+
003768_0.jpg 015697_1.jpg
|
| 392 |
+
003777_0.jpg 000082_1.jpg
|
| 393 |
+
003787_0.jpg 001966_1.jpg
|
| 394 |
+
003795_0.jpg 003414_1.jpg
|
| 395 |
+
003803_0.jpg 011916_1.jpg
|
| 396 |
+
003813_0.jpg 014612_1.jpg
|
| 397 |
+
003821_0.jpg 014292_1.jpg
|
| 398 |
+
003833_0.jpg 008326_1.jpg
|
| 399 |
+
003842_0.jpg 012219_1.jpg
|
| 400 |
+
003852_0.jpg 011466_1.jpg
|
| 401 |
+
003861_0.jpg 011962_1.jpg
|
| 402 |
+
003874_0.jpg 014349_1.jpg
|
| 403 |
+
003882_0.jpg 017583_1.jpg
|
| 404 |
+
003890_0.jpg 018921_1.jpg
|
| 405 |
+
003898_0.jpg 004196_1.jpg
|
| 406 |
+
003915_0.jpg 013688_1.jpg
|
| 407 |
+
003925_0.jpg 004397_1.jpg
|
| 408 |
+
003935_0.jpg 012889_1.jpg
|
| 409 |
+
003945_0.jpg 000898_1.jpg
|
| 410 |
+
003953_0.jpg 002379_1.jpg
|
| 411 |
+
003963_0.jpg 008160_1.jpg
|
| 412 |
+
003972_0.jpg 012694_1.jpg
|
| 413 |
+
003981_0.jpg 008307_1.jpg
|
| 414 |
+
003990_0.jpg 004636_1.jpg
|
| 415 |
+
003998_0.jpg 007405_1.jpg
|
| 416 |
+
004006_0.jpg 001725_1.jpg
|
| 417 |
+
004015_0.jpg 015785_1.jpg
|
| 418 |
+
004023_0.jpg 000488_1.jpg
|
| 419 |
+
004033_0.jpg 010583_1.jpg
|
| 420 |
+
004042_0.jpg 004580_1.jpg
|
| 421 |
+
004051_0.jpg 000028_1.jpg
|
| 422 |
+
004061_0.jpg 012531_1.jpg
|
| 423 |
+
004071_0.jpg 012838_1.jpg
|
| 424 |
+
004080_0.jpg 012006_1.jpg
|
| 425 |
+
004091_0.jpg 002769_1.jpg
|
| 426 |
+
004099_0.jpg 000320_1.jpg
|
| 427 |
+
004107_0.jpg 005317_1.jpg
|
| 428 |
+
004115_0.jpg 009949_1.jpg
|
| 429 |
+
004123_0.jpg 008196_1.jpg
|
| 430 |
+
004131_0.jpg 013199_1.jpg
|
| 431 |
+
004139_0.jpg 017814_1.jpg
|
| 432 |
+
004148_0.jpg 017555_1.jpg
|
| 433 |
+
004158_0.jpg 017130_1.jpg
|
| 434 |
+
004167_0.jpg 005388_1.jpg
|
| 435 |
+
004177_0.jpg 015133_1.jpg
|
| 436 |
+
004185_0.jpg 000501_1.jpg
|
| 437 |
+
004196_0.jpg 004158_1.jpg
|
| 438 |
+
004210_0.jpg 008663_1.jpg
|
| 439 |
+
004220_0.jpg 014332_1.jpg
|
| 440 |
+
004234_0.jpg 009766_1.jpg
|
| 441 |
+
004243_0.jpg 010454_1.jpg
|
| 442 |
+
004252_0.jpg 004553_1.jpg
|
| 443 |
+
004260_0.jpg 013899_1.jpg
|
| 444 |
+
004268_0.jpg 017474_1.jpg
|
| 445 |
+
004277_0.jpg 017545_1.jpg
|
| 446 |
+
004285_0.jpg 008110_1.jpg
|
| 447 |
+
004294_0.jpg 015560_1.jpg
|
| 448 |
+
004304_0.jpg 009689_1.jpg
|
| 449 |
+
004314_0.jpg 017896_1.jpg
|
| 450 |
+
004325_0.jpg 003600_1.jpg
|
| 451 |
+
004333_0.jpg 007579_1.jpg
|
| 452 |
+
004342_0.jpg 018460_1.jpg
|
| 453 |
+
004357_0.jpg 001559_1.jpg
|
| 454 |
+
004366_0.jpg 002812_1.jpg
|
| 455 |
+
004378_0.jpg 008367_1.jpg
|
| 456 |
+
004387_0.jpg 010244_1.jpg
|
| 457 |
+
004397_0.jpg 008672_1.jpg
|
| 458 |
+
004415_0.jpg 002000_1.jpg
|
| 459 |
+
004423_0.jpg 011034_1.jpg
|
| 460 |
+
004431_0.jpg 001181_1.jpg
|
| 461 |
+
004441_0.jpg 009545_1.jpg
|
| 462 |
+
004451_0.jpg 007789_1.jpg
|
| 463 |
+
004462_0.jpg 004015_1.jpg
|
| 464 |
+
004470_0.jpg 008900_1.jpg
|
| 465 |
+
004478_0.jpg 011015_1.jpg
|
| 466 |
+
004487_0.jpg 003349_1.jpg
|
| 467 |
+
004497_0.jpg 015209_1.jpg
|
| 468 |
+
004508_0.jpg 009709_1.jpg
|
| 469 |
+
004516_0.jpg 001974_1.jpg
|
| 470 |
+
004529_0.jpg 005995_1.jpg
|
| 471 |
+
004537_0.jpg 019429_1.jpg
|
| 472 |
+
004545_0.jpg 014396_1.jpg
|
| 473 |
+
004553_0.jpg 017400_1.jpg
|
| 474 |
+
004561_0.jpg 019174_1.jpg
|
| 475 |
+
004572_0.jpg 002180_1.jpg
|
| 476 |
+
004580_0.jpg 019252_1.jpg
|
| 477 |
+
004590_0.jpg 011833_1.jpg
|
| 478 |
+
004598_0.jpg 014939_1.jpg
|
| 479 |
+
004609_0.jpg 013698_1.jpg
|
| 480 |
+
004620_0.jpg 002464_1.jpg
|
| 481 |
+
004628_0.jpg 011825_1.jpg
|
| 482 |
+
004636_0.jpg 013806_1.jpg
|
| 483 |
+
004646_0.jpg 001109_1.jpg
|
| 484 |
+
004657_0.jpg 000258_1.jpg
|
| 485 |
+
004666_0.jpg 002628_1.jpg
|
| 486 |
+
004674_0.jpg 007732_1.jpg
|
| 487 |
+
004683_0.jpg 012330_1.jpg
|
| 488 |
+
004691_0.jpg 019287_1.jpg
|
| 489 |
+
004702_0.jpg 010869_1.jpg
|
| 490 |
+
004710_0.jpg 005022_1.jpg
|
| 491 |
+
004718_0.jpg 017496_1.jpg
|
| 492 |
+
004727_0.jpg 008771_1.jpg
|
| 493 |
+
004737_0.jpg 000248_1.jpg
|
| 494 |
+
004745_0.jpg 014591_1.jpg
|
| 495 |
+
004758_0.jpg 001715_1.jpg
|
| 496 |
+
004766_0.jpg 004628_1.jpg
|
| 497 |
+
004774_0.jpg 005120_1.jpg
|
| 498 |
+
004785_0.jpg 000445_1.jpg
|
| 499 |
+
004795_0.jpg 005262_1.jpg
|
| 500 |
+
004804_0.jpg 013907_1.jpg
|
| 501 |
+
004814_0.jpg 002268_1.jpg
|
| 502 |
+
004823_0.jpg 000183_1.jpg
|
| 503 |
+
004833_0.jpg 014014_1.jpg
|
| 504 |
+
004844_0.jpg 015497_1.jpg
|
| 505 |
+
004854_0.jpg 018047_1.jpg
|
| 506 |
+
004867_0.jpg 016777_1.jpg
|
| 507 |
+
004878_0.jpg 013338_1.jpg
|
| 508 |
+
004888_0.jpg 006429_1.jpg
|
| 509 |
+
004896_0.jpg 015803_1.jpg
|
| 510 |
+
004904_0.jpg 012072_1.jpg
|
| 511 |
+
004912_0.jpg 009605_1.jpg
|
| 512 |
+
004922_0.jpg 000934_1.jpg
|
| 513 |
+
004933_0.jpg 010381_1.jpg
|
| 514 |
+
004941_0.jpg 016533_1.jpg
|
| 515 |
+
004949_0.jpg 004451_1.jpg
|
| 516 |
+
004957_0.jpg 006959_1.jpg
|
| 517 |
+
004965_0.jpg 018532_1.jpg
|
| 518 |
+
004981_0.jpg 002820_1.jpg
|
| 519 |
+
004989_0.jpg 010261_1.jpg
|
| 520 |
+
004997_0.jpg 004933_1.jpg
|
| 521 |
+
005006_0.jpg 004415_1.jpg
|
| 522 |
+
005014_0.jpg 008891_1.jpg
|
| 523 |
+
005022_0.jpg 009780_1.jpg
|
| 524 |
+
005031_0.jpg 003218_1.jpg
|
| 525 |
+
005044_0.jpg 012944_1.jpg
|
| 526 |
+
005053_0.jpg 012127_1.jpg
|
| 527 |
+
005062_0.jpg 015767_1.jpg
|
| 528 |
+
005072_0.jpg 018826_1.jpg
|
| 529 |
+
005081_0.jpg 013410_1.jpg
|
| 530 |
+
005091_0.jpg 012404_1.jpg
|
| 531 |
+
005101_0.jpg 007304_1.jpg
|
| 532 |
+
005110_0.jpg 005349_1.jpg
|
| 533 |
+
005120_0.jpg 003842_1.jpg
|
| 534 |
+
005131_0.jpg 007473_1.jpg
|
| 535 |
+
005145_0.jpg 003693_1.jpg
|
| 536 |
+
005153_0.jpg 006658_1.jpg
|
| 537 |
+
005166_0.jpg 007446_1.jpg
|
| 538 |
+
005175_0.jpg 007434_1.jpg
|
| 539 |
+
005186_0.jpg 013948_1.jpg
|
| 540 |
+
005195_0.jpg 002561_1.jpg
|
| 541 |
+
005203_0.jpg 016888_1.jpg
|
| 542 |
+
005213_0.jpg 015264_1.jpg
|
| 543 |
+
005222_0.jpg 007065_1.jpg
|
| 544 |
+
005231_0.jpg 002431_1.jpg
|
| 545 |
+
005241_0.jpg 006789_1.jpg
|
| 546 |
+
005251_0.jpg 014314_1.jpg
|
| 547 |
+
005262_0.jpg 018192_1.jpg
|
| 548 |
+
005271_0.jpg 011954_1.jpg
|
| 549 |
+
005285_0.jpg 006285_1.jpg
|
| 550 |
+
005298_0.jpg 015280_1.jpg
|
| 551 |
+
005306_0.jpg 018681_1.jpg
|
| 552 |
+
005317_0.jpg 011436_1.jpg
|
| 553 |
+
005328_0.jpg 000997_1.jpg
|
| 554 |
+
005336_0.jpg 000404_1.jpg
|
| 555 |
+
005349_0.jpg 006717_1.jpg
|
| 556 |
+
005360_0.jpg 010967_1.jpg
|
| 557 |
+
005368_0.jpg 005379_1.jpg
|
| 558 |
+
005379_0.jpg 016962_1.jpg
|
| 559 |
+
005388_0.jpg 006137_1.jpg
|
| 560 |
+
005396_0.jpg 012545_1.jpg
|
| 561 |
+
005404_0.jpg 013572_1.jpg
|
| 562 |
+
005413_0.jpg 005413_1.jpg
|
| 563 |
+
005422_0.jpg 018470_1.jpg
|
| 564 |
+
005430_0.jpg 004537_1.jpg
|
| 565 |
+
005440_0.jpg 015825_1.jpg
|
| 566 |
+
005449_0.jpg 017904_1.jpg
|
| 567 |
+
005457_0.jpg 017315_1.jpg
|
| 568 |
+
005470_0.jpg 010599_1.jpg
|
| 569 |
+
005480_0.jpg 000988_1.jpg
|
| 570 |
+
005489_0.jpg 007518_1.jpg
|
| 571 |
+
005501_0.jpg 008784_1.jpg
|
| 572 |
+
005510_0.jpg 004294_1.jpg
|
| 573 |
+
005525_0.jpg 006339_1.jpg
|
| 574 |
+
005533_0.jpg 016662_1.jpg
|
| 575 |
+
005542_0.jpg 007345_1.jpg
|
| 576 |
+
005552_0.jpg 012505_1.jpg
|
| 577 |
+
005562_0.jpg 007864_1.jpg
|
| 578 |
+
005570_0.jpg 010481_1.jpg
|
| 579 |
+
005578_0.jpg 019454_1.jpg
|
| 580 |
+
005586_0.jpg 019494_1.jpg
|
| 581 |
+
005594_0.jpg 006016_1.jpg
|
| 582 |
+
005603_0.jpg 017667_1.jpg
|
| 583 |
+
005614_0.jpg 019110_1.jpg
|
| 584 |
+
005622_0.jpg 010947_1.jpg
|
| 585 |
+
005631_0.jpg 019384_1.jpg
|
| 586 |
+
005648_0.jpg 018946_1.jpg
|
| 587 |
+
005657_0.jpg 003443_1.jpg
|
| 588 |
+
005666_0.jpg 016281_1.jpg
|
| 589 |
+
005675_0.jpg 001301_1.jpg
|
| 590 |
+
005683_0.jpg 012099_1.jpg
|
| 591 |
+
005691_0.jpg 011355_1.jpg
|
| 592 |
+
005702_0.jpg 001798_1.jpg
|
| 593 |
+
005711_0.jpg 010096_1.jpg
|
| 594 |
+
005720_0.jpg 009758_1.jpg
|
| 595 |
+
005728_0.jpg 014114_1.jpg
|
| 596 |
+
005737_0.jpg 012063_1.jpg
|
| 597 |
+
005747_0.jpg 004529_1.jpg
|
| 598 |
+
005755_0.jpg 014370_1.jpg
|
| 599 |
+
005763_0.jpg 007834_1.jpg
|
| 600 |
+
005771_0.jpg 018069_1.jpg
|
| 601 |
+
005784_0.jpg 018700_1.jpg
|
| 602 |
+
005797_0.jpg 015881_1.jpg
|
| 603 |
+
005809_0.jpg 010371_1.jpg
|
| 604 |
+
005820_0.jpg 016899_1.jpg
|
| 605 |
+
005828_0.jpg 002049_1.jpg
|
| 606 |
+
005837_0.jpg 016183_1.jpg
|
| 607 |
+
005846_0.jpg 008006_1.jpg
|
| 608 |
+
005857_0.jpg 010628_1.jpg
|
| 609 |
+
005866_0.jpg 013469_1.jpg
|
| 610 |
+
005877_0.jpg 010021_1.jpg
|
| 611 |
+
005887_0.jpg 013593_1.jpg
|
| 612 |
+
005898_0.jpg 000057_1.jpg
|
| 613 |
+
005908_0.jpg 000867_1.jpg
|
| 614 |
+
005920_0.jpg 013327_1.jpg
|
| 615 |
+
005929_0.jpg 011401_1.jpg
|
| 616 |
+
005940_0.jpg 000593_1.jpg
|
| 617 |
+
005952_0.jpg 014201_1.jpg
|
| 618 |
+
005963_0.jpg 009922_1.jpg
|
| 619 |
+
005975_0.jpg 010431_1.jpg
|
| 620 |
+
005984_0.jpg 007710_1.jpg
|
| 621 |
+
005995_0.jpg 001083_1.jpg
|
| 622 |
+
006004_0.jpg 018954_1.jpg
|
| 623 |
+
006016_0.jpg 010691_1.jpg
|
| 624 |
+
006026_0.jpg 003641_1.jpg
|
| 625 |
+
006036_0.jpg 000750_1.jpg
|
| 626 |
+
006045_0.jpg 008681_1.jpg
|
| 627 |
+
006057_0.jpg 010910_1.jpg
|
| 628 |
+
006065_0.jpg 011415_1.jpg
|
| 629 |
+
006073_0.jpg 010840_1.jpg
|
| 630 |
+
006081_0.jpg 008908_1.jpg
|
| 631 |
+
006090_0.jpg 007997_1.jpg
|
| 632 |
+
006099_0.jpg 015900_1.jpg
|
| 633 |
+
006110_0.jpg 009034_1.jpg
|
| 634 |
+
006118_0.jpg 015861_1.jpg
|
| 635 |
+
006129_0.jpg 006165_1.jpg
|
| 636 |
+
006137_0.jpg 008379_1.jpg
|
| 637 |
+
006145_0.jpg 016379_1.jpg
|
| 638 |
+
006155_0.jpg 016878_1.jpg
|
| 639 |
+
006165_0.jpg 010040_1.jpg
|
| 640 |
+
006173_0.jpg 001776_1.jpg
|
| 641 |
+
006186_0.jpg 007891_1.jpg
|
| 642 |
+
006194_0.jpg 015969_1.jpg
|
| 643 |
+
006203_0.jpg 005820_1.jpg
|
| 644 |
+
006213_0.jpg 014900_1.jpg
|
| 645 |
+
006224_0.jpg 016748_1.jpg
|
| 646 |
+
006232_0.jpg 010636_1.jpg
|
| 647 |
+
006241_0.jpg 018327_1.jpg
|
| 648 |
+
006250_0.jpg 013097_1.jpg
|
| 649 |
+
006260_0.jpg 007103_1.jpg
|
| 650 |
+
006268_0.jpg 007073_1.jpg
|
| 651 |
+
006276_0.jpg 011128_1.jpg
|
| 652 |
+
006285_0.jpg 019319_1.jpg
|
| 653 |
+
006296_0.jpg 002952_1.jpg
|
| 654 |
+
006304_0.jpg 002371_1.jpg
|
| 655 |
+
006313_0.jpg 014553_1.jpg
|
| 656 |
+
006321_0.jpg 014489_1.jpg
|
| 657 |
+
006329_0.jpg 005866_1.jpg
|
| 658 |
+
006339_0.jpg 019368_1.jpg
|
| 659 |
+
006347_0.jpg 006402_1.jpg
|
| 660 |
+
006358_0.jpg 002422_1.jpg
|
| 661 |
+
006371_0.jpg 011842_1.jpg
|
| 662 |
+
006381_0.jpg 019446_1.jpg
|
| 663 |
+
006393_0.jpg 012015_1.jpg
|
| 664 |
+
006402_0.jpg 013382_1.jpg
|
| 665 |
+
006410_0.jpg 000038_1.jpg
|
| 666 |
+
006419_0.jpg 014959_1.jpg
|
| 667 |
+
006429_0.jpg 018837_1.jpg
|
| 668 |
+
006440_0.jpg 017750_1.jpg
|
| 669 |
+
006452_0.jpg 003259_1.jpg
|
| 670 |
+
006462_0.jpg 018009_1.jpg
|
| 671 |
+
006470_0.jpg 013309_1.jpg
|
| 672 |
+
006478_0.jpg 014712_1.jpg
|
| 673 |
+
006486_0.jpg 000228_1.jpg
|
| 674 |
+
006494_0.jpg 005614_1.jpg
|
| 675 |
+
006502_0.jpg 010535_1.jpg
|
| 676 |
+
006512_0.jpg 007741_1.jpg
|
| 677 |
+
006523_0.jpg 015990_1.jpg
|
| 678 |
+
006535_0.jpg 011231_1.jpg
|
| 679 |
+
006545_0.jpg 016584_1.jpg
|
| 680 |
+
006555_0.jpg 015105_1.jpg
|
| 681 |
+
006563_0.jpg 001494_1.jpg
|
| 682 |
+
006571_0.jpg 007376_1.jpg
|
| 683 |
+
006581_0.jpg 003404_1.jpg
|
| 684 |
+
006589_0.jpg 008346_1.jpg
|
| 685 |
+
006597_0.jpg 008014_1.jpg
|
| 686 |
+
006606_0.jpg 002511_1.jpg
|
| 687 |
+
006620_0.jpg 017196_1.jpg
|
| 688 |
+
006628_0.jpg 009084_1.jpg
|
| 689 |
+
006640_0.jpg 014086_1.jpg
|
| 690 |
+
006649_0.jpg 004508_1.jpg
|
| 691 |
+
006658_0.jpg 014131_1.jpg
|
| 692 |
+
006670_0.jpg 000979_1.jpg
|
| 693 |
+
006678_0.jpg 002523_1.jpg
|
| 694 |
+
006688_0.jpg 011988_1.jpg
|
| 695 |
+
006697_0.jpg 018200_1.jpg
|
| 696 |
+
006709_0.jpg 017840_1.jpg
|
| 697 |
+
006717_0.jpg 018524_1.jpg
|
| 698 |
+
006728_0.jpg 013418_1.jpg
|
| 699 |
+
006738_0.jpg 011457_1.jpg
|
| 700 |
+
006748_0.jpg 016031_1.jpg
|
| 701 |
+
006757_0.jpg 001520_1.jpg
|
| 702 |
+
006768_0.jpg 008172_1.jpg
|
| 703 |
+
006776_0.jpg 000651_1.jpg
|
| 704 |
+
006789_0.jpg 017110_1.jpg
|
| 705 |
+
006799_0.jpg 001292_1.jpg
|
| 706 |
+
006808_0.jpg 002128_1.jpg
|
| 707 |
+
006817_0.jpg 004357_1.jpg
|
| 708 |
+
006825_0.jpg 012245_1.jpg
|
| 709 |
+
006834_0.jpg 014324_1.jpg
|
| 710 |
+
006842_0.jpg 009635_1.jpg
|
| 711 |
+
006850_0.jpg 012166_1.jpg
|
| 712 |
+
006859_0.jpg 003086_1.jpg
|
| 713 |
+
006868_0.jpg 010859_1.jpg
|
| 714 |
+
006881_0.jpg 004646_1.jpg
|
| 715 |
+
006889_0.jpg 014507_1.jpg
|
| 716 |
+
006897_0.jpg 012849_1.jpg
|
| 717 |
+
006908_0.jpg 006535_1.jpg
|
| 718 |
+
006916_0.jpg 000696_1.jpg
|
| 719 |
+
006928_0.jpg 017290_1.jpg
|
| 720 |
+
006937_0.jpg 008276_1.jpg
|
| 721 |
+
006945_0.jpg 009197_1.jpg
|
| 722 |
+
006959_0.jpg 013706_1.jpg
|
| 723 |
+
006968_0.jpg 015908_1.jpg
|
| 724 |
+
006976_0.jpg 018929_1.jpg
|
| 725 |
+
006984_0.jpg 005631_1.jpg
|
| 726 |
+
006992_0.jpg 000837_1.jpg
|
| 727 |
+
007003_0.jpg 010168_1.jpg
|
| 728 |
+
007013_0.jpg 006984_1.jpg
|
| 729 |
+
007021_0.jpg 006321_1.jpg
|
| 730 |
+
007029_0.jpg 007808_1.jpg
|
| 731 |
+
007037_0.jpg 011278_1.jpg
|
| 732 |
+
007045_0.jpg 008496_1.jpg
|
| 733 |
+
007056_0.jpg 016943_1.jpg
|
| 734 |
+
007065_0.jpg 015381_1.jpg
|
| 735 |
+
007073_0.jpg 007013_1.jpg
|
| 736 |
+
007086_0.jpg 017264_1.jpg
|
| 737 |
+
007094_0.jpg 004210_1.jpg
|
| 738 |
+
007103_0.jpg 011585_1.jpg
|
| 739 |
+
007113_0.jpg 016992_1.jpg
|
| 740 |
+
007121_0.jpg 009263_1.jpg
|
| 741 |
+
007129_0.jpg 000220_1.jpg
|
| 742 |
+
007138_0.jpg 017428_1.jpg
|
| 743 |
+
007149_0.jpg 010816_1.jpg
|
| 744 |
+
007159_0.jpg 018227_1.jpg
|
| 745 |
+
007168_0.jpg 002589_1.jpg
|
| 746 |
+
007180_0.jpg 011300_1.jpg
|
| 747 |
+
007188_0.jpg 000943_1.jpg
|
| 748 |
+
007199_0.jpg 016358_1.jpg
|
| 749 |
+
007212_0.jpg 007094_1.jpg
|
| 750 |
+
007221_0.jpg 002962_1.jpg
|
| 751 |
+
007232_0.jpg 005570_1.jpg
|
| 752 |
+
007243_0.jpg 004888_1.jpg
|
| 753 |
+
007252_0.jpg 003803_1.jpg
|
| 754 |
+
007261_0.jpg 006850_1.jpg
|
| 755 |
+
007269_0.jpg 017639_1.jpg
|
| 756 |
+
007278_0.jpg 001369_1.jpg
|
| 757 |
+
007286_0.jpg 009131_1.jpg
|
| 758 |
+
007294_0.jpg 004774_1.jpg
|
| 759 |
+
007304_0.jpg 003395_1.jpg
|
| 760 |
+
007313_0.jpg 014184_1.jpg
|
| 761 |
+
007324_0.jpg 008847_1.jpg
|
| 762 |
+
007336_0.jpg 001537_1.jpg
|
| 763 |
+
007345_0.jpg 015979_1.jpg
|
| 764 |
+
007357_0.jpg 019561_1.jpg
|
| 765 |
+
007365_0.jpg 005828_1.jpg
|
| 766 |
+
007376_0.jpg 010078_1.jpg
|
| 767 |
+
007388_0.jpg 006945_1.jpg
|
| 768 |
+
007397_0.jpg 012236_1.jpg
|
| 769 |
+
007405_0.jpg 015732_1.jpg
|
| 770 |
+
007415_0.jpg 009426_1.jpg
|
| 771 |
+
007423_0.jpg 012879_1.jpg
|
| 772 |
+
007434_0.jpg 012597_1.jpg
|
| 773 |
+
007446_0.jpg 015317_1.jpg
|
| 774 |
+
007455_0.jpg 009274_1.jpg
|
| 775 |
+
007463_0.jpg 003016_1.jpg
|
| 776 |
+
007473_0.jpg 013725_1.jpg
|
| 777 |
+
007484_0.jpg 003501_1.jpg
|
| 778 |
+
007495_0.jpg 005908_1.jpg
|
| 779 |
+
007505_0.jpg 011970_1.jpg
|
| 780 |
+
007518_0.jpg 005784_1.jpg
|
| 781 |
+
007526_0.jpg 015550_1.jpg
|
| 782 |
+
007536_0.jpg 015853_1.jpg
|
| 783 |
+
007549_0.jpg 015420_1.jpg
|
| 784 |
+
007561_0.jpg 013036_1.jpg
|
| 785 |
+
007570_0.jpg 005306_1.jpg
|
| 786 |
+
007579_0.jpg 006628_1.jpg
|
| 787 |
+
007592_0.jpg 001623_1.jpg
|
| 788 |
+
007601_0.jpg 014463_1.jpg
|
| 789 |
+
007609_0.jpg 009525_1.jpg
|
| 790 |
+
007617_0.jpg 015085_1.jpg
|
| 791 |
+
007628_0.jpg 000074_1.jpg
|
| 792 |
+
007639_0.jpg 014477_1.jpg
|
| 793 |
+
007648_0.jpg 004099_1.jpg
|
| 794 |
+
007656_0.jpg 008138_1.jpg
|
| 795 |
+
007664_0.jpg 002217_1.jpg
|
| 796 |
+
007672_0.jpg 016550_1.jpg
|
| 797 |
+
007681_0.jpg 004833_1.jpg
|
| 798 |
+
007692_0.jpg 003852_1.jpg
|
| 799 |
+
007702_0.jpg 015291_1.jpg
|
| 800 |
+
007710_0.jpg 011050_1.jpg
|
| 801 |
+
007719_0.jpg 005963_1.jpg
|
| 802 |
+
007732_0.jpg 008715_1.jpg
|
| 803 |
+
007741_0.jpg 019302_1.jpg
|
| 804 |
+
007750_0.jpg 018690_1.jpg
|
| 805 |
+
007762_0.jpg 006597_1.jpg
|
| 806 |
+
007772_0.jpg 002691_1.jpg
|
| 807 |
+
007781_0.jpg 002942_1.jpg
|
| 808 |
+
007789_0.jpg 017370_1.jpg
|
| 809 |
+
007797_0.jpg 006916_1.jpg
|
| 810 |
+
007808_0.jpg 014844_1.jpg
|
| 811 |
+
007817_0.jpg 015916_1.jpg
|
| 812 |
+
007826_0.jpg 004766_1.jpg
|
| 813 |
+
007834_0.jpg 011447_1.jpg
|
| 814 |
+
007848_0.jpg 008051_1.jpg
|
| 815 |
+
007856_0.jpg 000129_1.jpg
|
| 816 |
+
007864_0.jpg 001017_1.jpg
|
| 817 |
+
007874_0.jpg 004033_1.jpg
|
| 818 |
+
007882_0.jpg 003890_1.jpg
|
| 819 |
+
007891_0.jpg 008696_1.jpg
|
| 820 |
+
007899_0.jpg 002317_1.jpg
|
| 821 |
+
007914_0.jpg 019130_1.jpg
|
| 822 |
+
007923_0.jpg 000417_1.jpg
|
| 823 |
+
007932_0.jpg 011670_1.jpg
|
| 824 |
+
007940_0.jpg 004441_1.jpg
|
| 825 |
+
007949_0.jpg 018018_1.jpg
|
| 826 |
+
007957_0.jpg 002599_1.jpg
|
| 827 |
+
007966_0.jpg 017761_1.jpg
|
| 828 |
+
007974_0.jpg 000523_1.jpg
|
| 829 |
+
007986_0.jpg 011560_1.jpg
|
| 830 |
+
007997_0.jpg 007592_1.jpg
|
| 831 |
+
008006_0.jpg 004718_1.jpg
|
| 832 |
+
008014_0.jpg 015006_1.jpg
|
| 833 |
+
008023_0.jpg 000803_1.jpg
|
| 834 |
+
008032_0.jpg 003167_1.jpg
|
| 835 |
+
008041_0.jpg 006992_1.jpg
|
| 836 |
+
008051_0.jpg 006697_1.jpg
|
| 837 |
+
008062_0.jpg 009008_1.jpg
|
| 838 |
+
008071_0.jpg 014805_1.jpg
|
| 839 |
+
008080_0.jpg 003578_1.jpg
|
| 840 |
+
008092_0.jpg 007113_1.jpg
|
| 841 |
+
008101_0.jpg 011596_1.jpg
|
| 842 |
+
008110_0.jpg 007628_1.jpg
|
| 843 |
+
008118_0.jpg 005231_1.jpg
|
| 844 |
+
008126_0.jpg 014816_1.jpg
|
| 845 |
+
008138_0.jpg 000266_1.jpg
|
| 846 |
+
008151_0.jpg 011392_1.jpg
|
| 847 |
+
008160_0.jpg 013127_1.jpg
|
| 848 |
+
008172_0.jpg 015026_1.jpg
|
| 849 |
+
008180_0.jpg 009482_1.jpg
|
| 850 |
+
008188_0.jpg 008938_1.jpg
|
| 851 |
+
008196_0.jpg 004737_1.jpg
|
| 852 |
+
008206_0.jpg 002865_1.jpg
|
| 853 |
+
008214_0.jpg 018902_1.jpg
|
| 854 |
+
008224_0.jpg 012626_1.jpg
|
| 855 |
+
008233_0.jpg 002620_1.jpg
|
| 856 |
+
008241_0.jpg 007826_1.jpg
|
| 857 |
+
008250_0.jpg 002486_1.jpg
|
| 858 |
+
008258_0.jpg 003158_1.jpg
|
| 859 |
+
008266_0.jpg 015571_1.jpg
|
| 860 |
+
008276_0.jpg 009418_1.jpg
|
| 861 |
+
008285_0.jpg 004965_1.jpg
|
| 862 |
+
008295_0.jpg 017678_1.jpg
|
| 863 |
+
008307_0.jpg 001428_1.jpg
|
| 864 |
+
008317_0.jpg 011577_1.jpg
|
| 865 |
+
008326_0.jpg 006881_1.jpg
|
| 866 |
+
008334_0.jpg 014863_1.jpg
|
| 867 |
+
008346_0.jpg 014341_1.jpg
|
| 868 |
+
008354_0.jpg 007914_1.jpg
|
| 869 |
+
008367_0.jpg 004904_1.jpg
|
| 870 |
+
008379_0.jpg 004957_1.jpg
|
| 871 |
+
008389_0.jpg 004878_1.jpg
|
| 872 |
+
008397_0.jpg 016786_1.jpg
|
| 873 |
+
008406_0.jpg 015428_1.jpg
|
| 874 |
+
008420_0.jpg 001448_1.jpg
|
| 875 |
+
008429_0.jpg 005747_1.jpg
|
| 876 |
+
008443_0.jpg 011087_1.jpg
|
| 877 |
+
008451_0.jpg 000619_1.jpg
|
| 878 |
+
008462_0.jpg 008224_1.jpg
|
| 879 |
+
008471_0.jpg 012743_1.jpg
|
| 880 |
+
008479_0.jpg 006129_1.jpg
|
| 881 |
+
008487_0.jpg 001378_1.jpg
|
| 882 |
+
008496_0.jpg 015141_1.jpg
|
| 883 |
+
008506_0.jpg 006110_1.jpg
|
| 884 |
+
008515_0.jpg 017630_1.jpg
|
| 885 |
+
008523_0.jpg 002236_1.jpg
|
| 886 |
+
008533_0.jpg 017457_1.jpg
|
| 887 |
+
008542_0.jpg 010620_1.jpg
|
| 888 |
+
008551_0.jpg 016799_1.jpg
|
| 889 |
+
008560_0.jpg 016317_1.jpg
|
| 890 |
+
008570_0.jpg 007648_1.jpg
|
| 891 |
+
008580_0.jpg 018219_1.jpg
|
| 892 |
+
008590_0.jpg 003179_1.jpg
|
| 893 |
+
008598_0.jpg 010527_1.jpg
|
| 894 |
+
008608_0.jpg 016716_1.jpg
|
| 895 |
+
008616_0.jpg 010206_1.jpg
|
| 896 |
+
008624_0.jpg 007664_1.jpg
|
| 897 |
+
008632_0.jpg 019411_1.jpg
|
| 898 |
+
008645_0.jpg 014434_1.jpg
|
| 899 |
+
008653_0.jpg 018710_1.jpg
|
| 900 |
+
008663_0.jpg 007397_1.jpg
|
| 901 |
+
008672_0.jpg 010662_1.jpg
|
| 902 |
+
008681_0.jpg 005552_1.jpg
|
| 903 |
+
008696_0.jpg 014302_1.jpg
|
| 904 |
+
008706_0.jpg 011097_1.jpg
|
| 905 |
+
008715_0.jpg 001437_1.jpg
|
| 906 |
+
008725_0.jpg 004304_1.jpg
|
| 907 |
+
008736_0.jpg 012734_1.jpg
|
| 908 |
+
008744_0.jpg 018796_1.jpg
|
| 909 |
+
008753_0.jpg 003472_1.jpg
|
| 910 |
+
008763_0.jpg 007856_1.jpg
|
| 911 |
+
008771_0.jpg 005186_1.jpg
|
| 912 |
+
008784_0.jpg 006329_1.jpg
|
| 913 |
+
008793_0.jpg 014240_1.jpg
|
| 914 |
+
008804_0.jpg 013490_1.jpg
|
| 915 |
+
008813_0.jpg 011347_1.jpg
|
| 916 |
+
008822_0.jpg 002553_1.jpg
|
| 917 |
+
008830_0.jpg 017118_1.jpg
|
| 918 |
+
008839_0.jpg 013989_1.jpg
|
| 919 |
+
008847_0.jpg 012754_1.jpg
|
| 920 |
+
008855_0.jpg 005241_1.jpg
|
| 921 |
+
008863_0.jpg 018848_1.jpg
|
| 922 |
+
008871_0.jpg 006738_1.jpg
|
| 923 |
+
008881_0.jpg 002739_1.jpg
|
| 924 |
+
008891_0.jpg 015816_1.jpg
|
| 925 |
+
008900_0.jpg 019376_1.jpg
|
| 926 |
+
008908_0.jpg 009975_1.jpg
|
| 927 |
+
008919_0.jpg 011798_1.jpg
|
| 928 |
+
008928_0.jpg 001337_1.jpg
|
| 929 |
+
008938_0.jpg 009074_1.jpg
|
| 930 |
+
008949_0.jpg 002039_1.jpg
|
| 931 |
+
008959_0.jpg 002681_1.jpg
|
| 932 |
+
008967_0.jpg 012033_1.jpg
|
| 933 |
+
008976_0.jpg 006440_1.jpg
|
| 934 |
+
008986_0.jpg 015524_1.jpg
|
| 935 |
+
008997_0.jpg 003226_1.jpg
|
| 936 |
+
009008_0.jpg 004691_1.jpg
|
| 937 |
+
009016_0.jpg 013855_1.jpg
|
| 938 |
+
009024_0.jpg 014379_1.jpg
|
| 939 |
+
009034_0.jpg 012385_1.jpg
|
| 940 |
+
009042_0.jpg 000685_1.jpg
|
| 941 |
+
009054_0.jpg 015403_1.jpg
|
| 942 |
+
009064_0.jpg 017449_1.jpg
|
| 943 |
+
009074_0.jpg 018112_1.jpg
|
| 944 |
+
009084_0.jpg 014220_1.jpg
|
| 945 |
+
009094_0.jpg 014076_1.jpg
|
| 946 |
+
009106_0.jpg 016039_1.jpg
|
| 947 |
+
009114_0.jpg 010653_1.jpg
|
| 948 |
+
009123_0.jpg 001756_1.jpg
|
| 949 |
+
009131_0.jpg 003953_1.jpg
|
| 950 |
+
009141_0.jpg 012917_1.jpg
|
| 951 |
+
009149_0.jpg 015476_1.jpg
|
| 952 |
+
009159_0.jpg 010762_1.jpg
|
| 953 |
+
009169_0.jpg 017648_1.jpg
|
| 954 |
+
009178_0.jpg 008919_1.jpg
|
| 955 |
+
009189_0.jpg 007463_1.jpg
|
| 956 |
+
009197_0.jpg 006065_1.jpg
|
| 957 |
+
009205_0.jpg 014537_1.jpg
|
| 958 |
+
009215_0.jpg 007252_1.jpg
|
| 959 |
+
009228_0.jpg 007212_1.jpg
|
| 960 |
+
009236_0.jpg 017622_1.jpg
|
| 961 |
+
009246_0.jpg 007232_1.jpg
|
| 962 |
+
009254_0.jpg 010918_1.jpg
|
| 963 |
+
009263_0.jpg 016094_1.jpg
|
| 964 |
+
009274_0.jpg 007221_1.jpg
|
| 965 |
+
009282_0.jpg 005691_1.jpg
|
| 966 |
+
009291_0.jpg 002345_1.jpg
|
| 967 |
+
009300_0.jpg 009300_1.jpg
|
| 968 |
+
009312_0.jpg 014629_1.jpg
|
| 969 |
+
009323_0.jpg 010133_1.jpg
|
| 970 |
+
009332_0.jpg 016697_1.jpg
|
| 971 |
+
009342_0.jpg 016262_1.jpg
|
| 972 |
+
009356_0.jpg 011568_1.jpg
|
| 973 |
+
009365_0.jpg 003115_1.jpg
|
| 974 |
+
009374_0.jpg 008542_1.jpg
|
| 975 |
+
009382_0.jpg 010789_1.jpg
|
| 976 |
+
009390_0.jpg 013743_1.jpg
|
| 977 |
+
009399_0.jpg 009374_1.jpg
|
| 978 |
+
009409_0.jpg 011106_1.jpg
|
| 979 |
+
009418_0.jpg 013620_1.jpg
|
| 980 |
+
009426_0.jpg 006817_1.jpg
|
| 981 |
+
009435_0.jpg 012702_1.jpg
|
| 982 |
+
009446_0.jpg 002575_1.jpg
|
| 983 |
+
009454_0.jpg 017730_1.jpg
|
| 984 |
+
009462_0.jpg 016831_1.jpg
|
| 985 |
+
009474_0.jpg 006194_1.jpg
|
| 986 |
+
009482_0.jpg 007086_1.jpg
|
| 987 |
+
009496_0.jpg 001064_1.jpg
|
| 988 |
+
009505_0.jpg 011004_1.jpg
|
| 989 |
+
009515_0.jpg 014968_1.jpg
|
| 990 |
+
009525_0.jpg 002259_1.jpg
|
| 991 |
+
009537_0.jpg 003545_1.jpg
|
| 992 |
+
009545_0.jpg 002147_1.jpg
|
| 993 |
+
009561_0.jpg 003833_1.jpg
|
| 994 |
+
009571_0.jpg 007966_1.jpg
|
| 995 |
+
009586_0.jpg 017877_1.jpg
|
| 996 |
+
009595_0.jpg 007003_1.jpg
|
| 997 |
+
009605_0.jpg 016220_1.jpg
|
| 998 |
+
009619_0.jpg 017306_1.jpg
|
| 999 |
+
009627_0.jpg 010644_1.jpg
|
| 1000 |
+
009635_0.jpg 008295_1.jpg
|
| 1001 |
+
009643_0.jpg 018318_1.jpg
|
| 1002 |
+
009651_0.jpg 013173_1.jpg
|
| 1003 |
+
009660_0.jpg 010445_1.jpg
|
| 1004 |
+
009668_0.jpg 002068_1.jpg
|
| 1005 |
+
009679_0.jpg 003187_1.jpg
|
| 1006 |
+
009689_0.jpg 011058_1.jpg
|
| 1007 |
+
009699_0.jpg 005657_1.jpg
|
| 1008 |
+
009709_0.jpg 009882_1.jpg
|
| 1009 |
+
009722_0.jpg 009228_1.jpg
|
| 1010 |
+
009730_0.jpg 015794_1.jpg
|
| 1011 |
+
009741_0.jpg 009399_1.jpg
|
| 1012 |
+
009758_0.jpg 013555_1.jpg
|
| 1013 |
+
009766_0.jpg 013265_1.jpg
|
| 1014 |
+
009780_0.jpg 013863_1.jpg
|
| 1015 |
+
009790_0.jpg 001283_1.jpg
|
| 1016 |
+
009799_0.jpg 018755_1.jpg
|
| 1017 |
+
009809_0.jpg 006393_1.jpg
|
| 1018 |
+
009822_0.jpg 009903_1.jpg
|
| 1019 |
+
009832_0.jpg 004148_1.jpg
|
| 1020 |
+
009843_0.jpg 018561_1.jpg
|
| 1021 |
+
009852_0.jpg 018059_1.jpg
|
| 1022 |
+
009860_0.jpg 010575_1.jpg
|
| 1023 |
+
009872_0.jpg 008266_1.jpg
|
| 1024 |
+
009882_0.jpg 015615_1.jpg
|
| 1025 |
+
009894_0.jpg 006250_1.jpg
|
| 1026 |
+
009903_0.jpg 014232_1.jpg
|
| 1027 |
+
009912_0.jpg 015707_1.jpg
|
| 1028 |
+
009922_0.jpg 016812_1.jpg
|
| 1029 |
+
009932_0.jpg 007672_1.jpg
|
| 1030 |
+
009941_0.jpg 012785_1.jpg
|
| 1031 |
+
009949_0.jpg 000924_1.jpg
|
| 1032 |
+
009959_0.jpg 009016_1.jpg
|
| 1033 |
+
009967_0.jpg 008976_1.jpg
|
| 1034 |
+
009975_0.jpg 017688_1.jpg
|
| 1035 |
+
009984_0.jpg 016426_1.jpg
|
| 1036 |
+
009995_0.jpg 003376_1.jpg
|
| 1037 |
+
010003_0.jpg 015637_1.jpg
|
| 1038 |
+
010011_0.jpg 014498_1.jpg
|
| 1039 |
+
010021_0.jpg 018236_1.jpg
|
| 1040 |
+
010031_0.jpg 016112_1.jpg
|
| 1041 |
+
010040_0.jpg 001957_1.jpg
|
| 1042 |
+
010049_0.jpg 015181_1.jpg
|
| 1043 |
+
010057_0.jpg 017860_1.jpg
|
| 1044 |
+
010067_0.jpg 015173_1.jpg
|
| 1045 |
+
010078_0.jpg 008706_1.jpg
|
| 1046 |
+
010088_0.jpg 009323_1.jpg
|
| 1047 |
+
010096_0.jpg 019096_1.jpg
|
| 1048 |
+
010105_0.jpg 001983_1.jpg
|
| 1049 |
+
010115_0.jpg 013165_1.jpg
|
| 1050 |
+
010125_0.jpg 001947_1.jpg
|
| 1051 |
+
010133_0.jpg 004785_1.jpg
|
| 1052 |
+
010143_0.jpg 010225_1.jpg
|
| 1053 |
+
010152_0.jpg 000610_1.jpg
|
| 1054 |
+
010160_0.jpg 004023_1.jpg
|
| 1055 |
+
010168_0.jpg 019001_1.jpg
|
| 1056 |
+
010177_0.jpg 006478_1.jpg
|
| 1057 |
+
010185_0.jpg 007336_1.jpg
|
| 1058 |
+
010195_0.jpg 017831_1.jpg
|
| 1059 |
+
010206_0.jpg 003712_1.jpg
|
| 1060 |
+
010215_0.jpg 015036_1.jpg
|
| 1061 |
+
010225_0.jpg 003972_1.jpg
|
| 1062 |
+
010234_0.jpg 001891_1.jpg
|
| 1063 |
+
010244_0.jpg 001387_1.jpg
|
| 1064 |
+
010253_0.jpg 014736_1.jpg
|
| 1065 |
+
010261_0.jpg 013923_1.jpg
|
| 1066 |
+
010270_0.jpg 006728_1.jpg
|
| 1067 |
+
010281_0.jpg 004896_1.jpg
|
| 1068 |
+
010289_0.jpg 011076_1.jpg
|
| 1069 |
+
010300_0.jpg 012303_1.jpg
|
| 1070 |
+
010308_0.jpg 001092_1.jpg
|
| 1071 |
+
010318_0.jpg 012089_1.jpg
|
| 1072 |
+
010329_0.jpg 006452_1.jpg
|
| 1073 |
+
010337_0.jpg 018263_1.jpg
|
| 1074 |
+
010346_0.jpg 016191_1.jpg
|
| 1075 |
+
010357_0.jpg 017145_1.jpg
|
| 1076 |
+
010371_0.jpg 010515_1.jpg
|
| 1077 |
+
010381_0.jpg 006709_1.jpg
|
| 1078 |
+
010392_0.jpg 013319_1.jpg
|
| 1079 |
+
010404_0.jpg 000659_1.jpg
|
| 1080 |
+
010415_0.jpg 016562_1.jpg
|
| 1081 |
+
010431_0.jpg 016254_1.jpg
|
| 1082 |
+
010445_0.jpg 014744_1.jpg
|
| 1083 |
+
010454_0.jpg 017722_1.jpg
|
| 1084 |
+
010463_0.jpg 003795_1.jpg
|
| 1085 |
+
010473_0.jpg 013753_1.jpg
|
| 1086 |
+
010481_0.jpg 009409_1.jpg
|
| 1087 |
+
010493_0.jpg 015230_1.jpg
|
| 1088 |
+
010503_0.jpg 017701_1.jpg
|
| 1089 |
+
010515_0.jpg 002930_1.jpg
|
| 1090 |
+
010527_0.jpg 008986_1.jpg
|
| 1091 |
+
010535_0.jpg 000827_1.jpg
|
| 1092 |
+
010543_0.jpg 008354_1.jpg
|
| 1093 |
+
010551_0.jpg 015069_1.jpg
|
| 1094 |
+
010559_0.jpg 012514_1.jpg
|
| 1095 |
+
010567_0.jpg 012681_1.jpg
|
| 1096 |
+
010575_0.jpg 017710_1.jpg
|
| 1097 |
+
010583_0.jpg 002852_1.jpg
|
| 1098 |
+
010591_0.jpg 006825_1.jpg
|
| 1099 |
+
010599_0.jpg 016154_1.jpg
|
| 1100 |
+
010608_0.jpg 015450_1.jpg
|
| 1101 |
+
010620_0.jpg 009064_1.jpg
|
| 1102 |
+
010628_0.jpg 002922_1.jpg
|
| 1103 |
+
010636_0.jpg 004131_1.jpg
|
| 1104 |
+
010644_0.jpg 007021_1.jpg
|
| 1105 |
+
010653_0.jpg 019438_1.jpg
|
| 1106 |
+
010662_0.jpg 003535_1.jpg
|
| 1107 |
+
010670_0.jpg 003060_1.jpg
|
| 1108 |
+
010683_0.jpg 001349_1.jpg
|
| 1109 |
+
010691_0.jpg 003874_1.jpg
|
| 1110 |
+
010699_0.jpg 017167_1.jpg
|
| 1111 |
+
010710_0.jpg 018441_1.jpg
|
| 1112 |
+
010718_0.jpg 011425_1.jpg
|
| 1113 |
+
010726_0.jpg 001038_1.jpg
|
| 1114 |
+
010735_0.jpg 007536_1.jpg
|
| 1115 |
+
010744_0.jpg 000676_1.jpg
|
| 1116 |
+
010753_0.jpg 011485_1.jpg
|
| 1117 |
+
010762_0.jpg 002200_1.jpg
|
| 1118 |
+
010770_0.jpg 007495_1.jpg
|
| 1119 |
+
010778_0.jpg 006462_1.jpg
|
| 1120 |
+
010789_0.jpg 016086_1.jpg
|
| 1121 |
+
010797_0.jpg 013298_1.jpg
|
| 1122 |
+
010806_0.jpg 015869_1.jpg
|
| 1123 |
+
010816_0.jpg 009832_1.jpg
|
| 1124 |
+
010830_0.jpg 013734_1.jpg
|
| 1125 |
+
010840_0.jpg 010011_1.jpg
|
| 1126 |
+
010851_0.jpg 009189_1.jpg
|
| 1127 |
+
010859_0.jpg 004997_1.jpg
|
| 1128 |
+
010869_0.jpg 004572_1.jpg
|
| 1129 |
+
010882_0.jpg 012898_1.jpg
|
| 1130 |
+
010891_0.jpg 011680_1.jpg
|
| 1131 |
+
010900_0.jpg 001919_1.jpg
|
| 1132 |
+
010910_0.jpg 006186_1.jpg
|
| 1133 |
+
010918_0.jpg 010346_1.jpg
|
| 1134 |
+
010929_0.jpg 007199_1.jpg
|
| 1135 |
+
010937_0.jpg 016388_1.jpg
|
| 1136 |
+
010947_0.jpg 017051_1.jpg
|
| 1137 |
+
010959_0.jpg 017273_1.jpg
|
| 1138 |
+
010967_0.jpg 012487_1.jpg
|
| 1139 |
+
010976_0.jpg 018980_1.jpg
|
| 1140 |
+
010984_0.jpg 018636_1.jpg
|
| 1141 |
+
010995_0.jpg 008126_1.jpg
|
| 1142 |
+
011004_0.jpg 014693_1.jpg
|
| 1143 |
+
011015_0.jpg 008080_1.jpg
|
| 1144 |
+
011023_0.jpg 002413_1.jpg
|
| 1145 |
+
011034_0.jpg 018807_1.jpg
|
| 1146 |
+
011042_0.jpg 007029_1.jpg
|
| 1147 |
+
011050_0.jpg 012116_1.jpg
|
| 1148 |
+
011058_0.jpg 019204_1.jpg
|
| 1149 |
+
011068_0.jpg 007681_1.jpg
|
| 1150 |
+
011076_0.jpg 000293_1.jpg
|
| 1151 |
+
011087_0.jpg 012265_1.jpg
|
| 1152 |
+
011097_0.jpg 019053_1.jpg
|
| 1153 |
+
011106_0.jpg 003668_1.jpg
|
| 1154 |
+
011120_0.jpg 014387_1.jpg
|
| 1155 |
+
011128_0.jpg 009159_1.jpg
|
| 1156 |
+
011137_0.jpg 003611_1.jpg
|
| 1157 |
+
011152_0.jpg 003676_1.jpg
|
| 1158 |
+
011164_0.jpg 018375_1.jpg
|
| 1159 |
+
011173_0.jpg 009106_1.jpg
|
| 1160 |
+
011181_0.jpg 005763_1.jpg
|
| 1161 |
+
011190_0.jpg 000370_1.jpg
|
| 1162 |
+
011203_0.jpg 001528_1.jpg
|
| 1163 |
+
011212_0.jpg 018737_1.jpg
|
| 1164 |
+
011221_0.jpg 005062_1.jpg
|
| 1165 |
+
011231_0.jpg 016021_1.jpg
|
| 1166 |
+
011240_0.jpg 008285_1.jpg
|
| 1167 |
+
011249_0.jpg 016612_1.jpg
|
| 1168 |
+
011258_0.jpg 012183_1.jpg
|
| 1169 |
+
011270_0.jpg 005510_1.jpg
|
| 1170 |
+
011278_0.jpg 014987_1.jpg
|
| 1171 |
+
011288_0.jpg 002651_1.jpg
|
| 1172 |
+
011300_0.jpg 006045_1.jpg
|
| 1173 |
+
011309_0.jpg 003981_1.jpg
|
| 1174 |
+
011318_0.jpg 006371_1.jpg
|
| 1175 |
+
011328_0.jpg 004091_1.jpg
|
| 1176 |
+
011336_0.jpg 009941_1.jpg
|
| 1177 |
+
011347_0.jpg 014360_1.jpg
|
| 1178 |
+
011355_0.jpg 004702_1.jpg
|
| 1179 |
+
011363_0.jpg 010195_1.jpg
|
| 1180 |
+
011372_0.jpg 008523_1.jpg
|
| 1181 |
+
011381_0.jpg 003077_1.jpg
|
| 1182 |
+
011392_0.jpg 018357_1.jpg
|
| 1183 |
+
011401_0.jpg 001056_1.jpg
|
| 1184 |
+
011415_0.jpg 016971_1.jpg
|
| 1185 |
+
011425_0.jpg 009799_1.jpg
|
| 1186 |
+
011436_0.jpg 009246_1.jpg
|
| 1187 |
+
011447_0.jpg 006502_1.jpg
|
| 1188 |
+
011457_0.jpg 005430_1.jpg
|
| 1189 |
+
011466_0.jpg 002447_1.jpg
|
| 1190 |
+
011475_0.jpg 015487_1.jpg
|
| 1191 |
+
011485_0.jpg 014666_1.jpg
|
| 1192 |
+
011495_0.jpg 009967_1.jpg
|
| 1193 |
+
011506_0.jpg 002839_1.jpg
|
| 1194 |
+
011515_0.jpg 006145_1.jpg
|
| 1195 |
+
011523_0.jpg 017990_1.jpg
|
| 1196 |
+
011536_0.jpg 010067_1.jpg
|
| 1197 |
+
011544_0.jpg 014280_1.jpg
|
| 1198 |
+
011552_0.jpg 017974_1.jpg
|
| 1199 |
+
011560_0.jpg 000734_1.jpg
|
| 1200 |
+
011568_0.jpg 012495_1.jpg
|
| 1201 |
+
011577_0.jpg 013601_1.jpg
|
| 1202 |
+
011585_0.jpg 018146_1.jpg
|
| 1203 |
+
011596_0.jpg 012149_1.jpg
|
| 1204 |
+
011604_0.jpg 002059_1.jpg
|
| 1205 |
+
011615_0.jpg 008736_1.jpg
|
| 1206 |
+
011623_0.jpg 004854_1.jpg
|
| 1207 |
+
011631_0.jpg 009332_1.jpg
|
| 1208 |
+
011641_0.jpg 003565_1.jpg
|
| 1209 |
+
011654_0.jpg 005898_1.jpg
|
| 1210 |
+
011662_0.jpg 000001_1.jpg
|
| 1211 |
+
011670_0.jpg 016484_1.jpg
|
| 1212 |
+
011680_0.jpg 015654_1.jpg
|
| 1213 |
+
011689_0.jpg 001655_1.jpg
|
| 1214 |
+
011699_0.jpg 006512_1.jpg
|
| 1215 |
+
011708_0.jpg 000768_1.jpg
|
| 1216 |
+
011716_0.jpg 001162_1.jpg
|
| 1217 |
+
011724_0.jpg 016495_1.jpg
|
| 1218 |
+
011736_0.jpg 012926_1.jpg
|
| 1219 |
+
011745_0.jpg 012202_1.jpg
|
| 1220 |
+
011761_0.jpg 006563_1.jpg
|
| 1221 |
+
011769_0.jpg 003133_1.jpg
|
| 1222 |
+
011781_0.jpg 002494_1.jpg
|
| 1223 |
+
011790_0.jpg 008997_1.jpg
|
| 1224 |
+
011798_0.jpg 012907_1.jpg
|
| 1225 |
+
011806_0.jpg 005622_1.jpg
|
| 1226 |
+
011816_0.jpg 014685_1.jpg
|
| 1227 |
+
011825_0.jpg 014582_1.jpg
|
| 1228 |
+
011833_0.jpg 008839_1.jpg
|
| 1229 |
+
011842_0.jpg 006670_1.jpg
|
| 1230 |
+
011850_0.jpg 015928_1.jpg
|
| 1231 |
+
011862_0.jpg 016839_1.jpg
|
| 1232 |
+
011872_0.jpg 000877_1.jpg
|
| 1233 |
+
011883_0.jpg 016644_1.jpg
|
| 1234 |
+
011891_0.jpg 010253_1.jpg
|
| 1235 |
+
011899_0.jpg 018488_1.jpg
|
| 1236 |
+
011908_0.jpg 011604_1.jpg
|
| 1237 |
+
011916_0.jpg 010057_1.jpg
|
| 1238 |
+
011924_0.jpg 000668_1.jpg
|
| 1239 |
+
011933_0.jpg 006410_1.jpg
|
| 1240 |
+
011944_0.jpg 011623_1.jpg
|
| 1241 |
+
011954_0.jpg 005195_1.jpg
|
| 1242 |
+
011962_0.jpg 004867_1.jpg
|
| 1243 |
+
011970_0.jpg 012616_1.jpg
|
| 1244 |
+
011980_0.jpg 009024_1.jpg
|
| 1245 |
+
011988_0.jpg 002610_1.jpg
|
| 1246 |
+
011996_0.jpg 012803_1.jpg
|
| 1247 |
+
012006_0.jpg 001457_1.jpg
|
| 1248 |
+
012015_0.jpg 018644_1.jpg
|
| 1249 |
+
012025_0.jpg 011790_1.jpg
|
| 1250 |
+
012033_0.jpg 006968_1.jpg
|
| 1251 |
+
012044_0.jpg 015095_1.jpg
|
| 1252 |
+
012054_0.jpg 007313_1.jpg
|
| 1253 |
+
012063_0.jpg 015516_1.jpg
|
| 1254 |
+
012072_0.jpg 006486_1.jpg
|
| 1255 |
+
012081_0.jpg 018590_1.jpg
|
| 1256 |
+
012089_0.jpg 013147_1.jpg
|
| 1257 |
+
012099_0.jpg 006224_1.jpg
|
| 1258 |
+
012107_0.jpg 001467_1.jpg
|
| 1259 |
+
012116_0.jpg 009454_1.jpg
|
| 1260 |
+
012127_0.jpg 005213_1.jpg
|
| 1261 |
+
012137_0.jpg 001269_1.jpg
|
| 1262 |
+
012149_0.jpg 010830_1.jpg
|
| 1263 |
+
012158_0.jpg 013510_1.jpg
|
| 1264 |
+
012166_0.jpg 018729_1.jpg
|
| 1265 |
+
012174_0.jpg 000957_1.jpg
|
| 1266 |
+
012183_0.jpg 018291_1.jpg
|
| 1267 |
+
012193_0.jpg 011249_1.jpg
|
| 1268 |
+
012202_0.jpg 003882_1.jpg
|
| 1269 |
+
012219_0.jpg 004277_1.jpg
|
| 1270 |
+
012228_0.jpg 006555_1.jpg
|
| 1271 |
+
012236_0.jpg 015045_1.jpg
|
| 1272 |
+
012245_0.jpg 008258_1.jpg
|
| 1273 |
+
012256_0.jpg 017099_1.jpg
|
| 1274 |
+
012265_0.jpg 009462_1.jpg
|
| 1275 |
+
012273_0.jpg 004516_1.jpg
|
| 1276 |
+
012282_0.jpg 008233_1.jpg
|
| 1277 |
+
012291_0.jpg 001009_1.jpg
|
| 1278 |
+
012303_0.jpg 018876_1.jpg
|
| 1279 |
+
012311_0.jpg 001845_1.jpg
|
| 1280 |
+
012322_0.jpg 013060_1.jpg
|
| 1281 |
+
012330_0.jpg 015645_1.jpg
|
| 1282 |
+
012338_0.jpg 000812_1.jpg
|
| 1283 |
+
012350_0.jpg 011023_1.jpg
|
| 1284 |
+
012359_0.jpg 013117_1.jpg
|
| 1285 |
+
012369_0.jpg 009474_1.jpg
|
| 1286 |
+
012377_0.jpg 017227_1.jpg
|
| 1287 |
+
012385_0.jpg 005110_1.jpg
|
| 1288 |
+
012395_0.jpg 015662_1.jpg
|
| 1289 |
+
012404_0.jpg 000174_1.jpg
|
| 1290 |
+
012413_0.jpg 007949_1.jpg
|
| 1291 |
+
012422_0.jpg 009042_1.jpg
|
| 1292 |
+
012430_0.jpg 006620_1.jpg
|
| 1293 |
+
012440_0.jpg 009446_1.jpg
|
| 1294 |
+
012451_0.jpg 007159_1.jpg
|
| 1295 |
+
012460_0.jpg 012025_1.jpg
|
| 1296 |
+
012469_0.jpg 015334_1.jpg
|
| 1297 |
+
012479_0.jpg 017021_1.jpg
|
| 1298 |
+
012487_0.jpg 014055_1.jpg
|
| 1299 |
+
012495_0.jpg 002156_1.jpg
|
| 1300 |
+
012505_0.jpg 002911_1.jpg
|
| 1301 |
+
012514_0.jpg 004285_1.jpg
|
| 1302 |
+
012522_0.jpg 015740_1.jpg
|
| 1303 |
+
012531_0.jpg 005702_1.jpg
|
| 1304 |
+
012545_0.jpg 005755_1.jpg
|
| 1305 |
+
012553_0.jpg 016415_1.jpg
|
| 1306 |
+
012564_0.jpg 013931_1.jpg
|
| 1307 |
+
012578_0.jpg 014252_1.jpg
|
| 1308 |
+
012587_0.jpg 016687_1.jpg
|
| 1309 |
+
012597_0.jpg 016309_1.jpg
|
| 1310 |
+
012605_0.jpg 004561_1.jpg
|
| 1311 |
+
012616_0.jpg 009790_1.jpg
|
| 1312 |
+
012626_0.jpg 000209_1.jpg
|
| 1313 |
+
012636_0.jpg 004666_1.jpg
|
| 1314 |
+
012644_0.jpg 017922_1.jpg
|
| 1315 |
+
012652_0.jpg 002545_1.jpg
|
| 1316 |
+
012660_0.jpg 017957_1.jpg
|
| 1317 |
+
012669_0.jpg 005846_1.jpg
|
| 1318 |
+
012681_0.jpg 015955_1.jpg
|
| 1319 |
+
012694_0.jpg 001683_1.jpg
|
| 1320 |
+
012702_0.jpg 015671_1.jpg
|
| 1321 |
+
012712_0.jpg 005457_1.jpg
|
| 1322 |
+
012725_0.jpg 019243_1.jpg
|
| 1323 |
+
012734_0.jpg 008041_1.jpg
|
| 1324 |
+
012743_0.jpg 001928_1.jpg
|
| 1325 |
+
012754_0.jpg 003142_1.jpg
|
| 1326 |
+
012763_0.jpg 006776_1.jpg
|
| 1327 |
+
012773_0.jpg 009679_1.jpg
|
| 1328 |
+
012785_0.jpg 015412_1.jpg
|
| 1329 |
+
012795_0.jpg 018337_1.jpg
|
| 1330 |
+
012803_0.jpg 013997_1.jpg
|
| 1331 |
+
012811_0.jpg 001834_1.jpg
|
| 1332 |
+
012822_0.jpg 013284_1.jpg
|
| 1333 |
+
012830_0.jpg 008479_1.jpg
|
| 1334 |
+
012838_0.jpg 015889_1.jpg
|
| 1335 |
+
012849_0.jpg 015439_1.jpg
|
| 1336 |
+
012860_0.jpg 012107_1.jpg
|
| 1337 |
+
012868_0.jpg 003250_1.jpg
|
| 1338 |
+
012879_0.jpg 017282_1.jpg
|
| 1339 |
+
012889_0.jpg 000795_1.jpg
|
| 1340 |
+
012898_0.jpg 002758_1.jpg
|
| 1341 |
+
012907_0.jpg 012987_1.jpg
|
| 1342 |
+
012917_0.jpg 016102_1.jpg
|
| 1343 |
+
012926_0.jpg 016328_1.jpg
|
| 1344 |
+
012934_0.jpg 010551_1.jpg
|
| 1345 |
+
012944_0.jpg 016921_1.jpg
|
| 1346 |
+
012953_0.jpg 001310_1.jpg
|
| 1347 |
+
012964_0.jpg 006203_1.jpg
|
| 1348 |
+
012975_0.jpg 007423_1.jpg
|
| 1349 |
+
012987_0.jpg 015200_1.jpg
|
| 1350 |
+
012996_0.jpg 012669_1.jpg
|
| 1351 |
+
013007_0.jpg 014920_1.jpg
|
| 1352 |
+
013019_0.jpg 003069_1.jpg
|
| 1353 |
+
013028_0.jpg 000164_1.jpg
|
| 1354 |
+
013036_0.jpg 008598_1.jpg
|
| 1355 |
+
013047_0.jpg 018507_1.jpg
|
| 1356 |
+
013060_0.jpg 009741_1.jpg
|
| 1357 |
+
013068_0.jpg 012081_1.jpg
|
| 1358 |
+
013076_0.jpg 011654_1.jpg
|
| 1359 |
+
013084_0.jpg 012830_1.jpg
|
| 1360 |
+
013097_0.jpg 002307_1.jpg
|
| 1361 |
+
013106_0.jpg 000542_1.jpg
|
| 1362 |
+
013117_0.jpg 014755_1.jpg
|
| 1363 |
+
013127_0.jpg 008763_1.jpg
|
| 1364 |
+
013139_0.jpg 009809_1.jpg
|
| 1365 |
+
013147_0.jpg 008462_1.jpg
|
| 1366 |
+
013155_0.jpg 013789_1.jpg
|
| 1367 |
+
013165_0.jpg 007526_1.jpg
|
| 1368 |
+
013173_0.jpg 010404_1.jpg
|
| 1369 |
+
013181_0.jpg 005222_1.jpg
|
| 1370 |
+
013190_0.jpg 014908_1.jpg
|
| 1371 |
+
013199_0.jpg 019486_1.jpg
|
| 1372 |
+
013214_0.jpg 017770_1.jpg
|
| 1373 |
+
013224_0.jpg 004590_1.jpg
|
| 1374 |
+
013233_0.jpg 007357_1.jpg
|
| 1375 |
+
013245_0.jpg 005562_1.jpg
|
| 1376 |
+
013256_0.jpg 012773_1.jpg
|
| 1377 |
+
013265_0.jpg 018039_1.jpg
|
| 1378 |
+
013273_0.jpg 017062_1.jpg
|
| 1379 |
+
013284_0.jpg 002474_1.jpg
|
| 1380 |
+
013298_0.jpg 002208_1.jpg
|
| 1381 |
+
013309_0.jpg 002031_1.jpg
|
| 1382 |
+
013319_0.jpg 009169_1.jpg
|
| 1383 |
+
013327_0.jpg 006036_1.jpg
|
| 1384 |
+
013338_0.jpg 012311_1.jpg
|
| 1385 |
+
013355_0.jpg 018626_1.jpg
|
| 1386 |
+
013365_0.jpg 014272_1.jpg
|
| 1387 |
+
013374_0.jpg 014035_1.jpg
|
| 1388 |
+
013382_0.jpg 016515_1.jpg
|
| 1389 |
+
013391_0.jpg 004758_1.jpg
|
| 1390 |
+
013400_0.jpg 002093_1.jpg
|
| 1391 |
+
013410_0.jpg 004462_1.jpg
|
| 1392 |
+
013418_0.jpg 000284_1.jpg
|
| 1393 |
+
013428_0.jpg 008188_1.jpg
|
| 1394 |
+
013437_0.jpg 006260_1.jpg
|
| 1395 |
+
013447_0.jpg 007188_1.jpg
|
| 1396 |
+
013456_0.jpg 017563_1.jpg
|
| 1397 |
+
013469_0.jpg 009984_1.jpg
|
| 1398 |
+
013478_0.jpg 005166_1.jpg
|
| 1399 |
+
013490_0.jpg 009205_1.jpg
|
| 1400 |
+
013502_0.jpg 008032_1.jpg
|
| 1401 |
+
013510_0.jpg 005153_1.jpg
|
| 1402 |
+
013518_0.jpg 000200_1.jpg
|
| 1403 |
+
013527_0.jpg 013478_1.jpg
|
| 1404 |
+
013539_0.jpg 012469_1.jpg
|
| 1405 |
+
013547_0.jpg 017779_1.jpg
|
| 1406 |
+
013555_0.jpg 019505_1.jpg
|
| 1407 |
+
013564_0.jpg 016271_1.jpg
|
| 1408 |
+
013572_0.jpg 014406_1.jpg
|
| 1409 |
+
013583_0.jpg 006296_1.jpg
|
| 1410 |
+
013593_0.jpg 009959_1.jpg
|
| 1411 |
+
013601_0.jpg 013968_1.jpg
|
| 1412 |
+
013611_0.jpg 004051_1.jpg
|
| 1413 |
+
013620_0.jpg 010160_1.jpg
|
| 1414 |
+
013634_0.jpg 009571_1.jpg
|
| 1415 |
+
013642_0.jpg 019475_1.jpg
|
| 1416 |
+
013654_0.jpg 011850_1.jpg
|
| 1417 |
+
013665_0.jpg 015352_1.jpg
|
| 1418 |
+
013680_0.jpg 018515_1.jpg
|
| 1419 |
+
013688_0.jpg 012137_1.jpg
|
| 1420 |
+
013698_0.jpg 015015_1.jpg
|
| 1421 |
+
013706_0.jpg 014834_1.jpg
|
| 1422 |
+
013715_0.jpg 019393_1.jpg
|
| 1423 |
+
013725_0.jpg 005920_1.jpg
|
| 1424 |
+
013734_0.jpg 007974_1.jpg
|
| 1425 |
+
013743_0.jpg 018411_1.jpg
|
| 1426 |
+
013753_0.jpg 008443_1.jpg
|
| 1427 |
+
013764_0.jpg 004431_1.jpg
|
| 1428 |
+
013772_0.jpg 000915_1.jpg
|
| 1429 |
+
013780_0.jpg 006026_1.jpg
|
| 1430 |
+
013789_0.jpg 005586_1.jpg
|
| 1431 |
+
013798_0.jpg 009505_1.jpg
|
| 1432 |
+
013806_0.jpg 019310_1.jpg
|
| 1433 |
+
013816_0.jpg 018671_1.jpg
|
| 1434 |
+
013827_0.jpg 010683_1.jpg
|
| 1435 |
+
013836_0.jpg 007129_1.jpg
|
| 1436 |
+
013845_0.jpg 019183_1.jpg
|
| 1437 |
+
013855_0.jpg 009149_1.jpg
|
| 1438 |
+
013863_0.jpg 005984_1.jpg
|
| 1439 |
+
013875_0.jpg 003367_1.jpg
|
| 1440 |
+
013883_0.jpg 005298_1.jpg
|
| 1441 |
+
013891_0.jpg 005336_1.jpg
|
| 1442 |
+
013899_0.jpg 003311_1.jpg
|
| 1443 |
+
013907_0.jpg 005480_1.jpg
|
| 1444 |
+
013915_0.jpg 014574_1.jpg
|
| 1445 |
+
013923_0.jpg 013981_1.jpg
|
| 1446 |
+
013931_0.jpg 001408_1.jpg
|
| 1447 |
+
013939_0.jpg 010900_1.jpg
|
| 1448 |
+
013948_0.jpg 012193_1.jpg
|
| 1449 |
+
013959_0.jpg 003008_1.jpg
|
| 1450 |
+
013968_0.jpg 003041_1.jpg
|
| 1451 |
+
013981_0.jpg 003632_1.jpg
|
| 1452 |
+
013989_0.jpg 003303_1.jpg
|
| 1453 |
+
013997_0.jpg 001485_1.jpg
|
| 1454 |
+
014006_0.jpg 005131_1.jpg
|
| 1455 |
+
014014_0.jpg 005837_1.jpg
|
| 1456 |
+
014025_0.jpg 001547_1.jpg
|
| 1457 |
+
014035_0.jpg 005271_1.jpg
|
| 1458 |
+
014046_0.jpg 014106_1.jpg
|
| 1459 |
+
014055_0.jpg 011120_1.jpg
|
| 1460 |
+
014066_0.jpg 019119_1.jpg
|
| 1461 |
+
014076_0.jpg 008062_1.jpg
|
| 1462 |
+
014086_0.jpg 016765_1.jpg
|
| 1463 |
+
014096_0.jpg 010289_1.jpg
|
| 1464 |
+
014106_0.jpg 003195_1.jpg
|
| 1465 |
+
014114_0.jpg 000706_1.jpg
|
| 1466 |
+
014123_0.jpg 016757_1.jpg
|
| 1467 |
+
014131_0.jpg 015507_1.jpg
|
| 1468 |
+
014140_0.jpg 005489_1.jpg
|
| 1469 |
+
014149_0.jpg 012934_1.jpg
|
| 1470 |
+
014159_0.jpg 012359_1.jpg
|
| 1471 |
+
014167_0.jpg 009860_1.jpg
|
| 1472 |
+
014176_0.jpg 011769_1.jpg
|
| 1473 |
+
014184_0.jpg 004260_1.jpg
|
| 1474 |
+
014192_0.jpg 018167_1.jpg
|
| 1475 |
+
014201_0.jpg 012451_1.jpg
|
| 1476 |
+
014209_0.jpg 003526_1.jpg
|
| 1477 |
+
014220_0.jpg 013028_1.jpg
|
| 1478 |
+
014232_0.jpg 005006_1.jpg
|
| 1479 |
+
014240_0.jpg 004598_1.jpg
|
| 1480 |
+
014252_0.jpg 011806_1.jpg
|
| 1481 |
+
014262_0.jpg 014176_1.jpg
|
| 1482 |
+
014272_0.jpg 008071_1.jpg
|
| 1483 |
+
014280_0.jpg 007817_1.jpg
|
| 1484 |
+
014292_0.jpg 013634_1.jpg
|
| 1485 |
+
014302_0.jpg 007719_1.jpg
|
| 1486 |
+
014314_0.jpg 013764_1.jpg
|
| 1487 |
+
014324_0.jpg 000532_1.jpg
|
| 1488 |
+
014332_0.jpg 012587_1.jpg
|
| 1489 |
+
014341_0.jpg 016397_1.jpg
|
| 1490 |
+
014349_0.jpg 018300_1.jpg
|
| 1491 |
+
014360_0.jpg 008118_1.jpg
|
| 1492 |
+
014370_0.jpg 000118_1.jpg
|
| 1493 |
+
014379_0.jpg 006173_1.jpg
|
| 1494 |
+
014387_0.jpg 002287_1.jpg
|
| 1495 |
+
014396_0.jpg 002405_1.jpg
|
| 1496 |
+
014406_0.jpg 011181_1.jpg
|
| 1497 |
+
014416_0.jpg 002388_1.jpg
|
| 1498 |
+
014426_0.jpg 003461_1.jpg
|
| 1499 |
+
014434_0.jpg 001937_1.jpg
|
| 1500 |
+
014443_0.jpg 019465_1.jpg
|
| 1501 |
+
014452_0.jpg 017657_1.jpg
|
| 1502 |
+
014463_0.jpg 001664_1.jpg
|
| 1503 |
+
014477_0.jpg 010984_1.jpg
|
| 1504 |
+
014489_0.jpg 014046_1.jpg
|
| 1505 |
+
014498_0.jpg 017932_1.jpg
|
| 1506 |
+
014507_0.jpg 003451_1.jpg
|
| 1507 |
+
014518_0.jpg 016338_1.jpg
|
| 1508 |
+
014528_0.jpg 008753_1.jpg
|
| 1509 |
+
014537_0.jpg 012660_1.jpg
|
| 1510 |
+
014553_0.jpg 017323_1.jpg
|
| 1511 |
+
014564_0.jpg 000568_1.jpg
|
| 1512 |
+
014574_0.jpg 013106_1.jpg
|
| 1513 |
+
014582_0.jpg 018894_1.jpg
|
| 1514 |
+
014591_0.jpg 013502_1.jpg
|
| 1515 |
+
014604_0.jpg 012712_1.jpg
|
| 1516 |
+
014612_0.jpg 005737_1.jpg
|
| 1517 |
+
014621_0.jpg 017041_1.jpg
|
| 1518 |
+
014629_0.jpg 019420_1.jpg
|
| 1519 |
+
014639_0.jpg 001868_1.jpg
|
| 1520 |
+
014652_0.jpg 016435_1.jpg
|
| 1521 |
+
014666_0.jpg 005285_1.jpg
|
| 1522 |
+
014675_0.jpg 004795_1.jpg
|
| 1523 |
+
014685_0.jpg 003434_1.jpg
|
| 1524 |
+
014693_0.jpg 013611_1.jpg
|
| 1525 |
+
014701_0.jpg 006589_1.jpg
|
| 1526 |
+
014712_0.jpg 011309_1.jpg
|
| 1527 |
+
014720_0.jpg 009586_1.jpg
|
| 1528 |
+
014728_0.jpg 015220_1.jpg
|
| 1529 |
+
014736_0.jpg 011137_1.jpg
|
| 1530 |
+
014744_0.jpg 007570_1.jpg
|
| 1531 |
+
014755_0.jpg 007056_1.jpg
|
| 1532 |
+
014765_0.jpg 012044_1.jpg
|
| 1533 |
+
014774_0.jpg 018254_1.jpg
|
| 1534 |
+
014785_0.jpg 000786_1.jpg
|
| 1535 |
+
014794_0.jpg 011372_1.jpg
|
| 1536 |
+
014805_0.jpg 001695_1.jpg
|
| 1537 |
+
014816_0.jpg 015598_1.jpg
|
| 1538 |
+
014825_0.jpg 002712_1.jpg
|
| 1539 |
+
014834_0.jpg 014452_1.jpg
|
| 1540 |
+
014844_0.jpg 011908_1.jpg
|
| 1541 |
+
014854_0.jpg 018129_1.jpg
|
| 1542 |
+
014863_0.jpg 017153_1.jpg
|
| 1543 |
+
014876_0.jpg 010976_1.jpg
|
| 1544 |
+
014888_0.jpg 016929_1.jpg
|
| 1545 |
+
014900_0.jpg 009365_1.jpg
|
| 1546 |
+
014908_0.jpg 012282_1.jpg
|
| 1547 |
+
014920_0.jpg 008389_1.jpg
|
| 1548 |
+
014930_0.jpg 012460_1.jpg
|
| 1549 |
+
014939_0.jpg 011631_1.jpg
|
| 1550 |
+
014950_0.jpg 013273_1.jpg
|
| 1551 |
+
014959_0.jpg 003768_1.jpg
|
| 1552 |
+
014968_0.jpg 002248_1.jpg
|
| 1553 |
+
014979_0.jpg 005675_1.jpg
|
| 1554 |
+
014987_0.jpg 013365_1.jpg
|
| 1555 |
+
014995_0.jpg 006688_1.jpg
|
| 1556 |
+
015006_0.jpg 006268_1.jpg
|
| 1557 |
+
015015_0.jpg 017982_1.jpg
|
| 1558 |
+
015026_0.jpg 006241_1.jpg
|
| 1559 |
+
015036_0.jpg 014167_1.jpg
|
| 1560 |
+
015045_0.jpg 016981_1.jpg
|
| 1561 |
+
015060_0.jpg 009382_1.jpg
|
| 1562 |
+
015069_0.jpg 005501_1.jpg
|
| 1563 |
+
015077_0.jpg 014518_1.jpg
|
| 1564 |
+
015085_0.jpg 016130_1.jpg
|
| 1565 |
+
015095_0.jpg 001614_1.jpg
|
| 1566 |
+
015105_0.jpg 011862_1.jpg
|
| 1567 |
+
015114_0.jpg 002455_1.jpg
|
| 1568 |
+
015125_0.jpg 016707_1.jpg
|
| 1569 |
+
015133_0.jpg 014443_1.jpg
|
| 1570 |
+
015141_0.jpg 000339_1.jpg
|
| 1571 |
+
015150_0.jpg 014825_1.jpg
|
| 1572 |
+
015158_0.jpg 005771_1.jpg
|
| 1573 |
+
015173_0.jpg 005929_1.jpg
|
| 1574 |
+
015181_0.jpg 003150_1.jpg
|
| 1575 |
+
015192_0.jpg 004683_1.jpg
|
| 1576 |
+
015200_0.jpg 007388_1.jpg
|
| 1577 |
+
015209_0.jpg 009356_1.jpg
|
| 1578 |
+
015220_0.jpg 011699_1.jpg
|
| 1579 |
+
015230_0.jpg 004487_1.jpg
|
| 1580 |
+
015238_0.jpg 013224_1.jpg
|
| 1581 |
+
015247_0.jpg 004674_1.jpg
|
| 1582 |
+
015256_0.jpg 018817_1.jpg
|
| 1583 |
+
015264_0.jpg 007561_1.jpg
|
| 1584 |
+
015272_0.jpg 010959_1.jpg
|
| 1585 |
+
015280_0.jpg 013845_1.jpg
|
| 1586 |
+
015291_0.jpg 011506_1.jpg
|
| 1587 |
+
015299_0.jpg 010670_1.jpg
|
| 1588 |
+
015308_0.jpg 019018_1.jpg
|
| 1589 |
+
015317_0.jpg 010185_1.jpg
|
| 1590 |
+
015325_0.jpg 006155_1.jpg
|
| 1591 |
+
015334_0.jpg 005578_1.jpg
|
| 1592 |
+
015344_0.jpg 000742_1.jpg
|
| 1593 |
+
015352_0.jpg 002327_1.jpg
|
| 1594 |
+
015362_0.jpg 005072_1.jpg
|
| 1595 |
+
015371_0.jpg 009912_1.jpg
|
| 1596 |
+
015381_0.jpg 009822_1.jpg
|
| 1597 |
+
015392_0.jpg 001073_1.jpg
|
| 1598 |
+
015403_0.jpg 005014_1.jpg
|
| 1599 |
+
015412_0.jpg 015542_1.jpg
|
| 1600 |
+
015420_0.jpg 007037_1.jpg
|
| 1601 |
+
015428_0.jpg 018245_1.jpg
|
| 1602 |
+
015439_0.jpg 006748_1.jpg
|
| 1603 |
+
015450_0.jpg 006099_1.jpg
|
| 1604 |
+
015465_0.jpg 008580_1.jpg
|
| 1605 |
+
015476_0.jpg 000330_1.jpg
|
| 1606 |
+
015487_0.jpg 013076_1.jpg
|
| 1607 |
+
015497_0.jpg 012953_1.jpg
|
| 1608 |
+
015507_0.jpg 018652_1.jpg
|
| 1609 |
+
015516_0.jpg 012430_1.jpg
|
| 1610 |
+
015524_0.jpg 014159_1.jpg
|
| 1611 |
+
015542_0.jpg 019531_1.jpg
|
| 1612 |
+
015550_0.jpg 013875_1.jpg
|
| 1613 |
+
015560_0.jpg 012422_1.jpg
|
| 1614 |
+
015571_0.jpg 018618_1.jpg
|
| 1615 |
+
015579_0.jpg 005031_1.jpg
|
| 1616 |
+
015590_0.jpg 003963_1.jpg
|
| 1617 |
+
015598_0.jpg 018159_1.jpg
|
| 1618 |
+
015607_0.jpg 005422_1.jpg
|
| 1619 |
+
015615_0.jpg 010699_1.jpg
|
| 1620 |
+
015627_0.jpg 018884_1.jpg
|
| 1621 |
+
015637_0.jpg 012522_1.jpg
|
| 1622 |
+
015645_0.jpg 017536_1.jpg
|
| 1623 |
+
015654_0.jpg 009843_1.jpg
|
| 1624 |
+
015662_0.jpg 002011_1.jpg
|
| 1625 |
+
015671_0.jpg 011152_1.jpg
|
| 1626 |
+
015680_0.jpg 005449_1.jpg
|
| 1627 |
+
015688_0.jpg 001419_1.jpg
|
| 1628 |
+
015697_0.jpg 004314_1.jpg
|
| 1629 |
+
015707_0.jpg 018121_1.jpg
|
| 1630 |
+
015715_0.jpg 013084_1.jpg
|
| 1631 |
+
015724_0.jpg 006313_1.jpg
|
| 1632 |
+
015732_0.jpg 013816_1.jpg
|
| 1633 |
+
015740_0.jpg 014995_1.jpg
|
| 1634 |
+
015748_0.jpg 001502_1.jpg
|
| 1635 |
+
015759_0.jpg 003649_1.jpg
|
| 1636 |
+
015767_0.jpg 000437_1.jpg
|
| 1637 |
+
015776_0.jpg 009651_1.jpg
|
| 1638 |
+
015785_0.jpg 005470_1.jpg
|
| 1639 |
+
015794_0.jpg 009123_1.jpg
|
| 1640 |
+
015803_0.jpg 005145_1.jpg
|
| 1641 |
+
015816_0.jpg 004115_1.jpg
|
| 1642 |
+
015825_0.jpg 008871_1.jpg
|
| 1643 |
+
015836_0.jpg 006118_1.jpg
|
| 1644 |
+
015844_0.jpg 007294_1.jpg
|
| 1645 |
+
015853_0.jpg 005101_1.jpg
|
| 1646 |
+
015861_0.jpg 017592_1.jpg
|
| 1647 |
+
015869_0.jpg 011724_1.jpg
|
| 1648 |
+
015881_0.jpg 008180_1.jpg
|
| 1649 |
+
015889_0.jpg 009699_1.jpg
|
| 1650 |
+
015900_0.jpg 017079_1.jpg
|
| 1651 |
+
015908_0.jpg 008533_1.jpg
|
| 1652 |
+
015916_0.jpg 002533_1.jpg
|
| 1653 |
+
015928_0.jpg 017418_1.jpg
|
| 1654 |
+
015938_0.jpg 007874_1.jpg
|
| 1655 |
+
015946_0.jpg 014426_1.jpg
|
| 1656 |
+
015955_0.jpg 018662_1.jpg
|
| 1657 |
+
015969_0.jpg 009561_1.jpg
|
| 1658 |
+
015979_0.jpg 007848_1.jpg
|
| 1659 |
+
015990_0.jpg 010882_1.jpg
|
| 1660 |
+
016002_0.jpg 006358_1.jpg
|
| 1661 |
+
016013_0.jpg 014528_1.jpg
|
| 1662 |
+
016021_0.jpg 003621_1.jpg
|
| 1663 |
+
016031_0.jpg 002883_1.jpg
|
| 1664 |
+
016039_0.jpg 009894_1.jpg
|
| 1665 |
+
016049_0.jpg 004252_1.jpg
|
| 1666 |
+
016059_0.jpg 012291_1.jpg
|
| 1667 |
+
016067_0.jpg 006523_1.jpg
|
| 1668 |
+
016075_0.jpg 007121_1.jpg
|
| 1669 |
+
016086_0.jpg 016505_1.jpg
|
| 1670 |
+
016094_0.jpg 004378_1.jpg
|
| 1671 |
+
016102_0.jpg 011716_1.jpg
|
| 1672 |
+
016112_0.jpg 000560_1.jpg
|
| 1673 |
+
016121_0.jpg 004478_1.jpg
|
| 1674 |
+
016130_0.jpg 002803_1.jpg
|
| 1675 |
+
016145_0.jpg 016455_1.jpg
|
| 1676 |
+
016154_0.jpg 008949_1.jpg
|
| 1677 |
+
016163_0.jpg 002276_1.jpg
|
| 1678 |
+
016172_0.jpg 016163_1.jpg
|
| 1679 |
+
016183_0.jpg 005728_1.jpg
|
| 1680 |
+
016191_0.jpg 011536_1.jpg
|
| 1681 |
+
016206_0.jpg 015344_1.jpg
|
| 1682 |
+
016220_0.jpg 002670_1.jpg
|
| 1683 |
+
016230_0.jpg 002226_1.jpg
|
| 1684 |
+
016238_0.jpg 008855_1.jpg
|
| 1685 |
+
016246_0.jpg 003481_1.jpg
|
| 1686 |
+
016254_0.jpg 015060_1.jpg
|
| 1687 |
+
016262_0.jpg 007138_1.jpg
|
| 1688 |
+
016271_0.jpg 017390_1.jpg
|
| 1689 |
+
016281_0.jpg 018598_1.jpg
|
| 1690 |
+
016290_0.jpg 015680_1.jpg
|
| 1691 |
+
016300_0.jpg 009627_1.jpg
|
| 1692 |
+
016309_0.jpg 015238_1.jpg
|
| 1693 |
+
016317_0.jpg 004107_1.jpg
|
| 1694 |
+
016328_0.jpg 015776_1.jpg
|
| 1695 |
+
016338_0.jpg 009668_1.jpg
|
| 1696 |
+
016349_0.jpg 008250_1.jpg
|
| 1697 |
+
016358_0.jpg 006889_1.jpg
|
| 1698 |
+
016367_0.jpg 008813_1.jpg
|
| 1699 |
+
016379_0.jpg 003107_1.jpg
|
| 1700 |
+
016388_0.jpg 014785_1.jpg
|
| 1701 |
+
016397_0.jpg 002728_1.jpg
|
| 1702 |
+
016405_0.jpg 000356_1.jpg
|
| 1703 |
+
016415_0.jpg 014096_1.jpg
|
| 1704 |
+
016426_0.jpg 016230_1.jpg
|
| 1705 |
+
016435_0.jpg 005175_1.jpg
|
| 1706 |
+
016445_0.jpg 010770_1.jpg
|
| 1707 |
+
016455_0.jpg 013518_1.jpg
|
| 1708 |
+
016465_0.jpg 012158_1.jpg
|
| 1709 |
+
016474_0.jpg 017613_1.jpg
|
| 1710 |
+
016484_0.jpg 019166_1.jpg
|
| 1711 |
+
016495_0.jpg 009722_1.jpg
|
| 1712 |
+
016505_0.jpg 018858_1.jpg
|
| 1713 |
+
016515_0.jpg 009515_1.jpg
|
| 1714 |
+
016524_0.jpg 009537_1.jpg
|
| 1715 |
+
016533_0.jpg 006276_1.jpg
|
| 1716 |
+
016541_0.jpg 016853_1.jpg
|
| 1717 |
+
016550_0.jpg 013772_1.jpg
|
| 1718 |
+
016562_0.jpg 019154_1.jpg
|
| 1719 |
+
016571_0.jpg 017514_1.jpg
|
| 1720 |
+
016584_0.jpg 013447_1.jpg
|
| 1721 |
+
016593_0.jpg 018309_1.jpg
|
| 1722 |
+
016602_0.jpg 010088_1.jpg
|
| 1723 |
+
016612_0.jpg 003658_1.jpg
|
| 1724 |
+
016620_0.jpg 003760_1.jpg
|
| 1725 |
+
016628_0.jpg 007750_1.jpg
|
| 1726 |
+
016636_0.jpg 004470_1.jpg
|
| 1727 |
+
016644_0.jpg 015158_1.jpg
|
| 1728 |
+
016653_0.jpg 008725_1.jpg
|
| 1729 |
+
016662_0.jpg 010357_1.jpg
|
| 1730 |
+
016676_0.jpg 016013_1.jpg
|
| 1731 |
+
016687_0.jpg 014025_1.jpg
|
| 1732 |
+
016697_0.jpg 008487_1.jpg
|
| 1733 |
+
016707_0.jpg 003094_1.jpg
|
| 1734 |
+
016716_0.jpg 014066_1.jpg
|
| 1735 |
+
016726_0.jpg 011164_1.jpg
|
| 1736 |
+
016739_0.jpg 017805_1.jpg
|
| 1737 |
+
016748_0.jpg 012822_1.jpg
|
| 1738 |
+
016757_0.jpg 009730_1.jpg
|
| 1739 |
+
016765_0.jpg 007180_1.jpg
|
| 1740 |
+
016777_0.jpg 000066_1.jpg
|
| 1741 |
+
016786_0.jpg 017340_1.jpg
|
| 1742 |
+
016799_0.jpg 007656_1.jpg
|
| 1743 |
+
016812_0.jpg 003032_1.jpg
|
| 1744 |
+
016820_0.jpg 000776_1.jpg
|
| 1745 |
+
016831_0.jpg 007702_1.jpg
|
| 1746 |
+
016839_0.jpg 004609_1.jpg
|
| 1747 |
+
016853_0.jpg 003386_1.jpg
|
| 1748 |
+
016866_0.jpg 010778_1.jpg
|
| 1749 |
+
016878_0.jpg 012479_1.jpg
|
| 1750 |
+
016888_0.jpg 003703_1.jpg
|
| 1751 |
+
016899_0.jpg 002778_1.jpg
|
| 1752 |
+
016908_0.jpg 018867_1.jpg
|
| 1753 |
+
016921_0.jpg 004177_1.jpg
|
| 1754 |
+
016929_0.jpg 005683_1.jpg
|
| 1755 |
+
016943_0.jpg 000109_1.jpg
|
| 1756 |
+
016951_0.jpg 006928_1.jpg
|
| 1757 |
+
016962_0.jpg 014675_1.jpg
|
| 1758 |
+
016971_0.jpg 007940_1.jpg
|
| 1759 |
+
016981_0.jpg 019270_1.jpg
|
| 1760 |
+
016992_0.jpg 013547_1.jpg
|
| 1761 |
+
017002_0.jpg 013665_1.jpg
|
| 1762 |
+
017012_0.jpg 008881_1.jpg
|
| 1763 |
+
017021_0.jpg 000048_1.jpg
|
| 1764 |
+
017030_0.jpg 004139_1.jpg
|
| 1765 |
+
017041_0.jpg 003236_1.jpg
|
| 1766 |
+
017051_0.jpg 001136_1.jpg
|
| 1767 |
+
017062_0.jpg 001320_1.jpg
|
| 1768 |
+
017070_0.jpg 016121_1.jpg
|
| 1769 |
+
017079_0.jpg 014728_1.jpg
|
| 1770 |
+
017091_0.jpg 010215_1.jpg
|
| 1771 |
+
017099_0.jpg 004941_1.jpg
|
| 1772 |
+
017110_0.jpg 018183_1.jpg
|
| 1773 |
+
017118_0.jpg 001048_1.jpg
|
| 1774 |
+
017130_0.jpg 002901_1.jpg
|
| 1775 |
+
017145_0.jpg 008793_1.jpg
|
| 1776 |
+
017153_0.jpg 015114_1.jpg
|
| 1777 |
+
017167_0.jpg 007168_1.jpg
|
| 1778 |
+
017175_0.jpg 014639_1.jpg
|
| 1779 |
+
017188_0.jpg 001706_1.jpg
|
| 1780 |
+
017196_0.jpg 010308_1.jpg
|
| 1781 |
+
017204_0.jpg 016349_1.jpg
|
| 1782 |
+
017213_0.jpg 002362_1.jpg
|
| 1783 |
+
017227_0.jpg 001219_1.jpg
|
| 1784 |
+
017235_0.jpg 010559_1.jpg
|
| 1785 |
+
017243_0.jpg 003024_1.jpg
|
| 1786 |
+
017254_0.jpg 003591_1.jpg
|
| 1787 |
+
017264_0.jpg 017358_1.jpg
|
| 1788 |
+
017273_0.jpg 004042_1.jpg
|
| 1789 |
+
017282_0.jpg 012377_1.jpg
|
| 1790 |
+
017290_0.jpg 007762_1.jpg
|
| 1791 |
+
017298_0.jpg 015247_1.jpg
|
| 1792 |
+
017306_0.jpg 018787_1.jpg
|
| 1793 |
+
017315_0.jpg 010503_1.jpg
|
| 1794 |
+
017323_0.jpg 000602_1.jpg
|
| 1795 |
+
017332_0.jpg 001635_1.jpg
|
| 1796 |
+
017340_0.jpg 006842_1.jpg
|
| 1797 |
+
017348_0.jpg 017482_1.jpg
|
| 1798 |
+
017358_0.jpg 012440_1.jpg
|
| 1799 |
+
017370_0.jpg 019215_1.jpg
|
| 1800 |
+
017382_0.jpg 019590_1.jpg
|
| 1801 |
+
017390_0.jpg 003990_1.jpg
|
| 1802 |
+
017400_0.jpg 008334_1.jpg
|
| 1803 |
+
017410_0.jpg 017213_1.jpg
|
| 1804 |
+
017418_0.jpg 010392_1.jpg
|
| 1805 |
+
017428_0.jpg 018991_1.jpg
|
| 1806 |
+
017438_0.jpg 001817_1.jpg
|
| 1807 |
+
017449_0.jpg 014950_1.jpg
|
| 1808 |
+
017457_0.jpg 006649_1.jpg
|
| 1809 |
+
017466_0.jpg 013437_1.jpg
|
| 1810 |
+
017474_0.jpg 016602_1.jpg
|
| 1811 |
+
017482_0.jpg 007269_1.jpg
|
| 1812 |
+
017496_0.jpg 011495_1.jpg
|
| 1813 |
+
017505_0.jpg 000386_1.jpg
|
| 1814 |
+
017514_0.jpg 013190_1.jpg
|
| 1815 |
+
017526_0.jpg 004387_1.jpg
|
| 1816 |
+
017536_0.jpg 003328_1.jpg
|
| 1817 |
+
017545_0.jpg 006799_1.jpg
|
| 1818 |
+
017555_0.jpg 012413_1.jpg
|
| 1819 |
+
017563_0.jpg 008515_1.jpg
|
| 1820 |
+
017575_0.jpg 010152_1.jpg
|
| 1821 |
+
017583_0.jpg 011328_1.jpg
|
| 1822 |
+
017592_0.jpg 018910_1.jpg
|
| 1823 |
+
017600_0.jpg 018718_1.jpg
|
| 1824 |
+
017613_0.jpg 000378_1.jpg
|
| 1825 |
+
017622_0.jpg 019193_1.jpg
|
| 1826 |
+
017630_0.jpg 018280_1.jpg
|
| 1827 |
+
017639_0.jpg 013181_1.jpg
|
| 1828 |
+
017648_0.jpg 011363_1.jpg
|
| 1829 |
+
017657_0.jpg 001173_1.jpg
|
| 1830 |
+
017667_0.jpg 004243_1.jpg
|
| 1831 |
+
017678_0.jpg 013959_1.jpg
|
| 1832 |
+
017688_0.jpg 016908_1.jpg
|
| 1833 |
+
017701_0.jpg 013539_1.jpg
|
| 1834 |
+
017710_0.jpg 013456_1.jpg
|
| 1835 |
+
017722_0.jpg 004234_1.jpg
|
| 1836 |
+
017730_0.jpg 001203_1.jpg
|
| 1837 |
+
017740_0.jpg 013400_1.jpg
|
| 1838 |
+
017750_0.jpg 011781_1.jpg
|
| 1839 |
+
017761_0.jpg 011258_1.jpg
|
| 1840 |
+
017770_0.jpg 006908_1.jpg
|
| 1841 |
+
017779_0.jpg 009660_1.jpg
|
| 1842 |
+
017788_0.jpg 002191_1.jpg
|
| 1843 |
+
017796_0.jpg 006757_1.jpg
|
| 1844 |
+
017805_0.jpg 005857_1.jpg
|
| 1845 |
+
017814_0.jpg 011641_1.jpg
|
| 1846 |
+
017823_0.jpg 007923_1.jpg
|
| 1847 |
+
017831_0.jpg 004949_1.jpg
|
| 1848 |
+
017840_0.jpg 018580_1.jpg
|
| 1849 |
+
017852_0.jpg 017999_1.jpg
|
| 1850 |
+
017860_0.jpg 008653_1.jpg
|
| 1851 |
+
017868_0.jpg 011980_1.jpg
|
| 1852 |
+
017877_0.jpg 017382_1.jpg
|
| 1853 |
+
017886_0.jpg 011899_1.jpg
|
| 1854 |
+
017896_0.jpg 002169_1.jpg
|
| 1855 |
+
017904_0.jpg 010318_1.jpg
|
| 1856 |
+
017914_0.jpg 017740_1.jpg
|
| 1857 |
+
017922_0.jpg 011221_1.jpg
|
| 1858 |
+
017932_0.jpg 004989_1.jpg
|
| 1859 |
+
017945_0.jpg 003915_1.jpg
|
| 1860 |
+
017957_0.jpg 001789_1.jpg
|
| 1861 |
+
017965_0.jpg 003925_1.jpg
|
| 1862 |
+
017974_0.jpg 002337_1.jpg
|
| 1863 |
+
017982_0.jpg 008624_1.jpg
|
| 1864 |
+
017990_0.jpg 004220_1.jpg
|
| 1865 |
+
017999_0.jpg 001594_1.jpg
|
| 1866 |
+
018009_0.jpg 006004_1.jpg
|
| 1867 |
+
018018_0.jpg 019350_1.jpg
|
| 1868 |
+
018031_0.jpg 018552_1.jpg
|
| 1869 |
+
018039_0.jpg 010031_1.jpg
|
| 1870 |
+
018047_0.jpg 013256_1.jpg
|
| 1871 |
+
018059_0.jpg 001809_1.jpg
|
| 1872 |
+
018069_0.jpg 006868_1.jpg
|
| 1873 |
+
018080_0.jpg 000303_1.jpg
|
| 1874 |
+
018089_0.jpg 007882_1.jpg
|
| 1875 |
+
018102_0.jpg 016676_1.jpg
|
| 1876 |
+
018112_0.jpg 009619_1.jpg
|
| 1877 |
+
018121_0.jpg 017965_1.jpg
|
| 1878 |
+
018129_0.jpg 010049_1.jpg
|
| 1879 |
+
018138_0.jpg 018938_1.jpg
|
| 1880 |
+
018146_0.jpg 014209_1.jpg
|
| 1881 |
+
018159_0.jpg 007549_1.jpg
|
| 1882 |
+
018167_0.jpg 009054_1.jpg
|
| 1883 |
+
018175_0.jpg 008214_1.jpg
|
| 1884 |
+
018183_0.jpg 003319_1.jpg
|
| 1885 |
+
018192_0.jpg 016206_1.jpg
|
| 1886 |
+
018200_0.jpg 017914_1.jpg
|
| 1887 |
+
018210_0.jpg 016820_1.jpg
|
| 1888 |
+
018219_0.jpg 007781_1.jpg
|
| 1889 |
+
018227_0.jpg 006545_1.jpg
|
| 1890 |
+
018236_0.jpg 001153_1.jpg
|
| 1891 |
+
018245_0.jpg 000426_1.jpg
|
| 1892 |
+
018254_0.jpg 014123_1.jpg
|
| 1893 |
+
018263_0.jpg 006678_1.jpg
|
| 1894 |
+
018271_0.jpg 017254_1.jpg
|
| 1895 |
+
018280_0.jpg 001900_1.jpg
|
| 1896 |
+
018291_0.jpg 019234_1.jpg
|
| 1897 |
+
018300_0.jpg 012636_1.jpg
|
| 1898 |
+
018309_0.jpg 001908_1.jpg
|
| 1899 |
+
018318_0.jpg 017188_1.jpg
|
| 1900 |
+
018327_0.jpg 009291_1.jpg
|
| 1901 |
+
018337_0.jpg 009932_1.jpg
|
| 1902 |
+
018348_0.jpg 003049_1.jpg
|
| 1903 |
+
018357_0.jpg 003280_1.jpg
|
| 1904 |
+
018366_0.jpg 000010_1.jpg
|
| 1905 |
+
018375_0.jpg 015946_1.jpg
|
| 1906 |
+
018393_0.jpg 002699_1.jpg
|
| 1907 |
+
018401_0.jpg 002502_1.jpg
|
| 1908 |
+
018411_0.jpg 004620_1.jpg
|
| 1909 |
+
018420_0.jpg 002828_1.jpg
|
| 1910 |
+
018431_0.jpg 016524_1.jpg
|
| 1911 |
+
018441_0.jpg 005091_1.jpg
|
| 1912 |
+
018452_0.jpg 015299_1.jpg
|
| 1913 |
+
018460_0.jpg 011996_1.jpg
|
| 1914 |
+
018470_0.jpg 006937_1.jpg
|
| 1915 |
+
018479_0.jpg 003861_1.jpg
|
| 1916 |
+
018488_0.jpg 015748_1.jpg
|
| 1917 |
+
018496_0.jpg 005940_1.jpg
|
| 1918 |
+
018507_0.jpg 001765_1.jpg
|
| 1919 |
+
018515_0.jpg 013798_1.jpg
|
| 1920 |
+
018524_0.jpg 017332_1.jpg
|
| 1921 |
+
018532_0.jpg 005404_1.jpg
|
| 1922 |
+
018544_0.jpg 010797_1.jpg
|
| 1923 |
+
018552_0.jpg 006419_1.jpg
|
| 1924 |
+
018561_0.jpg 019078_1.jpg
|
| 1925 |
+
018569_0.jpg 014564_1.jpg
|
| 1926 |
+
018580_0.jpg 008830_1.jpg
|
| 1927 |
+
018590_0.jpg 016571_1.jpg
|
| 1928 |
+
018598_0.jpg 011745_1.jpg
|
| 1929 |
+
018608_0.jpg 000347_1.jpg
|
| 1930 |
+
018618_0.jpg 003739_1.jpg
|
| 1931 |
+
018626_0.jpg 011662_1.jpg
|
| 1932 |
+
018636_0.jpg 001399_1.jpg
|
| 1933 |
+
018644_0.jpg 004912_1.jpg
|
| 1934 |
+
018652_0.jpg 017600_1.jpg
|
| 1935 |
+
018662_0.jpg 018175_1.jpg
|
| 1936 |
+
018671_0.jpg 013939_1.jpg
|
| 1937 |
+
018681_0.jpg 006768_1.jpg
|
| 1938 |
+
018690_0.jpg 014604_1.jpg
|
| 1939 |
+
018700_0.jpg 009643_1.jpg
|
| 1940 |
+
018710_0.jpg 005542_1.jpg
|
| 1941 |
+
018718_0.jpg 003555_1.jpg
|
| 1942 |
+
018729_0.jpg 006073_1.jpg
|
| 1943 |
+
018737_0.jpg 014720_1.jpg
|
| 1944 |
+
018746_0.jpg 017030_1.jpg
|
| 1945 |
+
018755_0.jpg 017505_1.jpg
|
| 1946 |
+
018769_0.jpg 003270_1.jpg
|
| 1947 |
+
018778_0.jpg 007045_1.jpg
|
| 1948 |
+
018787_0.jpg 004823_1.jpg
|
| 1949 |
+
018796_0.jpg 007278_1.jpg
|
| 1950 |
+
018807_0.jpg 002659_1.jpg
|
| 1951 |
+
018817_0.jpg 008551_1.jpg
|
| 1952 |
+
018826_0.jpg 011318_1.jpg
|
| 1953 |
+
018837_0.jpg 016620_1.jpg
|
| 1954 |
+
018848_0.jpg 011933_1.jpg
|
| 1955 |
+
018858_0.jpg 019360_1.jpg
|
| 1956 |
+
018867_0.jpg 004545_1.jpg
|
| 1957 |
+
018876_0.jpg 000192_1.jpg
|
| 1958 |
+
018884_0.jpg 005809_1.jpg
|
| 1959 |
+
018894_0.jpg 012369_1.jpg
|
| 1960 |
+
018902_0.jpg 019581_1.jpg
|
| 1961 |
+
018910_0.jpg 004745_1.jpg
|
| 1962 |
+
018921_0.jpg 013233_1.jpg
|
| 1963 |
+
018929_0.jpg 008570_1.jpg
|
| 1964 |
+
018938_0.jpg 012564_1.jpg
|
| 1965 |
+
018946_0.jpg 013915_1.jpg
|
| 1966 |
+
018954_0.jpg 011872_1.jpg
|
| 1967 |
+
018962_0.jpg 014930_1.jpg
|
| 1968 |
+
018971_0.jpg 017823_1.jpg
|
| 1969 |
+
018980_0.jpg 018366_1.jpg
|
| 1970 |
+
018991_0.jpg 006897_1.jpg
|
| 1971 |
+
019001_0.jpg 010473_1.jpg
|
| 1972 |
+
019009_0.jpg 011924_1.jpg
|
| 1973 |
+
019018_0.jpg 001575_1.jpg
|
| 1974 |
+
019029_0.jpg 002970_1.jpg
|
| 1975 |
+
019037_0.jpg 000477_1.jpg
|
| 1976 |
+
019045_0.jpg 018080_1.jpg
|
| 1977 |
+
019053_0.jpg 008616_1.jpg
|
| 1978 |
+
019066_0.jpg 017852_1.jpg
|
| 1979 |
+
019078_0.jpg 007639_1.jpg
|
| 1980 |
+
019087_0.jpg 000907_1.jpg
|
| 1981 |
+
019096_0.jpg 009312_1.jpg
|
| 1982 |
+
019110_0.jpg 004657_1.jpg
|
| 1983 |
+
019119_0.jpg 001028_1.jpg
|
| 1984 |
+
019130_0.jpg 006232_1.jpg
|
| 1985 |
+
019140_0.jpg 011203_1.jpg
|
| 1986 |
+
019154_0.jpg 012795_1.jpg
|
| 1987 |
+
019166_0.jpg 013068_1.jpg
|
| 1988 |
+
019174_0.jpg 000097_1.jpg
|
| 1989 |
+
019183_0.jpg 009872_1.jpg
|
| 1990 |
+
019193_0.jpg 013428_1.jpg
|
| 1991 |
+
019204_0.jpg 016075_1.jpg
|
| 1992 |
+
019215_0.jpg 004071_1.jpg
|
| 1993 |
+
019224_0.jpg 011475_1.jpg
|
| 1994 |
+
019234_0.jpg 013642_1.jpg
|
| 1995 |
+
019243_0.jpg 018271_1.jpg
|
| 1996 |
+
019252_0.jpg 011552_1.jpg
|
| 1997 |
+
019262_0.jpg 005594_1.jpg
|
| 1998 |
+
019270_0.jpg 016405_1.jpg
|
| 1999 |
+
019279_0.jpg 010329_1.jpg
|
| 2000 |
+
019287_0.jpg 010493_1.jpg
|
| 2001 |
+
019302_0.jpg 018089_1.jpg
|
| 2002 |
+
019310_0.jpg 019262_1.jpg
|
| 2003 |
+
019319_0.jpg 017788_1.jpg
|
| 2004 |
+
019332_0.jpg 014774_1.jpg
|
| 2005 |
+
019340_0.jpg 009254_1.jpg
|
| 2006 |
+
019350_0.jpg 012725_1.jpg
|
| 2007 |
+
019360_0.jpg 008317_1.jpg
|
| 2008 |
+
019368_0.jpg 000629_1.jpg
|
| 2009 |
+
019376_0.jpg 017575_1.jpg
|
| 2010 |
+
019384_0.jpg 007324_1.jpg
|
| 2011 |
+
019393_0.jpg 013139_1.jpg
|
| 2012 |
+
019402_0.jpg 012868_1.jpg
|
| 2013 |
+
019411_0.jpg 001228_1.jpg
|
| 2014 |
+
019420_0.jpg 006347_1.jpg
|
| 2015 |
+
019429_0.jpg 006494_1.jpg
|
| 2016 |
+
019438_0.jpg 008590_1.jpg
|
| 2017 |
+
019446_0.jpg 006571_1.jpg
|
| 2018 |
+
019454_0.jpg 012228_1.jpg
|
| 2019 |
+
019465_0.jpg 010003_1.jpg
|
| 2020 |
+
019475_0.jpg 006304_1.jpg
|
| 2021 |
+
019486_0.jpg 013019_1.jpg
|
| 2022 |
+
019494_0.jpg 010929_1.jpg
|
| 2023 |
+
019505_0.jpg 010753_1.jpg
|
| 2024 |
+
019514_0.jpg 012054_1.jpg
|
| 2025 |
+
019522_0.jpg 018102_1.jpg
|
| 2026 |
+
019531_0.jpg 015077_1.jpg
|
| 2027 |
+
019540_0.jpg 008151_1.jpg
|
| 2028 |
+
019552_0.jpg 003787_1.jpg
|
| 2029 |
+
019561_0.jpg 006090_1.jpg
|
| 2030 |
+
019573_0.jpg 008608_1.jpg
|
| 2031 |
+
019581_0.jpg 006081_1.jpg
|
| 2032 |
+
019590_0.jpg 012964_1.jpg
|
VITON-Extends_test/next.config.mjs
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/** @type {import('next').NextConfig} */
|
| 2 |
+
const nextConfig = {
|
| 3 |
+
eslint: {
|
| 4 |
+
ignoreDuringBuilds: true,
|
| 5 |
+
},
|
| 6 |
+
typescript: {
|
| 7 |
+
ignoreBuildErrors: true,
|
| 8 |
+
},
|
| 9 |
+
images: {
|
| 10 |
+
unoptimized: true,
|
| 11 |
+
},
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
export default nextConfig
|
VITON-Extends_test/output_2.png
ADDED
|
VITON-Extends_test/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "my-v0-project",
|
| 3 |
+
"version": "0.1.0",
|
| 4 |
+
"private": true,
|
| 5 |
+
"scripts": {
|
| 6 |
+
"dev": "next dev",
|
| 7 |
+
"build": "next build",
|
| 8 |
+
"start": "next start",
|
| 9 |
+
"lint": "next lint"
|
| 10 |
+
},
|
| 11 |
+
"dependencies": {
|
| 12 |
+
"@emotion/is-prop-valid": "latest",
|
| 13 |
+
"@hookform/resolvers": "^3.9.1",
|
| 14 |
+
"@radix-ui/react-accordion": "1.2.2",
|
| 15 |
+
"@radix-ui/react-alert-dialog": "1.1.4",
|
| 16 |
+
"@radix-ui/react-aspect-ratio": "1.1.1",
|
| 17 |
+
"@radix-ui/react-avatar": "1.1.2",
|
| 18 |
+
"@radix-ui/react-checkbox": "1.1.3",
|
| 19 |
+
"@radix-ui/react-collapsible": "1.1.2",
|
| 20 |
+
"@radix-ui/react-context-menu": "2.2.4",
|
| 21 |
+
"@radix-ui/react-dialog": "1.1.4",
|
| 22 |
+
"@radix-ui/react-dropdown-menu": "2.1.4",
|
| 23 |
+
"@radix-ui/react-hover-card": "1.1.4",
|
| 24 |
+
"@radix-ui/react-label": "2.1.1",
|
| 25 |
+
"@radix-ui/react-menubar": "1.1.4",
|
| 26 |
+
"@radix-ui/react-navigation-menu": "1.2.3",
|
| 27 |
+
"@radix-ui/react-popover": "1.1.4",
|
| 28 |
+
"@radix-ui/react-progress": "1.1.1",
|
| 29 |
+
"@radix-ui/react-radio-group": "1.2.2",
|
| 30 |
+
"@radix-ui/react-scroll-area": "1.2.2",
|
| 31 |
+
"@radix-ui/react-select": "2.1.4",
|
| 32 |
+
"@radix-ui/react-separator": "1.1.1",
|
| 33 |
+
"@radix-ui/react-slider": "1.2.2",
|
| 34 |
+
"@radix-ui/react-slot": "1.1.1",
|
| 35 |
+
"@radix-ui/react-switch": "1.1.2",
|
| 36 |
+
"@radix-ui/react-tabs": "1.1.2",
|
| 37 |
+
"@radix-ui/react-toast": "1.2.4",
|
| 38 |
+
"@radix-ui/react-toggle": "1.1.1",
|
| 39 |
+
"@radix-ui/react-toggle-group": "1.1.1",
|
| 40 |
+
"@radix-ui/react-tooltip": "1.1.6",
|
| 41 |
+
"autoprefixer": "^10.4.20",
|
| 42 |
+
"class-variance-authority": "^0.7.1",
|
| 43 |
+
"clsx": "^2.1.1",
|
| 44 |
+
"cmdk": "1.0.4",
|
| 45 |
+
"date-fns": "4.1.0",
|
| 46 |
+
"embla-carousel-react": "8.5.1",
|
| 47 |
+
"framer-motion": "latest",
|
| 48 |
+
"input-otp": "1.4.1",
|
| 49 |
+
"lucide-react": "^0.454.0",
|
| 50 |
+
"next": "15.2.4",
|
| 51 |
+
"next-themes": "^0.4.4",
|
| 52 |
+
"react": "^19",
|
| 53 |
+
"react-day-picker": "8.10.1",
|
| 54 |
+
"react-dom": "^19",
|
| 55 |
+
"react-hook-form": "^7.54.1",
|
| 56 |
+
"react-resizable-panels": "^2.1.7",
|
| 57 |
+
"recharts": "2.15.0",
|
| 58 |
+
"sonner": "^1.7.1",
|
| 59 |
+
"tailwind-merge": "^2.5.5",
|
| 60 |
+
"tailwindcss-animate": "^1.0.7",
|
| 61 |
+
"vaul": "^0.9.6",
|
| 62 |
+
"zod": "^3.24.1"
|
| 63 |
+
},
|
| 64 |
+
"devDependencies": {
|
| 65 |
+
"@types/node": "^22",
|
| 66 |
+
"@types/react": "^19",
|
| 67 |
+
"@types/react-dom": "^19",
|
| 68 |
+
"postcss": "^8",
|
| 69 |
+
"tailwindcss": "^3.4.17",
|
| 70 |
+
"typescript": "^5"
|
| 71 |
+
}
|
| 72 |
+
}
|
VITON-Extends_test/pnpm-lock.yaml
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
lockfileVersion: '9.0'
|
| 2 |
+
|
| 3 |
+
settings:
|
| 4 |
+
autoInstallPeers: true
|
| 5 |
+
excludeLinksFromLockfile: false
|
VITON-Extends_test/postcss.config.mjs
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/** @type {import('postcss-load-config').Config} */
|
| 2 |
+
const config = {
|
| 3 |
+
plugins: {
|
| 4 |
+
tailwindcss: {},
|
| 5 |
+
},
|
| 6 |
+
};
|
| 7 |
+
|
| 8 |
+
export default config;
|
VITON-Extends_test/tailwind.config.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Config } from "tailwindcss"
|
| 2 |
+
|
| 3 |
+
const config = {
|
| 4 |
+
darkMode: ["class"],
|
| 5 |
+
content: [
|
| 6 |
+
"./pages/**/*.{ts,tsx}",
|
| 7 |
+
"./components/**/*.{ts,tsx}",
|
| 8 |
+
"./app/**/*.{ts,tsx}",
|
| 9 |
+
"./src/**/*.{ts,tsx}",
|
| 10 |
+
"*.{js,ts,jsx,tsx,mdx}",
|
| 11 |
+
],
|
| 12 |
+
prefix: "",
|
| 13 |
+
theme: {
|
| 14 |
+
container: {
|
| 15 |
+
center: true,
|
| 16 |
+
padding: "2rem",
|
| 17 |
+
screens: {
|
| 18 |
+
"2xl": "1400px",
|
| 19 |
+
},
|
| 20 |
+
},
|
| 21 |
+
extend: {
|
| 22 |
+
colors: {
|
| 23 |
+
border: "hsl(var(--border))",
|
| 24 |
+
input: "hsl(var(--input))",
|
| 25 |
+
ring: "hsl(var(--ring))",
|
| 26 |
+
background: "hsl(var(--background))",
|
| 27 |
+
foreground: "hsl(var(--foreground))",
|
| 28 |
+
primary: {
|
| 29 |
+
DEFAULT: "hsl(var(--primary))",
|
| 30 |
+
foreground: "hsl(var(--primary-foreground))",
|
| 31 |
+
},
|
| 32 |
+
secondary: {
|
| 33 |
+
DEFAULT: "hsl(var(--secondary))",
|
| 34 |
+
foreground: "hsl(var(--secondary-foreground))",
|
| 35 |
+
},
|
| 36 |
+
destructive: {
|
| 37 |
+
DEFAULT: "hsl(var(--destructive))",
|
| 38 |
+
foreground: "hsl(var(--destructive-foreground))",
|
| 39 |
+
},
|
| 40 |
+
muted: {
|
| 41 |
+
DEFAULT: "hsl(var(--muted))",
|
| 42 |
+
foreground: "hsl(var(--muted-foreground))",
|
| 43 |
+
},
|
| 44 |
+
accent: {
|
| 45 |
+
DEFAULT: "hsl(var(--accent))",
|
| 46 |
+
foreground: "hsl(var(--accent-foreground))",
|
| 47 |
+
},
|
| 48 |
+
popover: {
|
| 49 |
+
DEFAULT: "hsl(var(--popover))",
|
| 50 |
+
foreground: "hsl(var(--popover-foreground))",
|
| 51 |
+
},
|
| 52 |
+
card: {
|
| 53 |
+
DEFAULT: "hsl(var(--card))",
|
| 54 |
+
foreground: "hsl(var(--card-foreground))",
|
| 55 |
+
},
|
| 56 |
+
purple: {
|
| 57 |
+
50: "#f5f3ff",
|
| 58 |
+
100: "#ede9fe",
|
| 59 |
+
200: "#ddd6fe",
|
| 60 |
+
300: "#c4b5fd",
|
| 61 |
+
400: "#a78bfa",
|
| 62 |
+
500: "#8b5cf6",
|
| 63 |
+
600: "#7c3aed",
|
| 64 |
+
700: "#6d28d9",
|
| 65 |
+
800: "#5b21b6",
|
| 66 |
+
900: "#4c1d95",
|
| 67 |
+
950: "#2e1065",
|
| 68 |
+
},
|
| 69 |
+
},
|
| 70 |
+
borderRadius: {
|
| 71 |
+
lg: "var(--radius)",
|
| 72 |
+
md: "calc(var(--radius) - 2px)",
|
| 73 |
+
sm: "calc(var(--radius) - 4px)",
|
| 74 |
+
},
|
| 75 |
+
keyframes: {
|
| 76 |
+
"accordion-down": {
|
| 77 |
+
from: { height: "0" },
|
| 78 |
+
to: { height: "var(--radix-accordion-content-height)" },
|
| 79 |
+
},
|
| 80 |
+
"accordion-up": {
|
| 81 |
+
from: { height: "var(--radix-accordion-content-height)" },
|
| 82 |
+
to: { height: "0" },
|
| 83 |
+
},
|
| 84 |
+
},
|
| 85 |
+
animation: {
|
| 86 |
+
"accordion-down": "accordion-down 0.2s ease-out",
|
| 87 |
+
"accordion-up": "accordion-up 0.2s ease-out",
|
| 88 |
+
},
|
| 89 |
+
},
|
| 90 |
+
},
|
| 91 |
+
plugins: [require("tailwindcss-animate")],
|
| 92 |
+
} satisfies Config
|
| 93 |
+
|
| 94 |
+
export default config
|
VITON-Extends_test/test.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import time
|
| 2 |
+
from options.test_options import TestOptions
|
| 3 |
+
from data.data_loader_test import CreateDataLoader
|
| 4 |
+
from models.networks import ResUnetGenerator, load_checkpoint
|
| 5 |
+
from models.afwm import AFWM
|
| 6 |
+
import torch.nn as nn
|
| 7 |
+
import os
|
| 8 |
+
import numpy as np
|
| 9 |
+
import torch
|
| 10 |
+
import cv2
|
| 11 |
+
import torch.nn.functional as F
|
| 12 |
+
if __name__ == '__main__':
|
| 13 |
+
opt = TestOptions().parse()
|
| 14 |
+
|
| 15 |
+
start_epoch, epoch_iter = 1, 0
|
| 16 |
+
|
| 17 |
+
data_loader = CreateDataLoader(opt)
|
| 18 |
+
dataset = data_loader.load_data()
|
| 19 |
+
dataset_size = len(data_loader)
|
| 20 |
+
print(dataset_size)
|
| 21 |
+
|
| 22 |
+
warp_model = AFWM(opt, 3)
|
| 23 |
+
print(warp_model)
|
| 24 |
+
warp_model.eval()
|
| 25 |
+
warp_model.cuda()
|
| 26 |
+
load_checkpoint(warp_model, opt.warp_checkpoint)
|
| 27 |
+
|
| 28 |
+
gen_model = ResUnetGenerator(7, 4, 5, ngf=64, norm_layer=nn.BatchNorm2d)
|
| 29 |
+
print(gen_model)
|
| 30 |
+
gen_model.eval()
|
| 31 |
+
gen_model.cuda()
|
| 32 |
+
load_checkpoint(gen_model, opt.gen_checkpoint)
|
| 33 |
+
|
| 34 |
+
total_steps = (start_epoch-1) * dataset_size + epoch_iter
|
| 35 |
+
step = 0
|
| 36 |
+
step_per_batch = dataset_size / opt.batchSize
|
| 37 |
+
|
| 38 |
+
for epoch in range(1,2):
|
| 39 |
+
|
| 40 |
+
for i, data in enumerate(dataset, start=epoch_iter):
|
| 41 |
+
iter_start_time = time.time()
|
| 42 |
+
total_steps += opt.batchSize
|
| 43 |
+
epoch_iter += opt.batchSize
|
| 44 |
+
|
| 45 |
+
real_image = data['image']
|
| 46 |
+
clothes = data['clothes']
|
| 47 |
+
##edge is extracted from the clothes image with the built-in function in python
|
| 48 |
+
edge = data['edge']
|
| 49 |
+
edge = torch.FloatTensor((edge.detach().numpy() > 0.5).astype(int))
|
| 50 |
+
clothes = clothes * edge
|
| 51 |
+
|
| 52 |
+
flow_out = warp_model(real_image.cuda(), clothes.cuda())
|
| 53 |
+
warped_cloth, last_flow, = flow_out
|
| 54 |
+
warped_edge = F.grid_sample(edge.cuda(), last_flow.permute(0, 2, 3, 1),
|
| 55 |
+
mode='bilinear', padding_mode='zeros')
|
| 56 |
+
|
| 57 |
+
gen_inputs = torch.cat([real_image.cuda(), warped_cloth, warped_edge], 1)
|
| 58 |
+
gen_outputs = gen_model(gen_inputs)
|
| 59 |
+
p_rendered, m_composite = torch.split(gen_outputs, [3, 1], 1)
|
| 60 |
+
p_rendered = torch.tanh(p_rendered)
|
| 61 |
+
m_composite = torch.sigmoid(m_composite)
|
| 62 |
+
m_composite = m_composite * warped_edge
|
| 63 |
+
p_tryon = warped_cloth * m_composite + p_rendered * (1 - m_composite)
|
| 64 |
+
|
| 65 |
+
path = 'results/' + opt.name
|
| 66 |
+
os.makedirs(path, exist_ok=True)
|
| 67 |
+
sub_path = path + '/VITON-Extends'
|
| 68 |
+
os.makedirs(sub_path,exist_ok=True)
|
| 69 |
+
|
| 70 |
+
if step % 1 == 0:
|
| 71 |
+
a = real_image.float().cuda()
|
| 72 |
+
b= clothes.cuda()
|
| 73 |
+
c = p_tryon
|
| 74 |
+
combine = torch.cat([a[0],b[0],c[0]], 2).squeeze()
|
| 75 |
+
cv_img=(combine.permute(1,2,0).detach().cpu().numpy()+1)/2
|
| 76 |
+
rgb=(cv_img*255).astype(np.uint8)
|
| 77 |
+
bgr=cv2.cvtColor(rgb,cv2.COLOR_RGB2BGR)
|
| 78 |
+
cv2.imwrite(sub_path+'/'+str(step)+'.jpg',bgr)
|
| 79 |
+
|
| 80 |
+
step += 1
|
| 81 |
+
if epoch_iter >= dataset_size:
|
| 82 |
+
break
|
| 83 |
+
|
| 84 |
+
|
VITON-Extends_test/test.sh
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
python test.py --name demo --resize_or_crop None --batchSize 1 --gpu_ids 0
|
VITON-Extends_test/test_1.jpg
ADDED
|
VITON-Extends_test/test_2.jpg
ADDED
|
VITON-Extends_test/tsconfig.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"compilerOptions": {
|
| 3 |
+
"lib": ["dom", "dom.iterable", "esnext"],
|
| 4 |
+
"allowJs": true,
|
| 5 |
+
"target": "ES6",
|
| 6 |
+
"skipLibCheck": true,
|
| 7 |
+
"strict": true,
|
| 8 |
+
"noEmit": true,
|
| 9 |
+
"esModuleInterop": true,
|
| 10 |
+
"module": "esnext",
|
| 11 |
+
"moduleResolution": "bundler",
|
| 12 |
+
"resolveJsonModule": true,
|
| 13 |
+
"isolatedModules": true,
|
| 14 |
+
"jsx": "preserve",
|
| 15 |
+
"incremental": true,
|
| 16 |
+
"plugins": [
|
| 17 |
+
{
|
| 18 |
+
"name": "next"
|
| 19 |
+
}
|
| 20 |
+
],
|
| 21 |
+
"paths": {
|
| 22 |
+
"@/*": ["./*"]
|
| 23 |
+
}
|
| 24 |
+
},
|
| 25 |
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
| 26 |
+
"exclude": ["node_modules"]
|
| 27 |
+
}
|
VITON-Extends_test/u2net.py
ADDED
|
@@ -0,0 +1,525 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
import torch.nn as nn
|
| 3 |
+
import torch.nn.functional as F
|
| 4 |
+
|
| 5 |
+
class REBNCONV(nn.Module):
|
| 6 |
+
def __init__(self,in_ch=3,out_ch=3,dirate=1):
|
| 7 |
+
super(REBNCONV,self).__init__()
|
| 8 |
+
|
| 9 |
+
self.conv_s1 = nn.Conv2d(in_ch,out_ch,3,padding=1*dirate,dilation=1*dirate)
|
| 10 |
+
self.bn_s1 = nn.BatchNorm2d(out_ch)
|
| 11 |
+
self.relu_s1 = nn.ReLU(inplace=True)
|
| 12 |
+
|
| 13 |
+
def forward(self,x):
|
| 14 |
+
|
| 15 |
+
hx = x
|
| 16 |
+
xout = self.relu_s1(self.bn_s1(self.conv_s1(hx)))
|
| 17 |
+
|
| 18 |
+
return xout
|
| 19 |
+
|
| 20 |
+
## upsample tensor 'src' to have the same spatial size with tensor 'tar'
|
| 21 |
+
def _upsample_like(src,tar):
|
| 22 |
+
|
| 23 |
+
src = F.upsample(src,size=tar.shape[2:],mode='bilinear')
|
| 24 |
+
|
| 25 |
+
return src
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
### RSU-7 ###
|
| 29 |
+
class RSU7(nn.Module):#UNet07DRES(nn.Module):
|
| 30 |
+
|
| 31 |
+
def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
|
| 32 |
+
super(RSU7,self).__init__()
|
| 33 |
+
|
| 34 |
+
self.rebnconvin = REBNCONV(in_ch,out_ch,dirate=1)
|
| 35 |
+
|
| 36 |
+
self.rebnconv1 = REBNCONV(out_ch,mid_ch,dirate=1)
|
| 37 |
+
self.pool1 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 38 |
+
|
| 39 |
+
self.rebnconv2 = REBNCONV(mid_ch,mid_ch,dirate=1)
|
| 40 |
+
self.pool2 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 41 |
+
|
| 42 |
+
self.rebnconv3 = REBNCONV(mid_ch,mid_ch,dirate=1)
|
| 43 |
+
self.pool3 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 44 |
+
|
| 45 |
+
self.rebnconv4 = REBNCONV(mid_ch,mid_ch,dirate=1)
|
| 46 |
+
self.pool4 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 47 |
+
|
| 48 |
+
self.rebnconv5 = REBNCONV(mid_ch,mid_ch,dirate=1)
|
| 49 |
+
self.pool5 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 50 |
+
|
| 51 |
+
self.rebnconv6 = REBNCONV(mid_ch,mid_ch,dirate=1)
|
| 52 |
+
|
| 53 |
+
self.rebnconv7 = REBNCONV(mid_ch,mid_ch,dirate=2)
|
| 54 |
+
|
| 55 |
+
self.rebnconv6d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
|
| 56 |
+
self.rebnconv5d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
|
| 57 |
+
self.rebnconv4d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
|
| 58 |
+
self.rebnconv3d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
|
| 59 |
+
self.rebnconv2d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
|
| 60 |
+
self.rebnconv1d = REBNCONV(mid_ch*2,out_ch,dirate=1)
|
| 61 |
+
|
| 62 |
+
def forward(self,x):
|
| 63 |
+
|
| 64 |
+
hx = x
|
| 65 |
+
hxin = self.rebnconvin(hx)
|
| 66 |
+
|
| 67 |
+
hx1 = self.rebnconv1(hxin)
|
| 68 |
+
hx = self.pool1(hx1)
|
| 69 |
+
|
| 70 |
+
hx2 = self.rebnconv2(hx)
|
| 71 |
+
hx = self.pool2(hx2)
|
| 72 |
+
|
| 73 |
+
hx3 = self.rebnconv3(hx)
|
| 74 |
+
hx = self.pool3(hx3)
|
| 75 |
+
|
| 76 |
+
hx4 = self.rebnconv4(hx)
|
| 77 |
+
hx = self.pool4(hx4)
|
| 78 |
+
|
| 79 |
+
hx5 = self.rebnconv5(hx)
|
| 80 |
+
hx = self.pool5(hx5)
|
| 81 |
+
|
| 82 |
+
hx6 = self.rebnconv6(hx)
|
| 83 |
+
|
| 84 |
+
hx7 = self.rebnconv7(hx6)
|
| 85 |
+
|
| 86 |
+
hx6d = self.rebnconv6d(torch.cat((hx7,hx6),1))
|
| 87 |
+
hx6dup = _upsample_like(hx6d,hx5)
|
| 88 |
+
|
| 89 |
+
hx5d = self.rebnconv5d(torch.cat((hx6dup,hx5),1))
|
| 90 |
+
hx5dup = _upsample_like(hx5d,hx4)
|
| 91 |
+
|
| 92 |
+
hx4d = self.rebnconv4d(torch.cat((hx5dup,hx4),1))
|
| 93 |
+
hx4dup = _upsample_like(hx4d,hx3)
|
| 94 |
+
|
| 95 |
+
hx3d = self.rebnconv3d(torch.cat((hx4dup,hx3),1))
|
| 96 |
+
hx3dup = _upsample_like(hx3d,hx2)
|
| 97 |
+
|
| 98 |
+
hx2d = self.rebnconv2d(torch.cat((hx3dup,hx2),1))
|
| 99 |
+
hx2dup = _upsample_like(hx2d,hx1)
|
| 100 |
+
|
| 101 |
+
hx1d = self.rebnconv1d(torch.cat((hx2dup,hx1),1))
|
| 102 |
+
|
| 103 |
+
return hx1d + hxin
|
| 104 |
+
|
| 105 |
+
### RSU-6 ###
|
| 106 |
+
class RSU6(nn.Module):#UNet06DRES(nn.Module):
|
| 107 |
+
|
| 108 |
+
def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
|
| 109 |
+
super(RSU6,self).__init__()
|
| 110 |
+
|
| 111 |
+
self.rebnconvin = REBNCONV(in_ch,out_ch,dirate=1)
|
| 112 |
+
|
| 113 |
+
self.rebnconv1 = REBNCONV(out_ch,mid_ch,dirate=1)
|
| 114 |
+
self.pool1 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 115 |
+
|
| 116 |
+
self.rebnconv2 = REBNCONV(mid_ch,mid_ch,dirate=1)
|
| 117 |
+
self.pool2 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 118 |
+
|
| 119 |
+
self.rebnconv3 = REBNCONV(mid_ch,mid_ch,dirate=1)
|
| 120 |
+
self.pool3 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 121 |
+
|
| 122 |
+
self.rebnconv4 = REBNCONV(mid_ch,mid_ch,dirate=1)
|
| 123 |
+
self.pool4 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 124 |
+
|
| 125 |
+
self.rebnconv5 = REBNCONV(mid_ch,mid_ch,dirate=1)
|
| 126 |
+
|
| 127 |
+
self.rebnconv6 = REBNCONV(mid_ch,mid_ch,dirate=2)
|
| 128 |
+
|
| 129 |
+
self.rebnconv5d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
|
| 130 |
+
self.rebnconv4d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
|
| 131 |
+
self.rebnconv3d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
|
| 132 |
+
self.rebnconv2d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
|
| 133 |
+
self.rebnconv1d = REBNCONV(mid_ch*2,out_ch,dirate=1)
|
| 134 |
+
|
| 135 |
+
def forward(self,x):
|
| 136 |
+
|
| 137 |
+
hx = x
|
| 138 |
+
|
| 139 |
+
hxin = self.rebnconvin(hx)
|
| 140 |
+
|
| 141 |
+
hx1 = self.rebnconv1(hxin)
|
| 142 |
+
hx = self.pool1(hx1)
|
| 143 |
+
|
| 144 |
+
hx2 = self.rebnconv2(hx)
|
| 145 |
+
hx = self.pool2(hx2)
|
| 146 |
+
|
| 147 |
+
hx3 = self.rebnconv3(hx)
|
| 148 |
+
hx = self.pool3(hx3)
|
| 149 |
+
|
| 150 |
+
hx4 = self.rebnconv4(hx)
|
| 151 |
+
hx = self.pool4(hx4)
|
| 152 |
+
|
| 153 |
+
hx5 = self.rebnconv5(hx)
|
| 154 |
+
|
| 155 |
+
hx6 = self.rebnconv6(hx5)
|
| 156 |
+
|
| 157 |
+
|
| 158 |
+
hx5d = self.rebnconv5d(torch.cat((hx6,hx5),1))
|
| 159 |
+
hx5dup = _upsample_like(hx5d,hx4)
|
| 160 |
+
|
| 161 |
+
hx4d = self.rebnconv4d(torch.cat((hx5dup,hx4),1))
|
| 162 |
+
hx4dup = _upsample_like(hx4d,hx3)
|
| 163 |
+
|
| 164 |
+
hx3d = self.rebnconv3d(torch.cat((hx4dup,hx3),1))
|
| 165 |
+
hx3dup = _upsample_like(hx3d,hx2)
|
| 166 |
+
|
| 167 |
+
hx2d = self.rebnconv2d(torch.cat((hx3dup,hx2),1))
|
| 168 |
+
hx2dup = _upsample_like(hx2d,hx1)
|
| 169 |
+
|
| 170 |
+
hx1d = self.rebnconv1d(torch.cat((hx2dup,hx1),1))
|
| 171 |
+
|
| 172 |
+
return hx1d + hxin
|
| 173 |
+
|
| 174 |
+
### RSU-5 ###
|
| 175 |
+
class RSU5(nn.Module):#UNet05DRES(nn.Module):
|
| 176 |
+
|
| 177 |
+
def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
|
| 178 |
+
super(RSU5,self).__init__()
|
| 179 |
+
|
| 180 |
+
self.rebnconvin = REBNCONV(in_ch,out_ch,dirate=1)
|
| 181 |
+
|
| 182 |
+
self.rebnconv1 = REBNCONV(out_ch,mid_ch,dirate=1)
|
| 183 |
+
self.pool1 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 184 |
+
|
| 185 |
+
self.rebnconv2 = REBNCONV(mid_ch,mid_ch,dirate=1)
|
| 186 |
+
self.pool2 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 187 |
+
|
| 188 |
+
self.rebnconv3 = REBNCONV(mid_ch,mid_ch,dirate=1)
|
| 189 |
+
self.pool3 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 190 |
+
|
| 191 |
+
self.rebnconv4 = REBNCONV(mid_ch,mid_ch,dirate=1)
|
| 192 |
+
|
| 193 |
+
self.rebnconv5 = REBNCONV(mid_ch,mid_ch,dirate=2)
|
| 194 |
+
|
| 195 |
+
self.rebnconv4d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
|
| 196 |
+
self.rebnconv3d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
|
| 197 |
+
self.rebnconv2d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
|
| 198 |
+
self.rebnconv1d = REBNCONV(mid_ch*2,out_ch,dirate=1)
|
| 199 |
+
|
| 200 |
+
def forward(self,x):
|
| 201 |
+
|
| 202 |
+
hx = x
|
| 203 |
+
|
| 204 |
+
hxin = self.rebnconvin(hx)
|
| 205 |
+
|
| 206 |
+
hx1 = self.rebnconv1(hxin)
|
| 207 |
+
hx = self.pool1(hx1)
|
| 208 |
+
|
| 209 |
+
hx2 = self.rebnconv2(hx)
|
| 210 |
+
hx = self.pool2(hx2)
|
| 211 |
+
|
| 212 |
+
hx3 = self.rebnconv3(hx)
|
| 213 |
+
hx = self.pool3(hx3)
|
| 214 |
+
|
| 215 |
+
hx4 = self.rebnconv4(hx)
|
| 216 |
+
|
| 217 |
+
hx5 = self.rebnconv5(hx4)
|
| 218 |
+
|
| 219 |
+
hx4d = self.rebnconv4d(torch.cat((hx5,hx4),1))
|
| 220 |
+
hx4dup = _upsample_like(hx4d,hx3)
|
| 221 |
+
|
| 222 |
+
hx3d = self.rebnconv3d(torch.cat((hx4dup,hx3),1))
|
| 223 |
+
hx3dup = _upsample_like(hx3d,hx2)
|
| 224 |
+
|
| 225 |
+
hx2d = self.rebnconv2d(torch.cat((hx3dup,hx2),1))
|
| 226 |
+
hx2dup = _upsample_like(hx2d,hx1)
|
| 227 |
+
|
| 228 |
+
hx1d = self.rebnconv1d(torch.cat((hx2dup,hx1),1))
|
| 229 |
+
|
| 230 |
+
return hx1d + hxin
|
| 231 |
+
|
| 232 |
+
### RSU-4 ###
|
| 233 |
+
class RSU4(nn.Module):#UNet04DRES(nn.Module):
|
| 234 |
+
|
| 235 |
+
def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
|
| 236 |
+
super(RSU4,self).__init__()
|
| 237 |
+
|
| 238 |
+
self.rebnconvin = REBNCONV(in_ch,out_ch,dirate=1)
|
| 239 |
+
|
| 240 |
+
self.rebnconv1 = REBNCONV(out_ch,mid_ch,dirate=1)
|
| 241 |
+
self.pool1 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 242 |
+
|
| 243 |
+
self.rebnconv2 = REBNCONV(mid_ch,mid_ch,dirate=1)
|
| 244 |
+
self.pool2 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 245 |
+
|
| 246 |
+
self.rebnconv3 = REBNCONV(mid_ch,mid_ch,dirate=1)
|
| 247 |
+
|
| 248 |
+
self.rebnconv4 = REBNCONV(mid_ch,mid_ch,dirate=2)
|
| 249 |
+
|
| 250 |
+
self.rebnconv3d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
|
| 251 |
+
self.rebnconv2d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
|
| 252 |
+
self.rebnconv1d = REBNCONV(mid_ch*2,out_ch,dirate=1)
|
| 253 |
+
|
| 254 |
+
def forward(self,x):
|
| 255 |
+
|
| 256 |
+
hx = x
|
| 257 |
+
|
| 258 |
+
hxin = self.rebnconvin(hx)
|
| 259 |
+
|
| 260 |
+
hx1 = self.rebnconv1(hxin)
|
| 261 |
+
hx = self.pool1(hx1)
|
| 262 |
+
|
| 263 |
+
hx2 = self.rebnconv2(hx)
|
| 264 |
+
hx = self.pool2(hx2)
|
| 265 |
+
|
| 266 |
+
hx3 = self.rebnconv3(hx)
|
| 267 |
+
|
| 268 |
+
hx4 = self.rebnconv4(hx3)
|
| 269 |
+
|
| 270 |
+
hx3d = self.rebnconv3d(torch.cat((hx4,hx3),1))
|
| 271 |
+
hx3dup = _upsample_like(hx3d,hx2)
|
| 272 |
+
|
| 273 |
+
hx2d = self.rebnconv2d(torch.cat((hx3dup,hx2),1))
|
| 274 |
+
hx2dup = _upsample_like(hx2d,hx1)
|
| 275 |
+
|
| 276 |
+
hx1d = self.rebnconv1d(torch.cat((hx2dup,hx1),1))
|
| 277 |
+
|
| 278 |
+
return hx1d + hxin
|
| 279 |
+
|
| 280 |
+
### RSU-4F ###
|
| 281 |
+
class RSU4F(nn.Module):#UNet04FRES(nn.Module):
|
| 282 |
+
|
| 283 |
+
def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
|
| 284 |
+
super(RSU4F,self).__init__()
|
| 285 |
+
|
| 286 |
+
self.rebnconvin = REBNCONV(in_ch,out_ch,dirate=1)
|
| 287 |
+
|
| 288 |
+
self.rebnconv1 = REBNCONV(out_ch,mid_ch,dirate=1)
|
| 289 |
+
self.rebnconv2 = REBNCONV(mid_ch,mid_ch,dirate=2)
|
| 290 |
+
self.rebnconv3 = REBNCONV(mid_ch,mid_ch,dirate=4)
|
| 291 |
+
|
| 292 |
+
self.rebnconv4 = REBNCONV(mid_ch,mid_ch,dirate=8)
|
| 293 |
+
|
| 294 |
+
self.rebnconv3d = REBNCONV(mid_ch*2,mid_ch,dirate=4)
|
| 295 |
+
self.rebnconv2d = REBNCONV(mid_ch*2,mid_ch,dirate=2)
|
| 296 |
+
self.rebnconv1d = REBNCONV(mid_ch*2,out_ch,dirate=1)
|
| 297 |
+
|
| 298 |
+
def forward(self,x):
|
| 299 |
+
|
| 300 |
+
hx = x
|
| 301 |
+
|
| 302 |
+
hxin = self.rebnconvin(hx)
|
| 303 |
+
|
| 304 |
+
hx1 = self.rebnconv1(hxin)
|
| 305 |
+
hx2 = self.rebnconv2(hx1)
|
| 306 |
+
hx3 = self.rebnconv3(hx2)
|
| 307 |
+
|
| 308 |
+
hx4 = self.rebnconv4(hx3)
|
| 309 |
+
|
| 310 |
+
hx3d = self.rebnconv3d(torch.cat((hx4,hx3),1))
|
| 311 |
+
hx2d = self.rebnconv2d(torch.cat((hx3d,hx2),1))
|
| 312 |
+
hx1d = self.rebnconv1d(torch.cat((hx2d,hx1),1))
|
| 313 |
+
|
| 314 |
+
return hx1d + hxin
|
| 315 |
+
|
| 316 |
+
|
| 317 |
+
##### U^2-Net ####
|
| 318 |
+
class U2NET(nn.Module):
|
| 319 |
+
|
| 320 |
+
def __init__(self,in_ch=3,out_ch=1):
|
| 321 |
+
super(U2NET,self).__init__()
|
| 322 |
+
|
| 323 |
+
self.stage1 = RSU7(in_ch,32,64)
|
| 324 |
+
self.pool12 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 325 |
+
|
| 326 |
+
self.stage2 = RSU6(64,32,128)
|
| 327 |
+
self.pool23 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 328 |
+
|
| 329 |
+
self.stage3 = RSU5(128,64,256)
|
| 330 |
+
self.pool34 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 331 |
+
|
| 332 |
+
self.stage4 = RSU4(256,128,512)
|
| 333 |
+
self.pool45 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 334 |
+
|
| 335 |
+
self.stage5 = RSU4F(512,256,512)
|
| 336 |
+
self.pool56 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 337 |
+
|
| 338 |
+
self.stage6 = RSU4F(512,256,512)
|
| 339 |
+
|
| 340 |
+
# decoder
|
| 341 |
+
self.stage5d = RSU4F(1024,256,512)
|
| 342 |
+
self.stage4d = RSU4(1024,128,256)
|
| 343 |
+
self.stage3d = RSU5(512,64,128)
|
| 344 |
+
self.stage2d = RSU6(256,32,64)
|
| 345 |
+
self.stage1d = RSU7(128,16,64)
|
| 346 |
+
|
| 347 |
+
self.side1 = nn.Conv2d(64,out_ch,3,padding=1)
|
| 348 |
+
self.side2 = nn.Conv2d(64,out_ch,3,padding=1)
|
| 349 |
+
self.side3 = nn.Conv2d(128,out_ch,3,padding=1)
|
| 350 |
+
self.side4 = nn.Conv2d(256,out_ch,3,padding=1)
|
| 351 |
+
self.side5 = nn.Conv2d(512,out_ch,3,padding=1)
|
| 352 |
+
self.side6 = nn.Conv2d(512,out_ch,3,padding=1)
|
| 353 |
+
|
| 354 |
+
self.outconv = nn.Conv2d(6*out_ch,out_ch,1)
|
| 355 |
+
|
| 356 |
+
def forward(self,x):
|
| 357 |
+
|
| 358 |
+
hx = x
|
| 359 |
+
|
| 360 |
+
#stage 1
|
| 361 |
+
hx1 = self.stage1(hx)
|
| 362 |
+
hx = self.pool12(hx1)
|
| 363 |
+
|
| 364 |
+
#stage 2
|
| 365 |
+
hx2 = self.stage2(hx)
|
| 366 |
+
hx = self.pool23(hx2)
|
| 367 |
+
|
| 368 |
+
#stage 3
|
| 369 |
+
hx3 = self.stage3(hx)
|
| 370 |
+
hx = self.pool34(hx3)
|
| 371 |
+
|
| 372 |
+
#stage 4
|
| 373 |
+
hx4 = self.stage4(hx)
|
| 374 |
+
hx = self.pool45(hx4)
|
| 375 |
+
|
| 376 |
+
#stage 5
|
| 377 |
+
hx5 = self.stage5(hx)
|
| 378 |
+
hx = self.pool56(hx5)
|
| 379 |
+
|
| 380 |
+
#stage 6
|
| 381 |
+
hx6 = self.stage6(hx)
|
| 382 |
+
hx6up = _upsample_like(hx6,hx5)
|
| 383 |
+
|
| 384 |
+
#-------------------- decoder --------------------
|
| 385 |
+
hx5d = self.stage5d(torch.cat((hx6up,hx5),1))
|
| 386 |
+
hx5dup = _upsample_like(hx5d,hx4)
|
| 387 |
+
|
| 388 |
+
hx4d = self.stage4d(torch.cat((hx5dup,hx4),1))
|
| 389 |
+
hx4dup = _upsample_like(hx4d,hx3)
|
| 390 |
+
|
| 391 |
+
hx3d = self.stage3d(torch.cat((hx4dup,hx3),1))
|
| 392 |
+
hx3dup = _upsample_like(hx3d,hx2)
|
| 393 |
+
|
| 394 |
+
hx2d = self.stage2d(torch.cat((hx3dup,hx2),1))
|
| 395 |
+
hx2dup = _upsample_like(hx2d,hx1)
|
| 396 |
+
|
| 397 |
+
hx1d = self.stage1d(torch.cat((hx2dup,hx1),1))
|
| 398 |
+
|
| 399 |
+
|
| 400 |
+
#side output
|
| 401 |
+
d1 = self.side1(hx1d)
|
| 402 |
+
|
| 403 |
+
d2 = self.side2(hx2d)
|
| 404 |
+
d2 = _upsample_like(d2,d1)
|
| 405 |
+
|
| 406 |
+
d3 = self.side3(hx3d)
|
| 407 |
+
d3 = _upsample_like(d3,d1)
|
| 408 |
+
|
| 409 |
+
d4 = self.side4(hx4d)
|
| 410 |
+
d4 = _upsample_like(d4,d1)
|
| 411 |
+
|
| 412 |
+
d5 = self.side5(hx5d)
|
| 413 |
+
d5 = _upsample_like(d5,d1)
|
| 414 |
+
|
| 415 |
+
d6 = self.side6(hx6)
|
| 416 |
+
d6 = _upsample_like(d6,d1)
|
| 417 |
+
|
| 418 |
+
d0 = self.outconv(torch.cat((d1,d2,d3,d4,d5,d6),1))
|
| 419 |
+
|
| 420 |
+
return F.sigmoid(d0), F.sigmoid(d1), F.sigmoid(d2), F.sigmoid(d3), F.sigmoid(d4), F.sigmoid(d5), F.sigmoid(d6)
|
| 421 |
+
|
| 422 |
+
### U^2-Net small ###
|
| 423 |
+
class U2NETP(nn.Module):
|
| 424 |
+
|
| 425 |
+
def __init__(self,in_ch=3,out_ch=1):
|
| 426 |
+
super(U2NETP,self).__init__()
|
| 427 |
+
|
| 428 |
+
self.stage1 = RSU7(in_ch,16,64)
|
| 429 |
+
self.pool12 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 430 |
+
|
| 431 |
+
self.stage2 = RSU6(64,16,64)
|
| 432 |
+
self.pool23 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 433 |
+
|
| 434 |
+
self.stage3 = RSU5(64,16,64)
|
| 435 |
+
self.pool34 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 436 |
+
|
| 437 |
+
self.stage4 = RSU4(64,16,64)
|
| 438 |
+
self.pool45 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 439 |
+
|
| 440 |
+
self.stage5 = RSU4F(64,16,64)
|
| 441 |
+
self.pool56 = nn.MaxPool2d(2,stride=2,ceil_mode=True)
|
| 442 |
+
|
| 443 |
+
self.stage6 = RSU4F(64,16,64)
|
| 444 |
+
|
| 445 |
+
# decoder
|
| 446 |
+
self.stage5d = RSU4F(128,16,64)
|
| 447 |
+
self.stage4d = RSU4(128,16,64)
|
| 448 |
+
self.stage3d = RSU5(128,16,64)
|
| 449 |
+
self.stage2d = RSU6(128,16,64)
|
| 450 |
+
self.stage1d = RSU7(128,16,64)
|
| 451 |
+
|
| 452 |
+
self.side1 = nn.Conv2d(64,out_ch,3,padding=1)
|
| 453 |
+
self.side2 = nn.Conv2d(64,out_ch,3,padding=1)
|
| 454 |
+
self.side3 = nn.Conv2d(64,out_ch,3,padding=1)
|
| 455 |
+
self.side4 = nn.Conv2d(64,out_ch,3,padding=1)
|
| 456 |
+
self.side5 = nn.Conv2d(64,out_ch,3,padding=1)
|
| 457 |
+
self.side6 = nn.Conv2d(64,out_ch,3,padding=1)
|
| 458 |
+
|
| 459 |
+
self.outconv = nn.Conv2d(6*out_ch,out_ch,1)
|
| 460 |
+
|
| 461 |
+
def forward(self,x):
|
| 462 |
+
|
| 463 |
+
hx = x
|
| 464 |
+
|
| 465 |
+
#stage 1
|
| 466 |
+
hx1 = self.stage1(hx)
|
| 467 |
+
hx = self.pool12(hx1)
|
| 468 |
+
|
| 469 |
+
#stage 2
|
| 470 |
+
hx2 = self.stage2(hx)
|
| 471 |
+
hx = self.pool23(hx2)
|
| 472 |
+
|
| 473 |
+
#stage 3
|
| 474 |
+
hx3 = self.stage3(hx)
|
| 475 |
+
hx = self.pool34(hx3)
|
| 476 |
+
|
| 477 |
+
#stage 4
|
| 478 |
+
hx4 = self.stage4(hx)
|
| 479 |
+
hx = self.pool45(hx4)
|
| 480 |
+
|
| 481 |
+
#stage 5
|
| 482 |
+
hx5 = self.stage5(hx)
|
| 483 |
+
hx = self.pool56(hx5)
|
| 484 |
+
|
| 485 |
+
#stage 6
|
| 486 |
+
hx6 = self.stage6(hx)
|
| 487 |
+
hx6up = _upsample_like(hx6,hx5)
|
| 488 |
+
|
| 489 |
+
#decoder
|
| 490 |
+
hx5d = self.stage5d(torch.cat((hx6up,hx5),1))
|
| 491 |
+
hx5dup = _upsample_like(hx5d,hx4)
|
| 492 |
+
|
| 493 |
+
hx4d = self.stage4d(torch.cat((hx5dup,hx4),1))
|
| 494 |
+
hx4dup = _upsample_like(hx4d,hx3)
|
| 495 |
+
|
| 496 |
+
hx3d = self.stage3d(torch.cat((hx4dup,hx3),1))
|
| 497 |
+
hx3dup = _upsample_like(hx3d,hx2)
|
| 498 |
+
|
| 499 |
+
hx2d = self.stage2d(torch.cat((hx3dup,hx2),1))
|
| 500 |
+
hx2dup = _upsample_like(hx2d,hx1)
|
| 501 |
+
|
| 502 |
+
hx1d = self.stage1d(torch.cat((hx2dup,hx1),1))
|
| 503 |
+
|
| 504 |
+
|
| 505 |
+
#side output
|
| 506 |
+
d1 = self.side1(hx1d)
|
| 507 |
+
|
| 508 |
+
d2 = self.side2(hx2d)
|
| 509 |
+
d2 = _upsample_like(d2,d1)
|
| 510 |
+
|
| 511 |
+
d3 = self.side3(hx3d)
|
| 512 |
+
d3 = _upsample_like(d3,d1)
|
| 513 |
+
|
| 514 |
+
d4 = self.side4(hx4d)
|
| 515 |
+
d4 = _upsample_like(d4,d1)
|
| 516 |
+
|
| 517 |
+
d5 = self.side5(hx5d)
|
| 518 |
+
d5 = _upsample_like(d5,d1)
|
| 519 |
+
|
| 520 |
+
d6 = self.side6(hx6)
|
| 521 |
+
d6 = _upsample_like(d6,d1)
|
| 522 |
+
|
| 523 |
+
d0 = self.outconv(torch.cat((d1,d2,d3,d4,d5,d6),1))
|
| 524 |
+
|
| 525 |
+
return F.sigmoid(d0), F.sigmoid(d1), F.sigmoid(d2), F.sigmoid(d3), F.sigmoid(d4), F.sigmoid(d5), F.sigmoid(d6)
|
VITON-Extends_test/unet.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import cv2
|
| 2 |
+
import torch
|
| 3 |
+
import numpy as np
|
| 4 |
+
from torchvision import transforms
|
| 5 |
+
from PIL import Image
|
| 6 |
+
from u2net import U2NET
|
| 7 |
+
|
| 8 |
+
# Load U2NET model
|
| 9 |
+
model = U2NET(3, 1)
|
| 10 |
+
model_path = 'checkpoints/u2net.pth'
|
| 11 |
+
model.load_state_dict(torch.load(model_path, map_location='cpu'))
|
| 12 |
+
model.eval()
|
| 13 |
+
|
| 14 |
+
# Tiền xử lý ảnh
|
| 15 |
+
def preprocess(img):
|
| 16 |
+
transform = transforms.Compose([
|
| 17 |
+
transforms.Resize((192, 256)),
|
| 18 |
+
transforms.ToTensor(),
|
| 19 |
+
transforms.Normalize([0.485, 0.456, 0.406],
|
| 20 |
+
[0.229, 0.224, 0.225])])
|
| 21 |
+
return transform(img).unsqueeze(0)
|
| 22 |
+
|
| 23 |
+
# Tạo mặt nạ từ ảnh đầu vào
|
| 24 |
+
def get_mask(image_path):
|
| 25 |
+
image = Image.open(image_path).convert('RGB')
|
| 26 |
+
input_tensor = preprocess(image)
|
| 27 |
+
with torch.no_grad():
|
| 28 |
+
d1, *_ = model(input_tensor)
|
| 29 |
+
pred = d1[0][0].numpy()
|
| 30 |
+
pred = (pred - pred.min()) / (pred.max() - pred.min())
|
| 31 |
+
mask = cv2.resize(pred, image.size)
|
| 32 |
+
return np.expand_dims(mask, axis=2)
|
| 33 |
+
|
| 34 |
+
# Áp dụng mặt nạ và đổi nền thành trắng
|
| 35 |
+
def apply_mask(img_path, output_path='output_2.png'):
|
| 36 |
+
original = cv2.imread(img_path)
|
| 37 |
+
original_rgb = cv2.cvtColor(original, cv2.COLOR_BGR2RGB)
|
| 38 |
+
mask = get_mask(img_path)
|
| 39 |
+
mask = cv2.resize(mask, (original.shape[1], original.shape[0]))
|
| 40 |
+
mask = np.expand_dims(mask, axis=2)
|
| 41 |
+
mask = np.repeat(mask, 3, axis=2)
|
| 42 |
+
result = (original_rgb * mask + 255 * (1 - mask)).astype(np.uint8)
|
| 43 |
+
result_bgr = cv2.cvtColor(result, cv2.COLOR_RGB2BGR)
|
| 44 |
+
result_bgr = cv2.resize(result_bgr, (192, 256))
|
| 45 |
+
cv2.imwrite(output_path, result_bgr)
|
| 46 |
+
print(f"[✔] Đã lưu ảnh tại: {output_path}")
|
| 47 |
+
|
| 48 |
+
# === CHẠY THỬ ===
|
| 49 |
+
apply_mask('test_2.jpg') # ⚠️ Thay bằng ảnh thật của bạn
|