duyv commited on
Commit
9a5f888
·
verified ·
1 Parent(s): 9ba4383

Upload 203 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +1 -0
  2. video-tetalking/CODE_OF_CONDUCT.md +43 -0
  3. video-tetalking/inference.py +345 -0
  4. video-tetalking/inference_videoretalking.sh +4 -0
  5. video-tetalking/models/DNet.py +118 -0
  6. video-tetalking/models/ENet.py +139 -0
  7. video-tetalking/models/LNet.py +139 -0
  8. video-tetalking/models/__init__.py +37 -0
  9. video-tetalking/models/base_blocks.py +554 -0
  10. video-tetalking/models/ffc.py +233 -0
  11. video-tetalking/models/transformer.py +119 -0
  12. video-tetalking/predict.py +552 -0
  13. video-tetalking/quick_demo.ipynb +293 -0
  14. video-tetalking/requirements.txt +10 -0
  15. video-tetalking/third_part/GFPGAN/LICENSE +351 -0
  16. video-tetalking/third_part/GFPGAN/gfpgan/__init__.py +8 -0
  17. video-tetalking/third_part/GFPGAN/gfpgan/archs/__init__.py +10 -0
  18. video-tetalking/third_part/GFPGAN/gfpgan/archs/arcface_arch.py +245 -0
  19. video-tetalking/third_part/GFPGAN/gfpgan/archs/gfpgan_bilinear_arch.py +312 -0
  20. video-tetalking/third_part/GFPGAN/gfpgan/archs/gfpganv1_arch.py +439 -0
  21. video-tetalking/third_part/GFPGAN/gfpgan/archs/gfpganv1_clean_arch.py +324 -0
  22. video-tetalking/third_part/GFPGAN/gfpgan/archs/stylegan2_bilinear_arch.py +613 -0
  23. video-tetalking/third_part/GFPGAN/gfpgan/archs/stylegan2_clean_arch.py +368 -0
  24. video-tetalking/third_part/GFPGAN/gfpgan/data/__init__.py +10 -0
  25. video-tetalking/third_part/GFPGAN/gfpgan/data/ffhq_degradation_dataset.py +230 -0
  26. video-tetalking/third_part/GFPGAN/gfpgan/models/__init__.py +10 -0
  27. video-tetalking/third_part/GFPGAN/gfpgan/models/gfpgan_model.py +580 -0
  28. video-tetalking/third_part/GFPGAN/gfpgan/train.py +11 -0
  29. video-tetalking/third_part/GFPGAN/gfpgan/utils.py +143 -0
  30. video-tetalking/third_part/GFPGAN/gfpgan/version.py +5 -0
  31. video-tetalking/third_part/GFPGAN/gfpgan/weights/README.md +3 -0
  32. video-tetalking/third_part/GFPGAN/options/train_gfpgan_v1.yml +216 -0
  33. video-tetalking/third_part/GFPGAN/options/train_gfpgan_v1_simple.yml +182 -0
  34. video-tetalking/third_part/GPEN/align_faces.py +271 -0
  35. video-tetalking/third_part/GPEN/face_detect/.DS_Store +0 -0
  36. video-tetalking/third_part/GPEN/face_detect/data/FDDB/img_list.txt +2845 -0
  37. video-tetalking/third_part/GPEN/face_detect/data/__init__.py +3 -0
  38. video-tetalking/third_part/GPEN/face_detect/data/config.py +42 -0
  39. video-tetalking/third_part/GPEN/face_detect/data/data_augment.py +237 -0
  40. video-tetalking/third_part/GPEN/face_detect/data/wider_face.py +101 -0
  41. video-tetalking/third_part/GPEN/face_detect/facemodels/__init__.py +0 -0
  42. video-tetalking/third_part/GPEN/face_detect/facemodels/net.py +137 -0
  43. video-tetalking/third_part/GPEN/face_detect/facemodels/retinaface.py +127 -0
  44. video-tetalking/third_part/GPEN/face_detect/layers/__init__.py +2 -0
  45. video-tetalking/third_part/GPEN/face_detect/layers/functions/prior_box.py +34 -0
  46. video-tetalking/third_part/GPEN/face_detect/layers/modules/__init__.py +3 -0
  47. video-tetalking/third_part/GPEN/face_detect/layers/modules/multibox_loss.py +125 -0
  48. video-tetalking/third_part/GPEN/face_detect/retinaface_detection.py +193 -0
  49. video-tetalking/third_part/GPEN/face_detect/utils/__init__.py +0 -0
  50. video-tetalking/third_part/GPEN/face_detect/utils/box_utils.py +330 -0
.gitattributes CHANGED
@@ -187,3 +187,4 @@ SimSwap/temp_results/frame_0000058.jpg filter=lfs diff=lfs merge=lfs -text
187
  SimSwap/temp_results/frame_0000059.jpg filter=lfs diff=lfs merge=lfs -text
188
  SimSwap/temp_results/frame_0000060.jpg filter=lfs diff=lfs merge=lfs -text
189
  SimSwap/temp_results/frame_0000061.jpg filter=lfs diff=lfs merge=lfs -text
 
 
187
  SimSwap/temp_results/frame_0000059.jpg filter=lfs diff=lfs merge=lfs -text
188
  SimSwap/temp_results/frame_0000060.jpg filter=lfs diff=lfs merge=lfs -text
189
  SimSwap/temp_results/frame_0000061.jpg filter=lfs diff=lfs merge=lfs -text
190
+ video-tetalking/third_part/GPEN/face_parse/test.png filter=lfs diff=lfs merge=lfs -text
video-tetalking/CODE_OF_CONDUCT.md ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
6
+
7
+ ## Our Standards
8
+
9
+ Examples of behavior that contributes to creating a positive environment include:
10
+
11
+ - Using welcoming and inclusive language
12
+ - Being respectful of differing viewpoints and experiences
13
+ - Gracefully accepting constructive criticism
14
+ - Focusing on what is best for the community
15
+ - Showing empathy towards other community members
16
+
17
+ Examples of unacceptable behavior by participants include:
18
+
19
+ - The use of sexualized language or imagery and unwelcome sexual attention or advances
20
+ - Trolling, insulting/derogatory comments, and personal or political attacks
21
+ - Public or private harassment
22
+ - Publishing others' private information, such as a physical or electronic address, without explicit permission
23
+ - Other conduct that could reasonably be considered inappropriate in a professional setting
24
+
25
+ ## Our Responsibilities
26
+
27
+ Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28
+
29
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned with this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30
+
31
+ ## Scope
32
+
33
+ This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project email address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
34
+
35
+ ## Enforcement
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident.
38
+
39
+ Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40
+
41
+ ## Attribution
42
+
43
+ This Code of Conduct is adapted from the Contributor Covenant, version 2.0, available at [https://www.contributor-covenant.org/version/2/0/code_of_conduct.html](https://www.contributor-covenant.org/version/2/0/code_of_conduct.html).
video-tetalking/inference.py ADDED
@@ -0,0 +1,345 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import cv2, os, sys, subprocess, platform, torch
3
+ from tqdm import tqdm
4
+ from PIL import Image
5
+ from scipy.io import loadmat
6
+
7
+ sys.path.insert(0, 'third_part')
8
+ sys.path.insert(0, 'third_part/GPEN')
9
+ sys.path.insert(0, 'third_part/GFPGAN')
10
+
11
+ # 3dmm extraction
12
+ from third_part.face3d.util.preprocess import align_img
13
+ from third_part.face3d.util.load_mats import load_lm3d
14
+ from third_part.face3d.extract_kp_videos import KeypointExtractor
15
+ # face enhancement
16
+ from third_part.GPEN.gpen_face_enhancer import FaceEnhancement
17
+ from third_part.GFPGAN.gfpgan import GFPGANer
18
+ # expression control
19
+ from third_part.ganimation_replicate.model.ganimation import GANimationModel
20
+
21
+ from utils import audio
22
+ from utils.ffhq_preprocess import Croper
23
+ from utils.alignment_stit import crop_faces, calc_alignment_coefficients, paste_image
24
+ from utils.inference_utils import Laplacian_Pyramid_Blending_with_mask, face_detect, load_model, options, split_coeff, \
25
+ trans_image, transform_semantic, find_crop_norm_ratio, load_face3d_net, exp_aus_dict
26
+ import warnings
27
+ warnings.filterwarnings("ignore")
28
+
29
+ args = options()
30
+
31
+ def main():
32
+ device = 'cuda' if torch.cuda.is_available() else 'cpu'
33
+ print('[Info] Using {} for inference.'.format(device))
34
+ os.makedirs(os.path.join('temp', args.tmp_dir), exist_ok=True)
35
+
36
+ enhancer = FaceEnhancement(base_dir='checkpoints', size=512, model='GPEN-BFR-512', use_sr=False, \
37
+ sr_model='rrdb_realesrnet_psnr', channel_multiplier=2, narrow=1, device=device)
38
+ restorer = GFPGANer(model_path='checkpoints/GFPGANv1.3.pth', upscale=1, arch='clean', \
39
+ channel_multiplier=2, bg_upsampler=None)
40
+
41
+ base_name = args.face.split('/')[-1]
42
+ if os.path.isfile(args.face) and args.face.split('.')[1] in ['jpg', 'png', 'jpeg']:
43
+ args.static = True
44
+ if not os.path.isfile(args.face):
45
+ raise ValueError('--face argument must be a valid path to video/image file')
46
+ elif args.face.split('.')[1] in ['jpg', 'png', 'jpeg']:
47
+ full_frames = [cv2.imread(args.face)]
48
+ fps = args.fps
49
+ else:
50
+ video_stream = cv2.VideoCapture(args.face)
51
+ fps = video_stream.get(cv2.CAP_PROP_FPS)
52
+
53
+ full_frames = []
54
+ while True:
55
+ still_reading, frame = video_stream.read()
56
+ if not still_reading:
57
+ video_stream.release()
58
+ break
59
+ y1, y2, x1, x2 = args.crop
60
+ if x2 == -1: x2 = frame.shape[1]
61
+ if y2 == -1: y2 = frame.shape[0]
62
+ frame = frame[y1:y2, x1:x2]
63
+ full_frames.append(frame)
64
+
65
+ print ("[Step 0] Number of frames available for inference: "+str(len(full_frames)))
66
+ # face detection & cropping, cropping the first frame as the style of FFHQ
67
+ croper = Croper('checkpoints/shape_predictor_68_face_landmarks.dat')
68
+ full_frames_RGB = [cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) for frame in full_frames]
69
+ full_frames_RGB, crop, quad = croper.crop(full_frames_RGB, xsize=512)
70
+
71
+ clx, cly, crx, cry = crop
72
+ lx, ly, rx, ry = quad
73
+ lx, ly, rx, ry = int(lx), int(ly), int(rx), int(ry)
74
+ oy1, oy2, ox1, ox2 = cly+ly, min(cly+ry, full_frames[0].shape[0]), clx+lx, min(clx+rx, full_frames[0].shape[1])
75
+ # original_size = (ox2 - ox1, oy2 - oy1)
76
+ frames_pil = [Image.fromarray(cv2.resize(frame,(256,256))) for frame in full_frames_RGB]
77
+
78
+ # get the landmark according to the detected face.
79
+ if not os.path.isfile('temp/'+base_name+'_landmarks.txt') or args.re_preprocess:
80
+ print('[Step 1] Landmarks Extraction in Video.')
81
+ kp_extractor = KeypointExtractor()
82
+ lm = kp_extractor.extract_keypoint(frames_pil, './temp/'+base_name+'_landmarks.txt')
83
+ else:
84
+ print('[Step 1] Using saved landmarks.')
85
+ lm = np.loadtxt('temp/'+base_name+'_landmarks.txt').astype(np.float32)
86
+ lm = lm.reshape([len(full_frames), -1, 2])
87
+
88
+ if not os.path.isfile('temp/'+base_name+'_coeffs.npy') or args.exp_img is not None or args.re_preprocess:
89
+ net_recon = load_face3d_net(args.face3d_net_path, device)
90
+ lm3d_std = load_lm3d('checkpoints/BFM')
91
+
92
+ video_coeffs = []
93
+ for idx in tqdm(range(len(frames_pil)), desc="[Step 2] 3DMM Extraction In Video:"):
94
+ frame = frames_pil[idx]
95
+ W, H = frame.size
96
+ lm_idx = lm[idx].reshape([-1, 2])
97
+ if np.mean(lm_idx) == -1:
98
+ lm_idx = (lm3d_std[:, :2]+1) / 2.
99
+ lm_idx = np.concatenate([lm_idx[:, :1] * W, lm_idx[:, 1:2] * H], 1)
100
+ else:
101
+ lm_idx[:, -1] = H - 1 - lm_idx[:, -1]
102
+
103
+ trans_params, im_idx, lm_idx, _ = align_img(frame, lm_idx, lm3d_std)
104
+ trans_params = np.array([float(item) for item in np.hsplit(trans_params, 5)]).astype(np.float32)
105
+ im_idx_tensor = torch.tensor(np.array(im_idx)/255., dtype=torch.float32).permute(2, 0, 1).to(device).unsqueeze(0)
106
+ with torch.no_grad():
107
+ coeffs = split_coeff(net_recon(im_idx_tensor))
108
+
109
+ pred_coeff = {key:coeffs[key].cpu().numpy() for key in coeffs}
110
+ pred_coeff = np.concatenate([pred_coeff['id'], pred_coeff['exp'], pred_coeff['tex'], pred_coeff['angle'],\
111
+ pred_coeff['gamma'], pred_coeff['trans'], trans_params[None]], 1)
112
+ video_coeffs.append(pred_coeff)
113
+ semantic_npy = np.array(video_coeffs)[:,0]
114
+ np.save('temp/'+base_name+'_coeffs.npy', semantic_npy)
115
+ else:
116
+ print('[Step 2] Using saved coeffs.')
117
+ semantic_npy = np.load('temp/'+base_name+'_coeffs.npy').astype(np.float32)
118
+
119
+ # generate the 3dmm coeff from a single image
120
+ if args.exp_img is not None and ('.png' in args.exp_img or '.jpg' in args.exp_img):
121
+ print('extract the exp from',args.exp_img)
122
+ exp_pil = Image.open(args.exp_img).convert('RGB')
123
+ lm3d_std = load_lm3d('third_part/face3d/BFM')
124
+
125
+ W, H = exp_pil.size
126
+ kp_extractor = KeypointExtractor()
127
+ lm_exp = kp_extractor.extract_keypoint([exp_pil], 'temp/'+base_name+'_temp.txt')[0]
128
+ if np.mean(lm_exp) == -1:
129
+ lm_exp = (lm3d_std[:, :2] + 1) / 2.
130
+ lm_exp = np.concatenate(
131
+ [lm_exp[:, :1] * W, lm_exp[:, 1:2] * H], 1)
132
+ else:
133
+ lm_exp[:, -1] = H - 1 - lm_exp[:, -1]
134
+
135
+ trans_params, im_exp, lm_exp, _ = align_img(exp_pil, lm_exp, lm3d_std)
136
+ trans_params = np.array([float(item) for item in np.hsplit(trans_params, 5)]).astype(np.float32)
137
+ im_exp_tensor = torch.tensor(np.array(im_exp)/255., dtype=torch.float32).permute(2, 0, 1).to(device).unsqueeze(0)
138
+ with torch.no_grad():
139
+ expression = split_coeff(net_recon(im_exp_tensor))['exp'][0]
140
+ del net_recon
141
+ elif args.exp_img == 'smile':
142
+ expression = torch.tensor(loadmat('checkpoints/expression.mat')['expression_mouth'])[0]
143
+ else:
144
+ print('using expression center')
145
+ expression = torch.tensor(loadmat('checkpoints/expression.mat')['expression_center'])[0]
146
+
147
+ # load DNet, model(LNet and ENet)
148
+ D_Net, model = load_model(args, device)
149
+
150
+ if not os.path.isfile('temp/'+base_name+'_stablized.npy') or args.re_preprocess:
151
+ imgs = []
152
+ for idx in tqdm(range(len(frames_pil)), desc="[Step 3] Stabilize the expression In Video:"):
153
+ if args.one_shot:
154
+ source_img = trans_image(frames_pil[0]).unsqueeze(0).to(device)
155
+ semantic_source_numpy = semantic_npy[0:1]
156
+ else:
157
+ source_img = trans_image(frames_pil[idx]).unsqueeze(0).to(device)
158
+ semantic_source_numpy = semantic_npy[idx:idx+1]
159
+ ratio = find_crop_norm_ratio(semantic_source_numpy, semantic_npy)
160
+ coeff = transform_semantic(semantic_npy, idx, ratio).unsqueeze(0).to(device)
161
+
162
+ # hacking the new expression
163
+ coeff[:, :64, :] = expression[None, :64, None].to(device)
164
+ with torch.no_grad():
165
+ output = D_Net(source_img, coeff)
166
+ img_stablized = np.uint8((output['fake_image'].squeeze(0).permute(1,2,0).cpu().clamp_(-1, 1).numpy() + 1 )/2. * 255)
167
+ imgs.append(cv2.cvtColor(img_stablized,cv2.COLOR_RGB2BGR))
168
+ np.save('temp/'+base_name+'_stablized.npy',imgs)
169
+ del D_Net
170
+ else:
171
+ print('[Step 3] Using saved stabilized video.')
172
+ imgs = np.load('temp/'+base_name+'_stablized.npy')
173
+ torch.cuda.empty_cache()
174
+
175
+ if not args.audio.endswith('.wav'):
176
+ command = 'ffmpeg -loglevel error -y -i {} -strict -2 {}'.format(args.audio, 'temp/{}/temp.wav'.format(args.tmp_dir))
177
+ subprocess.call(command, shell=True)
178
+ args.audio = 'temp/{}/temp.wav'.format(args.tmp_dir)
179
+ wav = audio.load_wav(args.audio, 16000)
180
+ mel = audio.melspectrogram(wav)
181
+ if np.isnan(mel.reshape(-1)).sum() > 0:
182
+ raise ValueError('Mel contains nan! Using a TTS voice? Add a small epsilon noise to the wav file and try again')
183
+
184
+ mel_step_size, mel_idx_multiplier, i, mel_chunks = 16, 80./fps, 0, []
185
+ while True:
186
+ start_idx = int(i * mel_idx_multiplier)
187
+ if start_idx + mel_step_size > len(mel[0]):
188
+ mel_chunks.append(mel[:, len(mel[0]) - mel_step_size:])
189
+ break
190
+ mel_chunks.append(mel[:, start_idx : start_idx + mel_step_size])
191
+ i += 1
192
+
193
+ print("[Step 4] Load audio; Length of mel chunks: {}".format(len(mel_chunks)))
194
+ imgs = imgs[:len(mel_chunks)]
195
+ full_frames = full_frames[:len(mel_chunks)]
196
+ lm = lm[:len(mel_chunks)]
197
+
198
+ imgs_enhanced = []
199
+ for idx in tqdm(range(len(imgs)), desc='[Step 5] Reference Enhancement'):
200
+ img = imgs[idx]
201
+ pred, _, _ = enhancer.process(img, img, face_enhance=True, possion_blending=False)
202
+ imgs_enhanced.append(pred)
203
+ gen = datagen(imgs_enhanced.copy(), mel_chunks, full_frames, None, (oy1,oy2,ox1,ox2))
204
+
205
+ frame_h, frame_w = full_frames[0].shape[:-1]
206
+ out = cv2.VideoWriter('temp/{}/result.mp4'.format(args.tmp_dir), cv2.VideoWriter_fourcc(*'mp4v'), fps, (frame_w, frame_h))
207
+
208
+ if args.up_face != 'original':
209
+ instance = GANimationModel()
210
+ instance.initialize()
211
+ instance.setup()
212
+
213
+ kp_extractor = KeypointExtractor()
214
+ for i, (img_batch, mel_batch, frames, coords, img_original, f_frames) in enumerate(tqdm(gen, desc='[Step 6] Lip Synthesis:', total=int(np.ceil(float(len(mel_chunks)) / args.LNet_batch_size)))):
215
+ img_batch = torch.FloatTensor(np.transpose(img_batch, (0, 3, 1, 2))).to(device)
216
+ mel_batch = torch.FloatTensor(np.transpose(mel_batch, (0, 3, 1, 2))).to(device)
217
+ img_original = torch.FloatTensor(np.transpose(img_original, (0, 3, 1, 2))).to(device)/255. # BGR -> RGB
218
+
219
+ with torch.no_grad():
220
+ incomplete, reference = torch.split(img_batch, 3, dim=1)
221
+ pred, low_res = model(mel_batch, img_batch, reference)
222
+ pred = torch.clamp(pred, 0, 1)
223
+
224
+ if args.up_face in ['sad', 'angry', 'surprise']:
225
+ tar_aus = exp_aus_dict[args.up_face]
226
+ else:
227
+ pass
228
+
229
+ if args.up_face == 'original':
230
+ cur_gen_faces = img_original
231
+ else:
232
+ test_batch = {'src_img': torch.nn.functional.interpolate((img_original * 2 - 1), size=(128, 128), mode='bilinear'),
233
+ 'tar_aus': tar_aus.repeat(len(incomplete), 1)}
234
+ instance.feed_batch(test_batch)
235
+ instance.forward()
236
+ cur_gen_faces = torch.nn.functional.interpolate(instance.fake_img / 2. + 0.5, size=(384, 384), mode='bilinear')
237
+
238
+ if args.without_rl1 is not False:
239
+ incomplete, reference = torch.split(img_batch, 3, dim=1)
240
+ mask = torch.where(incomplete==0, torch.ones_like(incomplete), torch.zeros_like(incomplete))
241
+ pred = pred * mask + cur_gen_faces * (1 - mask)
242
+
243
+ pred = pred.cpu().numpy().transpose(0, 2, 3, 1) * 255.
244
+
245
+ torch.cuda.empty_cache()
246
+ for p, f, xf, c in zip(pred, frames, f_frames, coords):
247
+ y1, y2, x1, x2 = c
248
+ p = cv2.resize(p.astype(np.uint8), (x2 - x1, y2 - y1))
249
+
250
+ ff = xf.copy()
251
+ ff[y1:y2, x1:x2] = p
252
+
253
+ # month region enhancement by GFPGAN
254
+ cropped_faces, restored_faces, restored_img = restorer.enhance(
255
+ ff, has_aligned=False, only_center_face=True, paste_back=True)
256
+ # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
257
+ mm = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0]
258
+ mouse_mask = np.zeros_like(restored_img)
259
+ tmp_mask = enhancer.faceparser.process(restored_img[y1:y2, x1:x2], mm)[0]
260
+ mouse_mask[y1:y2, x1:x2]= cv2.resize(tmp_mask, (x2 - x1, y2 - y1))[:, :, np.newaxis] / 255.
261
+
262
+ height, width = ff.shape[:2]
263
+ restored_img, ff, full_mask = [cv2.resize(x, (512, 512)) for x in (restored_img, ff, np.float32(mouse_mask))]
264
+ img = Laplacian_Pyramid_Blending_with_mask(restored_img, ff, full_mask[:, :, 0], 10)
265
+ pp = np.uint8(cv2.resize(np.clip(img, 0 ,255), (width, height)))
266
+
267
+ pp, orig_faces, enhanced_faces = enhancer.process(pp, xf, bbox=c, face_enhance=False, possion_blending=True)
268
+ out.write(pp)
269
+ out.release()
270
+
271
+ if not os.path.isdir(os.path.dirname(args.outfile)):
272
+ os.makedirs(os.path.dirname(args.outfile), exist_ok=True)
273
+ command = 'ffmpeg -loglevel error -y -i {} -i {} -strict -2 -q:v 1 {}'.format(args.audio, 'temp/{}/result.mp4'.format(args.tmp_dir), args.outfile)
274
+ subprocess.call(command, shell=platform.system() != 'Windows')
275
+ print('outfile:', args.outfile)
276
+
277
+
278
+ # frames:256x256, full_frames: original size
279
+ def datagen(frames, mels, full_frames, frames_pil, cox):
280
+ img_batch, mel_batch, frame_batch, coords_batch, ref_batch, full_frame_batch = [], [], [], [], [], []
281
+ base_name = args.face.split('/')[-1]
282
+ refs = []
283
+ image_size = 256
284
+
285
+ # original frames
286
+ kp_extractor = KeypointExtractor()
287
+ fr_pil = [Image.fromarray(frame) for frame in frames]
288
+ lms = kp_extractor.extract_keypoint(fr_pil, 'temp/'+base_name+'x12_landmarks.txt')
289
+ frames_pil = [ (lm, frame) for frame,lm in zip(fr_pil, lms)] # frames is the croped version of modified face
290
+ crops, orig_images, quads = crop_faces(image_size, frames_pil, scale=1.0, use_fa=True)
291
+ inverse_transforms = [calc_alignment_coefficients(quad + 0.5, [[0, 0], [0, image_size], [image_size, image_size], [image_size, 0]]) for quad in quads]
292
+ del kp_extractor.detector
293
+
294
+ oy1,oy2,ox1,ox2 = cox
295
+ face_det_results = face_detect(full_frames, args, jaw_correction=True)
296
+
297
+ for inverse_transform, crop, full_frame, face_det in zip(inverse_transforms, crops, full_frames, face_det_results):
298
+ imc_pil = paste_image(inverse_transform, crop, Image.fromarray(
299
+ cv2.resize(full_frame[int(oy1):int(oy2), int(ox1):int(ox2)], (256, 256))))
300
+
301
+ ff = full_frame.copy()
302
+ ff[int(oy1):int(oy2), int(ox1):int(ox2)] = cv2.resize(np.array(imc_pil.convert('RGB')), (ox2 - ox1, oy2 - oy1))
303
+ oface, coords = face_det
304
+ y1, y2, x1, x2 = coords
305
+ refs.append(ff[y1: y2, x1:x2])
306
+
307
+ for i, m in enumerate(mels):
308
+ idx = 0 if args.static else i % len(frames)
309
+ frame_to_save = frames[idx].copy()
310
+ face = refs[idx]
311
+ oface, coords = face_det_results[idx].copy()
312
+
313
+ face = cv2.resize(face, (args.img_size, args.img_size))
314
+ oface = cv2.resize(oface, (args.img_size, args.img_size))
315
+
316
+ img_batch.append(oface)
317
+ ref_batch.append(face)
318
+ mel_batch.append(m)
319
+ coords_batch.append(coords)
320
+ frame_batch.append(frame_to_save)
321
+ full_frame_batch.append(full_frames[idx].copy())
322
+
323
+ if len(img_batch) >= args.LNet_batch_size:
324
+ img_batch, mel_batch, ref_batch = np.asarray(img_batch), np.asarray(mel_batch), np.asarray(ref_batch)
325
+ img_masked = img_batch.copy()
326
+ img_original = img_batch.copy()
327
+ img_masked[:, args.img_size//2:] = 0
328
+ img_batch = np.concatenate((img_masked, ref_batch), axis=3) / 255.
329
+ mel_batch = np.reshape(mel_batch, [len(mel_batch), mel_batch.shape[1], mel_batch.shape[2], 1])
330
+
331
+ yield img_batch, mel_batch, frame_batch, coords_batch, img_original, full_frame_batch
332
+ img_batch, mel_batch, frame_batch, coords_batch, img_original, full_frame_batch, ref_batch = [], [], [], [], [], [], []
333
+
334
+ if len(img_batch) > 0:
335
+ img_batch, mel_batch, ref_batch = np.asarray(img_batch), np.asarray(mel_batch), np.asarray(ref_batch)
336
+ img_masked = img_batch.copy()
337
+ img_original = img_batch.copy()
338
+ img_masked[:, args.img_size//2:] = 0
339
+ img_batch = np.concatenate((img_masked, ref_batch), axis=3) / 255.
340
+ mel_batch = np.reshape(mel_batch, [len(mel_batch), mel_batch.shape[1], mel_batch.shape[2], 1])
341
+ yield img_batch, mel_batch, frame_batch, coords_batch, img_original, full_frame_batch
342
+
343
+
344
+ if __name__ == '__main__':
345
+ main()
video-tetalking/inference_videoretalking.sh ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ python3 inference.py \
2
+ --face ./examples/face/1.mp4 \
3
+ --audio ./examples/audio/1.wav \
4
+ --outfile results/1_1.mp4
video-tetalking/models/DNet.py ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # TODO
2
+ import functools
3
+ import numpy as np
4
+
5
+ import torch
6
+ import torch.nn as nn
7
+ import torch.nn.functional as F
8
+
9
+ from utils import flow_util
10
+ from models.base_blocks import LayerNorm2d, ADAINHourglass, FineEncoder, FineDecoder
11
+
12
+ # DNet
13
+ class DNet(nn.Module):
14
+ def __init__(self):
15
+ super(DNet, self).__init__()
16
+ self.mapping_net = MappingNet()
17
+ self.warpping_net = WarpingNet()
18
+ self.editing_net = EditingNet()
19
+
20
+ def forward(self, input_image, driving_source, stage=None):
21
+ if stage == 'warp':
22
+ descriptor = self.mapping_net(driving_source)
23
+ output = self.warpping_net(input_image, descriptor)
24
+ else:
25
+ descriptor = self.mapping_net(driving_source)
26
+ output = self.warpping_net(input_image, descriptor)
27
+ output['fake_image'] = self.editing_net(input_image, output['warp_image'], descriptor)
28
+ return output
29
+
30
+ class MappingNet(nn.Module):
31
+ def __init__(self, coeff_nc=73, descriptor_nc=256, layer=3):
32
+ super( MappingNet, self).__init__()
33
+
34
+ self.layer = layer
35
+ nonlinearity = nn.LeakyReLU(0.1)
36
+
37
+ self.first = nn.Sequential(
38
+ torch.nn.Conv1d(coeff_nc, descriptor_nc, kernel_size=7, padding=0, bias=True))
39
+
40
+ for i in range(layer):
41
+ net = nn.Sequential(nonlinearity,
42
+ torch.nn.Conv1d(descriptor_nc, descriptor_nc, kernel_size=3, padding=0, dilation=3))
43
+ setattr(self, 'encoder' + str(i), net)
44
+
45
+ self.pooling = nn.AdaptiveAvgPool1d(1)
46
+ self.output_nc = descriptor_nc
47
+
48
+ def forward(self, input_3dmm):
49
+ out = self.first(input_3dmm)
50
+ for i in range(self.layer):
51
+ model = getattr(self, 'encoder' + str(i))
52
+ out = model(out) + out[:,:,3:-3]
53
+ out = self.pooling(out)
54
+ return out
55
+
56
+ class WarpingNet(nn.Module):
57
+ def __init__(
58
+ self,
59
+ image_nc=3,
60
+ descriptor_nc=256,
61
+ base_nc=32,
62
+ max_nc=256,
63
+ encoder_layer=5,
64
+ decoder_layer=3,
65
+ use_spect=False
66
+ ):
67
+ super( WarpingNet, self).__init__()
68
+
69
+ nonlinearity = nn.LeakyReLU(0.1)
70
+ norm_layer = functools.partial(LayerNorm2d, affine=True)
71
+ kwargs = {'nonlinearity':nonlinearity, 'use_spect':use_spect}
72
+
73
+ self.descriptor_nc = descriptor_nc
74
+ self.hourglass = ADAINHourglass(image_nc, self.descriptor_nc, base_nc,
75
+ max_nc, encoder_layer, decoder_layer, **kwargs)
76
+
77
+ self.flow_out = nn.Sequential(norm_layer(self.hourglass.output_nc),
78
+ nonlinearity,
79
+ nn.Conv2d(self.hourglass.output_nc, 2, kernel_size=7, stride=1, padding=3))
80
+
81
+ self.pool = nn.AdaptiveAvgPool2d(1)
82
+
83
+ def forward(self, input_image, descriptor):
84
+ final_output={}
85
+ output = self.hourglass(input_image, descriptor)
86
+ final_output['flow_field'] = self.flow_out(output)
87
+
88
+ deformation = flow_util.convert_flow_to_deformation(final_output['flow_field'])
89
+ final_output['warp_image'] = flow_util.warp_image(input_image, deformation)
90
+ return final_output
91
+
92
+
93
+ class EditingNet(nn.Module):
94
+ def __init__(
95
+ self,
96
+ image_nc=3,
97
+ descriptor_nc=256,
98
+ layer=3,
99
+ base_nc=64,
100
+ max_nc=256,
101
+ num_res_blocks=2,
102
+ use_spect=False):
103
+ super(EditingNet, self).__init__()
104
+
105
+ nonlinearity = nn.LeakyReLU(0.1)
106
+ norm_layer = functools.partial(LayerNorm2d, affine=True)
107
+ kwargs = {'norm_layer':norm_layer, 'nonlinearity':nonlinearity, 'use_spect':use_spect}
108
+ self.descriptor_nc = descriptor_nc
109
+
110
+ # encoder part
111
+ self.encoder = FineEncoder(image_nc*2, base_nc, max_nc, layer, **kwargs)
112
+ self.decoder = FineDecoder(image_nc, self.descriptor_nc, base_nc, max_nc, layer, num_res_blocks, **kwargs)
113
+
114
+ def forward(self, input_image, warp_image, descriptor):
115
+ x = torch.cat([input_image, warp_image], 1)
116
+ x = self.encoder(x)
117
+ gen_image = self.decoder(x, descriptor)
118
+ return gen_image
video-tetalking/models/ENet.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.nn.functional as F
4
+
5
+ from models.base_blocks import ResBlock, StyleConv, ToRGB
6
+
7
+
8
+ class ENet(nn.Module):
9
+ def __init__(
10
+ self,
11
+ num_style_feat=512,
12
+ lnet=None,
13
+ concat=False
14
+ ):
15
+ super(ENet, self).__init__()
16
+
17
+ self.low_res = lnet
18
+ for param in self.low_res.parameters():
19
+ param.requires_grad = False
20
+
21
+ channel_multiplier, narrow = 2, 1
22
+ channels = {
23
+ '4': int(512 * narrow),
24
+ '8': int(512 * narrow),
25
+ '16': int(512 * narrow),
26
+ '32': int(512 * narrow),
27
+ '64': int(256 * channel_multiplier * narrow),
28
+ '128': int(128 * channel_multiplier * narrow),
29
+ '256': int(64 * channel_multiplier * narrow),
30
+ '512': int(32 * channel_multiplier * narrow),
31
+ '1024': int(16 * channel_multiplier * narrow)
32
+ }
33
+
34
+ self.log_size = 8
35
+ first_out_size = 128
36
+ self.conv_body_first = nn.Conv2d(3, channels[f'{first_out_size}'], 1) # 256 -> 128
37
+
38
+ # downsample
39
+ in_channels = channels[f'{first_out_size}']
40
+ self.conv_body_down = nn.ModuleList()
41
+ for i in range(8, 2, -1):
42
+ out_channels = channels[f'{2**(i - 1)}']
43
+ self.conv_body_down.append(ResBlock(in_channels, out_channels, mode='down'))
44
+ in_channels = out_channels
45
+
46
+ self.num_style_feat = num_style_feat
47
+ linear_out_channel = num_style_feat
48
+ self.final_linear = nn.Linear(channels['4'] * 4 * 4, linear_out_channel)
49
+ self.final_conv = nn.Conv2d(in_channels, channels['4'], 3, 1, 1)
50
+
51
+ self.style_convs = nn.ModuleList()
52
+ self.to_rgbs = nn.ModuleList()
53
+ self.noises = nn.Module()
54
+
55
+ self.concat = concat
56
+ if concat:
57
+ in_channels = 3 + 32 # channels['64']
58
+ else:
59
+ in_channels = 3
60
+
61
+ for i in range(7, 9): # 128, 256
62
+ out_channels = channels[f'{2**i}'] #
63
+ self.style_convs.append(
64
+ StyleConv(
65
+ in_channels,
66
+ out_channels,
67
+ kernel_size=3,
68
+ num_style_feat=num_style_feat,
69
+ demodulate=True,
70
+ sample_mode='upsample'))
71
+ self.style_convs.append(
72
+ StyleConv(
73
+ out_channels,
74
+ out_channels,
75
+ kernel_size=3,
76
+ num_style_feat=num_style_feat,
77
+ demodulate=True,
78
+ sample_mode=None))
79
+ self.to_rgbs.append(ToRGB(out_channels, num_style_feat, upsample=True))
80
+ in_channels = out_channels
81
+
82
+ def forward(self, audio_sequences, face_sequences, gt_sequences):
83
+ B = audio_sequences.size(0)
84
+ input_dim_size = len(face_sequences.size())
85
+ inp, ref = torch.split(face_sequences,3,dim=1)
86
+
87
+ if input_dim_size > 4:
88
+ audio_sequences = torch.cat([audio_sequences[:, i] for i in range(audio_sequences.size(1))], dim=0)
89
+ inp = torch.cat([inp[:, :, i] for i in range(inp.size(2))], dim=0)
90
+ ref = torch.cat([ref[:, :, i] for i in range(ref.size(2))], dim=0)
91
+ gt_sequences = torch.cat([gt_sequences[:, :, i] for i in range(gt_sequences.size(2))], dim=0)
92
+
93
+ # get the global style
94
+ feat = F.leaky_relu_(self.conv_body_first(F.interpolate(ref, size=(256,256), mode='bilinear')), negative_slope=0.2)
95
+ for i in range(self.log_size - 2):
96
+ feat = self.conv_body_down[i](feat)
97
+ feat = F.leaky_relu_(self.final_conv(feat), negative_slope=0.2)
98
+
99
+ # style code
100
+ style_code = self.final_linear(feat.reshape(feat.size(0), -1))
101
+ style_code = style_code.reshape(style_code.size(0), -1, self.num_style_feat)
102
+
103
+ LNet_input = torch.cat([inp, gt_sequences], dim=1)
104
+ LNet_input = F.interpolate(LNet_input, size=(96,96), mode='bilinear')
105
+
106
+ if self.concat:
107
+ low_res_img, low_res_feat = self.low_res(audio_sequences, LNet_input)
108
+ low_res_img.detach()
109
+ low_res_feat.detach()
110
+ out = torch.cat([low_res_img, low_res_feat], dim=1)
111
+
112
+ else:
113
+ low_res_img = self.low_res(audio_sequences, LNet_input)
114
+ low_res_img.detach()
115
+ # 96 x 96
116
+ out = low_res_img
117
+
118
+ p2d = (2,2,2,2)
119
+ out = F.pad(out, p2d, "reflect", 0)
120
+ skip = out
121
+
122
+ for conv1, conv2, to_rgb in zip(self.style_convs[::2], self.style_convs[1::2], self.to_rgbs):
123
+ out = conv1(out, style_code) # 96, 192, 384
124
+ out = conv2(out, style_code)
125
+ skip = to_rgb(out, style_code, skip)
126
+ _outputs = skip
127
+
128
+ # remove padding
129
+ _outputs = _outputs[:,:,8:-8,8:-8]
130
+
131
+ if input_dim_size > 4:
132
+ _outputs = torch.split(_outputs, B, dim=0)
133
+ outputs = torch.stack(_outputs, dim=2)
134
+ low_res_img = F.interpolate(low_res_img, outputs.size()[3:])
135
+ low_res_img = torch.split(low_res_img, B, dim=0)
136
+ low_res_img = torch.stack(low_res_img, dim=2)
137
+ else:
138
+ outputs = _outputs
139
+ return outputs, low_res_img
video-tetalking/models/LNet.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import functools
2
+ import torch
3
+ import torch.nn as nn
4
+
5
+ from models.transformer import RETURNX, Transformer
6
+ from models.base_blocks import Conv2d, LayerNorm2d, FirstBlock2d, DownBlock2d, UpBlock2d, \
7
+ FFCADAINResBlocks, Jump, FinalBlock2d
8
+
9
+
10
+ class Visual_Encoder(nn.Module):
11
+ def __init__(self, image_nc, ngf, img_f, layers, norm_layer=nn.BatchNorm2d, nonlinearity=nn.LeakyReLU(), use_spect=False):
12
+ super(Visual_Encoder, self).__init__()
13
+ self.layers = layers
14
+ self.first_inp = FirstBlock2d(image_nc, ngf, norm_layer, nonlinearity, use_spect)
15
+ self.first_ref = FirstBlock2d(image_nc, ngf, norm_layer, nonlinearity, use_spect)
16
+ for i in range(layers):
17
+ in_channels = min(ngf*(2**i), img_f)
18
+ out_channels = min(ngf*(2**(i+1)), img_f)
19
+ model_ref = DownBlock2d(in_channels, out_channels, norm_layer, nonlinearity, use_spect)
20
+ model_inp = DownBlock2d(in_channels, out_channels, norm_layer, nonlinearity, use_spect)
21
+ if i < 2:
22
+ ca_layer = RETURNX()
23
+ else:
24
+ ca_layer = Transformer(2**(i+1) * ngf,2,4,ngf,ngf*4)
25
+ setattr(self, 'ca' + str(i), ca_layer)
26
+ setattr(self, 'ref_down' + str(i), model_ref)
27
+ setattr(self, 'inp_down' + str(i), model_inp)
28
+ self.output_nc = out_channels * 2
29
+
30
+ def forward(self, maskGT, ref):
31
+ x_maskGT, x_ref = self.first_inp(maskGT), self.first_ref(ref)
32
+ out=[x_maskGT]
33
+ for i in range(self.layers):
34
+ model_ref = getattr(self, 'ref_down'+str(i))
35
+ model_inp = getattr(self, 'inp_down'+str(i))
36
+ ca_layer = getattr(self, 'ca'+str(i))
37
+ x_maskGT, x_ref = model_inp(x_maskGT), model_ref(x_ref)
38
+ x_maskGT = ca_layer(x_maskGT, x_ref)
39
+ if i < self.layers - 1:
40
+ out.append(x_maskGT)
41
+ else:
42
+ out.append(torch.cat([x_maskGT, x_ref], dim=1)) # concat ref features !
43
+ return out
44
+
45
+
46
+ class Decoder(nn.Module):
47
+ def __init__(self, image_nc, feature_nc, ngf, img_f, layers, num_block, norm_layer=nn.BatchNorm2d, nonlinearity=nn.LeakyReLU(), use_spect=False):
48
+ super(Decoder, self).__init__()
49
+ self.layers = layers
50
+ for i in range(layers)[::-1]:
51
+ if i == layers-1:
52
+ in_channels = ngf*(2**(i+1)) * 2
53
+ else:
54
+ in_channels = min(ngf*(2**(i+1)), img_f)
55
+ out_channels = min(ngf*(2**i), img_f)
56
+ up = UpBlock2d(in_channels, out_channels, norm_layer, nonlinearity, use_spect)
57
+ res = FFCADAINResBlocks(num_block, in_channels, feature_nc, norm_layer, nonlinearity, use_spect)
58
+ jump = Jump(out_channels, norm_layer, nonlinearity, use_spect)
59
+
60
+ setattr(self, 'up' + str(i), up)
61
+ setattr(self, 'res' + str(i), res)
62
+ setattr(self, 'jump' + str(i), jump)
63
+
64
+ self.final = FinalBlock2d(out_channels, image_nc, use_spect, 'sigmoid')
65
+ self.output_nc = out_channels
66
+
67
+ def forward(self, x, z):
68
+ out = x.pop()
69
+ for i in range(self.layers)[::-1]:
70
+ res_model = getattr(self, 'res' + str(i))
71
+ up_model = getattr(self, 'up' + str(i))
72
+ jump_model = getattr(self, 'jump' + str(i))
73
+ out = res_model(out, z)
74
+ out = up_model(out)
75
+ out = jump_model(x.pop()) + out
76
+ out_image = self.final(out)
77
+ return out_image
78
+
79
+
80
+ class LNet(nn.Module):
81
+ def __init__(
82
+ self,
83
+ image_nc=3,
84
+ descriptor_nc=512,
85
+ layer=3,
86
+ base_nc=64,
87
+ max_nc=512,
88
+ num_res_blocks=9,
89
+ use_spect=True,
90
+ encoder=Visual_Encoder,
91
+ decoder=Decoder
92
+ ):
93
+ super(LNet, self).__init__()
94
+
95
+ nonlinearity = nn.LeakyReLU(0.1)
96
+ norm_layer = functools.partial(LayerNorm2d, affine=True)
97
+ kwargs = {'norm_layer':norm_layer, 'nonlinearity':nonlinearity, 'use_spect':use_spect}
98
+ self.descriptor_nc = descriptor_nc
99
+
100
+ self.encoder = encoder(image_nc, base_nc, max_nc, layer, **kwargs)
101
+ self.decoder = decoder(image_nc, self.descriptor_nc, base_nc, max_nc, layer, num_res_blocks, **kwargs)
102
+ self.audio_encoder = nn.Sequential(
103
+ Conv2d(1, 32, kernel_size=3, stride=1, padding=1),
104
+ Conv2d(32, 32, kernel_size=3, stride=1, padding=1, residual=True),
105
+ Conv2d(32, 32, kernel_size=3, stride=1, padding=1, residual=True),
106
+
107
+ Conv2d(32, 64, kernel_size=3, stride=(3, 1), padding=1),
108
+ Conv2d(64, 64, kernel_size=3, stride=1, padding=1, residual=True),
109
+ Conv2d(64, 64, kernel_size=3, stride=1, padding=1, residual=True),
110
+
111
+ Conv2d(64, 128, kernel_size=3, stride=3, padding=1),
112
+ Conv2d(128, 128, kernel_size=3, stride=1, padding=1, residual=True),
113
+ Conv2d(128, 128, kernel_size=3, stride=1, padding=1, residual=True),
114
+
115
+ Conv2d(128, 256, kernel_size=3, stride=(3, 2), padding=1),
116
+ Conv2d(256, 256, kernel_size=3, stride=1, padding=1, residual=True),
117
+
118
+ Conv2d(256, 512, kernel_size=3, stride=1, padding=0),
119
+ Conv2d(512, descriptor_nc, kernel_size=1, stride=1, padding=0),
120
+ )
121
+
122
+ def forward(self, audio_sequences, face_sequences):
123
+ B = audio_sequences.size(0)
124
+ input_dim_size = len(face_sequences.size())
125
+ if input_dim_size > 4:
126
+ audio_sequences = torch.cat([audio_sequences[:, i] for i in range(audio_sequences.size(1))], dim=0)
127
+ face_sequences = torch.cat([face_sequences[:, :, i] for i in range(face_sequences.size(2))], dim=0)
128
+ cropped, ref = torch.split(face_sequences, 3, dim=1)
129
+
130
+ vis_feat = self.encoder(cropped, ref)
131
+ audio_feat = self.audio_encoder(audio_sequences)
132
+ _outputs = self.decoder(vis_feat, audio_feat)
133
+
134
+ if input_dim_size > 4:
135
+ _outputs = torch.split(_outputs, B, dim=0)
136
+ outputs = torch.stack(_outputs, dim=2)
137
+ else:
138
+ outputs = _outputs
139
+ return outputs
video-tetalking/models/__init__.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from models.DNet import DNet
3
+ from models.LNet import LNet
4
+ from models.ENet import ENet
5
+
6
+
7
+ def _load(checkpoint_path):
8
+ map_location=None if torch.cuda.is_available() else torch.device('cpu')
9
+ checkpoint = torch.load(checkpoint_path, map_location=map_location)
10
+ return checkpoint
11
+
12
+ def load_checkpoint(path, model):
13
+ print("Load checkpoint from: {}".format(path))
14
+ checkpoint = _load(path)
15
+ s = checkpoint["state_dict"] if 'arcface' not in path else checkpoint
16
+ new_s = {}
17
+ for k, v in s.items():
18
+ if 'low_res' in k:
19
+ continue
20
+ else:
21
+ new_s[k.replace('module.', '')] = v
22
+ model.load_state_dict(new_s, strict=False)
23
+ return model
24
+
25
+ def load_network(args):
26
+ L_net = LNet()
27
+ L_net = load_checkpoint(args.LNet_path, L_net)
28
+ E_net = ENet(lnet=L_net)
29
+ model = load_checkpoint(args.ENet_path, E_net)
30
+ return model.eval()
31
+
32
+ def load_DNet(args):
33
+ D_Net = DNet()
34
+ print("Load checkpoint from: {}".format(args.DNet_path))
35
+ checkpoint = torch.load(args.DNet_path, map_location=lambda storage, loc: storage)
36
+ D_Net.load_state_dict(checkpoint['net_G_ema'], strict=False)
37
+ return D_Net.eval()
video-tetalking/models/base_blocks.py ADDED
@@ -0,0 +1,554 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.nn.functional as F
5
+ from torch.nn.modules.batchnorm import BatchNorm2d
6
+ from torch.nn.utils.spectral_norm import spectral_norm as SpectralNorm
7
+
8
+ from models.ffc import FFC
9
+ from basicsr.archs.arch_util import default_init_weights
10
+
11
+
12
+ class Conv2d(nn.Module):
13
+ def __init__(self, cin, cout, kernel_size, stride, padding, residual=False, *args, **kwargs):
14
+ super().__init__(*args, **kwargs)
15
+ self.conv_block = nn.Sequential(
16
+ nn.Conv2d(cin, cout, kernel_size, stride, padding),
17
+ nn.BatchNorm2d(cout)
18
+ )
19
+ self.act = nn.ReLU()
20
+ self.residual = residual
21
+
22
+ def forward(self, x):
23
+ out = self.conv_block(x)
24
+ if self.residual:
25
+ out += x
26
+ return self.act(out)
27
+
28
+
29
+ class ResBlock(nn.Module):
30
+ def __init__(self, in_channels, out_channels, mode='down'):
31
+ super(ResBlock, self).__init__()
32
+ self.conv1 = nn.Conv2d(in_channels, in_channels, 3, 1, 1)
33
+ self.conv2 = nn.Conv2d(in_channels, out_channels, 3, 1, 1)
34
+ self.skip = nn.Conv2d(in_channels, out_channels, 1, bias=False)
35
+ if mode == 'down':
36
+ self.scale_factor = 0.5
37
+ elif mode == 'up':
38
+ self.scale_factor = 2
39
+
40
+ def forward(self, x):
41
+ out = F.leaky_relu_(self.conv1(x), negative_slope=0.2)
42
+ # upsample/downsample
43
+ out = F.interpolate(out, scale_factor=self.scale_factor, mode='bilinear', align_corners=False)
44
+ out = F.leaky_relu_(self.conv2(out), negative_slope=0.2)
45
+ # skip
46
+ x = F.interpolate(x, scale_factor=self.scale_factor, mode='bilinear', align_corners=False)
47
+ skip = self.skip(x)
48
+ out = out + skip
49
+ return out
50
+
51
+
52
+ class LayerNorm2d(nn.Module):
53
+ def __init__(self, n_out, affine=True):
54
+ super(LayerNorm2d, self).__init__()
55
+ self.n_out = n_out
56
+ self.affine = affine
57
+
58
+ if self.affine:
59
+ self.weight = nn.Parameter(torch.ones(n_out, 1, 1))
60
+ self.bias = nn.Parameter(torch.zeros(n_out, 1, 1))
61
+
62
+ def forward(self, x):
63
+ normalized_shape = x.size()[1:]
64
+ if self.affine:
65
+ return F.layer_norm(x, normalized_shape, \
66
+ self.weight.expand(normalized_shape),
67
+ self.bias.expand(normalized_shape))
68
+ else:
69
+ return F.layer_norm(x, normalized_shape)
70
+
71
+
72
+ def spectral_norm(module, use_spect=True):
73
+ if use_spect:
74
+ return SpectralNorm(module)
75
+ else:
76
+ return module
77
+
78
+
79
+ class FirstBlock2d(nn.Module):
80
+ def __init__(self, input_nc, output_nc, norm_layer=nn.BatchNorm2d, nonlinearity=nn.LeakyReLU(), use_spect=False):
81
+ super(FirstBlock2d, self).__init__()
82
+ kwargs = {'kernel_size': 7, 'stride': 1, 'padding': 3}
83
+ conv = spectral_norm(nn.Conv2d(input_nc, output_nc, **kwargs), use_spect)
84
+
85
+ if type(norm_layer) == type(None):
86
+ self.model = nn.Sequential(conv, nonlinearity)
87
+ else:
88
+ self.model = nn.Sequential(conv, norm_layer(output_nc), nonlinearity)
89
+
90
+ def forward(self, x):
91
+ out = self.model(x)
92
+ return out
93
+
94
+
95
+ class DownBlock2d(nn.Module):
96
+ def __init__(self, input_nc, output_nc, norm_layer=nn.BatchNorm2d, nonlinearity=nn.LeakyReLU(), use_spect=False):
97
+ super(DownBlock2d, self).__init__()
98
+ kwargs = {'kernel_size': 3, 'stride': 1, 'padding': 1}
99
+ conv = spectral_norm(nn.Conv2d(input_nc, output_nc, **kwargs), use_spect)
100
+ pool = nn.AvgPool2d(kernel_size=(2, 2))
101
+
102
+ if type(norm_layer) == type(None):
103
+ self.model = nn.Sequential(conv, nonlinearity, pool)
104
+ else:
105
+ self.model = nn.Sequential(conv, norm_layer(output_nc), nonlinearity, pool)
106
+
107
+ def forward(self, x):
108
+ out = self.model(x)
109
+ return out
110
+
111
+
112
+ class UpBlock2d(nn.Module):
113
+ def __init__(self, input_nc, output_nc, norm_layer=nn.BatchNorm2d, nonlinearity=nn.LeakyReLU(), use_spect=False):
114
+ super(UpBlock2d, self).__init__()
115
+ kwargs = {'kernel_size': 3, 'stride': 1, 'padding': 1}
116
+ conv = spectral_norm(nn.Conv2d(input_nc, output_nc, **kwargs), use_spect)
117
+ if type(norm_layer) == type(None):
118
+ self.model = nn.Sequential(conv, nonlinearity)
119
+ else:
120
+ self.model = nn.Sequential(conv, norm_layer(output_nc), nonlinearity)
121
+
122
+ def forward(self, x):
123
+ out = self.model(F.interpolate(x, scale_factor=2))
124
+ return out
125
+
126
+
127
+ class ADAIN(nn.Module):
128
+ def __init__(self, norm_nc, feature_nc):
129
+ super().__init__()
130
+
131
+ self.param_free_norm = nn.InstanceNorm2d(norm_nc, affine=False)
132
+
133
+ nhidden = 128
134
+ use_bias=True
135
+
136
+ self.mlp_shared = nn.Sequential(
137
+ nn.Linear(feature_nc, nhidden, bias=use_bias),
138
+ nn.ReLU()
139
+ )
140
+ self.mlp_gamma = nn.Linear(nhidden, norm_nc, bias=use_bias)
141
+ self.mlp_beta = nn.Linear(nhidden, norm_nc, bias=use_bias)
142
+
143
+ def forward(self, x, feature):
144
+
145
+ # Part 1. generate parameter-free normalized activations
146
+ normalized = self.param_free_norm(x)
147
+ # Part 2. produce scaling and bias conditioned on feature
148
+ feature = feature.view(feature.size(0), -1)
149
+ actv = self.mlp_shared(feature)
150
+ gamma = self.mlp_gamma(actv)
151
+ beta = self.mlp_beta(actv)
152
+
153
+ # apply scale and bias
154
+ gamma = gamma.view(*gamma.size()[:2], 1,1)
155
+ beta = beta.view(*beta.size()[:2], 1,1)
156
+ out = normalized * (1 + gamma) + beta
157
+ return out
158
+
159
+
160
+ class FineADAINResBlock2d(nn.Module):
161
+ """
162
+ Define an Residual block for different types
163
+ """
164
+ def __init__(self, input_nc, feature_nc, norm_layer=nn.BatchNorm2d, nonlinearity=nn.LeakyReLU(), use_spect=False):
165
+ super(FineADAINResBlock2d, self).__init__()
166
+ kwargs = {'kernel_size': 3, 'stride': 1, 'padding': 1}
167
+ self.conv1 = spectral_norm(nn.Conv2d(input_nc, input_nc, **kwargs), use_spect)
168
+ self.conv2 = spectral_norm(nn.Conv2d(input_nc, input_nc, **kwargs), use_spect)
169
+ self.norm1 = ADAIN(input_nc, feature_nc)
170
+ self.norm2 = ADAIN(input_nc, feature_nc)
171
+ self.actvn = nonlinearity
172
+
173
+ def forward(self, x, z):
174
+ dx = self.actvn(self.norm1(self.conv1(x), z))
175
+ dx = self.norm2(self.conv2(x), z)
176
+ out = dx + x
177
+ return out
178
+
179
+
180
+ class FineADAINResBlocks(nn.Module):
181
+ def __init__(self, num_block, input_nc, feature_nc, norm_layer=nn.BatchNorm2d, nonlinearity=nn.LeakyReLU(), use_spect=False):
182
+ super(FineADAINResBlocks, self).__init__()
183
+ self.num_block = num_block
184
+ for i in range(num_block):
185
+ model = FineADAINResBlock2d(input_nc, feature_nc, norm_layer, nonlinearity, use_spect)
186
+ setattr(self, 'res'+str(i), model)
187
+
188
+ def forward(self, x, z):
189
+ for i in range(self.num_block):
190
+ model = getattr(self, 'res'+str(i))
191
+ x = model(x, z)
192
+ return x
193
+
194
+
195
+ class ADAINEncoderBlock(nn.Module):
196
+ def __init__(self, input_nc, output_nc, feature_nc, nonlinearity=nn.LeakyReLU(), use_spect=False):
197
+ super(ADAINEncoderBlock, self).__init__()
198
+ kwargs_down = {'kernel_size': 4, 'stride': 2, 'padding': 1}
199
+ kwargs_fine = {'kernel_size': 3, 'stride': 1, 'padding': 1}
200
+
201
+ self.conv_0 = spectral_norm(nn.Conv2d(input_nc, output_nc, **kwargs_down), use_spect)
202
+ self.conv_1 = spectral_norm(nn.Conv2d(output_nc, output_nc, **kwargs_fine), use_spect)
203
+
204
+
205
+ self.norm_0 = ADAIN(input_nc, feature_nc)
206
+ self.norm_1 = ADAIN(output_nc, feature_nc)
207
+ self.actvn = nonlinearity
208
+
209
+ def forward(self, x, z):
210
+ x = self.conv_0(self.actvn(self.norm_0(x, z)))
211
+ x = self.conv_1(self.actvn(self.norm_1(x, z)))
212
+ return x
213
+
214
+
215
+ class ADAINDecoderBlock(nn.Module):
216
+ def __init__(self, input_nc, output_nc, hidden_nc, feature_nc, use_transpose=True, nonlinearity=nn.LeakyReLU(), use_spect=False):
217
+ super(ADAINDecoderBlock, self).__init__()
218
+ # Attributes
219
+ self.actvn = nonlinearity
220
+ hidden_nc = min(input_nc, output_nc) if hidden_nc is None else hidden_nc
221
+
222
+ kwargs_fine = {'kernel_size':3, 'stride':1, 'padding':1}
223
+ if use_transpose:
224
+ kwargs_up = {'kernel_size':3, 'stride':2, 'padding':1, 'output_padding':1}
225
+ else:
226
+ kwargs_up = {'kernel_size':3, 'stride':1, 'padding':1}
227
+
228
+ # create conv layers
229
+ self.conv_0 = spectral_norm(nn.Conv2d(input_nc, hidden_nc, **kwargs_fine), use_spect)
230
+ if use_transpose:
231
+ self.conv_1 = spectral_norm(nn.ConvTranspose2d(hidden_nc, output_nc, **kwargs_up), use_spect)
232
+ self.conv_s = spectral_norm(nn.ConvTranspose2d(input_nc, output_nc, **kwargs_up), use_spect)
233
+ else:
234
+ self.conv_1 = nn.Sequential(spectral_norm(nn.Conv2d(hidden_nc, output_nc, **kwargs_up), use_spect),
235
+ nn.Upsample(scale_factor=2))
236
+ self.conv_s = nn.Sequential(spectral_norm(nn.Conv2d(input_nc, output_nc, **kwargs_up), use_spect),
237
+ nn.Upsample(scale_factor=2))
238
+ # define normalization layers
239
+ self.norm_0 = ADAIN(input_nc, feature_nc)
240
+ self.norm_1 = ADAIN(hidden_nc, feature_nc)
241
+ self.norm_s = ADAIN(input_nc, feature_nc)
242
+
243
+ def forward(self, x, z):
244
+ x_s = self.shortcut(x, z)
245
+ dx = self.conv_0(self.actvn(self.norm_0(x, z)))
246
+ dx = self.conv_1(self.actvn(self.norm_1(dx, z)))
247
+ out = x_s + dx
248
+ return out
249
+
250
+ def shortcut(self, x, z):
251
+ x_s = self.conv_s(self.actvn(self.norm_s(x, z)))
252
+ return x_s
253
+
254
+
255
+ class FineEncoder(nn.Module):
256
+ """docstring for Encoder"""
257
+ def __init__(self, image_nc, ngf, img_f, layers, norm_layer=nn.BatchNorm2d, nonlinearity=nn.LeakyReLU(), use_spect=False):
258
+ super(FineEncoder, self).__init__()
259
+ self.layers = layers
260
+ self.first = FirstBlock2d(image_nc, ngf, norm_layer, nonlinearity, use_spect)
261
+ for i in range(layers):
262
+ in_channels = min(ngf*(2**i), img_f)
263
+ out_channels = min(ngf*(2**(i+1)), img_f)
264
+ model = DownBlock2d(in_channels, out_channels, norm_layer, nonlinearity, use_spect)
265
+ setattr(self, 'down' + str(i), model)
266
+ self.output_nc = out_channels
267
+
268
+ def forward(self, x):
269
+ x = self.first(x)
270
+ out=[x]
271
+ for i in range(self.layers):
272
+ model = getattr(self, 'down'+str(i))
273
+ x = model(x)
274
+ out.append(x)
275
+ return out
276
+
277
+
278
+ class FineDecoder(nn.Module):
279
+ """docstring for FineDecoder"""
280
+ def __init__(self, image_nc, feature_nc, ngf, img_f, layers, num_block, norm_layer=nn.BatchNorm2d, nonlinearity=nn.LeakyReLU(), use_spect=False):
281
+ super(FineDecoder, self).__init__()
282
+ self.layers = layers
283
+ for i in range(layers)[::-1]:
284
+ in_channels = min(ngf*(2**(i+1)), img_f)
285
+ out_channels = min(ngf*(2**i), img_f)
286
+ up = UpBlock2d(in_channels, out_channels, norm_layer, nonlinearity, use_spect)
287
+ res = FineADAINResBlocks(num_block, in_channels, feature_nc, norm_layer, nonlinearity, use_spect)
288
+ jump = Jump(out_channels, norm_layer, nonlinearity, use_spect)
289
+ setattr(self, 'up' + str(i), up)
290
+ setattr(self, 'res' + str(i), res)
291
+ setattr(self, 'jump' + str(i), jump)
292
+ self.final = FinalBlock2d(out_channels, image_nc, use_spect, 'tanh')
293
+ self.output_nc = out_channels
294
+
295
+ def forward(self, x, z):
296
+ out = x.pop()
297
+ for i in range(self.layers)[::-1]:
298
+ res_model = getattr(self, 'res' + str(i))
299
+ up_model = getattr(self, 'up' + str(i))
300
+ jump_model = getattr(self, 'jump' + str(i))
301
+ out = res_model(out, z)
302
+ out = up_model(out)
303
+ out = jump_model(x.pop()) + out
304
+ out_image = self.final(out)
305
+ return out_image
306
+
307
+
308
+ class ADAINEncoder(nn.Module):
309
+ def __init__(self, image_nc, pose_nc, ngf, img_f, layers, nonlinearity=nn.LeakyReLU(), use_spect=False):
310
+ super(ADAINEncoder, self).__init__()
311
+ self.layers = layers
312
+ self.input_layer = nn.Conv2d(image_nc, ngf, kernel_size=7, stride=1, padding=3)
313
+ for i in range(layers):
314
+ in_channels = min(ngf * (2**i), img_f)
315
+ out_channels = min(ngf *(2**(i+1)), img_f)
316
+ model = ADAINEncoderBlock(in_channels, out_channels, pose_nc, nonlinearity, use_spect)
317
+ setattr(self, 'encoder' + str(i), model)
318
+ self.output_nc = out_channels
319
+
320
+ def forward(self, x, z):
321
+ out = self.input_layer(x)
322
+ out_list = [out]
323
+ for i in range(self.layers):
324
+ model = getattr(self, 'encoder' + str(i))
325
+ out = model(out, z)
326
+ out_list.append(out)
327
+ return out_list
328
+
329
+
330
+ class ADAINDecoder(nn.Module):
331
+ """docstring for ADAINDecoder"""
332
+ def __init__(self, pose_nc, ngf, img_f, encoder_layers, decoder_layers, skip_connect=True,
333
+ nonlinearity=nn.LeakyReLU(), use_spect=False):
334
+
335
+ super(ADAINDecoder, self).__init__()
336
+ self.encoder_layers = encoder_layers
337
+ self.decoder_layers = decoder_layers
338
+ self.skip_connect = skip_connect
339
+ use_transpose = True
340
+ for i in range(encoder_layers-decoder_layers, encoder_layers)[::-1]:
341
+ in_channels = min(ngf * (2**(i+1)), img_f)
342
+ in_channels = in_channels*2 if i != (encoder_layers-1) and self.skip_connect else in_channels
343
+ out_channels = min(ngf * (2**i), img_f)
344
+ model = ADAINDecoderBlock(in_channels, out_channels, out_channels, pose_nc, use_transpose, nonlinearity, use_spect)
345
+ setattr(self, 'decoder' + str(i), model)
346
+ self.output_nc = out_channels*2 if self.skip_connect else out_channels
347
+
348
+ def forward(self, x, z):
349
+ out = x.pop() if self.skip_connect else x
350
+ for i in range(self.encoder_layers-self.decoder_layers, self.encoder_layers)[::-1]:
351
+ model = getattr(self, 'decoder' + str(i))
352
+ out = model(out, z)
353
+ out = torch.cat([out, x.pop()], 1) if self.skip_connect else out
354
+ return out
355
+
356
+
357
+ class ADAINHourglass(nn.Module):
358
+ def __init__(self, image_nc, pose_nc, ngf, img_f, encoder_layers, decoder_layers, nonlinearity, use_spect):
359
+ super(ADAINHourglass, self).__init__()
360
+ self.encoder = ADAINEncoder(image_nc, pose_nc, ngf, img_f, encoder_layers, nonlinearity, use_spect)
361
+ self.decoder = ADAINDecoder(pose_nc, ngf, img_f, encoder_layers, decoder_layers, True, nonlinearity, use_spect)
362
+ self.output_nc = self.decoder.output_nc
363
+
364
+ def forward(self, x, z):
365
+ return self.decoder(self.encoder(x, z), z)
366
+
367
+
368
+ class FineADAINLama(nn.Module):
369
+ def __init__(self, input_nc, feature_nc, norm_layer=nn.BatchNorm2d, nonlinearity=nn.LeakyReLU(), use_spect=False):
370
+ super(FineADAINLama, self).__init__()
371
+ kwargs = {'kernel_size': 3, 'stride': 1, 'padding': 1}
372
+ self.actvn = nonlinearity
373
+ ratio_gin = 0.75
374
+ ratio_gout = 0.75
375
+ self.ffc = FFC(input_nc, input_nc, 3,
376
+ ratio_gin, ratio_gout, 1, 1, 1,
377
+ 1, False, False, padding_type='reflect')
378
+ global_channels = int(input_nc * ratio_gout)
379
+ self.bn_l = ADAIN(input_nc - global_channels, feature_nc)
380
+ self.bn_g = ADAIN(global_channels, feature_nc)
381
+
382
+ def forward(self, x, z):
383
+ x_l, x_g = self.ffc(x)
384
+ x_l = self.actvn(self.bn_l(x_l,z))
385
+ x_g = self.actvn(self.bn_g(x_g,z))
386
+ return x_l, x_g
387
+
388
+
389
+ class FFCResnetBlock(nn.Module):
390
+ def __init__(self, dim, feature_dim, padding_type='reflect', norm_layer=BatchNorm2d, activation_layer=nn.ReLU, dilation=1,
391
+ spatial_transform_kwargs=None, inline=False, **conv_kwargs):
392
+ super().__init__()
393
+ self.conv1 = FineADAINLama(dim, feature_dim, **conv_kwargs)
394
+ self.conv2 = FineADAINLama(dim, feature_dim, **conv_kwargs)
395
+ self.inline = True
396
+
397
+ def forward(self, x, z):
398
+ if self.inline:
399
+ x_l, x_g = x[:, :-self.conv1.ffc.global_in_num], x[:, -self.conv1.ffc.global_in_num:]
400
+ else:
401
+ x_l, x_g = x if type(x) is tuple else (x, 0)
402
+
403
+ id_l, id_g = x_l, x_g
404
+ x_l, x_g = self.conv1((x_l, x_g), z)
405
+ x_l, x_g = self.conv2((x_l, x_g), z)
406
+
407
+ x_l, x_g = id_l + x_l, id_g + x_g
408
+ out = x_l, x_g
409
+ if self.inline:
410
+ out = torch.cat(out, dim=1)
411
+ return out
412
+
413
+
414
+ class FFCADAINResBlocks(nn.Module):
415
+ def __init__(self, num_block, input_nc, feature_nc, norm_layer=nn.BatchNorm2d, nonlinearity=nn.LeakyReLU(), use_spect=False):
416
+ super(FFCADAINResBlocks, self).__init__()
417
+ self.num_block = num_block
418
+ for i in range(num_block):
419
+ model = FFCResnetBlock(input_nc, feature_nc, norm_layer, nonlinearity, use_spect)
420
+ setattr(self, 'res'+str(i), model)
421
+
422
+ def forward(self, x, z):
423
+ for i in range(self.num_block):
424
+ model = getattr(self, 'res'+str(i))
425
+ x = model(x, z)
426
+ return x
427
+
428
+
429
+ class Jump(nn.Module):
430
+ def __init__(self, input_nc, norm_layer=nn.BatchNorm2d, nonlinearity=nn.LeakyReLU(), use_spect=False):
431
+ super(Jump, self).__init__()
432
+ kwargs = {'kernel_size': 3, 'stride': 1, 'padding': 1}
433
+ conv = spectral_norm(nn.Conv2d(input_nc, input_nc, **kwargs), use_spect)
434
+ if type(norm_layer) == type(None):
435
+ self.model = nn.Sequential(conv, nonlinearity)
436
+ else:
437
+ self.model = nn.Sequential(conv, norm_layer(input_nc), nonlinearity)
438
+
439
+ def forward(self, x):
440
+ out = self.model(x)
441
+ return out
442
+
443
+
444
+ class FinalBlock2d(nn.Module):
445
+ def __init__(self, input_nc, output_nc, use_spect=False, tanh_or_sigmoid='tanh'):
446
+ super(FinalBlock2d, self).__init__()
447
+ kwargs = {'kernel_size': 7, 'stride': 1, 'padding':3}
448
+ conv = spectral_norm(nn.Conv2d(input_nc, output_nc, **kwargs), use_spect)
449
+ if tanh_or_sigmoid == 'sigmoid':
450
+ out_nonlinearity = nn.Sigmoid()
451
+ else:
452
+ out_nonlinearity = nn.Tanh()
453
+ self.model = nn.Sequential(conv, out_nonlinearity)
454
+
455
+ def forward(self, x):
456
+ out = self.model(x)
457
+ return out
458
+
459
+
460
+ class ModulatedConv2d(nn.Module):
461
+ def __init__(self,
462
+ in_channels,
463
+ out_channels,
464
+ kernel_size,
465
+ num_style_feat,
466
+ demodulate=True,
467
+ sample_mode=None,
468
+ eps=1e-8):
469
+ super(ModulatedConv2d, self).__init__()
470
+ self.in_channels = in_channels
471
+ self.out_channels = out_channels
472
+ self.kernel_size = kernel_size
473
+ self.demodulate = demodulate
474
+ self.sample_mode = sample_mode
475
+ self.eps = eps
476
+
477
+ # modulation inside each modulated conv
478
+ self.modulation = nn.Linear(num_style_feat, in_channels, bias=True)
479
+ # initialization
480
+ default_init_weights(self.modulation, scale=1, bias_fill=1, a=0, mode='fan_in', nonlinearity='linear')
481
+
482
+ self.weight = nn.Parameter(
483
+ torch.randn(1, out_channels, in_channels, kernel_size, kernel_size) /
484
+ math.sqrt(in_channels * kernel_size**2))
485
+ self.padding = kernel_size // 2
486
+
487
+ def forward(self, x, style):
488
+ b, c, h, w = x.shape
489
+ style = self.modulation(style).view(b, 1, c, 1, 1)
490
+ weight = self.weight * style
491
+
492
+ if self.demodulate:
493
+ demod = torch.rsqrt(weight.pow(2).sum([2, 3, 4]) + self.eps)
494
+ weight = weight * demod.view(b, self.out_channels, 1, 1, 1)
495
+
496
+ weight = weight.view(b * self.out_channels, c, self.kernel_size, self.kernel_size)
497
+
498
+ # upsample or downsample if necessary
499
+ if self.sample_mode == 'upsample':
500
+ x = F.interpolate(x, scale_factor=2, mode='bilinear', align_corners=False)
501
+ elif self.sample_mode == 'downsample':
502
+ x = F.interpolate(x, scale_factor=0.5, mode='bilinear', align_corners=False)
503
+
504
+ b, c, h, w = x.shape
505
+ x = x.view(1, b * c, h, w)
506
+ out = F.conv2d(x, weight, padding=self.padding, groups=b)
507
+ out = out.view(b, self.out_channels, *out.shape[2:4])
508
+ return out
509
+
510
+ def __repr__(self):
511
+ return (f'{self.__class__.__name__}(in_channels={self.in_channels}, out_channels={self.out_channels}, '
512
+ f'kernel_size={self.kernel_size}, demodulate={self.demodulate}, sample_mode={self.sample_mode})')
513
+
514
+
515
+ class StyleConv(nn.Module):
516
+ def __init__(self, in_channels, out_channels, kernel_size, num_style_feat, demodulate=True, sample_mode=None):
517
+ super(StyleConv, self).__init__()
518
+ self.modulated_conv = ModulatedConv2d(
519
+ in_channels, out_channels, kernel_size, num_style_feat, demodulate=demodulate, sample_mode=sample_mode)
520
+ self.weight = nn.Parameter(torch.zeros(1)) # for noise injection
521
+ self.bias = nn.Parameter(torch.zeros(1, out_channels, 1, 1))
522
+ self.activate = nn.LeakyReLU(negative_slope=0.2, inplace=True)
523
+
524
+ def forward(self, x, style, noise=None):
525
+ # modulate
526
+ out = self.modulated_conv(x, style) * 2**0.5 # for conversion
527
+ # noise injection
528
+ if noise is None:
529
+ b, _, h, w = out.shape
530
+ noise = out.new_empty(b, 1, h, w).normal_()
531
+ out = out + self.weight * noise
532
+ # add bias
533
+ out = out + self.bias
534
+ # activation
535
+ out = self.activate(out)
536
+ return out
537
+
538
+
539
+ class ToRGB(nn.Module):
540
+ def __init__(self, in_channels, num_style_feat, upsample=True):
541
+ super(ToRGB, self).__init__()
542
+ self.upsample = upsample
543
+ self.modulated_conv = ModulatedConv2d(
544
+ in_channels, 3, kernel_size=1, num_style_feat=num_style_feat, demodulate=False, sample_mode=None)
545
+ self.bias = nn.Parameter(torch.zeros(1, 3, 1, 1))
546
+
547
+ def forward(self, x, style, skip=None):
548
+ out = self.modulated_conv(x, style)
549
+ out = out + self.bias
550
+ if skip is not None:
551
+ if self.upsample:
552
+ skip = F.interpolate(skip, scale_factor=2, mode='bilinear', align_corners=False)
553
+ out = out + skip
554
+ return out
video-tetalking/models/ffc.py ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Fast Fourier Convolution NeurIPS 2020
2
+ # original implementation https://github.com/pkumivision/FFC/blob/main/model_zoo/ffc.py
3
+ # paper https://proceedings.neurips.cc/paper/2020/file/2fd5d41ec6cfab47e32164d5624269b1-Paper.pdf
4
+
5
+ import torch
6
+ import torch.nn as nn
7
+ import torch.nn.functional as F
8
+ # from models.modules.squeeze_excitation import SELayer
9
+ import torch.fft
10
+
11
+ class SELayer(nn.Module):
12
+ def __init__(self, channel, reduction=16):
13
+ super(SELayer, self).__init__()
14
+ self.avg_pool = nn.AdaptiveAvgPool2d(1)
15
+ self.fc = nn.Sequential(
16
+ nn.Linear(channel, channel // reduction, bias=False),
17
+ nn.ReLU(inplace=True),
18
+ nn.Linear(channel // reduction, channel, bias=False),
19
+ nn.Sigmoid()
20
+ )
21
+
22
+ def forward(self, x):
23
+ b, c, _, _ = x.size()
24
+ y = self.avg_pool(x).view(b, c)
25
+ y = self.fc(y).view(b, c, 1, 1)
26
+ res = x * y.expand_as(x)
27
+ return res
28
+
29
+
30
+ class FFCSE_block(nn.Module):
31
+ def __init__(self, channels, ratio_g):
32
+ super(FFCSE_block, self).__init__()
33
+ in_cg = int(channels * ratio_g)
34
+ in_cl = channels - in_cg
35
+ r = 16
36
+
37
+ self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
38
+ self.conv1 = nn.Conv2d(channels, channels // r,
39
+ kernel_size=1, bias=True)
40
+ self.relu1 = nn.ReLU(inplace=True)
41
+ self.conv_a2l = None if in_cl == 0 else nn.Conv2d(
42
+ channels // r, in_cl, kernel_size=1, bias=True)
43
+ self.conv_a2g = None if in_cg == 0 else nn.Conv2d(
44
+ channels // r, in_cg, kernel_size=1, bias=True)
45
+ self.sigmoid = nn.Sigmoid()
46
+
47
+ def forward(self, x):
48
+ x = x if type(x) is tuple else (x, 0)
49
+ id_l, id_g = x
50
+
51
+ x = id_l if type(id_g) is int else torch.cat([id_l, id_g], dim=1)
52
+ x = self.avgpool(x)
53
+ x = self.relu1(self.conv1(x))
54
+
55
+ x_l = 0 if self.conv_a2l is None else id_l * \
56
+ self.sigmoid(self.conv_a2l(x))
57
+ x_g = 0 if self.conv_a2g is None else id_g * \
58
+ self.sigmoid(self.conv_a2g(x))
59
+ return x_l, x_g
60
+
61
+
62
+ class FourierUnit(nn.Module):
63
+
64
+ def __init__(self, in_channels, out_channels, groups=1, spatial_scale_factor=None, spatial_scale_mode='bilinear',
65
+ spectral_pos_encoding=False, use_se=False, se_kwargs=None, ffc3d=False, fft_norm='ortho'):
66
+ # bn_layer not used
67
+ super(FourierUnit, self).__init__()
68
+ self.groups = groups
69
+
70
+ self.conv_layer = torch.nn.Conv2d(in_channels=in_channels * 2 + (2 if spectral_pos_encoding else 0),
71
+ out_channels=out_channels * 2,
72
+ kernel_size=1, stride=1, padding=0, groups=self.groups, bias=False)
73
+ self.bn = torch.nn.BatchNorm2d(out_channels * 2)
74
+ self.relu = torch.nn.ReLU(inplace=True)
75
+
76
+ # squeeze and excitation block
77
+ self.use_se = use_se
78
+ if use_se:
79
+ if se_kwargs is None:
80
+ se_kwargs = {}
81
+ self.se = SELayer(self.conv_layer.in_channels, **se_kwargs)
82
+
83
+ self.spatial_scale_factor = spatial_scale_factor
84
+ self.spatial_scale_mode = spatial_scale_mode
85
+ self.spectral_pos_encoding = spectral_pos_encoding
86
+ self.ffc3d = ffc3d
87
+ self.fft_norm = fft_norm
88
+
89
+ def forward(self, x):
90
+ batch = x.shape[0]
91
+
92
+ if self.spatial_scale_factor is not None:
93
+ orig_size = x.shape[-2:]
94
+ x = F.interpolate(x, scale_factor=self.spatial_scale_factor, mode=self.spatial_scale_mode, align_corners=False)
95
+
96
+ r_size = x.size()
97
+ # (batch, c, h, w/2+1, 2)
98
+ fft_dim = (-3, -2, -1) if self.ffc3d else (-2, -1)
99
+ ffted = torch.fft.rfftn(x, dim=fft_dim, norm=self.fft_norm)
100
+ ffted = torch.stack((ffted.real, ffted.imag), dim=-1)
101
+ ffted = ffted.permute(0, 1, 4, 2, 3).contiguous() # (batch, c, 2, h, w/2+1)
102
+ ffted = ffted.view((batch, -1,) + ffted.size()[3:])
103
+
104
+ if self.spectral_pos_encoding:
105
+ height, width = ffted.shape[-2:]
106
+ coords_vert = torch.linspace(0, 1, height)[None, None, :, None].expand(batch, 1, height, width).to(ffted)
107
+ coords_hor = torch.linspace(0, 1, width)[None, None, None, :].expand(batch, 1, height, width).to(ffted)
108
+ ffted = torch.cat((coords_vert, coords_hor, ffted), dim=1)
109
+
110
+ if self.use_se:
111
+ ffted = self.se(ffted)
112
+
113
+ ffted = self.conv_layer(ffted) # (batch, c*2, h, w/2+1)
114
+ ffted = self.relu(self.bn(ffted))
115
+
116
+ ffted = ffted.view((batch, -1, 2,) + ffted.size()[2:]).permute(
117
+ 0, 1, 3, 4, 2).contiguous() # (batch,c, t, h, w/2+1, 2)
118
+ ffted = torch.complex(ffted[..., 0], ffted[..., 1])
119
+
120
+ ifft_shape_slice = x.shape[-3:] if self.ffc3d else x.shape[-2:]
121
+ output = torch.fft.irfftn(ffted, s=ifft_shape_slice, dim=fft_dim, norm=self.fft_norm)
122
+
123
+ if self.spatial_scale_factor is not None:
124
+ output = F.interpolate(output, size=orig_size, mode=self.spatial_scale_mode, align_corners=False)
125
+
126
+ return output
127
+
128
+
129
+ class SpectralTransform(nn.Module):
130
+ def __init__(self, in_channels, out_channels, stride=1, groups=1, enable_lfu=True, **fu_kwargs):
131
+ # bn_layer not used
132
+ super(SpectralTransform, self).__init__()
133
+ self.enable_lfu = enable_lfu
134
+ if stride == 2:
135
+ self.downsample = nn.AvgPool2d(kernel_size=(2, 2), stride=2)
136
+ else:
137
+ self.downsample = nn.Identity()
138
+
139
+ self.stride = stride
140
+ self.conv1 = nn.Sequential(
141
+ nn.Conv2d(in_channels, out_channels //
142
+ 2, kernel_size=1, groups=groups, bias=False),
143
+ nn.BatchNorm2d(out_channels // 2),
144
+ nn.ReLU(inplace=True)
145
+ )
146
+ self.fu = FourierUnit(
147
+ out_channels // 2, out_channels // 2, groups, **fu_kwargs)
148
+ if self.enable_lfu:
149
+ self.lfu = FourierUnit(
150
+ out_channels // 2, out_channels // 2, groups)
151
+ self.conv2 = torch.nn.Conv2d(
152
+ out_channels // 2, out_channels, kernel_size=1, groups=groups, bias=False)
153
+
154
+ def forward(self, x):
155
+ x = self.downsample(x)
156
+ x = self.conv1(x)
157
+ output = self.fu(x)
158
+
159
+ if self.enable_lfu:
160
+ n, c, h, w = x.shape
161
+ split_no = 2
162
+ split_s = h // split_no
163
+ xs = torch.cat(torch.split(
164
+ x[:, :c // 4], split_s, dim=-2), dim=1).contiguous()
165
+ xs = torch.cat(torch.split(xs, split_s, dim=-1),
166
+ dim=1).contiguous()
167
+ xs = self.lfu(xs)
168
+ xs = xs.repeat(1, 1, split_no, split_no).contiguous()
169
+ else:
170
+ xs = 0
171
+
172
+ output = self.conv2(x + output + xs)
173
+ return output
174
+
175
+
176
+ class FFC(nn.Module):
177
+
178
+ def __init__(self, in_channels, out_channels, kernel_size,
179
+ ratio_gin, ratio_gout, stride=1, padding=0,
180
+ dilation=1, groups=1, bias=False, enable_lfu=True,
181
+ padding_type='reflect', gated=False, **spectral_kwargs):
182
+ super(FFC, self).__init__()
183
+
184
+ assert stride == 1 or stride == 2, "Stride should be 1 or 2."
185
+ self.stride = stride
186
+
187
+ in_cg = int(in_channels * ratio_gin)
188
+ in_cl = in_channels - in_cg
189
+ out_cg = int(out_channels * ratio_gout)
190
+ out_cl = out_channels - out_cg
191
+
192
+ self.ratio_gin = ratio_gin
193
+ self.ratio_gout = ratio_gout
194
+ self.global_in_num = in_cg
195
+
196
+ module = nn.Identity if in_cl == 0 or out_cl == 0 else nn.Conv2d
197
+ self.convl2l = module(in_cl, out_cl, kernel_size,
198
+ stride, padding, dilation, groups, bias, padding_mode=padding_type)
199
+ module = nn.Identity if in_cl == 0 or out_cg == 0 else nn.Conv2d
200
+ self.convl2g = module(in_cl, out_cg, kernel_size,
201
+ stride, padding, dilation, groups, bias, padding_mode=padding_type)
202
+ module = nn.Identity if in_cg == 0 or out_cl == 0 else nn.Conv2d
203
+ self.convg2l = module(in_cg, out_cl, kernel_size,
204
+ stride, padding, dilation, groups, bias, padding_mode=padding_type)
205
+ module = nn.Identity if in_cg == 0 or out_cg == 0 else SpectralTransform
206
+ self.convg2g = module(
207
+ in_cg, out_cg, stride, 1 if groups == 1 else groups // 2, enable_lfu, **spectral_kwargs)
208
+
209
+ self.gated = gated
210
+ module = nn.Identity if in_cg == 0 or out_cl == 0 or not self.gated else nn.Conv2d
211
+ self.gate = module(in_channels, 2, 1)
212
+
213
+ def forward(self, x):
214
+ x_l, x_g = x if type(x) is tuple else (x, 0)
215
+ out_xl, out_xg = 0, 0
216
+
217
+ if self.gated:
218
+ total_input_parts = [x_l]
219
+ if torch.is_tensor(x_g):
220
+ total_input_parts.append(x_g)
221
+ total_input = torch.cat(total_input_parts, dim=1)
222
+
223
+ gates = torch.sigmoid(self.gate(total_input))
224
+ g2l_gate, l2g_gate = gates.chunk(2, dim=1)
225
+ else:
226
+ g2l_gate, l2g_gate = 1, 1
227
+
228
+ if self.ratio_gout != 1:
229
+ out_xl = self.convl2l(x_l) + self.convg2l(x_g) * g2l_gate
230
+ if self.ratio_gout != 0:
231
+ out_xg = self.convl2g(x_l) * l2g_gate + self.convg2g(x_g)
232
+
233
+ return out_xl, out_xg
video-tetalking/models/transformer.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from torch import nn
3
+
4
+ from einops import rearrange
5
+
6
+ import torch.nn as nn
7
+ import torch.nn.functional as F
8
+ import numpy as np
9
+
10
+
11
+ class GELU(nn.Module):
12
+ def __init__(self):
13
+ super(GELU, self).__init__()
14
+ def forward(self, x):
15
+ return 0.5*x*(1+F.tanh(np.sqrt(2/np.pi)*(x+0.044715*torch.pow(x,3))))
16
+
17
+ # helpers
18
+
19
+ def pair(t):
20
+ return t if isinstance(t, tuple) else (t, t)
21
+
22
+ # classes
23
+
24
+ class PreNorm(nn.Module):
25
+ def __init__(self, dim, fn):
26
+ super().__init__()
27
+ self.norm = nn.LayerNorm(dim)
28
+ self.fn = fn
29
+ def forward(self, x, **kwargs):
30
+ return self.fn(self.norm(x), **kwargs)
31
+
32
+ class DualPreNorm(nn.Module):
33
+ def __init__(self, dim, fn):
34
+ super().__init__()
35
+ self.normx = nn.LayerNorm(dim)
36
+ self.normy = nn.LayerNorm(dim)
37
+ self.fn = fn
38
+ def forward(self, x, y, **kwargs):
39
+ return self.fn(self.normx(x), self.normy(y), **kwargs)
40
+
41
+ class FeedForward(nn.Module):
42
+ def __init__(self, dim, hidden_dim, dropout = 0.):
43
+ super().__init__()
44
+ self.net = nn.Sequential(
45
+ nn.Linear(dim, hidden_dim),
46
+ GELU(),
47
+ nn.Dropout(dropout),
48
+ nn.Linear(hidden_dim, dim),
49
+ nn.Dropout(dropout)
50
+ )
51
+ def forward(self, x):
52
+ return self.net(x)
53
+
54
+ class Attention(nn.Module):
55
+ def __init__(self, dim, heads = 8, dim_head = 64, dropout = 0.):
56
+ super().__init__()
57
+ inner_dim = dim_head * heads
58
+ project_out = not (heads == 1 and dim_head == dim)
59
+
60
+ self.heads = heads
61
+ self.scale = dim_head ** -0.5
62
+
63
+ self.attend = nn.Softmax(dim = -1)
64
+
65
+ self.to_q = nn.Linear(dim, inner_dim, bias = False)
66
+ self.to_k = nn.Linear(dim, inner_dim, bias = False)
67
+ self.to_v = nn.Linear(dim, inner_dim, bias = False)
68
+
69
+
70
+ self.to_out = nn.Sequential(
71
+ nn.Linear(inner_dim, dim),
72
+ nn.Dropout(dropout)
73
+ ) if project_out else nn.Identity()
74
+
75
+ def forward(self, x, y):
76
+ # qk = self.to_qk(x).chunk(2, dim = -1) #
77
+ q = rearrange(self.to_q(x), 'b n (h d) -> b h n d', h = self.heads) # q,k from the zero feature
78
+ k = rearrange(self.to_k(x), 'b n (h d) -> b h n d', h = self.heads) # v from the reference features
79
+ v = rearrange(self.to_v(y), 'b n (h d) -> b h n d', h = self.heads)
80
+
81
+ dots = torch.matmul(q, k.transpose(-1, -2)) * self.scale
82
+
83
+ attn = self.attend(dots)
84
+
85
+ out = torch.matmul(attn, v)
86
+ out = rearrange(out, 'b h n d -> b n (h d)')
87
+ return self.to_out(out)
88
+
89
+ class Transformer(nn.Module):
90
+ def __init__(self, dim, depth, heads, dim_head, mlp_dim, dropout = 0.):
91
+ super().__init__()
92
+ self.layers = nn.ModuleList([])
93
+ for _ in range(depth):
94
+ self.layers.append(nn.ModuleList([
95
+ DualPreNorm(dim, Attention(dim, heads = heads, dim_head = dim_head, dropout = dropout)),
96
+ PreNorm(dim, FeedForward(dim, mlp_dim, dropout = dropout))
97
+ ]))
98
+
99
+
100
+ def forward(self, x, y): # x is the cropped, y is the foreign reference
101
+ bs,c,h,w = x.size()
102
+
103
+ # img to embedding
104
+ x = x.view(bs,c,-1).permute(0,2,1)
105
+ y = y.view(bs,c,-1).permute(0,2,1)
106
+
107
+ for attn, ff in self.layers:
108
+ x = attn(x, y) + x
109
+ x = ff(x) + x
110
+
111
+ x = x.view(bs,h,w,c).permute(0,3,1,2)
112
+ return x
113
+
114
+ class RETURNX(nn.Module):
115
+ def __init__(self,):
116
+ super().__init__()
117
+
118
+ def forward(self, x, y): # x is the cropped, y is the foreign reference
119
+ return x
video-tetalking/predict.py ADDED
@@ -0,0 +1,552 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Prediction interface for Cog ⚙️
2
+ # https://github.com/replicate/cog/blob/main/docs/python.md
3
+
4
+ import os
5
+ import sys
6
+ import argparse
7
+ import subprocess
8
+ import numpy as np
9
+ from tqdm import tqdm
10
+ from PIL import Image
11
+ from scipy.io import loadmat
12
+ import torch
13
+ import cv2
14
+ from cog import BasePredictor, Input, Path
15
+
16
+ sys.path.insert(0, "third_part")
17
+ sys.path.insert(0, "third_part/GPEN")
18
+ sys.path.insert(0, "third_part/GFPGAN")
19
+
20
+ # 3dmm extraction
21
+ from third_part.face3d.util.preprocess import align_img
22
+ from third_part.face3d.util.load_mats import load_lm3d
23
+ from third_part.face3d.extract_kp_videos import KeypointExtractor
24
+
25
+ # face enhancement
26
+ from third_part.GPEN.gpen_face_enhancer import FaceEnhancement
27
+ from third_part.GFPGAN.gfpgan import GFPGANer
28
+
29
+ # expression control
30
+ from third_part.ganimation_replicate.model.ganimation import GANimationModel
31
+
32
+ from utils import audio
33
+ from utils.ffhq_preprocess import Croper
34
+ from utils.alignment_stit import crop_faces, calc_alignment_coefficients, paste_image
35
+ from utils.inference_utils import (
36
+ Laplacian_Pyramid_Blending_with_mask,
37
+ face_detect,
38
+ load_model,
39
+ options,
40
+ split_coeff,
41
+ trans_image,
42
+ transform_semantic,
43
+ find_crop_norm_ratio,
44
+ load_face3d_net,
45
+ exp_aus_dict,
46
+ )
47
+
48
+
49
+ class Predictor(BasePredictor):
50
+ def setup(self) -> None:
51
+ """Load the model into memory to make running multiple predictions efficient"""
52
+ self.enhancer = FaceEnhancement(
53
+ base_dir="checkpoints",
54
+ size=512,
55
+ model="GPEN-BFR-512",
56
+ use_sr=False,
57
+ sr_model="rrdb_realesrnet_psnr",
58
+ channel_multiplier=2,
59
+ narrow=1,
60
+ device="cuda",
61
+ )
62
+ self.restorer = GFPGANer(
63
+ model_path="checkpoints/GFPGANv1.3.pth",
64
+ upscale=1,
65
+ arch="clean",
66
+ channel_multiplier=2,
67
+ bg_upsampler=None,
68
+ )
69
+ self.croper = Croper("checkpoints/shape_predictor_68_face_landmarks.dat")
70
+ self.kp_extractor = KeypointExtractor()
71
+
72
+ face3d_net_path = "checkpoints/face3d_pretrain_epoch_20.pth"
73
+
74
+ self.net_recon = load_face3d_net(face3d_net_path, "cuda")
75
+ self.lm3d_std = load_lm3d("checkpoints/BFM")
76
+
77
+ def predict(
78
+ self,
79
+ face: Path = Input(description="Input video file of a talking-head."),
80
+ input_audio: Path = Input(description="Input audio file."),
81
+ ) -> Path:
82
+ """Run a single prediction on the model"""
83
+ device = "cuda"
84
+ args = argparse.Namespace(
85
+ DNet_path="checkpoints/DNet.pt",
86
+ LNet_path="checkpoints/LNet.pth",
87
+ ENet_path="checkpoints/ENet.pth",
88
+ face3d_net_path="checkpoints/face3d_pretrain_epoch_20.pth",
89
+ face=str(face),
90
+ audio=str(input_audio),
91
+ exp_img="neutral",
92
+ outfile=None,
93
+ fps=25,
94
+ pads=[0, 20, 0, 0],
95
+ face_det_batch_size=4,
96
+ LNet_batch_size=16,
97
+ img_size=384,
98
+ crop=[0, -1, 0, -1],
99
+ box=[-1, -1, -1, -1],
100
+ nosmooth=False,
101
+ static=False,
102
+ up_face="original",
103
+ one_shot=False,
104
+ without_rl1=False,
105
+ tmp_dir="temp",
106
+ re_preprocess=False,
107
+ )
108
+
109
+ base_name = args.face.split("/")[-1]
110
+
111
+ if args.face.split(".")[1] in ["jpg", "png", "jpeg"]:
112
+ full_frames = [cv2.imread(args.face)]
113
+ args.static = True
114
+ fps = args.fps
115
+ else:
116
+ video_stream = cv2.VideoCapture(args.face)
117
+ fps = video_stream.get(cv2.CAP_PROP_FPS)
118
+ full_frames = []
119
+ while True:
120
+ still_reading, frame = video_stream.read()
121
+ if not still_reading:
122
+ video_stream.release()
123
+ break
124
+ y1, y2, x1, x2 = args.crop
125
+ if x2 == -1:
126
+ x2 = frame.shape[1]
127
+ if y2 == -1:
128
+ y2 = frame.shape[0]
129
+ frame = frame[y1:y2, x1:x2]
130
+ full_frames.append(frame)
131
+
132
+ full_frames_RGB = [
133
+ cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) for frame in full_frames
134
+ ]
135
+ full_frames_RGB, crop, quad = self.croper.crop(full_frames_RGB, xsize=512)
136
+
137
+ clx, cly, crx, cry = crop
138
+ lx, ly, rx, ry = quad
139
+ lx, ly, rx, ry = int(lx), int(ly), int(rx), int(ry)
140
+ oy1, oy2, ox1, ox2 = (
141
+ cly + ly,
142
+ min(cly + ry, full_frames[0].shape[0]),
143
+ clx + lx,
144
+ min(clx + rx, full_frames[0].shape[1]),
145
+ )
146
+ # original_size = (ox2 - ox1, oy2 - oy1)
147
+ frames_pil = [
148
+ Image.fromarray(cv2.resize(frame, (256, 256))) for frame in full_frames_RGB
149
+ ]
150
+
151
+ # get the landmark according to the detected face.
152
+ if (
153
+ not os.path.isfile("temp/" + base_name + "_landmarks.txt")
154
+ or args.re_preprocess
155
+ ):
156
+ print("[Step 1] Landmarks Extraction in Video.")
157
+ lm = self.kp_extractor.extract_keypoint(
158
+ frames_pil, "./temp/" + base_name + "_landmarks.txt"
159
+ )
160
+ else:
161
+ print("[Step 1] Using saved landmarks.")
162
+ lm = np.loadtxt("temp/" + base_name + "_landmarks.txt").astype(np.float32)
163
+ lm = lm.reshape([len(full_frames), -1, 2])
164
+
165
+ if (
166
+ not os.path.isfile("temp/" + base_name + "_coeffs.npy")
167
+ or args.exp_img is not None
168
+ or args.re_preprocess
169
+ ):
170
+ video_coeffs = []
171
+ for idx in tqdm(
172
+ range(len(frames_pil)), desc="[Step 2] 3DMM Extraction In Video:"
173
+ ):
174
+ frame = frames_pil[idx]
175
+ W, H = frame.size
176
+ lm_idx = lm[idx].reshape([-1, 2])
177
+ if np.mean(lm_idx) == -1:
178
+ lm_idx = (self.lm3d_std[:, :2] + 1) / 2.0
179
+ lm_idx = np.concatenate([lm_idx[:, :1] * W, lm_idx[:, 1:2] * H], 1)
180
+ else:
181
+ lm_idx[:, -1] = H - 1 - lm_idx[:, -1]
182
+
183
+ trans_params, im_idx, lm_idx, _ = align_img(
184
+ frame, lm_idx, self.lm3d_std
185
+ )
186
+ trans_params = np.array(
187
+ [float(item) for item in np.hsplit(trans_params, 5)]
188
+ ).astype(np.float32)
189
+ im_idx_tensor = (
190
+ torch.tensor(np.array(im_idx) / 255.0, dtype=torch.float32)
191
+ .permute(2, 0, 1)
192
+ .to(device)
193
+ .unsqueeze(0)
194
+ )
195
+ with torch.no_grad():
196
+ coeffs = split_coeff(self.net_recon(im_idx_tensor))
197
+
198
+ pred_coeff = {key: coeffs[key].cpu().numpy() for key in coeffs}
199
+ pred_coeff = np.concatenate(
200
+ [
201
+ pred_coeff["id"],
202
+ pred_coeff["exp"],
203
+ pred_coeff["tex"],
204
+ pred_coeff["angle"],
205
+ pred_coeff["gamma"],
206
+ pred_coeff["trans"],
207
+ trans_params[None],
208
+ ],
209
+ 1,
210
+ )
211
+ video_coeffs.append(pred_coeff)
212
+ semantic_npy = np.array(video_coeffs)[:, 0]
213
+ np.save("temp/" + base_name + "_coeffs.npy", semantic_npy)
214
+ else:
215
+ print("[Step 2] Using saved coeffs.")
216
+ semantic_npy = np.load("temp/" + base_name + "_coeffs.npy").astype(
217
+ np.float32
218
+ )
219
+
220
+ # generate the 3dmm coeff from a single image
221
+ if args.exp_img == "smile":
222
+ expression = torch.tensor(
223
+ loadmat("checkpoints/expression.mat")["expression_mouth"]
224
+ )[0]
225
+ else:
226
+ print("using expression center")
227
+ expression = torch.tensor(
228
+ loadmat("checkpoints/expression.mat")["expression_center"]
229
+ )[0]
230
+
231
+ # load DNet, model(LNet and ENet)
232
+ D_Net, model = load_model(args, device)
233
+
234
+ if (
235
+ not os.path.isfile("temp/" + base_name + "_stablized.npy")
236
+ or args.re_preprocess
237
+ ):
238
+ imgs = []
239
+ for idx in tqdm(
240
+ range(len(frames_pil)),
241
+ desc="[Step 3] Stabilize the expression In Video:",
242
+ ):
243
+ if args.one_shot:
244
+ source_img = trans_image(frames_pil[0]).unsqueeze(0).to(device)
245
+ semantic_source_numpy = semantic_npy[0:1]
246
+ else:
247
+ source_img = trans_image(frames_pil[idx]).unsqueeze(0).to(device)
248
+ semantic_source_numpy = semantic_npy[idx : idx + 1]
249
+ ratio = find_crop_norm_ratio(semantic_source_numpy, semantic_npy)
250
+ coeff = (
251
+ transform_semantic(semantic_npy, idx, ratio).unsqueeze(0).to(device)
252
+ )
253
+
254
+ # hacking the new expression
255
+ coeff[:, :64, :] = expression[None, :64, None].to(device)
256
+ with torch.no_grad():
257
+ output = D_Net(source_img, coeff)
258
+ img_stablized = np.uint8(
259
+ (
260
+ output["fake_image"]
261
+ .squeeze(0)
262
+ .permute(1, 2, 0)
263
+ .cpu()
264
+ .clamp_(-1, 1)
265
+ .numpy()
266
+ + 1
267
+ )
268
+ / 2.0
269
+ * 255
270
+ )
271
+ imgs.append(cv2.cvtColor(img_stablized, cv2.COLOR_RGB2BGR))
272
+ np.save("temp/" + base_name + "_stablized.npy", imgs)
273
+ del D_Net
274
+ else:
275
+ print("[Step 3] Using saved stabilized video.")
276
+ imgs = np.load("temp/" + base_name + "_stablized.npy")
277
+ torch.cuda.empty_cache()
278
+
279
+ if not args.audio.endswith(".wav"):
280
+ command = "ffmpeg -loglevel error -y -i {} -strict -2 {}".format(
281
+ args.audio, "temp/{}/temp.wav".format(args.tmp_dir)
282
+ )
283
+ subprocess.call(command, shell=True)
284
+ args.audio = "temp/{}/temp.wav".format(args.tmp_dir)
285
+ wav = audio.load_wav(args.audio, 16000)
286
+ mel = audio.melspectrogram(wav)
287
+ if np.isnan(mel.reshape(-1)).sum() > 0:
288
+ raise ValueError(
289
+ "Mel contains nan! Using a TTS voice? Add a small epsilon noise to the wav file and try again"
290
+ )
291
+
292
+ mel_step_size, mel_idx_multiplier, i, mel_chunks = 16, 80.0 / fps, 0, []
293
+ while True:
294
+ start_idx = int(i * mel_idx_multiplier)
295
+ if start_idx + mel_step_size > len(mel[0]):
296
+ mel_chunks.append(mel[:, len(mel[0]) - mel_step_size :])
297
+ break
298
+ mel_chunks.append(mel[:, start_idx : start_idx + mel_step_size])
299
+ i += 1
300
+
301
+ print("[Step 4] Load audio; Length of mel chunks: {}".format(len(mel_chunks)))
302
+ imgs = imgs[: len(mel_chunks)]
303
+ full_frames = full_frames[: len(mel_chunks)]
304
+ lm = lm[: len(mel_chunks)]
305
+
306
+ imgs_enhanced = []
307
+ for idx in tqdm(range(len(imgs)), desc="[Step 5] Reference Enhancement"):
308
+ img = imgs[idx]
309
+ pred, _, _ = self.enhancer.process(
310
+ img, img, face_enhance=True, possion_blending=False
311
+ )
312
+ imgs_enhanced.append(pred)
313
+ gen = datagen(
314
+ imgs_enhanced.copy(), mel_chunks, full_frames, args, (oy1, oy2, ox1, ox2)
315
+ )
316
+
317
+ frame_h, frame_w = full_frames[0].shape[:-1]
318
+ out = cv2.VideoWriter(
319
+ "temp/{}/result.mp4".format(args.tmp_dir),
320
+ cv2.VideoWriter_fourcc(*"mp4v"),
321
+ fps,
322
+ (frame_w, frame_h),
323
+ )
324
+
325
+ if args.up_face != "original":
326
+ instance = GANimationModel()
327
+ instance.initialize()
328
+ instance.setup()
329
+
330
+ # kp_extractor = KeypointExtractor()
331
+ for i, (
332
+ img_batch,
333
+ mel_batch,
334
+ frames,
335
+ coords,
336
+ img_original,
337
+ f_frames,
338
+ ) in enumerate(
339
+ tqdm(
340
+ gen,
341
+ desc="[Step 6] Lip Synthesis:",
342
+ total=int(np.ceil(float(len(mel_chunks)) / args.LNet_batch_size)),
343
+ )
344
+ ):
345
+ img_batch = torch.FloatTensor(np.transpose(img_batch, (0, 3, 1, 2))).to(
346
+ device
347
+ )
348
+ mel_batch = torch.FloatTensor(np.transpose(mel_batch, (0, 3, 1, 2))).to(
349
+ device
350
+ )
351
+ img_original = (
352
+ torch.FloatTensor(np.transpose(img_original, (0, 3, 1, 2))).to(device)
353
+ / 255.0
354
+ ) # BGR -> RGB
355
+
356
+ with torch.no_grad():
357
+ incomplete, reference = torch.split(img_batch, 3, dim=1)
358
+ pred, low_res = model(mel_batch, img_batch, reference)
359
+ pred = torch.clamp(pred, 0, 1)
360
+
361
+ if args.up_face in ["sad", "angry", "surprise"]:
362
+ tar_aus = exp_aus_dict[args.up_face]
363
+ else:
364
+ pass
365
+
366
+ if args.up_face == "original":
367
+ cur_gen_faces = img_original
368
+ else:
369
+ test_batch = {
370
+ "src_img": torch.nn.functional.interpolate(
371
+ (img_original * 2 - 1), size=(128, 128), mode="bilinear"
372
+ ),
373
+ "tar_aus": tar_aus.repeat(len(incomplete), 1),
374
+ }
375
+ instance.feed_batch(test_batch)
376
+ instance.forward()
377
+ cur_gen_faces = torch.nn.functional.interpolate(
378
+ instance.fake_img / 2.0 + 0.5, size=(384, 384), mode="bilinear"
379
+ )
380
+
381
+ if args.without_rl1 is not False:
382
+ incomplete, reference = torch.split(img_batch, 3, dim=1)
383
+ mask = torch.where(
384
+ incomplete == 0,
385
+ torch.ones_like(incomplete),
386
+ torch.zeros_like(incomplete),
387
+ )
388
+ pred = pred * mask + cur_gen_faces * (1 - mask)
389
+
390
+ pred = pred.cpu().numpy().transpose(0, 2, 3, 1) * 255.0
391
+
392
+ torch.cuda.empty_cache()
393
+ for p, f, xf, c in zip(pred, frames, f_frames, coords):
394
+ y1, y2, x1, x2 = c
395
+ p = cv2.resize(p.astype(np.uint8), (x2 - x1, y2 - y1))
396
+
397
+ ff = xf.copy()
398
+ ff[y1:y2, x1:x2] = p
399
+
400
+ # month region enhancement by GFPGAN
401
+ cropped_faces, restored_faces, restored_img = self.restorer.enhance(
402
+ ff, has_aligned=False, only_center_face=True, paste_back=True
403
+ )
404
+ # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
405
+ mm = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0]
406
+ mouse_mask = np.zeros_like(restored_img)
407
+ tmp_mask = self.enhancer.faceparser.process(
408
+ restored_img[y1:y2, x1:x2], mm
409
+ )[0]
410
+ mouse_mask[y1:y2, x1:x2] = (
411
+ cv2.resize(tmp_mask, (x2 - x1, y2 - y1))[:, :, np.newaxis] / 255.0
412
+ )
413
+
414
+ height, width = ff.shape[:2]
415
+ restored_img, ff, full_mask = [
416
+ cv2.resize(x, (512, 512))
417
+ for x in (restored_img, ff, np.float32(mouse_mask))
418
+ ]
419
+ img = Laplacian_Pyramid_Blending_with_mask(
420
+ restored_img, ff, full_mask[:, :, 0], 10
421
+ )
422
+ pp = np.uint8(cv2.resize(np.clip(img, 0, 255), (width, height)))
423
+
424
+ pp, orig_faces, enhanced_faces = self.enhancer.process(
425
+ pp, xf, bbox=c, face_enhance=False, possion_blending=True
426
+ )
427
+ out.write(pp)
428
+ out.release()
429
+
430
+ output_file = "/tmp/output.mp4"
431
+ command = "ffmpeg -loglevel error -y -i {} -i {} -strict -2 -q:v 1 {}".format(
432
+ args.audio, "temp/{}/result.mp4".format(args.tmp_dir), output_file
433
+ )
434
+ subprocess.call(command, shell=True)
435
+
436
+ return Path(output_file)
437
+
438
+
439
+ # frames:256x256, full_frames: original size
440
+ def datagen(frames, mels, full_frames, args, cox):
441
+ img_batch, mel_batch, frame_batch, coords_batch, ref_batch, full_frame_batch = (
442
+ [],
443
+ [],
444
+ [],
445
+ [],
446
+ [],
447
+ [],
448
+ )
449
+ base_name = args.face.split("/")[-1]
450
+ refs = []
451
+ image_size = 256
452
+
453
+ # original frames
454
+ kp_extractor = KeypointExtractor()
455
+ fr_pil = [Image.fromarray(frame) for frame in frames]
456
+ lms = kp_extractor.extract_keypoint(
457
+ fr_pil, "temp/" + base_name + "x12_landmarks.txt"
458
+ )
459
+ frames_pil = [
460
+ (lm, frame) for frame, lm in zip(fr_pil, lms)
461
+ ] # frames is the croped version of modified face
462
+ crops, orig_images, quads = crop_faces(
463
+ image_size, frames_pil, scale=1.0, use_fa=True
464
+ )
465
+ inverse_transforms = [
466
+ calc_alignment_coefficients(
467
+ quad + 0.5,
468
+ [[0, 0], [0, image_size], [image_size, image_size], [image_size, 0]],
469
+ )
470
+ for quad in quads
471
+ ]
472
+ del kp_extractor.detector
473
+
474
+ oy1, oy2, ox1, ox2 = cox
475
+ face_det_results = face_detect(full_frames, args, jaw_correction=True)
476
+
477
+ for inverse_transform, crop, full_frame, face_det in zip(
478
+ inverse_transforms, crops, full_frames, face_det_results
479
+ ):
480
+ imc_pil = paste_image(
481
+ inverse_transform,
482
+ crop,
483
+ Image.fromarray(
484
+ cv2.resize(
485
+ full_frame[int(oy1) : int(oy2), int(ox1) : int(ox2)], (256, 256)
486
+ )
487
+ ),
488
+ )
489
+
490
+ ff = full_frame.copy()
491
+ ff[int(oy1) : int(oy2), int(ox1) : int(ox2)] = cv2.resize(
492
+ np.array(imc_pil.convert("RGB")), (ox2 - ox1, oy2 - oy1)
493
+ )
494
+ oface, coords = face_det
495
+ y1, y2, x1, x2 = coords
496
+ refs.append(ff[y1:y2, x1:x2])
497
+
498
+ for i, m in enumerate(mels):
499
+ idx = 0 if args.static else i % len(frames)
500
+ frame_to_save = frames[idx].copy()
501
+ face = refs[idx]
502
+ oface, coords = face_det_results[idx].copy()
503
+
504
+ face = cv2.resize(face, (args.img_size, args.img_size))
505
+ oface = cv2.resize(oface, (args.img_size, args.img_size))
506
+
507
+ img_batch.append(oface)
508
+ ref_batch.append(face)
509
+ mel_batch.append(m)
510
+ coords_batch.append(coords)
511
+ frame_batch.append(frame_to_save)
512
+ full_frame_batch.append(full_frames[idx].copy())
513
+
514
+ if len(img_batch) >= args.LNet_batch_size:
515
+ img_batch, mel_batch, ref_batch = (
516
+ np.asarray(img_batch),
517
+ np.asarray(mel_batch),
518
+ np.asarray(ref_batch),
519
+ )
520
+ img_masked = img_batch.copy()
521
+ img_original = img_batch.copy()
522
+ img_masked[:, args.img_size // 2 :] = 0
523
+ img_batch = np.concatenate((img_masked, ref_batch), axis=3) / 255.0
524
+ mel_batch = np.reshape(
525
+ mel_batch, [len(mel_batch), mel_batch.shape[1], mel_batch.shape[2], 1]
526
+ )
527
+
528
+ yield img_batch, mel_batch, frame_batch, coords_batch, img_original, full_frame_batch
529
+ (
530
+ img_batch,
531
+ mel_batch,
532
+ frame_batch,
533
+ coords_batch,
534
+ img_original,
535
+ full_frame_batch,
536
+ ref_batch,
537
+ ) = ([], [], [], [], [], [], [])
538
+
539
+ if len(img_batch) > 0:
540
+ img_batch, mel_batch, ref_batch = (
541
+ np.asarray(img_batch),
542
+ np.asarray(mel_batch),
543
+ np.asarray(ref_batch),
544
+ )
545
+ img_masked = img_batch.copy()
546
+ img_original = img_batch.copy()
547
+ img_masked[:, args.img_size // 2 :] = 0
548
+ img_batch = np.concatenate((img_masked, ref_batch), axis=3) / 255.0
549
+ mel_batch = np.reshape(
550
+ mel_batch, [len(mel_batch), mel_batch.shape[1], mel_batch.shape[2], 1]
551
+ )
552
+ yield img_batch, mel_batch, frame_batch, coords_batch, img_original, full_frame_batch
video-tetalking/quick_demo.ipynb ADDED
@@ -0,0 +1,293 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "nbformat": 4,
3
+ "nbformat_minor": 0,
4
+ "metadata": {
5
+ "colab": {
6
+ "provenance": [],
7
+ "authorship_tag": "ABX9TyMPin07iIA2oewCCP9ZTz6w",
8
+ "include_colab_link": true
9
+ },
10
+ "kernelspec": {
11
+ "name": "python3",
12
+ "display_name": "Python 3"
13
+ },
14
+ "language_info": {
15
+ "name": "python"
16
+ },
17
+ "accelerator": "GPU",
18
+ "gpuClass": "standard"
19
+ },
20
+ "cells": [
21
+ {
22
+ "cell_type": "markdown",
23
+ "metadata": {
24
+ "id": "view-in-github",
25
+ "colab_type": "text"
26
+ },
27
+ "source": [
28
+ "<a href=\"https://colab.research.google.com/github/vinthony/video-retalking/blob/main/quick_demo.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
29
+ ]
30
+ },
31
+ {
32
+ "cell_type": "markdown",
33
+ "source": [
34
+ "## VideoReTalking:Audio-based Lip Synchronization for Talking Head Video Editing In the Wild\n",
35
+ "\n",
36
+ "[Arxiv](https://arxiv.org/abs/2211.14758) | [Project](https://vinthony.github.io/video-retalking/) | [Github](https://github.com/vinthony/video-retalking)\n",
37
+ "\n",
38
+ "Kun Cheng, Xiaodong Cun, Yong Zhang, Menghan Xia, Fei Yin, Mingrui Zhu, Xuan Wang, Jue Wang, Nannan Wang\n",
39
+ "\n",
40
+ "Xidian University, Tencent AI Lab, Tsinghua University\n",
41
+ "\n",
42
+ "*SIGGRAPH Asia 2022 Conferenence Track*\n",
43
+ "\n"
44
+ ],
45
+ "metadata": {
46
+ "id": "NVfkv2BXSpr3"
47
+ }
48
+ },
49
+ {
50
+ "cell_type": "markdown",
51
+ "source": [
52
+ "**Installation** (30s)"
53
+ ],
54
+ "metadata": {
55
+ "id": "u9hdPaH6UL_F"
56
+ }
57
+ },
58
+ {
59
+ "cell_type": "code",
60
+ "execution_count": null,
61
+ "metadata": {
62
+ "id": "PnKT9goiQ3Hk"
63
+ },
64
+ "outputs": [],
65
+ "source": [
66
+ "#@title\n",
67
+ "### make sure that CUDA is available in Edit -> Nootbook settings -> GPU\n",
68
+ "!nvidia-smi\n",
69
+ "\n",
70
+ "!python --version \n",
71
+ "!apt-get update\n",
72
+ "!apt install ffmpeg &> /dev/null \n",
73
+ "\n",
74
+ "print('Git clone project and install requirements...')\n",
75
+ "!git clone https://github.com/vinthony/video-retalking.git &> /dev/null\n",
76
+ "%cd video-retalking\n",
77
+ "# !pip install torch==1.9.0+cu111 torchvision==0.10.0+cu111 -f https://download.pytorch.org/whl/torch_stable.html\n",
78
+ "!pip install -r requirements.txt"
79
+ ]
80
+ },
81
+ {
82
+ "cell_type": "markdown",
83
+ "source": [
84
+ "**Download Pretrained Models**"
85
+ ],
86
+ "metadata": {
87
+ "id": "uwJS0eaM61Cq"
88
+ }
89
+ },
90
+ {
91
+ "cell_type": "code",
92
+ "source": [
93
+ "#@title\n",
94
+ "print('Download pre-trained models...')\n",
95
+ "!mkdir ./checkpoints \n",
96
+ "!wget https://github.com/vinthony/video-retalking/releases/download/v0.0.1/30_net_gen.pth -O ./checkpoints/30_net_gen.pth\n",
97
+ "!wget https://github.com/vinthony/video-retalking/releases/download/v0.0.1/BFM.zip -O ./checkpoints/BFM.zip\n",
98
+ "!wget https://github.com/vinthony/video-retalking/releases/download/v0.0.1/DNet.pt -O ./checkpoints/DNet.pt\n",
99
+ "!wget https://github.com/vinthony/video-retalking/releases/download/v0.0.1/ENet.pth -O ./checkpoints/ENet.pth\n",
100
+ "!wget https://github.com/vinthony/video-retalking/releases/download/v0.0.1/expression.mat -O ./checkpoints/expression.mat\n",
101
+ "!wget https://github.com/vinthony/video-retalking/releases/download/v0.0.1/face3d_pretrain_epoch_20.pth -O ./checkpoints/face3d_pretrain_epoch_20.pth\n",
102
+ "!wget https://github.com/vinthony/video-retalking/releases/download/v0.0.1/GFPGANv1.3.pth -O ./checkpoints/GFPGANv1.3.pth\n",
103
+ "!wget https://github.com/vinthony/video-retalking/releases/download/v0.0.1/GPEN-BFR-512.pth -O ./checkpoints/GPEN-BFR-512.pth\n",
104
+ "!wget https://github.com/vinthony/video-retalking/releases/download/v0.0.1/LNet.pth -O ./checkpoints/LNet.pth\n",
105
+ "!wget https://github.com/vinthony/video-retalking/releases/download/v0.0.1/ParseNet-latest.pth -O ./checkpoints/ParseNet-latest.pth\n",
106
+ "!wget https://github.com/vinthony/video-retalking/releases/download/v0.0.1/RetinaFace-R50.pth -O ./checkpoints/RetinaFace-R50.pth\n",
107
+ "!wget https://github.com/vinthony/video-retalking/releases/download/v0.0.1/shape_predictor_68_face_landmarks.dat -O ./checkpoints/shape_predictor_68_face_landmarks.dat\n",
108
+ "!unzip -d ./checkpoints/BFM ./checkpoints/BFM.zip"
109
+ ],
110
+ "metadata": {
111
+ "id": "x18qYuQY678E"
112
+ },
113
+ "execution_count": null,
114
+ "outputs": []
115
+ },
116
+ {
117
+ "cell_type": "markdown",
118
+ "source": [
119
+ "**Inference**\n",
120
+ "\n",
121
+ "`--face`: Input video.\n",
122
+ "\n",
123
+ "`--audio`: Input audio. Both *.wav* and *.mp4* files are supported.\n",
124
+ "\n",
125
+ "You can choose our provided data from `./examples` folder or upload from your local computer.\n",
126
+ "\n",
127
+ "\n",
128
+ "\n",
129
+ "\n"
130
+ ],
131
+ "metadata": {
132
+ "id": "QJRTF4U8UOjv"
133
+ }
134
+ },
135
+ {
136
+ "cell_type": "code",
137
+ "source": [
138
+ "#@title\n",
139
+ "import glob, os, sys\n",
140
+ "import ipywidgets as widgets\n",
141
+ "from IPython.display import HTML\n",
142
+ "from base64 import b64encode\n",
143
+ "\n",
144
+ "print(\"Choose the Video name to edit: (saved in folder 'examples/face')\")\n",
145
+ "vid_list = glob.glob1('examples/face/', '*.mp4')\n",
146
+ "vid_list.sort()\n",
147
+ "default_vid_name = widgets.Dropdown(options=vid_list, value='1.mp4')\n",
148
+ "display(default_vid_name)\n",
149
+ "\n",
150
+ "print(\"Choose the Audio name to edit: (saved in folder 'examples/audio')\")\n",
151
+ "audio_list = glob.glob1('examples/audio/', '*')\n",
152
+ "audio_list.sort()\n",
153
+ "default_audio_name = widgets.Dropdown(options=audio_list, value='1.wav')\n",
154
+ "display(default_audio_name)\n"
155
+ ],
156
+ "metadata": {
157
+ "id": "U-IY-cBSporP",
158
+ "cellView": "form"
159
+ },
160
+ "execution_count": null,
161
+ "outputs": []
162
+ },
163
+ {
164
+ "cell_type": "markdown",
165
+ "source": [
166
+ "Visualize the input video and audio:"
167
+ ],
168
+ "metadata": {
169
+ "id": "-MtI_R1bLJ-f"
170
+ }
171
+ },
172
+ {
173
+ "cell_type": "code",
174
+ "source": [
175
+ "#@title\n",
176
+ "input_video_name = './examples/face/{}'.format(default_vid_name.value)\n",
177
+ "input_video_mp4 = open('{}'.format(input_video_name),'rb').read()\n",
178
+ "input_video_data_url = \"data:video/x-m4v;base64,\" + b64encode(input_video_mp4).decode()\n",
179
+ "print('Display input video: {}'.format(input_video_name), file=sys.stderr)\n",
180
+ "display(HTML(\"\"\"\n",
181
+ " <video width=400 controls>\n",
182
+ " <source src=\"%s\" type=\"video/mp4\">\n",
183
+ " </video>\n",
184
+ " \"\"\" % input_video_data_url))\n",
185
+ "\n",
186
+ "input_audio_name = './examples/audio/{}'.format(default_audio_name.value)\n",
187
+ "input_audio_mp4 = open('{}'.format(input_audio_name),'rb').read()\n",
188
+ "input_audio_data_url = \"data:audio/wav;base64,\" + b64encode(input_audio_mp4).decode()\n",
189
+ "print('Display input audio: {}'.format(input_audio_name), file=sys.stderr)\n",
190
+ "display(HTML(\"\"\"\n",
191
+ " <audio width=400 controls>\n",
192
+ " <source src=\"%s\" type=\"audio/wav\">\n",
193
+ " </audio>\n",
194
+ " \"\"\" % input_audio_data_url))\n"
195
+ ],
196
+ "metadata": {
197
+ "id": "ljbScdofJyGO",
198
+ "cellView": "form"
199
+ },
200
+ "execution_count": null,
201
+ "outputs": []
202
+ },
203
+ {
204
+ "cell_type": "code",
205
+ "source": [
206
+ "input_video_path = 'examples/face/{}'.format(default_vid_name.value)\n",
207
+ "input_audio_path = 'examples/audio/{}'.format(default_audio_name.value)\n",
208
+ "\n",
209
+ "!python3 inference.py \\\n",
210
+ " --face {input_video_path} \\\n",
211
+ " --audio {input_audio_path} \\\n",
212
+ " --outfile results/output.mp4"
213
+ ],
214
+ "metadata": {
215
+ "id": "D7hUwRCyUYEA"
216
+ },
217
+ "execution_count": null,
218
+ "outputs": []
219
+ },
220
+ {
221
+ "cell_type": "markdown",
222
+ "source": [
223
+ "Visualize the output video:"
224
+ ],
225
+ "metadata": {
226
+ "id": "JB5RbKc-njkB"
227
+ }
228
+ },
229
+ {
230
+ "cell_type": "code",
231
+ "source": [
232
+ "#@title\n",
233
+ "# visualize code from makeittalk\n",
234
+ "from IPython.display import HTML\n",
235
+ "from base64 import b64encode\n",
236
+ "import os, sys, glob, cv2, subprocess, platform\n",
237
+ "\n",
238
+ "def read_video(vid_name):\n",
239
+ " video_stream = cv2.VideoCapture(vid_name)\n",
240
+ " fps = video_stream.get(cv2.CAP_PROP_FPS)\n",
241
+ " full_frames = []\n",
242
+ " while True:\n",
243
+ " still_reading, frame = video_stream.read()\n",
244
+ " if not still_reading:\n",
245
+ " video_stream.release()\n",
246
+ " break\n",
247
+ " full_frames.append(frame)\n",
248
+ " return full_frames, fps\n",
249
+ "\n",
250
+ "input_video_frames, fps = read_video(input_video_path)\n",
251
+ "output_video_frames, _ = read_video('./results/output.mp4')\n",
252
+ "\n",
253
+ "frame_h, frame_w = input_video_frames[0].shape[:-1]\n",
254
+ "out_concat = cv2.VideoWriter('./temp/temp/result_concat.mp4', cv2.VideoWriter_fourcc(*'mp4v'), fps, (frame_w*2, frame_h))\n",
255
+ "for i in range(len(output_video_frames)):\n",
256
+ " frame_input = input_video_frames[i % len(input_video_frames)]\n",
257
+ " frame_output = output_video_frames[i]\n",
258
+ " out_concat.write(cv2.hconcat([frame_input, frame_output]))\n",
259
+ "out_concat.release()\n",
260
+ "\n",
261
+ "command = 'ffmpeg -loglevel error -y -i {} -i {} -strict -2 -q:v 1 {}'.format(input_audio_path, './temp/temp/result_concat.mp4', './results/output_concat_input.mp4')\n",
262
+ "subprocess.call(command, shell=platform.system() != 'Windows')\n",
263
+ "\n",
264
+ "\n",
265
+ "output_video_name = './results/output.mp4'\n",
266
+ "output_video_mp4 = open('{}'.format(output_video_name),'rb').read()\n",
267
+ "output_video_data_url = \"data:video/mp4;base64,\" + b64encode(output_video_mp4).decode()\n",
268
+ "print('Display lip-syncing video: {}'.format(output_video_name), file=sys.stderr)\n",
269
+ "display(HTML(\"\"\"\n",
270
+ " <video height=400 controls>\n",
271
+ " <source src=\"%s\" type=\"video/mp4\">\n",
272
+ " </video>\n",
273
+ " \"\"\" % output_video_data_url))\n",
274
+ "\n",
275
+ "output_concat_video_name = './results/output_concat_input.mp4'\n",
276
+ "output_concat_video_mp4 = open('{}'.format(output_concat_video_name),'rb').read()\n",
277
+ "output_concat_video_data_url = \"data:video/mp4;base64,\" + b64encode(output_concat_video_mp4).decode()\n",
278
+ "print('Display input video and lip-syncing video: {}'.format(output_concat_video_name), file=sys.stderr)\n",
279
+ "display(HTML(\"\"\"\n",
280
+ " <video height=400 controls>\n",
281
+ " <source src=\"%s\" type=\"video/mp4\">\n",
282
+ " </video>\n",
283
+ " \"\"\" % output_concat_video_data_url))\n"
284
+ ],
285
+ "metadata": {
286
+ "id": "ravs9UDucMfy",
287
+ "cellView": "form"
288
+ },
289
+ "execution_count": null,
290
+ "outputs": []
291
+ }
292
+ ]
293
+ }
video-tetalking/requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ basicsr==1.4.2
2
+ kornia==0.5.1
3
+ face-alignment==1.3.4
4
+ ninja==1.10.2.3
5
+ einops==0.4.1
6
+ facexlib==0.2.5
7
+ librosa==0.9.2
8
+ dlib==19.24.0
9
+ gradio>=3.7.0
10
+ numpy==1.23.4
video-tetalking/third_part/GFPGAN/LICENSE ADDED
@@ -0,0 +1,351 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Tencent is pleased to support the open source community by making GFPGAN available.
2
+
3
+ Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
4
+
5
+ GFPGAN is licensed under the Apache License Version 2.0 except for the third-party components listed below.
6
+
7
+
8
+ Terms of the Apache License Version 2.0:
9
+ ---------------------------------------------
10
+ Apache License
11
+
12
+ Version 2.0, January 2004
13
+
14
+ http://www.apache.org/licenses/
15
+
16
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
17
+ 1. Definitions.
18
+
19
+ “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
20
+
21
+ “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
22
+
23
+ “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
24
+
25
+ “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
26
+
27
+ “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
28
+
29
+ “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
30
+
31
+ “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
32
+
33
+ “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
34
+
35
+ “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
36
+
37
+ “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
38
+
39
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
40
+
41
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
42
+
43
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
44
+
45
+ You must give any other recipients of the Work or Derivative Works a copy of this License; and
46
+
47
+ You must cause any modified files to carry prominent notices stating that You changed the files; and
48
+
49
+ You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
50
+
51
+ If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
52
+
53
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
54
+
55
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
56
+
57
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
58
+
59
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
60
+
61
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
62
+
63
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
64
+
65
+ END OF TERMS AND CONDITIONS
66
+
67
+
68
+
69
+ Other dependencies and licenses:
70
+
71
+
72
+ Open Source Software licensed under the Apache 2.0 license and Other Licenses of the Third-Party Components therein:
73
+ ---------------------------------------------
74
+ 1. basicsr
75
+ Copyright 2018-2020 BasicSR Authors
76
+
77
+
78
+ This BasicSR project is released under the Apache 2.0 license.
79
+
80
+ A copy of Apache 2.0 is included in this file.
81
+
82
+ StyleGAN2
83
+ The codes are modified from the repository stylegan2-pytorch. Many thanks to the author - Kim Seonghyeon 😊 for translating from the official TensorFlow codes to PyTorch ones. Here is the license of stylegan2-pytorch.
84
+ The official repository is https://github.com/NVlabs/stylegan2, and here is the NVIDIA license.
85
+ DFDNet
86
+ The codes are largely modified from the repository DFDNet. Their license is Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
87
+
88
+ Terms of the Nvidia License:
89
+ ---------------------------------------------
90
+
91
+ 1. Definitions
92
+
93
+ "Licensor" means any person or entity that distributes its Work.
94
+
95
+ "Software" means the original work of authorship made available under
96
+ this License.
97
+
98
+ "Work" means the Software and any additions to or derivative works of
99
+ the Software that are made available under this License.
100
+
101
+ "Nvidia Processors" means any central processing unit (CPU), graphics
102
+ processing unit (GPU), field-programmable gate array (FPGA),
103
+ application-specific integrated circuit (ASIC) or any combination
104
+ thereof designed, made, sold, or provided by Nvidia or its affiliates.
105
+
106
+ The terms "reproduce," "reproduction," "derivative works," and
107
+ "distribution" have the meaning as provided under U.S. copyright law;
108
+ provided, however, that for the purposes of this License, derivative
109
+ works shall not include works that remain separable from, or merely
110
+ link (or bind by name) to the interfaces of, the Work.
111
+
112
+ Works, including the Software, are "made available" under this License
113
+ by including in or with the Work either (a) a copyright notice
114
+ referencing the applicability of this License to the Work, or (b) a
115
+ copy of this License.
116
+
117
+ 2. License Grants
118
+
119
+ 2.1 Copyright Grant. Subject to the terms and conditions of this
120
+ License, each Licensor grants to you a perpetual, worldwide,
121
+ non-exclusive, royalty-free, copyright license to reproduce,
122
+ prepare derivative works of, publicly display, publicly perform,
123
+ sublicense and distribute its Work and any resulting derivative
124
+ works in any form.
125
+
126
+ 3. Limitations
127
+
128
+ 3.1 Redistribution. You may reproduce or distribute the Work only
129
+ if (a) you do so under this License, (b) you include a complete
130
+ copy of this License with your distribution, and (c) you retain
131
+ without modification any copyright, patent, trademark, or
132
+ attribution notices that are present in the Work.
133
+
134
+ 3.2 Derivative Works. You may specify that additional or different
135
+ terms apply to the use, reproduction, and distribution of your
136
+ derivative works of the Work ("Your Terms") only if (a) Your Terms
137
+ provide that the use limitation in Section 3.3 applies to your
138
+ derivative works, and (b) you identify the specific derivative
139
+ works that are subject to Your Terms. Notwithstanding Your Terms,
140
+ this License (including the redistribution requirements in Section
141
+ 3.1) will continue to apply to the Work itself.
142
+
143
+ 3.3 Use Limitation. The Work and any derivative works thereof only
144
+ may be used or intended for use non-commercially. The Work or
145
+ derivative works thereof may be used or intended for use by Nvidia
146
+ or its affiliates commercially or non-commercially. As used herein,
147
+ "non-commercially" means for research or evaluation purposes only.
148
+
149
+ 3.4 Patent Claims. If you bring or threaten to bring a patent claim
150
+ against any Licensor (including any claim, cross-claim or
151
+ counterclaim in a lawsuit) to enforce any patents that you allege
152
+ are infringed by any Work, then your rights under this License from
153
+ such Licensor (including the grants in Sections 2.1 and 2.2) will
154
+ terminate immediately.
155
+
156
+ 3.5 Trademarks. This License does not grant any rights to use any
157
+ Licensor's or its affiliates' names, logos, or trademarks, except
158
+ as necessary to reproduce the notices described in this License.
159
+
160
+ 3.6 Termination. If you violate any term of this License, then your
161
+ rights under this License (including the grants in Sections 2.1 and
162
+ 2.2) will terminate immediately.
163
+
164
+ 4. Disclaimer of Warranty.
165
+
166
+ THE WORK IS PROVIDED "AS IS" WITHOUT WARRANTIES OR CONDITIONS OF ANY
167
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OR CONDITIONS OF
168
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR
169
+ NON-INFRINGEMENT. YOU BEAR THE RISK OF UNDERTAKING ANY ACTIVITIES UNDER
170
+ THIS LICENSE.
171
+
172
+ 5. Limitation of Liability.
173
+
174
+ EXCEPT AS PROHIBITED BY APPLICABLE LAW, IN NO EVENT AND UNDER NO LEGAL
175
+ THEORY, WHETHER IN TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE
176
+ SHALL ANY LICENSOR BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT,
177
+ INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
178
+ OR RELATED TO THIS LICENSE, THE USE OR INABILITY TO USE THE WORK
179
+ (INCLUDING BUT NOT LIMITED TO LOSS OF GOODWILL, BUSINESS INTERRUPTION,
180
+ LOST PROFITS OR DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY OTHER
181
+ COMMERCIAL DAMAGES OR LOSSES), EVEN IF THE LICENSOR HAS BEEN ADVISED OF
182
+ THE POSSIBILITY OF SUCH DAMAGES.
183
+
184
+ MIT License
185
+
186
+ Copyright (c) 2019 Kim Seonghyeon
187
+
188
+ Permission is hereby granted, free of charge, to any person obtaining a copy
189
+ of this software and associated documentation files (the "Software"), to deal
190
+ in the Software without restriction, including without limitation the rights
191
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
192
+ copies of the Software, and to permit persons to whom the Software is
193
+ furnished to do so, subject to the following conditions:
194
+
195
+ The above copyright notice and this permission notice shall be included in all
196
+ copies or substantial portions of the Software.
197
+
198
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
199
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
200
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
201
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
202
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
203
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
204
+ SOFTWARE.
205
+
206
+
207
+
208
+ Open Source Software licensed under the BSD 3-Clause license:
209
+ ---------------------------------------------
210
+ 1. torchvision
211
+ Copyright (c) Soumith Chintala 2016,
212
+ All rights reserved.
213
+
214
+ 2. torch
215
+ Copyright (c) 2016- Facebook, Inc (Adam Paszke)
216
+ Copyright (c) 2014- Facebook, Inc (Soumith Chintala)
217
+ Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert)
218
+ Copyright (c) 2012-2014 Deepmind Technologies (Koray Kavukcuoglu)
219
+ Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu)
220
+ Copyright (c) 2011-2013 NYU (Clement Farabet)
221
+ Copyright (c) 2006-2010 NEC Laboratories America (Ronan Collobert, Leon Bottou, Iain Melvin, Jason Weston)
222
+ Copyright (c) 2006 Idiap Research Institute (Samy Bengio)
223
+ Copyright (c) 2001-2004 Idiap Research Institute (Ronan Collobert, Samy Bengio, Johnny Mariethoz)
224
+
225
+
226
+ Terms of the BSD 3-Clause License:
227
+ ---------------------------------------------
228
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
229
+
230
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
231
+
232
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
233
+
234
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
235
+
236
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
237
+
238
+
239
+
240
+ Open Source Software licensed under the BSD 3-Clause License and Other Licenses of the Third-Party Components therein:
241
+ ---------------------------------------------
242
+ 1. numpy
243
+ Copyright (c) 2005-2020, NumPy Developers.
244
+ All rights reserved.
245
+
246
+ A copy of BSD 3-Clause License is included in this file.
247
+
248
+ The NumPy repository and source distributions bundle several libraries that are
249
+ compatibly licensed. We list these here.
250
+
251
+ Name: Numpydoc
252
+ Files: doc/sphinxext/numpydoc/*
253
+ License: BSD-2-Clause
254
+ For details, see doc/sphinxext/LICENSE.txt
255
+
256
+ Name: scipy-sphinx-theme
257
+ Files: doc/scipy-sphinx-theme/*
258
+ License: BSD-3-Clause AND PSF-2.0 AND Apache-2.0
259
+ For details, see doc/scipy-sphinx-theme/LICENSE.txt
260
+
261
+ Name: lapack-lite
262
+ Files: numpy/linalg/lapack_lite/*
263
+ License: BSD-3-Clause
264
+ For details, see numpy/linalg/lapack_lite/LICENSE.txt
265
+
266
+ Name: tempita
267
+ Files: tools/npy_tempita/*
268
+ License: MIT
269
+ For details, see tools/npy_tempita/license.txt
270
+
271
+ Name: dragon4
272
+ Files: numpy/core/src/multiarray/dragon4.c
273
+ License: MIT
274
+ For license text, see numpy/core/src/multiarray/dragon4.c
275
+
276
+
277
+
278
+ Open Source Software licensed under the MIT license:
279
+ ---------------------------------------------
280
+ 1. facexlib
281
+ Copyright (c) 2020 Xintao Wang
282
+
283
+ 2. opencv-python
284
+ Copyright (c) Olli-Pekka Heinisuo
285
+ Please note that only files in cv2 package are used.
286
+
287
+
288
+ Terms of the MIT License:
289
+ ---------------------------------------------
290
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
291
+
292
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
293
+
294
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
295
+
296
+
297
+
298
+ Open Source Software licensed under the MIT license and Other Licenses of the Third-Party Components therein:
299
+ ---------------------------------------------
300
+ 1. tqdm
301
+ Copyright (c) 2013 noamraph
302
+
303
+ `tqdm` is a product of collaborative work.
304
+ Unless otherwise stated, all authors (see commit logs) retain copyright
305
+ for their respective work, and release the work under the MIT licence
306
+ (text below).
307
+
308
+ Exceptions or notable authors are listed below
309
+ in reverse chronological order:
310
+
311
+ * files: *
312
+ MPLv2.0 2015-2020 (c) Casper da Costa-Luis
313
+ [casperdcl](https://github.com/casperdcl).
314
+ * files: tqdm/_tqdm.py
315
+ MIT 2016 (c) [PR #96] on behalf of Google Inc.
316
+ * files: tqdm/_tqdm.py setup.py README.rst MANIFEST.in .gitignore
317
+ MIT 2013 (c) Noam Yorav-Raphael, original author.
318
+
319
+ [PR #96]: https://github.com/tqdm/tqdm/pull/96
320
+
321
+
322
+ Mozilla Public Licence (MPL) v. 2.0 - Exhibit A
323
+ -----------------------------------------------
324
+
325
+ This Source Code Form is subject to the terms of the
326
+ Mozilla Public License, v. 2.0.
327
+ If a copy of the MPL was not distributed with this file,
328
+ You can obtain one at https://mozilla.org/MPL/2.0/.
329
+
330
+
331
+ MIT License (MIT)
332
+ -----------------
333
+
334
+ Copyright (c) 2013 noamraph
335
+
336
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
337
+ this software and associated documentation files (the "Software"), to deal in
338
+ the Software without restriction, including without limitation the rights to
339
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
340
+ the Software, and to permit persons to whom the Software is furnished to do so,
341
+ subject to the following conditions:
342
+
343
+ The above copyright notice and this permission notice shall be included in all
344
+ copies or substantial portions of the Software.
345
+
346
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
347
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
348
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
349
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
350
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
351
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
video-tetalking/third_part/GFPGAN/gfpgan/__init__.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ # flake8: noqa
2
+
3
+ from .archs import *
4
+ from .data import *
5
+ from .models import *
6
+ from .utils import *
7
+
8
+ # from .version import *
video-tetalking/third_part/GFPGAN/gfpgan/archs/__init__.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import importlib
2
+ from basicsr.utils import scandir
3
+ from os import path as osp
4
+
5
+ # automatically scan and import arch modules for registry
6
+ # scan all the files that end with '_arch.py' under the archs folder
7
+ arch_folder = osp.dirname(osp.abspath(__file__))
8
+ arch_filenames = [osp.splitext(osp.basename(v))[0] for v in scandir(arch_folder) if v.endswith('_arch.py')]
9
+ # import all the arch modules
10
+ _arch_modules = [importlib.import_module(f'gfpgan.archs.{file_name}') for file_name in arch_filenames]
video-tetalking/third_part/GFPGAN/gfpgan/archs/arcface_arch.py ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch.nn as nn
2
+ from basicsr.utils.registry import ARCH_REGISTRY
3
+
4
+
5
+ def conv3x3(inplanes, outplanes, stride=1):
6
+ """A simple wrapper for 3x3 convolution with padding.
7
+
8
+ Args:
9
+ inplanes (int): Channel number of inputs.
10
+ outplanes (int): Channel number of outputs.
11
+ stride (int): Stride in convolution. Default: 1.
12
+ """
13
+ return nn.Conv2d(inplanes, outplanes, kernel_size=3, stride=stride, padding=1, bias=False)
14
+
15
+
16
+ class BasicBlock(nn.Module):
17
+ """Basic residual block used in the ResNetArcFace architecture.
18
+
19
+ Args:
20
+ inplanes (int): Channel number of inputs.
21
+ planes (int): Channel number of outputs.
22
+ stride (int): Stride in convolution. Default: 1.
23
+ downsample (nn.Module): The downsample module. Default: None.
24
+ """
25
+ expansion = 1 # output channel expansion ratio
26
+
27
+ def __init__(self, inplanes, planes, stride=1, downsample=None):
28
+ super(BasicBlock, self).__init__()
29
+ self.conv1 = conv3x3(inplanes, planes, stride)
30
+ self.bn1 = nn.BatchNorm2d(planes)
31
+ self.relu = nn.ReLU(inplace=True)
32
+ self.conv2 = conv3x3(planes, planes)
33
+ self.bn2 = nn.BatchNorm2d(planes)
34
+ self.downsample = downsample
35
+ self.stride = stride
36
+
37
+ def forward(self, x):
38
+ residual = x
39
+
40
+ out = self.conv1(x)
41
+ out = self.bn1(out)
42
+ out = self.relu(out)
43
+
44
+ out = self.conv2(out)
45
+ out = self.bn2(out)
46
+
47
+ if self.downsample is not None:
48
+ residual = self.downsample(x)
49
+
50
+ out += residual
51
+ out = self.relu(out)
52
+
53
+ return out
54
+
55
+
56
+ class IRBlock(nn.Module):
57
+ """Improved residual block (IR Block) used in the ResNetArcFace architecture.
58
+
59
+ Args:
60
+ inplanes (int): Channel number of inputs.
61
+ planes (int): Channel number of outputs.
62
+ stride (int): Stride in convolution. Default: 1.
63
+ downsample (nn.Module): The downsample module. Default: None.
64
+ use_se (bool): Whether use the SEBlock (squeeze and excitation block). Default: True.
65
+ """
66
+ expansion = 1 # output channel expansion ratio
67
+
68
+ def __init__(self, inplanes, planes, stride=1, downsample=None, use_se=True):
69
+ super(IRBlock, self).__init__()
70
+ self.bn0 = nn.BatchNorm2d(inplanes)
71
+ self.conv1 = conv3x3(inplanes, inplanes)
72
+ self.bn1 = nn.BatchNorm2d(inplanes)
73
+ self.prelu = nn.PReLU()
74
+ self.conv2 = conv3x3(inplanes, planes, stride)
75
+ self.bn2 = nn.BatchNorm2d(planes)
76
+ self.downsample = downsample
77
+ self.stride = stride
78
+ self.use_se = use_se
79
+ if self.use_se:
80
+ self.se = SEBlock(planes)
81
+
82
+ def forward(self, x):
83
+ residual = x
84
+ out = self.bn0(x)
85
+ out = self.conv1(out)
86
+ out = self.bn1(out)
87
+ out = self.prelu(out)
88
+
89
+ out = self.conv2(out)
90
+ out = self.bn2(out)
91
+ if self.use_se:
92
+ out = self.se(out)
93
+
94
+ if self.downsample is not None:
95
+ residual = self.downsample(x)
96
+
97
+ out += residual
98
+ out = self.prelu(out)
99
+
100
+ return out
101
+
102
+
103
+ class Bottleneck(nn.Module):
104
+ """Bottleneck block used in the ResNetArcFace architecture.
105
+
106
+ Args:
107
+ inplanes (int): Channel number of inputs.
108
+ planes (int): Channel number of outputs.
109
+ stride (int): Stride in convolution. Default: 1.
110
+ downsample (nn.Module): The downsample module. Default: None.
111
+ """
112
+ expansion = 4 # output channel expansion ratio
113
+
114
+ def __init__(self, inplanes, planes, stride=1, downsample=None):
115
+ super(Bottleneck, self).__init__()
116
+ self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
117
+ self.bn1 = nn.BatchNorm2d(planes)
118
+ self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
119
+ self.bn2 = nn.BatchNorm2d(planes)
120
+ self.conv3 = nn.Conv2d(planes, planes * self.expansion, kernel_size=1, bias=False)
121
+ self.bn3 = nn.BatchNorm2d(planes * self.expansion)
122
+ self.relu = nn.ReLU(inplace=True)
123
+ self.downsample = downsample
124
+ self.stride = stride
125
+
126
+ def forward(self, x):
127
+ residual = x
128
+
129
+ out = self.conv1(x)
130
+ out = self.bn1(out)
131
+ out = self.relu(out)
132
+
133
+ out = self.conv2(out)
134
+ out = self.bn2(out)
135
+ out = self.relu(out)
136
+
137
+ out = self.conv3(out)
138
+ out = self.bn3(out)
139
+
140
+ if self.downsample is not None:
141
+ residual = self.downsample(x)
142
+
143
+ out += residual
144
+ out = self.relu(out)
145
+
146
+ return out
147
+
148
+
149
+ class SEBlock(nn.Module):
150
+ """The squeeze-and-excitation block (SEBlock) used in the IRBlock.
151
+
152
+ Args:
153
+ channel (int): Channel number of inputs.
154
+ reduction (int): Channel reduction ration. Default: 16.
155
+ """
156
+
157
+ def __init__(self, channel, reduction=16):
158
+ super(SEBlock, self).__init__()
159
+ self.avg_pool = nn.AdaptiveAvgPool2d(1) # pool to 1x1 without spatial information
160
+ self.fc = nn.Sequential(
161
+ nn.Linear(channel, channel // reduction), nn.PReLU(), nn.Linear(channel // reduction, channel),
162
+ nn.Sigmoid())
163
+
164
+ def forward(self, x):
165
+ b, c, _, _ = x.size()
166
+ y = self.avg_pool(x).view(b, c)
167
+ y = self.fc(y).view(b, c, 1, 1)
168
+ return x * y
169
+
170
+
171
+ @ARCH_REGISTRY.register()
172
+ class ResNetArcFace(nn.Module):
173
+ """ArcFace with ResNet architectures.
174
+
175
+ Ref: ArcFace: Additive Angular Margin Loss for Deep Face Recognition.
176
+
177
+ Args:
178
+ block (str): Block used in the ArcFace architecture.
179
+ layers (tuple(int)): Block numbers in each layer.
180
+ use_se (bool): Whether use the SEBlock (squeeze and excitation block). Default: True.
181
+ """
182
+
183
+ def __init__(self, block, layers, use_se=True):
184
+ if block == 'IRBlock':
185
+ block = IRBlock
186
+ self.inplanes = 64
187
+ self.use_se = use_se
188
+ super(ResNetArcFace, self).__init__()
189
+
190
+ self.conv1 = nn.Conv2d(1, 64, kernel_size=3, padding=1, bias=False)
191
+ self.bn1 = nn.BatchNorm2d(64)
192
+ self.prelu = nn.PReLU()
193
+ self.maxpool = nn.MaxPool2d(kernel_size=2, stride=2)
194
+ self.layer1 = self._make_layer(block, 64, layers[0])
195
+ self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
196
+ self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
197
+ self.layer4 = self._make_layer(block, 512, layers[3], stride=2)
198
+ self.bn4 = nn.BatchNorm2d(512)
199
+ self.dropout = nn.Dropout()
200
+ self.fc5 = nn.Linear(512 * 8 * 8, 512)
201
+ self.bn5 = nn.BatchNorm1d(512)
202
+
203
+ # initialization
204
+ for m in self.modules():
205
+ if isinstance(m, nn.Conv2d):
206
+ nn.init.xavier_normal_(m.weight)
207
+ elif isinstance(m, nn.BatchNorm2d) or isinstance(m, nn.BatchNorm1d):
208
+ nn.init.constant_(m.weight, 1)
209
+ nn.init.constant_(m.bias, 0)
210
+ elif isinstance(m, nn.Linear):
211
+ nn.init.xavier_normal_(m.weight)
212
+ nn.init.constant_(m.bias, 0)
213
+
214
+ def _make_layer(self, block, planes, num_blocks, stride=1):
215
+ downsample = None
216
+ if stride != 1 or self.inplanes != planes * block.expansion:
217
+ downsample = nn.Sequential(
218
+ nn.Conv2d(self.inplanes, planes * block.expansion, kernel_size=1, stride=stride, bias=False),
219
+ nn.BatchNorm2d(planes * block.expansion),
220
+ )
221
+ layers = []
222
+ layers.append(block(self.inplanes, planes, stride, downsample, use_se=self.use_se))
223
+ self.inplanes = planes
224
+ for _ in range(1, num_blocks):
225
+ layers.append(block(self.inplanes, planes, use_se=self.use_se))
226
+
227
+ return nn.Sequential(*layers)
228
+
229
+ def forward(self, x):
230
+ x = self.conv1(x)
231
+ x = self.bn1(x)
232
+ x = self.prelu(x)
233
+ x = self.maxpool(x)
234
+
235
+ x = self.layer1(x)
236
+ x = self.layer2(x)
237
+ x = self.layer3(x)
238
+ x = self.layer4(x)
239
+ x = self.bn4(x)
240
+ x = self.dropout(x)
241
+ x = x.view(x.size(0), -1)
242
+ x = self.fc5(x)
243
+ x = self.bn5(x)
244
+
245
+ return x
video-tetalking/third_part/GFPGAN/gfpgan/archs/gfpgan_bilinear_arch.py ADDED
@@ -0,0 +1,312 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import random
3
+ import torch
4
+ from basicsr.utils.registry import ARCH_REGISTRY
5
+ from torch import nn
6
+
7
+ from .gfpganv1_arch import ResUpBlock
8
+ from .stylegan2_bilinear_arch import (ConvLayer, EqualConv2d, EqualLinear, ResBlock, ScaledLeakyReLU,
9
+ StyleGAN2GeneratorBilinear)
10
+
11
+
12
+ class StyleGAN2GeneratorBilinearSFT(StyleGAN2GeneratorBilinear):
13
+ """StyleGAN2 Generator with SFT modulation (Spatial Feature Transform).
14
+
15
+ It is the bilinear version. It does not use the complicated UpFirDnSmooth function that is not friendly for
16
+ deployment. It can be easily converted to the clean version: StyleGAN2GeneratorCSFT.
17
+
18
+ Args:
19
+ out_size (int): The spatial size of outputs.
20
+ num_style_feat (int): Channel number of style features. Default: 512.
21
+ num_mlp (int): Layer number of MLP style layers. Default: 8.
22
+ channel_multiplier (int): Channel multiplier for large networks of StyleGAN2. Default: 2.
23
+ lr_mlp (float): Learning rate multiplier for mlp layers. Default: 0.01.
24
+ narrow (float): The narrow ratio for channels. Default: 1.
25
+ sft_half (bool): Whether to apply SFT on half of the input channels. Default: False.
26
+ """
27
+
28
+ def __init__(self,
29
+ out_size,
30
+ num_style_feat=512,
31
+ num_mlp=8,
32
+ channel_multiplier=2,
33
+ lr_mlp=0.01,
34
+ narrow=1,
35
+ sft_half=False):
36
+ super(StyleGAN2GeneratorBilinearSFT, self).__init__(
37
+ out_size,
38
+ num_style_feat=num_style_feat,
39
+ num_mlp=num_mlp,
40
+ channel_multiplier=channel_multiplier,
41
+ lr_mlp=lr_mlp,
42
+ narrow=narrow)
43
+ self.sft_half = sft_half
44
+
45
+ def forward(self,
46
+ styles,
47
+ conditions,
48
+ input_is_latent=False,
49
+ noise=None,
50
+ randomize_noise=True,
51
+ truncation=1,
52
+ truncation_latent=None,
53
+ inject_index=None,
54
+ return_latents=False):
55
+ """Forward function for StyleGAN2GeneratorBilinearSFT.
56
+
57
+ Args:
58
+ styles (list[Tensor]): Sample codes of styles.
59
+ conditions (list[Tensor]): SFT conditions to generators.
60
+ input_is_latent (bool): Whether input is latent style. Default: False.
61
+ noise (Tensor | None): Input noise or None. Default: None.
62
+ randomize_noise (bool): Randomize noise, used when 'noise' is False. Default: True.
63
+ truncation (float): The truncation ratio. Default: 1.
64
+ truncation_latent (Tensor | None): The truncation latent tensor. Default: None.
65
+ inject_index (int | None): The injection index for mixing noise. Default: None.
66
+ return_latents (bool): Whether to return style latents. Default: False.
67
+ """
68
+ # style codes -> latents with Style MLP layer
69
+ if not input_is_latent:
70
+ styles = [self.style_mlp(s) for s in styles]
71
+ # noises
72
+ if noise is None:
73
+ if randomize_noise:
74
+ noise = [None] * self.num_layers # for each style conv layer
75
+ else: # use the stored noise
76
+ noise = [getattr(self.noises, f'noise{i}') for i in range(self.num_layers)]
77
+ # style truncation
78
+ if truncation < 1:
79
+ style_truncation = []
80
+ for style in styles:
81
+ style_truncation.append(truncation_latent + truncation * (style - truncation_latent))
82
+ styles = style_truncation
83
+ # get style latents with injection
84
+ if len(styles) == 1:
85
+ inject_index = self.num_latent
86
+
87
+ if styles[0].ndim < 3:
88
+ # repeat latent code for all the layers
89
+ latent = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
90
+ else: # used for encoder with different latent code for each layer
91
+ latent = styles[0]
92
+ elif len(styles) == 2: # mixing noises
93
+ if inject_index is None:
94
+ inject_index = random.randint(1, self.num_latent - 1)
95
+ latent1 = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
96
+ latent2 = styles[1].unsqueeze(1).repeat(1, self.num_latent - inject_index, 1)
97
+ latent = torch.cat([latent1, latent2], 1)
98
+
99
+ # main generation
100
+ out = self.constant_input(latent.shape[0])
101
+ out = self.style_conv1(out, latent[:, 0], noise=noise[0])
102
+ skip = self.to_rgb1(out, latent[:, 1])
103
+
104
+ i = 1
105
+ for conv1, conv2, noise1, noise2, to_rgb in zip(self.style_convs[::2], self.style_convs[1::2], noise[1::2],
106
+ noise[2::2], self.to_rgbs):
107
+ out = conv1(out, latent[:, i], noise=noise1)
108
+
109
+ # the conditions may have fewer levels
110
+ if i < len(conditions):
111
+ # SFT part to combine the conditions
112
+ if self.sft_half: # only apply SFT to half of the channels
113
+ out_same, out_sft = torch.split(out, int(out.size(1) // 2), dim=1)
114
+ out_sft = out_sft * conditions[i - 1] + conditions[i]
115
+ out = torch.cat([out_same, out_sft], dim=1)
116
+ else: # apply SFT to all the channels
117
+ out = out * conditions[i - 1] + conditions[i]
118
+
119
+ out = conv2(out, latent[:, i + 1], noise=noise2)
120
+ skip = to_rgb(out, latent[:, i + 2], skip) # feature back to the rgb space
121
+ i += 2
122
+
123
+ image = skip
124
+
125
+ if return_latents:
126
+ return image, latent
127
+ else:
128
+ return image, None
129
+
130
+
131
+ @ARCH_REGISTRY.register()
132
+ class GFPGANBilinear(nn.Module):
133
+ """The GFPGAN architecture: Unet + StyleGAN2 decoder with SFT.
134
+
135
+ It is the bilinear version and it does not use the complicated UpFirDnSmooth function that is not friendly for
136
+ deployment. It can be easily converted to the clean version: GFPGANv1Clean.
137
+
138
+
139
+ Ref: GFP-GAN: Towards Real-World Blind Face Restoration with Generative Facial Prior.
140
+
141
+ Args:
142
+ out_size (int): The spatial size of outputs.
143
+ num_style_feat (int): Channel number of style features. Default: 512.
144
+ channel_multiplier (int): Channel multiplier for large networks of StyleGAN2. Default: 2.
145
+ decoder_load_path (str): The path to the pre-trained decoder model (usually, the StyleGAN2). Default: None.
146
+ fix_decoder (bool): Whether to fix the decoder. Default: True.
147
+
148
+ num_mlp (int): Layer number of MLP style layers. Default: 8.
149
+ lr_mlp (float): Learning rate multiplier for mlp layers. Default: 0.01.
150
+ input_is_latent (bool): Whether input is latent style. Default: False.
151
+ different_w (bool): Whether to use different latent w for different layers. Default: False.
152
+ narrow (float): The narrow ratio for channels. Default: 1.
153
+ sft_half (bool): Whether to apply SFT on half of the input channels. Default: False.
154
+ """
155
+
156
+ def __init__(
157
+ self,
158
+ out_size,
159
+ num_style_feat=512,
160
+ channel_multiplier=1,
161
+ decoder_load_path=None,
162
+ fix_decoder=True,
163
+ # for stylegan decoder
164
+ num_mlp=8,
165
+ lr_mlp=0.01,
166
+ input_is_latent=False,
167
+ different_w=False,
168
+ narrow=1,
169
+ sft_half=False):
170
+
171
+ super(GFPGANBilinear, self).__init__()
172
+ self.input_is_latent = input_is_latent
173
+ self.different_w = different_w
174
+ self.num_style_feat = num_style_feat
175
+
176
+ unet_narrow = narrow * 0.5 # by default, use a half of input channels
177
+ channels = {
178
+ '4': int(512 * unet_narrow),
179
+ '8': int(512 * unet_narrow),
180
+ '16': int(512 * unet_narrow),
181
+ '32': int(512 * unet_narrow),
182
+ '64': int(256 * channel_multiplier * unet_narrow),
183
+ '128': int(128 * channel_multiplier * unet_narrow),
184
+ '256': int(64 * channel_multiplier * unet_narrow),
185
+ '512': int(32 * channel_multiplier * unet_narrow),
186
+ '1024': int(16 * channel_multiplier * unet_narrow)
187
+ }
188
+
189
+ self.log_size = int(math.log(out_size, 2))
190
+ first_out_size = 2**(int(math.log(out_size, 2)))
191
+
192
+ self.conv_body_first = ConvLayer(3, channels[f'{first_out_size}'], 1, bias=True, activate=True)
193
+
194
+ # downsample
195
+ in_channels = channels[f'{first_out_size}']
196
+ self.conv_body_down = nn.ModuleList()
197
+ for i in range(self.log_size, 2, -1):
198
+ out_channels = channels[f'{2**(i - 1)}']
199
+ self.conv_body_down.append(ResBlock(in_channels, out_channels))
200
+ in_channels = out_channels
201
+
202
+ self.final_conv = ConvLayer(in_channels, channels['4'], 3, bias=True, activate=True)
203
+
204
+ # upsample
205
+ in_channels = channels['4']
206
+ self.conv_body_up = nn.ModuleList()
207
+ for i in range(3, self.log_size + 1):
208
+ out_channels = channels[f'{2**i}']
209
+ self.conv_body_up.append(ResUpBlock(in_channels, out_channels))
210
+ in_channels = out_channels
211
+
212
+ # to RGB
213
+ self.toRGB = nn.ModuleList()
214
+ for i in range(3, self.log_size + 1):
215
+ self.toRGB.append(EqualConv2d(channels[f'{2**i}'], 3, 1, stride=1, padding=0, bias=True, bias_init_val=0))
216
+
217
+ if different_w:
218
+ linear_out_channel = (int(math.log(out_size, 2)) * 2 - 2) * num_style_feat
219
+ else:
220
+ linear_out_channel = num_style_feat
221
+
222
+ self.final_linear = EqualLinear(
223
+ channels['4'] * 4 * 4, linear_out_channel, bias=True, bias_init_val=0, lr_mul=1, activation=None)
224
+
225
+ # the decoder: stylegan2 generator with SFT modulations
226
+ self.stylegan_decoder = StyleGAN2GeneratorBilinearSFT(
227
+ out_size=out_size,
228
+ num_style_feat=num_style_feat,
229
+ num_mlp=num_mlp,
230
+ channel_multiplier=channel_multiplier,
231
+ lr_mlp=lr_mlp,
232
+ narrow=narrow,
233
+ sft_half=sft_half)
234
+
235
+ # load pre-trained stylegan2 model if necessary
236
+ if decoder_load_path:
237
+ self.stylegan_decoder.load_state_dict(
238
+ torch.load(decoder_load_path, map_location=lambda storage, loc: storage)['params_ema'])
239
+ # fix decoder without updating params
240
+ if fix_decoder:
241
+ for _, param in self.stylegan_decoder.named_parameters():
242
+ param.requires_grad = False
243
+
244
+ # for SFT modulations (scale and shift)
245
+ self.condition_scale = nn.ModuleList()
246
+ self.condition_shift = nn.ModuleList()
247
+ for i in range(3, self.log_size + 1):
248
+ out_channels = channels[f'{2**i}']
249
+ if sft_half:
250
+ sft_out_channels = out_channels
251
+ else:
252
+ sft_out_channels = out_channels * 2
253
+ self.condition_scale.append(
254
+ nn.Sequential(
255
+ EqualConv2d(out_channels, out_channels, 3, stride=1, padding=1, bias=True, bias_init_val=0),
256
+ ScaledLeakyReLU(0.2),
257
+ EqualConv2d(out_channels, sft_out_channels, 3, stride=1, padding=1, bias=True, bias_init_val=1)))
258
+ self.condition_shift.append(
259
+ nn.Sequential(
260
+ EqualConv2d(out_channels, out_channels, 3, stride=1, padding=1, bias=True, bias_init_val=0),
261
+ ScaledLeakyReLU(0.2),
262
+ EqualConv2d(out_channels, sft_out_channels, 3, stride=1, padding=1, bias=True, bias_init_val=0)))
263
+
264
+ def forward(self, x, return_latents=False, return_rgb=True, randomize_noise=True):
265
+ """Forward function for GFPGANBilinear.
266
+
267
+ Args:
268
+ x (Tensor): Input images.
269
+ return_latents (bool): Whether to return style latents. Default: False.
270
+ return_rgb (bool): Whether return intermediate rgb images. Default: True.
271
+ randomize_noise (bool): Randomize noise, used when 'noise' is False. Default: True.
272
+ """
273
+ conditions = []
274
+ unet_skips = []
275
+ out_rgbs = []
276
+
277
+ # encoder
278
+ feat = self.conv_body_first(x)
279
+ for i in range(self.log_size - 2):
280
+ feat = self.conv_body_down[i](feat)
281
+ unet_skips.insert(0, feat)
282
+
283
+ feat = self.final_conv(feat)
284
+
285
+ # style code
286
+ style_code = self.final_linear(feat.view(feat.size(0), -1))
287
+ if self.different_w:
288
+ style_code = style_code.view(style_code.size(0), -1, self.num_style_feat)
289
+
290
+ # decode
291
+ for i in range(self.log_size - 2):
292
+ # add unet skip
293
+ feat = feat + unet_skips[i]
294
+ # ResUpLayer
295
+ feat = self.conv_body_up[i](feat)
296
+ # generate scale and shift for SFT layers
297
+ scale = self.condition_scale[i](feat)
298
+ conditions.append(scale.clone())
299
+ shift = self.condition_shift[i](feat)
300
+ conditions.append(shift.clone())
301
+ # generate rgb images
302
+ if return_rgb:
303
+ out_rgbs.append(self.toRGB[i](feat))
304
+
305
+ # decoder
306
+ image, _ = self.stylegan_decoder([style_code],
307
+ conditions,
308
+ return_latents=return_latents,
309
+ input_is_latent=self.input_is_latent,
310
+ randomize_noise=randomize_noise)
311
+
312
+ return image, out_rgbs
video-tetalking/third_part/GFPGAN/gfpgan/archs/gfpganv1_arch.py ADDED
@@ -0,0 +1,439 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import random
3
+ import torch
4
+ from basicsr.archs.stylegan2_arch import (ConvLayer, EqualConv2d, EqualLinear, ResBlock, ScaledLeakyReLU,
5
+ StyleGAN2Generator)
6
+ from basicsr.ops.fused_act import FusedLeakyReLU
7
+ from basicsr.utils.registry import ARCH_REGISTRY
8
+ from torch import nn
9
+ from torch.nn import functional as F
10
+
11
+
12
+ class StyleGAN2GeneratorSFT(StyleGAN2Generator):
13
+ """StyleGAN2 Generator with SFT modulation (Spatial Feature Transform).
14
+
15
+ Args:
16
+ out_size (int): The spatial size of outputs.
17
+ num_style_feat (int): Channel number of style features. Default: 512.
18
+ num_mlp (int): Layer number of MLP style layers. Default: 8.
19
+ channel_multiplier (int): Channel multiplier for large networks of StyleGAN2. Default: 2.
20
+ resample_kernel (list[int]): A list indicating the 1D resample kernel magnitude. A cross production will be
21
+ applied to extent 1D resample kernel to 2D resample kernel. Default: (1, 3, 3, 1).
22
+ lr_mlp (float): Learning rate multiplier for mlp layers. Default: 0.01.
23
+ narrow (float): The narrow ratio for channels. Default: 1.
24
+ sft_half (bool): Whether to apply SFT on half of the input channels. Default: False.
25
+ """
26
+
27
+ def __init__(self,
28
+ out_size,
29
+ num_style_feat=512,
30
+ num_mlp=8,
31
+ channel_multiplier=2,
32
+ resample_kernel=(1, 3, 3, 1),
33
+ lr_mlp=0.01,
34
+ narrow=1,
35
+ sft_half=False):
36
+ super(StyleGAN2GeneratorSFT, self).__init__(
37
+ out_size,
38
+ num_style_feat=num_style_feat,
39
+ num_mlp=num_mlp,
40
+ channel_multiplier=channel_multiplier,
41
+ resample_kernel=resample_kernel,
42
+ lr_mlp=lr_mlp,
43
+ narrow=narrow)
44
+ self.sft_half = sft_half
45
+
46
+ def forward(self,
47
+ styles,
48
+ conditions,
49
+ input_is_latent=False,
50
+ noise=None,
51
+ randomize_noise=True,
52
+ truncation=1,
53
+ truncation_latent=None,
54
+ inject_index=None,
55
+ return_latents=False):
56
+ """Forward function for StyleGAN2GeneratorSFT.
57
+
58
+ Args:
59
+ styles (list[Tensor]): Sample codes of styles.
60
+ conditions (list[Tensor]): SFT conditions to generators.
61
+ input_is_latent (bool): Whether input is latent style. Default: False.
62
+ noise (Tensor | None): Input noise or None. Default: None.
63
+ randomize_noise (bool): Randomize noise, used when 'noise' is False. Default: True.
64
+ truncation (float): The truncation ratio. Default: 1.
65
+ truncation_latent (Tensor | None): The truncation latent tensor. Default: None.
66
+ inject_index (int | None): The injection index for mixing noise. Default: None.
67
+ return_latents (bool): Whether to return style latents. Default: False.
68
+ """
69
+ # style codes -> latents with Style MLP layer
70
+ if not input_is_latent:
71
+ styles = [self.style_mlp(s) for s in styles]
72
+ # noises
73
+ if noise is None:
74
+ if randomize_noise:
75
+ noise = [None] * self.num_layers # for each style conv layer
76
+ else: # use the stored noise
77
+ noise = [getattr(self.noises, f'noise{i}') for i in range(self.num_layers)]
78
+ # style truncation
79
+ if truncation < 1:
80
+ style_truncation = []
81
+ for style in styles:
82
+ style_truncation.append(truncation_latent + truncation * (style - truncation_latent))
83
+ styles = style_truncation
84
+ # get style latents with injection
85
+ if len(styles) == 1:
86
+ inject_index = self.num_latent
87
+
88
+ if styles[0].ndim < 3:
89
+ # repeat latent code for all the layers
90
+ latent = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
91
+ else: # used for encoder with different latent code for each layer
92
+ latent = styles[0]
93
+ elif len(styles) == 2: # mixing noises
94
+ if inject_index is None:
95
+ inject_index = random.randint(1, self.num_latent - 1)
96
+ latent1 = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
97
+ latent2 = styles[1].unsqueeze(1).repeat(1, self.num_latent - inject_index, 1)
98
+ latent = torch.cat([latent1, latent2], 1)
99
+
100
+ # main generation
101
+ out = self.constant_input(latent.shape[0])
102
+ out = self.style_conv1(out, latent[:, 0], noise=noise[0])
103
+ skip = self.to_rgb1(out, latent[:, 1])
104
+
105
+ i = 1
106
+ for conv1, conv2, noise1, noise2, to_rgb in zip(self.style_convs[::2], self.style_convs[1::2], noise[1::2],
107
+ noise[2::2], self.to_rgbs):
108
+ out = conv1(out, latent[:, i], noise=noise1)
109
+
110
+ # the conditions may have fewer levels
111
+ if i < len(conditions):
112
+ # SFT part to combine the conditions
113
+ if self.sft_half: # only apply SFT to half of the channels
114
+ out_same, out_sft = torch.split(out, int(out.size(1) // 2), dim=1)
115
+ out_sft = out_sft * conditions[i - 1] + conditions[i]
116
+ out = torch.cat([out_same, out_sft], dim=1)
117
+ else: # apply SFT to all the channels
118
+ out = out * conditions[i - 1] + conditions[i]
119
+
120
+ out = conv2(out, latent[:, i + 1], noise=noise2)
121
+ skip = to_rgb(out, latent[:, i + 2], skip) # feature back to the rgb space
122
+ i += 2
123
+
124
+ image = skip
125
+
126
+ if return_latents:
127
+ return image, latent
128
+ else:
129
+ return image, None
130
+
131
+
132
+ class ConvUpLayer(nn.Module):
133
+ """Convolutional upsampling layer. It uses bilinear upsampler + Conv.
134
+
135
+ Args:
136
+ in_channels (int): Channel number of the input.
137
+ out_channels (int): Channel number of the output.
138
+ kernel_size (int): Size of the convolving kernel.
139
+ stride (int): Stride of the convolution. Default: 1
140
+ padding (int): Zero-padding added to both sides of the input. Default: 0.
141
+ bias (bool): If ``True``, adds a learnable bias to the output. Default: ``True``.
142
+ bias_init_val (float): Bias initialized value. Default: 0.
143
+ activate (bool): Whether use activateion. Default: True.
144
+ """
145
+
146
+ def __init__(self,
147
+ in_channels,
148
+ out_channels,
149
+ kernel_size,
150
+ stride=1,
151
+ padding=0,
152
+ bias=True,
153
+ bias_init_val=0,
154
+ activate=True):
155
+ super(ConvUpLayer, self).__init__()
156
+ self.in_channels = in_channels
157
+ self.out_channels = out_channels
158
+ self.kernel_size = kernel_size
159
+ self.stride = stride
160
+ self.padding = padding
161
+ # self.scale is used to scale the convolution weights, which is related to the common initializations.
162
+ self.scale = 1 / math.sqrt(in_channels * kernel_size**2)
163
+
164
+ self.weight = nn.Parameter(torch.randn(out_channels, in_channels, kernel_size, kernel_size))
165
+
166
+ if bias and not activate:
167
+ self.bias = nn.Parameter(torch.zeros(out_channels).fill_(bias_init_val))
168
+ else:
169
+ self.register_parameter('bias', None)
170
+
171
+ # activation
172
+ if activate:
173
+ if bias:
174
+ self.activation = FusedLeakyReLU(out_channels)
175
+ else:
176
+ self.activation = ScaledLeakyReLU(0.2)
177
+ else:
178
+ self.activation = None
179
+
180
+ def forward(self, x):
181
+ # bilinear upsample
182
+ out = F.interpolate(x, scale_factor=2, mode='bilinear', align_corners=False)
183
+ # conv
184
+ out = F.conv2d(
185
+ out,
186
+ self.weight * self.scale,
187
+ bias=self.bias,
188
+ stride=self.stride,
189
+ padding=self.padding,
190
+ )
191
+ # activation
192
+ if self.activation is not None:
193
+ out = self.activation(out)
194
+ return out
195
+
196
+
197
+ class ResUpBlock(nn.Module):
198
+ """Residual block with upsampling.
199
+
200
+ Args:
201
+ in_channels (int): Channel number of the input.
202
+ out_channels (int): Channel number of the output.
203
+ """
204
+
205
+ def __init__(self, in_channels, out_channels):
206
+ super(ResUpBlock, self).__init__()
207
+
208
+ self.conv1 = ConvLayer(in_channels, in_channels, 3, bias=True, activate=True)
209
+ self.conv2 = ConvUpLayer(in_channels, out_channels, 3, stride=1, padding=1, bias=True, activate=True)
210
+ self.skip = ConvUpLayer(in_channels, out_channels, 1, bias=False, activate=False)
211
+
212
+ def forward(self, x):
213
+ out = self.conv1(x)
214
+ out = self.conv2(out)
215
+ skip = self.skip(x)
216
+ out = (out + skip) / math.sqrt(2)
217
+ return out
218
+
219
+
220
+ @ARCH_REGISTRY.register()
221
+ class GFPGANv1(nn.Module):
222
+ """The GFPGAN architecture: Unet + StyleGAN2 decoder with SFT.
223
+
224
+ Ref: GFP-GAN: Towards Real-World Blind Face Restoration with Generative Facial Prior.
225
+
226
+ Args:
227
+ out_size (int): The spatial size of outputs.
228
+ num_style_feat (int): Channel number of style features. Default: 512.
229
+ channel_multiplier (int): Channel multiplier for large networks of StyleGAN2. Default: 2.
230
+ resample_kernel (list[int]): A list indicating the 1D resample kernel magnitude. A cross production will be
231
+ applied to extent 1D resample kernel to 2D resample kernel. Default: (1, 3, 3, 1).
232
+ decoder_load_path (str): The path to the pre-trained decoder model (usually, the StyleGAN2). Default: None.
233
+ fix_decoder (bool): Whether to fix the decoder. Default: True.
234
+
235
+ num_mlp (int): Layer number of MLP style layers. Default: 8.
236
+ lr_mlp (float): Learning rate multiplier for mlp layers. Default: 0.01.
237
+ input_is_latent (bool): Whether input is latent style. Default: False.
238
+ different_w (bool): Whether to use different latent w for different layers. Default: False.
239
+ narrow (float): The narrow ratio for channels. Default: 1.
240
+ sft_half (bool): Whether to apply SFT on half of the input channels. Default: False.
241
+ """
242
+
243
+ def __init__(
244
+ self,
245
+ out_size,
246
+ num_style_feat=512,
247
+ channel_multiplier=1,
248
+ resample_kernel=(1, 3, 3, 1),
249
+ decoder_load_path=None,
250
+ fix_decoder=True,
251
+ # for stylegan decoder
252
+ num_mlp=8,
253
+ lr_mlp=0.01,
254
+ input_is_latent=False,
255
+ different_w=False,
256
+ narrow=1,
257
+ sft_half=False):
258
+
259
+ super(GFPGANv1, self).__init__()
260
+ self.input_is_latent = input_is_latent
261
+ self.different_w = different_w
262
+ self.num_style_feat = num_style_feat
263
+
264
+ unet_narrow = narrow * 0.5 # by default, use a half of input channels
265
+ channels = {
266
+ '4': int(512 * unet_narrow),
267
+ '8': int(512 * unet_narrow),
268
+ '16': int(512 * unet_narrow),
269
+ '32': int(512 * unet_narrow),
270
+ '64': int(256 * channel_multiplier * unet_narrow),
271
+ '128': int(128 * channel_multiplier * unet_narrow),
272
+ '256': int(64 * channel_multiplier * unet_narrow),
273
+ '512': int(32 * channel_multiplier * unet_narrow),
274
+ '1024': int(16 * channel_multiplier * unet_narrow)
275
+ }
276
+
277
+ self.log_size = int(math.log(out_size, 2))
278
+ first_out_size = 2**(int(math.log(out_size, 2)))
279
+
280
+ self.conv_body_first = ConvLayer(3, channels[f'{first_out_size}'], 1, bias=True, activate=True)
281
+
282
+ # downsample
283
+ in_channels = channels[f'{first_out_size}']
284
+ self.conv_body_down = nn.ModuleList()
285
+ for i in range(self.log_size, 2, -1):
286
+ out_channels = channels[f'{2**(i - 1)}']
287
+ self.conv_body_down.append(ResBlock(in_channels, out_channels, resample_kernel))
288
+ in_channels = out_channels
289
+
290
+ self.final_conv = ConvLayer(in_channels, channels['4'], 3, bias=True, activate=True)
291
+
292
+ # upsample
293
+ in_channels = channels['4']
294
+ self.conv_body_up = nn.ModuleList()
295
+ for i in range(3, self.log_size + 1):
296
+ out_channels = channels[f'{2**i}']
297
+ self.conv_body_up.append(ResUpBlock(in_channels, out_channels))
298
+ in_channels = out_channels
299
+
300
+ # to RGB
301
+ self.toRGB = nn.ModuleList()
302
+ for i in range(3, self.log_size + 1):
303
+ self.toRGB.append(EqualConv2d(channels[f'{2**i}'], 3, 1, stride=1, padding=0, bias=True, bias_init_val=0))
304
+
305
+ if different_w:
306
+ linear_out_channel = (int(math.log(out_size, 2)) * 2 - 2) * num_style_feat
307
+ else:
308
+ linear_out_channel = num_style_feat
309
+
310
+ self.final_linear = EqualLinear(
311
+ channels['4'] * 4 * 4, linear_out_channel, bias=True, bias_init_val=0, lr_mul=1, activation=None)
312
+
313
+ # the decoder: stylegan2 generator with SFT modulations
314
+ self.stylegan_decoder = StyleGAN2GeneratorSFT(
315
+ out_size=out_size,
316
+ num_style_feat=num_style_feat,
317
+ num_mlp=num_mlp,
318
+ channel_multiplier=channel_multiplier,
319
+ resample_kernel=resample_kernel,
320
+ lr_mlp=lr_mlp,
321
+ narrow=narrow,
322
+ sft_half=sft_half)
323
+
324
+ # load pre-trained stylegan2 model if necessary
325
+ if decoder_load_path:
326
+ self.stylegan_decoder.load_state_dict(
327
+ torch.load(decoder_load_path, map_location=lambda storage, loc: storage)['params_ema'])
328
+ # fix decoder without updating params
329
+ if fix_decoder:
330
+ for _, param in self.stylegan_decoder.named_parameters():
331
+ param.requires_grad = False
332
+
333
+ # for SFT modulations (scale and shift)
334
+ self.condition_scale = nn.ModuleList()
335
+ self.condition_shift = nn.ModuleList()
336
+ for i in range(3, self.log_size + 1):
337
+ out_channels = channels[f'{2**i}']
338
+ if sft_half:
339
+ sft_out_channels = out_channels
340
+ else:
341
+ sft_out_channels = out_channels * 2
342
+ self.condition_scale.append(
343
+ nn.Sequential(
344
+ EqualConv2d(out_channels, out_channels, 3, stride=1, padding=1, bias=True, bias_init_val=0),
345
+ ScaledLeakyReLU(0.2),
346
+ EqualConv2d(out_channels, sft_out_channels, 3, stride=1, padding=1, bias=True, bias_init_val=1)))
347
+ self.condition_shift.append(
348
+ nn.Sequential(
349
+ EqualConv2d(out_channels, out_channels, 3, stride=1, padding=1, bias=True, bias_init_val=0),
350
+ ScaledLeakyReLU(0.2),
351
+ EqualConv2d(out_channels, sft_out_channels, 3, stride=1, padding=1, bias=True, bias_init_val=0)))
352
+
353
+ def forward(self, x, return_latents=False, return_rgb=True, randomize_noise=True):
354
+ """Forward function for GFPGANv1.
355
+
356
+ Args:
357
+ x (Tensor): Input images.
358
+ return_latents (bool): Whether to return style latents. Default: False.
359
+ return_rgb (bool): Whether return intermediate rgb images. Default: True.
360
+ randomize_noise (bool): Randomize noise, used when 'noise' is False. Default: True.
361
+ """
362
+ conditions = []
363
+ unet_skips = []
364
+ out_rgbs = []
365
+
366
+ # encoder
367
+ feat = self.conv_body_first(x)
368
+ for i in range(self.log_size - 2):
369
+ feat = self.conv_body_down[i](feat)
370
+ unet_skips.insert(0, feat)
371
+
372
+ feat = self.final_conv(feat)
373
+
374
+ # style code
375
+ style_code = self.final_linear(feat.view(feat.size(0), -1))
376
+ if self.different_w:
377
+ style_code = style_code.view(style_code.size(0), -1, self.num_style_feat)
378
+
379
+ # decode
380
+ for i in range(self.log_size - 2):
381
+ # add unet skip
382
+ feat = feat + unet_skips[i]
383
+ # ResUpLayer
384
+ feat = self.conv_body_up[i](feat)
385
+ # generate scale and shift for SFT layers
386
+ scale = self.condition_scale[i](feat)
387
+ conditions.append(scale.clone())
388
+ shift = self.condition_shift[i](feat)
389
+ conditions.append(shift.clone())
390
+ # generate rgb images
391
+ if return_rgb:
392
+ out_rgbs.append(self.toRGB[i](feat))
393
+
394
+ # decoder
395
+ image, _ = self.stylegan_decoder([style_code],
396
+ conditions,
397
+ return_latents=return_latents,
398
+ input_is_latent=self.input_is_latent,
399
+ randomize_noise=randomize_noise)
400
+
401
+ return image, out_rgbs
402
+
403
+
404
+ @ARCH_REGISTRY.register()
405
+ class FacialComponentDiscriminator(nn.Module):
406
+ """Facial component (eyes, mouth, noise) discriminator used in GFPGAN.
407
+ """
408
+
409
+ def __init__(self):
410
+ super(FacialComponentDiscriminator, self).__init__()
411
+ # It now uses a VGG-style architectrue with fixed model size
412
+ self.conv1 = ConvLayer(3, 64, 3, downsample=False, resample_kernel=(1, 3, 3, 1), bias=True, activate=True)
413
+ self.conv2 = ConvLayer(64, 128, 3, downsample=True, resample_kernel=(1, 3, 3, 1), bias=True, activate=True)
414
+ self.conv3 = ConvLayer(128, 128, 3, downsample=False, resample_kernel=(1, 3, 3, 1), bias=True, activate=True)
415
+ self.conv4 = ConvLayer(128, 256, 3, downsample=True, resample_kernel=(1, 3, 3, 1), bias=True, activate=True)
416
+ self.conv5 = ConvLayer(256, 256, 3, downsample=False, resample_kernel=(1, 3, 3, 1), bias=True, activate=True)
417
+ self.final_conv = ConvLayer(256, 1, 3, bias=True, activate=False)
418
+
419
+ def forward(self, x, return_feats=False):
420
+ """Forward function for FacialComponentDiscriminator.
421
+
422
+ Args:
423
+ x (Tensor): Input images.
424
+ return_feats (bool): Whether to return intermediate features. Default: False.
425
+ """
426
+ feat = self.conv1(x)
427
+ feat = self.conv3(self.conv2(feat))
428
+ rlt_feats = []
429
+ if return_feats:
430
+ rlt_feats.append(feat.clone())
431
+ feat = self.conv5(self.conv4(feat))
432
+ if return_feats:
433
+ rlt_feats.append(feat.clone())
434
+ out = self.final_conv(feat)
435
+
436
+ if return_feats:
437
+ return out, rlt_feats
438
+ else:
439
+ return out, None
video-tetalking/third_part/GFPGAN/gfpgan/archs/gfpganv1_clean_arch.py ADDED
@@ -0,0 +1,324 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import random
3
+ import torch
4
+ from basicsr.utils.registry import ARCH_REGISTRY
5
+ from torch import nn
6
+ from torch.nn import functional as F
7
+
8
+ from .stylegan2_clean_arch import StyleGAN2GeneratorClean
9
+
10
+
11
+ class StyleGAN2GeneratorCSFT(StyleGAN2GeneratorClean):
12
+ """StyleGAN2 Generator with SFT modulation (Spatial Feature Transform).
13
+
14
+ It is the clean version without custom compiled CUDA extensions used in StyleGAN2.
15
+
16
+ Args:
17
+ out_size (int): The spatial size of outputs.
18
+ num_style_feat (int): Channel number of style features. Default: 512.
19
+ num_mlp (int): Layer number of MLP style layers. Default: 8.
20
+ channel_multiplier (int): Channel multiplier for large networks of StyleGAN2. Default: 2.
21
+ narrow (float): The narrow ratio for channels. Default: 1.
22
+ sft_half (bool): Whether to apply SFT on half of the input channels. Default: False.
23
+ """
24
+
25
+ def __init__(self, out_size, num_style_feat=512, num_mlp=8, channel_multiplier=2, narrow=1, sft_half=False):
26
+ super(StyleGAN2GeneratorCSFT, self).__init__(
27
+ out_size,
28
+ num_style_feat=num_style_feat,
29
+ num_mlp=num_mlp,
30
+ channel_multiplier=channel_multiplier,
31
+ narrow=narrow)
32
+ self.sft_half = sft_half
33
+
34
+ def forward(self,
35
+ styles,
36
+ conditions,
37
+ input_is_latent=False,
38
+ noise=None,
39
+ randomize_noise=True,
40
+ truncation=1,
41
+ truncation_latent=None,
42
+ inject_index=None,
43
+ return_latents=False):
44
+ """Forward function for StyleGAN2GeneratorCSFT.
45
+
46
+ Args:
47
+ styles (list[Tensor]): Sample codes of styles.
48
+ conditions (list[Tensor]): SFT conditions to generators.
49
+ input_is_latent (bool): Whether input is latent style. Default: False.
50
+ noise (Tensor | None): Input noise or None. Default: None.
51
+ randomize_noise (bool): Randomize noise, used when 'noise' is False. Default: True.
52
+ truncation (float): The truncation ratio. Default: 1.
53
+ truncation_latent (Tensor | None): The truncation latent tensor. Default: None.
54
+ inject_index (int | None): The injection index for mixing noise. Default: None.
55
+ return_latents (bool): Whether to return style latents. Default: False.
56
+ """
57
+ # style codes -> latents with Style MLP layer
58
+ if not input_is_latent:
59
+ styles = [self.style_mlp(s) for s in styles]
60
+ # noises
61
+ if noise is None:
62
+ if randomize_noise:
63
+ noise = [None] * self.num_layers # for each style conv layer
64
+ else: # use the stored noise
65
+ noise = [getattr(self.noises, f'noise{i}') for i in range(self.num_layers)]
66
+ # style truncation
67
+ if truncation < 1:
68
+ style_truncation = []
69
+ for style in styles:
70
+ style_truncation.append(truncation_latent + truncation * (style - truncation_latent))
71
+ styles = style_truncation
72
+ # get style latents with injection
73
+ if len(styles) == 1:
74
+ inject_index = self.num_latent
75
+
76
+ if styles[0].ndim < 3:
77
+ # repeat latent code for all the layers
78
+ latent = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
79
+ else: # used for encoder with different latent code for each layer
80
+ latent = styles[0]
81
+ elif len(styles) == 2: # mixing noises
82
+ if inject_index is None:
83
+ inject_index = random.randint(1, self.num_latent - 1)
84
+ latent1 = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
85
+ latent2 = styles[1].unsqueeze(1).repeat(1, self.num_latent - inject_index, 1)
86
+ latent = torch.cat([latent1, latent2], 1)
87
+
88
+ # main generation
89
+ out = self.constant_input(latent.shape[0])
90
+ out = self.style_conv1(out, latent[:, 0], noise=noise[0])
91
+ skip = self.to_rgb1(out, latent[:, 1])
92
+
93
+ i = 1
94
+ for conv1, conv2, noise1, noise2, to_rgb in zip(self.style_convs[::2], self.style_convs[1::2], noise[1::2],
95
+ noise[2::2], self.to_rgbs):
96
+ out = conv1(out, latent[:, i], noise=noise1)
97
+
98
+ # the conditions may have fewer levels
99
+ if i < len(conditions):
100
+ # SFT part to combine the conditions
101
+ if self.sft_half: # only apply SFT to half of the channels
102
+ out_same, out_sft = torch.split(out, int(out.size(1) // 2), dim=1)
103
+ out_sft = out_sft * conditions[i - 1] + conditions[i]
104
+ out = torch.cat([out_same, out_sft], dim=1)
105
+ else: # apply SFT to all the channels
106
+ out = out * conditions[i - 1] + conditions[i]
107
+
108
+ out = conv2(out, latent[:, i + 1], noise=noise2)
109
+ skip = to_rgb(out, latent[:, i + 2], skip) # feature back to the rgb space
110
+ i += 2
111
+
112
+ image = skip
113
+
114
+ if return_latents:
115
+ return image, latent
116
+ else:
117
+ return image, None
118
+
119
+
120
+ class ResBlock(nn.Module):
121
+ """Residual block with bilinear upsampling/downsampling.
122
+
123
+ Args:
124
+ in_channels (int): Channel number of the input.
125
+ out_channels (int): Channel number of the output.
126
+ mode (str): Upsampling/downsampling mode. Options: down | up. Default: down.
127
+ """
128
+
129
+ def __init__(self, in_channels, out_channels, mode='down'):
130
+ super(ResBlock, self).__init__()
131
+
132
+ self.conv1 = nn.Conv2d(in_channels, in_channels, 3, 1, 1)
133
+ self.conv2 = nn.Conv2d(in_channels, out_channels, 3, 1, 1)
134
+ self.skip = nn.Conv2d(in_channels, out_channels, 1, bias=False)
135
+ if mode == 'down':
136
+ self.scale_factor = 0.5
137
+ elif mode == 'up':
138
+ self.scale_factor = 2
139
+
140
+ def forward(self, x):
141
+ out = F.leaky_relu_(self.conv1(x), negative_slope=0.2)
142
+ # upsample/downsample
143
+ out = F.interpolate(out, scale_factor=self.scale_factor, mode='bilinear', align_corners=False)
144
+ out = F.leaky_relu_(self.conv2(out), negative_slope=0.2)
145
+ # skip
146
+ x = F.interpolate(x, scale_factor=self.scale_factor, mode='bilinear', align_corners=False)
147
+ skip = self.skip(x)
148
+ out = out + skip
149
+ return out
150
+
151
+
152
+ @ARCH_REGISTRY.register()
153
+ class GFPGANv1Clean(nn.Module):
154
+ """The GFPGAN architecture: Unet + StyleGAN2 decoder with SFT.
155
+
156
+ It is the clean version without custom compiled CUDA extensions used in StyleGAN2.
157
+
158
+ Ref: GFP-GAN: Towards Real-World Blind Face Restoration with Generative Facial Prior.
159
+
160
+ Args:
161
+ out_size (int): The spatial size of outputs.
162
+ num_style_feat (int): Channel number of style features. Default: 512.
163
+ channel_multiplier (int): Channel multiplier for large networks of StyleGAN2. Default: 2.
164
+ decoder_load_path (str): The path to the pre-trained decoder model (usually, the StyleGAN2). Default: None.
165
+ fix_decoder (bool): Whether to fix the decoder. Default: True.
166
+
167
+ num_mlp (int): Layer number of MLP style layers. Default: 8.
168
+ input_is_latent (bool): Whether input is latent style. Default: False.
169
+ different_w (bool): Whether to use different latent w for different layers. Default: False.
170
+ narrow (float): The narrow ratio for channels. Default: 1.
171
+ sft_half (bool): Whether to apply SFT on half of the input channels. Default: False.
172
+ """
173
+
174
+ def __init__(
175
+ self,
176
+ out_size,
177
+ num_style_feat=512,
178
+ channel_multiplier=1,
179
+ decoder_load_path=None,
180
+ fix_decoder=True,
181
+ # for stylegan decoder
182
+ num_mlp=8,
183
+ input_is_latent=False,
184
+ different_w=False,
185
+ narrow=1,
186
+ sft_half=False):
187
+
188
+ super(GFPGANv1Clean, self).__init__()
189
+ self.input_is_latent = input_is_latent
190
+ self.different_w = different_w
191
+ self.num_style_feat = num_style_feat
192
+
193
+ unet_narrow = narrow * 0.5 # by default, use a half of input channels
194
+ channels = {
195
+ '4': int(512 * unet_narrow),
196
+ '8': int(512 * unet_narrow),
197
+ '16': int(512 * unet_narrow),
198
+ '32': int(512 * unet_narrow),
199
+ '64': int(256 * channel_multiplier * unet_narrow),
200
+ '128': int(128 * channel_multiplier * unet_narrow),
201
+ '256': int(64 * channel_multiplier * unet_narrow),
202
+ '512': int(32 * channel_multiplier * unet_narrow),
203
+ '1024': int(16 * channel_multiplier * unet_narrow)
204
+ }
205
+
206
+ self.log_size = int(math.log(out_size, 2))
207
+ first_out_size = 2**(int(math.log(out_size, 2)))
208
+
209
+ self.conv_body_first = nn.Conv2d(3, channels[f'{first_out_size}'], 1)
210
+
211
+ # downsample
212
+ in_channels = channels[f'{first_out_size}']
213
+ self.conv_body_down = nn.ModuleList()
214
+ for i in range(self.log_size, 2, -1):
215
+ out_channels = channels[f'{2**(i - 1)}']
216
+ self.conv_body_down.append(ResBlock(in_channels, out_channels, mode='down'))
217
+ in_channels = out_channels
218
+
219
+ self.final_conv = nn.Conv2d(in_channels, channels['4'], 3, 1, 1)
220
+
221
+ # upsample
222
+ in_channels = channels['4']
223
+ self.conv_body_up = nn.ModuleList()
224
+ for i in range(3, self.log_size + 1):
225
+ out_channels = channels[f'{2**i}']
226
+ self.conv_body_up.append(ResBlock(in_channels, out_channels, mode='up'))
227
+ in_channels = out_channels
228
+
229
+ # to RGB
230
+ self.toRGB = nn.ModuleList()
231
+ for i in range(3, self.log_size + 1):
232
+ self.toRGB.append(nn.Conv2d(channels[f'{2**i}'], 3, 1))
233
+
234
+ if different_w:
235
+ linear_out_channel = (int(math.log(out_size, 2)) * 2 - 2) * num_style_feat
236
+ else:
237
+ linear_out_channel = num_style_feat
238
+
239
+ self.final_linear = nn.Linear(channels['4'] * 4 * 4, linear_out_channel)
240
+
241
+ # the decoder: stylegan2 generator with SFT modulations
242
+ self.stylegan_decoder = StyleGAN2GeneratorCSFT(
243
+ out_size=out_size,
244
+ num_style_feat=num_style_feat,
245
+ num_mlp=num_mlp,
246
+ channel_multiplier=channel_multiplier,
247
+ narrow=narrow,
248
+ sft_half=sft_half)
249
+
250
+ # load pre-trained stylegan2 model if necessary
251
+ if decoder_load_path:
252
+ self.stylegan_decoder.load_state_dict(
253
+ torch.load(decoder_load_path, map_location=lambda storage, loc: storage)['params_ema'])
254
+ # fix decoder without updating params
255
+ if fix_decoder:
256
+ for _, param in self.stylegan_decoder.named_parameters():
257
+ param.requires_grad = False
258
+
259
+ # for SFT modulations (scale and shift)
260
+ self.condition_scale = nn.ModuleList()
261
+ self.condition_shift = nn.ModuleList()
262
+ for i in range(3, self.log_size + 1):
263
+ out_channels = channels[f'{2**i}']
264
+ if sft_half:
265
+ sft_out_channels = out_channels
266
+ else:
267
+ sft_out_channels = out_channels * 2
268
+ self.condition_scale.append(
269
+ nn.Sequential(
270
+ nn.Conv2d(out_channels, out_channels, 3, 1, 1), nn.LeakyReLU(0.2, True),
271
+ nn.Conv2d(out_channels, sft_out_channels, 3, 1, 1)))
272
+ self.condition_shift.append(
273
+ nn.Sequential(
274
+ nn.Conv2d(out_channels, out_channels, 3, 1, 1), nn.LeakyReLU(0.2, True),
275
+ nn.Conv2d(out_channels, sft_out_channels, 3, 1, 1)))
276
+
277
+ def forward(self, x, return_latents=False, return_rgb=True, randomize_noise=True):
278
+ """Forward function for GFPGANv1Clean.
279
+
280
+ Args:
281
+ x (Tensor): Input images.
282
+ return_latents (bool): Whether to return style latents. Default: False.
283
+ return_rgb (bool): Whether return intermediate rgb images. Default: True.
284
+ randomize_noise (bool): Randomize noise, used when 'noise' is False. Default: True.
285
+ """
286
+ conditions = []
287
+ unet_skips = []
288
+ out_rgbs = []
289
+
290
+ # encoder
291
+ feat = F.leaky_relu_(self.conv_body_first(x), negative_slope=0.2)
292
+ for i in range(self.log_size - 2):
293
+ feat = self.conv_body_down[i](feat)
294
+ unet_skips.insert(0, feat)
295
+ feat = F.leaky_relu_(self.final_conv(feat), negative_slope=0.2)
296
+
297
+ # style code
298
+ style_code = self.final_linear(feat.view(feat.size(0), -1))
299
+ if self.different_w:
300
+ style_code = style_code.view(style_code.size(0), -1, self.num_style_feat)
301
+
302
+ # decode
303
+ for i in range(self.log_size - 2):
304
+ # add unet skip
305
+ feat = feat + unet_skips[i]
306
+ # ResUpLayer
307
+ feat = self.conv_body_up[i](feat)
308
+ # generate scale and shift for SFT layers
309
+ scale = self.condition_scale[i](feat)
310
+ conditions.append(scale.clone())
311
+ shift = self.condition_shift[i](feat)
312
+ conditions.append(shift.clone())
313
+ # generate rgb images
314
+ if return_rgb:
315
+ out_rgbs.append(self.toRGB[i](feat))
316
+
317
+ # decoder
318
+ image, _ = self.stylegan_decoder([style_code],
319
+ conditions,
320
+ return_latents=return_latents,
321
+ input_is_latent=self.input_is_latent,
322
+ randomize_noise=randomize_noise)
323
+
324
+ return image, out_rgbs
video-tetalking/third_part/GFPGAN/gfpgan/archs/stylegan2_bilinear_arch.py ADDED
@@ -0,0 +1,613 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import random
3
+ import torch
4
+ from basicsr.ops.fused_act import FusedLeakyReLU, fused_leaky_relu
5
+ from basicsr.utils.registry import ARCH_REGISTRY
6
+ from torch import nn
7
+ from torch.nn import functional as F
8
+
9
+
10
+ class NormStyleCode(nn.Module):
11
+
12
+ def forward(self, x):
13
+ """Normalize the style codes.
14
+
15
+ Args:
16
+ x (Tensor): Style codes with shape (b, c).
17
+
18
+ Returns:
19
+ Tensor: Normalized tensor.
20
+ """
21
+ return x * torch.rsqrt(torch.mean(x**2, dim=1, keepdim=True) + 1e-8)
22
+
23
+
24
+ class EqualLinear(nn.Module):
25
+ """Equalized Linear as StyleGAN2.
26
+
27
+ Args:
28
+ in_channels (int): Size of each sample.
29
+ out_channels (int): Size of each output sample.
30
+ bias (bool): If set to ``False``, the layer will not learn an additive
31
+ bias. Default: ``True``.
32
+ bias_init_val (float): Bias initialized value. Default: 0.
33
+ lr_mul (float): Learning rate multiplier. Default: 1.
34
+ activation (None | str): The activation after ``linear`` operation.
35
+ Supported: 'fused_lrelu', None. Default: None.
36
+ """
37
+
38
+ def __init__(self, in_channels, out_channels, bias=True, bias_init_val=0, lr_mul=1, activation=None):
39
+ super(EqualLinear, self).__init__()
40
+ self.in_channels = in_channels
41
+ self.out_channels = out_channels
42
+ self.lr_mul = lr_mul
43
+ self.activation = activation
44
+ if self.activation not in ['fused_lrelu', None]:
45
+ raise ValueError(f'Wrong activation value in EqualLinear: {activation}'
46
+ "Supported ones are: ['fused_lrelu', None].")
47
+ self.scale = (1 / math.sqrt(in_channels)) * lr_mul
48
+
49
+ self.weight = nn.Parameter(torch.randn(out_channels, in_channels).div_(lr_mul))
50
+ if bias:
51
+ self.bias = nn.Parameter(torch.zeros(out_channels).fill_(bias_init_val))
52
+ else:
53
+ self.register_parameter('bias', None)
54
+
55
+ def forward(self, x):
56
+ if self.bias is None:
57
+ bias = None
58
+ else:
59
+ bias = self.bias * self.lr_mul
60
+ if self.activation == 'fused_lrelu':
61
+ out = F.linear(x, self.weight * self.scale)
62
+ out = fused_leaky_relu(out, bias)
63
+ else:
64
+ out = F.linear(x, self.weight * self.scale, bias=bias)
65
+ return out
66
+
67
+ def __repr__(self):
68
+ return (f'{self.__class__.__name__}(in_channels={self.in_channels}, '
69
+ f'out_channels={self.out_channels}, bias={self.bias is not None})')
70
+
71
+
72
+ class ModulatedConv2d(nn.Module):
73
+ """Modulated Conv2d used in StyleGAN2.
74
+
75
+ There is no bias in ModulatedConv2d.
76
+
77
+ Args:
78
+ in_channels (int): Channel number of the input.
79
+ out_channels (int): Channel number of the output.
80
+ kernel_size (int): Size of the convolving kernel.
81
+ num_style_feat (int): Channel number of style features.
82
+ demodulate (bool): Whether to demodulate in the conv layer.
83
+ Default: True.
84
+ sample_mode (str | None): Indicating 'upsample', 'downsample' or None.
85
+ Default: None.
86
+ eps (float): A value added to the denominator for numerical stability.
87
+ Default: 1e-8.
88
+ """
89
+
90
+ def __init__(self,
91
+ in_channels,
92
+ out_channels,
93
+ kernel_size,
94
+ num_style_feat,
95
+ demodulate=True,
96
+ sample_mode=None,
97
+ eps=1e-8,
98
+ interpolation_mode='bilinear'):
99
+ super(ModulatedConv2d, self).__init__()
100
+ self.in_channels = in_channels
101
+ self.out_channels = out_channels
102
+ self.kernel_size = kernel_size
103
+ self.demodulate = demodulate
104
+ self.sample_mode = sample_mode
105
+ self.eps = eps
106
+ self.interpolation_mode = interpolation_mode
107
+ if self.interpolation_mode == 'nearest':
108
+ self.align_corners = None
109
+ else:
110
+ self.align_corners = False
111
+
112
+ self.scale = 1 / math.sqrt(in_channels * kernel_size**2)
113
+ # modulation inside each modulated conv
114
+ self.modulation = EqualLinear(
115
+ num_style_feat, in_channels, bias=True, bias_init_val=1, lr_mul=1, activation=None)
116
+
117
+ self.weight = nn.Parameter(torch.randn(1, out_channels, in_channels, kernel_size, kernel_size))
118
+ self.padding = kernel_size // 2
119
+
120
+ def forward(self, x, style):
121
+ """Forward function.
122
+
123
+ Args:
124
+ x (Tensor): Tensor with shape (b, c, h, w).
125
+ style (Tensor): Tensor with shape (b, num_style_feat).
126
+
127
+ Returns:
128
+ Tensor: Modulated tensor after convolution.
129
+ """
130
+ b, c, h, w = x.shape # c = c_in
131
+ # weight modulation
132
+ style = self.modulation(style).view(b, 1, c, 1, 1)
133
+ # self.weight: (1, c_out, c_in, k, k); style: (b, 1, c, 1, 1)
134
+ weight = self.scale * self.weight * style # (b, c_out, c_in, k, k)
135
+
136
+ if self.demodulate:
137
+ demod = torch.rsqrt(weight.pow(2).sum([2, 3, 4]) + self.eps)
138
+ weight = weight * demod.view(b, self.out_channels, 1, 1, 1)
139
+
140
+ weight = weight.view(b * self.out_channels, c, self.kernel_size, self.kernel_size)
141
+
142
+ if self.sample_mode == 'upsample':
143
+ x = F.interpolate(x, scale_factor=2, mode=self.interpolation_mode, align_corners=self.align_corners)
144
+ elif self.sample_mode == 'downsample':
145
+ x = F.interpolate(x, scale_factor=0.5, mode=self.interpolation_mode, align_corners=self.align_corners)
146
+
147
+ b, c, h, w = x.shape
148
+ x = x.view(1, b * c, h, w)
149
+ # weight: (b*c_out, c_in, k, k), groups=b
150
+ out = F.conv2d(x, weight, padding=self.padding, groups=b)
151
+ out = out.view(b, self.out_channels, *out.shape[2:4])
152
+
153
+ return out
154
+
155
+ def __repr__(self):
156
+ return (f'{self.__class__.__name__}(in_channels={self.in_channels}, '
157
+ f'out_channels={self.out_channels}, '
158
+ f'kernel_size={self.kernel_size}, '
159
+ f'demodulate={self.demodulate}, sample_mode={self.sample_mode})')
160
+
161
+
162
+ class StyleConv(nn.Module):
163
+ """Style conv.
164
+
165
+ Args:
166
+ in_channels (int): Channel number of the input.
167
+ out_channels (int): Channel number of the output.
168
+ kernel_size (int): Size of the convolving kernel.
169
+ num_style_feat (int): Channel number of style features.
170
+ demodulate (bool): Whether demodulate in the conv layer. Default: True.
171
+ sample_mode (str | None): Indicating 'upsample', 'downsample' or None.
172
+ Default: None.
173
+ """
174
+
175
+ def __init__(self,
176
+ in_channels,
177
+ out_channels,
178
+ kernel_size,
179
+ num_style_feat,
180
+ demodulate=True,
181
+ sample_mode=None,
182
+ interpolation_mode='bilinear'):
183
+ super(StyleConv, self).__init__()
184
+ self.modulated_conv = ModulatedConv2d(
185
+ in_channels,
186
+ out_channels,
187
+ kernel_size,
188
+ num_style_feat,
189
+ demodulate=demodulate,
190
+ sample_mode=sample_mode,
191
+ interpolation_mode=interpolation_mode)
192
+ self.weight = nn.Parameter(torch.zeros(1)) # for noise injection
193
+ self.activate = FusedLeakyReLU(out_channels)
194
+
195
+ def forward(self, x, style, noise=None):
196
+ # modulate
197
+ out = self.modulated_conv(x, style)
198
+ # noise injection
199
+ if noise is None:
200
+ b, _, h, w = out.shape
201
+ noise = out.new_empty(b, 1, h, w).normal_()
202
+ out = out + self.weight * noise
203
+ # activation (with bias)
204
+ out = self.activate(out)
205
+ return out
206
+
207
+
208
+ class ToRGB(nn.Module):
209
+ """To RGB from features.
210
+
211
+ Args:
212
+ in_channels (int): Channel number of input.
213
+ num_style_feat (int): Channel number of style features.
214
+ upsample (bool): Whether to upsample. Default: True.
215
+ """
216
+
217
+ def __init__(self, in_channels, num_style_feat, upsample=True, interpolation_mode='bilinear'):
218
+ super(ToRGB, self).__init__()
219
+ self.upsample = upsample
220
+ self.interpolation_mode = interpolation_mode
221
+ if self.interpolation_mode == 'nearest':
222
+ self.align_corners = None
223
+ else:
224
+ self.align_corners = False
225
+ self.modulated_conv = ModulatedConv2d(
226
+ in_channels,
227
+ 3,
228
+ kernel_size=1,
229
+ num_style_feat=num_style_feat,
230
+ demodulate=False,
231
+ sample_mode=None,
232
+ interpolation_mode=interpolation_mode)
233
+ self.bias = nn.Parameter(torch.zeros(1, 3, 1, 1))
234
+
235
+ def forward(self, x, style, skip=None):
236
+ """Forward function.
237
+
238
+ Args:
239
+ x (Tensor): Feature tensor with shape (b, c, h, w).
240
+ style (Tensor): Tensor with shape (b, num_style_feat).
241
+ skip (Tensor): Base/skip tensor. Default: None.
242
+
243
+ Returns:
244
+ Tensor: RGB images.
245
+ """
246
+ out = self.modulated_conv(x, style)
247
+ out = out + self.bias
248
+ if skip is not None:
249
+ if self.upsample:
250
+ skip = F.interpolate(
251
+ skip, scale_factor=2, mode=self.interpolation_mode, align_corners=self.align_corners)
252
+ out = out + skip
253
+ return out
254
+
255
+
256
+ class ConstantInput(nn.Module):
257
+ """Constant input.
258
+
259
+ Args:
260
+ num_channel (int): Channel number of constant input.
261
+ size (int): Spatial size of constant input.
262
+ """
263
+
264
+ def __init__(self, num_channel, size):
265
+ super(ConstantInput, self).__init__()
266
+ self.weight = nn.Parameter(torch.randn(1, num_channel, size, size))
267
+
268
+ def forward(self, batch):
269
+ out = self.weight.repeat(batch, 1, 1, 1)
270
+ return out
271
+
272
+
273
+ @ARCH_REGISTRY.register()
274
+ class StyleGAN2GeneratorBilinear(nn.Module):
275
+ """StyleGAN2 Generator.
276
+
277
+ Args:
278
+ out_size (int): The spatial size of outputs.
279
+ num_style_feat (int): Channel number of style features. Default: 512.
280
+ num_mlp (int): Layer number of MLP style layers. Default: 8.
281
+ channel_multiplier (int): Channel multiplier for large networks of
282
+ StyleGAN2. Default: 2.
283
+ lr_mlp (float): Learning rate multiplier for mlp layers. Default: 0.01.
284
+ narrow (float): Narrow ratio for channels. Default: 1.0.
285
+ """
286
+
287
+ def __init__(self,
288
+ out_size,
289
+ num_style_feat=512,
290
+ num_mlp=8,
291
+ channel_multiplier=2,
292
+ lr_mlp=0.01,
293
+ narrow=1,
294
+ interpolation_mode='bilinear'):
295
+ super(StyleGAN2GeneratorBilinear, self).__init__()
296
+ # Style MLP layers
297
+ self.num_style_feat = num_style_feat
298
+ style_mlp_layers = [NormStyleCode()]
299
+ for i in range(num_mlp):
300
+ style_mlp_layers.append(
301
+ EqualLinear(
302
+ num_style_feat, num_style_feat, bias=True, bias_init_val=0, lr_mul=lr_mlp,
303
+ activation='fused_lrelu'))
304
+ self.style_mlp = nn.Sequential(*style_mlp_layers)
305
+
306
+ channels = {
307
+ '4': int(512 * narrow),
308
+ '8': int(512 * narrow),
309
+ '16': int(512 * narrow),
310
+ '32': int(512 * narrow),
311
+ '64': int(256 * channel_multiplier * narrow),
312
+ '128': int(128 * channel_multiplier * narrow),
313
+ '256': int(64 * channel_multiplier * narrow),
314
+ '512': int(32 * channel_multiplier * narrow),
315
+ '1024': int(16 * channel_multiplier * narrow)
316
+ }
317
+ self.channels = channels
318
+
319
+ self.constant_input = ConstantInput(channels['4'], size=4)
320
+ self.style_conv1 = StyleConv(
321
+ channels['4'],
322
+ channels['4'],
323
+ kernel_size=3,
324
+ num_style_feat=num_style_feat,
325
+ demodulate=True,
326
+ sample_mode=None,
327
+ interpolation_mode=interpolation_mode)
328
+ self.to_rgb1 = ToRGB(channels['4'], num_style_feat, upsample=False, interpolation_mode=interpolation_mode)
329
+
330
+ self.log_size = int(math.log(out_size, 2))
331
+ self.num_layers = (self.log_size - 2) * 2 + 1
332
+ self.num_latent = self.log_size * 2 - 2
333
+
334
+ self.style_convs = nn.ModuleList()
335
+ self.to_rgbs = nn.ModuleList()
336
+ self.noises = nn.Module()
337
+
338
+ in_channels = channels['4']
339
+ # noise
340
+ for layer_idx in range(self.num_layers):
341
+ resolution = 2**((layer_idx + 5) // 2)
342
+ shape = [1, 1, resolution, resolution]
343
+ self.noises.register_buffer(f'noise{layer_idx}', torch.randn(*shape))
344
+ # style convs and to_rgbs
345
+ for i in range(3, self.log_size + 1):
346
+ out_channels = channels[f'{2**i}']
347
+ self.style_convs.append(
348
+ StyleConv(
349
+ in_channels,
350
+ out_channels,
351
+ kernel_size=3,
352
+ num_style_feat=num_style_feat,
353
+ demodulate=True,
354
+ sample_mode='upsample',
355
+ interpolation_mode=interpolation_mode))
356
+ self.style_convs.append(
357
+ StyleConv(
358
+ out_channels,
359
+ out_channels,
360
+ kernel_size=3,
361
+ num_style_feat=num_style_feat,
362
+ demodulate=True,
363
+ sample_mode=None,
364
+ interpolation_mode=interpolation_mode))
365
+ self.to_rgbs.append(
366
+ ToRGB(out_channels, num_style_feat, upsample=True, interpolation_mode=interpolation_mode))
367
+ in_channels = out_channels
368
+
369
+ def make_noise(self):
370
+ """Make noise for noise injection."""
371
+ device = self.constant_input.weight.device
372
+ noises = [torch.randn(1, 1, 4, 4, device=device)]
373
+
374
+ for i in range(3, self.log_size + 1):
375
+ for _ in range(2):
376
+ noises.append(torch.randn(1, 1, 2**i, 2**i, device=device))
377
+
378
+ return noises
379
+
380
+ def get_latent(self, x):
381
+ return self.style_mlp(x)
382
+
383
+ def mean_latent(self, num_latent):
384
+ latent_in = torch.randn(num_latent, self.num_style_feat, device=self.constant_input.weight.device)
385
+ latent = self.style_mlp(latent_in).mean(0, keepdim=True)
386
+ return latent
387
+
388
+ def forward(self,
389
+ styles,
390
+ input_is_latent=False,
391
+ noise=None,
392
+ randomize_noise=True,
393
+ truncation=1,
394
+ truncation_latent=None,
395
+ inject_index=None,
396
+ return_latents=False):
397
+ """Forward function for StyleGAN2Generator.
398
+
399
+ Args:
400
+ styles (list[Tensor]): Sample codes of styles.
401
+ input_is_latent (bool): Whether input is latent style.
402
+ Default: False.
403
+ noise (Tensor | None): Input noise or None. Default: None.
404
+ randomize_noise (bool): Randomize noise, used when 'noise' is
405
+ False. Default: True.
406
+ truncation (float): TODO. Default: 1.
407
+ truncation_latent (Tensor | None): TODO. Default: None.
408
+ inject_index (int | None): The injection index for mixing noise.
409
+ Default: None.
410
+ return_latents (bool): Whether to return style latents.
411
+ Default: False.
412
+ """
413
+ # style codes -> latents with Style MLP layer
414
+ if not input_is_latent:
415
+ styles = [self.style_mlp(s) for s in styles]
416
+ # noises
417
+ if noise is None:
418
+ if randomize_noise:
419
+ noise = [None] * self.num_layers # for each style conv layer
420
+ else: # use the stored noise
421
+ noise = [getattr(self.noises, f'noise{i}') for i in range(self.num_layers)]
422
+ # style truncation
423
+ if truncation < 1:
424
+ style_truncation = []
425
+ for style in styles:
426
+ style_truncation.append(truncation_latent + truncation * (style - truncation_latent))
427
+ styles = style_truncation
428
+ # get style latent with injection
429
+ if len(styles) == 1:
430
+ inject_index = self.num_latent
431
+
432
+ if styles[0].ndim < 3:
433
+ # repeat latent code for all the layers
434
+ latent = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
435
+ else: # used for encoder with different latent code for each layer
436
+ latent = styles[0]
437
+ elif len(styles) == 2: # mixing noises
438
+ if inject_index is None:
439
+ inject_index = random.randint(1, self.num_latent - 1)
440
+ latent1 = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
441
+ latent2 = styles[1].unsqueeze(1).repeat(1, self.num_latent - inject_index, 1)
442
+ latent = torch.cat([latent1, latent2], 1)
443
+
444
+ # main generation
445
+ out = self.constant_input(latent.shape[0])
446
+ out = self.style_conv1(out, latent[:, 0], noise=noise[0])
447
+ skip = self.to_rgb1(out, latent[:, 1])
448
+
449
+ i = 1
450
+ for conv1, conv2, noise1, noise2, to_rgb in zip(self.style_convs[::2], self.style_convs[1::2], noise[1::2],
451
+ noise[2::2], self.to_rgbs):
452
+ out = conv1(out, latent[:, i], noise=noise1)
453
+ out = conv2(out, latent[:, i + 1], noise=noise2)
454
+ skip = to_rgb(out, latent[:, i + 2], skip)
455
+ i += 2
456
+
457
+ image = skip
458
+
459
+ if return_latents:
460
+ return image, latent
461
+ else:
462
+ return image, None
463
+
464
+
465
+ class ScaledLeakyReLU(nn.Module):
466
+ """Scaled LeakyReLU.
467
+
468
+ Args:
469
+ negative_slope (float): Negative slope. Default: 0.2.
470
+ """
471
+
472
+ def __init__(self, negative_slope=0.2):
473
+ super(ScaledLeakyReLU, self).__init__()
474
+ self.negative_slope = negative_slope
475
+
476
+ def forward(self, x):
477
+ out = F.leaky_relu(x, negative_slope=self.negative_slope)
478
+ return out * math.sqrt(2)
479
+
480
+
481
+ class EqualConv2d(nn.Module):
482
+ """Equalized Linear as StyleGAN2.
483
+
484
+ Args:
485
+ in_channels (int): Channel number of the input.
486
+ out_channels (int): Channel number of the output.
487
+ kernel_size (int): Size of the convolving kernel.
488
+ stride (int): Stride of the convolution. Default: 1
489
+ padding (int): Zero-padding added to both sides of the input.
490
+ Default: 0.
491
+ bias (bool): If ``True``, adds a learnable bias to the output.
492
+ Default: ``True``.
493
+ bias_init_val (float): Bias initialized value. Default: 0.
494
+ """
495
+
496
+ def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, bias=True, bias_init_val=0):
497
+ super(EqualConv2d, self).__init__()
498
+ self.in_channels = in_channels
499
+ self.out_channels = out_channels
500
+ self.kernel_size = kernel_size
501
+ self.stride = stride
502
+ self.padding = padding
503
+ self.scale = 1 / math.sqrt(in_channels * kernel_size**2)
504
+
505
+ self.weight = nn.Parameter(torch.randn(out_channels, in_channels, kernel_size, kernel_size))
506
+ if bias:
507
+ self.bias = nn.Parameter(torch.zeros(out_channels).fill_(bias_init_val))
508
+ else:
509
+ self.register_parameter('bias', None)
510
+
511
+ def forward(self, x):
512
+ out = F.conv2d(
513
+ x,
514
+ self.weight * self.scale,
515
+ bias=self.bias,
516
+ stride=self.stride,
517
+ padding=self.padding,
518
+ )
519
+
520
+ return out
521
+
522
+ def __repr__(self):
523
+ return (f'{self.__class__.__name__}(in_channels={self.in_channels}, '
524
+ f'out_channels={self.out_channels}, '
525
+ f'kernel_size={self.kernel_size},'
526
+ f' stride={self.stride}, padding={self.padding}, '
527
+ f'bias={self.bias is not None})')
528
+
529
+
530
+ class ConvLayer(nn.Sequential):
531
+ """Conv Layer used in StyleGAN2 Discriminator.
532
+
533
+ Args:
534
+ in_channels (int): Channel number of the input.
535
+ out_channels (int): Channel number of the output.
536
+ kernel_size (int): Kernel size.
537
+ downsample (bool): Whether downsample by a factor of 2.
538
+ Default: False.
539
+ bias (bool): Whether with bias. Default: True.
540
+ activate (bool): Whether use activateion. Default: True.
541
+ """
542
+
543
+ def __init__(self,
544
+ in_channels,
545
+ out_channels,
546
+ kernel_size,
547
+ downsample=False,
548
+ bias=True,
549
+ activate=True,
550
+ interpolation_mode='bilinear'):
551
+ layers = []
552
+ self.interpolation_mode = interpolation_mode
553
+ # downsample
554
+ if downsample:
555
+ if self.interpolation_mode == 'nearest':
556
+ self.align_corners = None
557
+ else:
558
+ self.align_corners = False
559
+
560
+ layers.append(
561
+ torch.nn.Upsample(scale_factor=0.5, mode=interpolation_mode, align_corners=self.align_corners))
562
+ stride = 1
563
+ self.padding = kernel_size // 2
564
+ # conv
565
+ layers.append(
566
+ EqualConv2d(
567
+ in_channels, out_channels, kernel_size, stride=stride, padding=self.padding, bias=bias
568
+ and not activate))
569
+ # activation
570
+ if activate:
571
+ if bias:
572
+ layers.append(FusedLeakyReLU(out_channels))
573
+ else:
574
+ layers.append(ScaledLeakyReLU(0.2))
575
+
576
+ super(ConvLayer, self).__init__(*layers)
577
+
578
+
579
+ class ResBlock(nn.Module):
580
+ """Residual block used in StyleGAN2 Discriminator.
581
+
582
+ Args:
583
+ in_channels (int): Channel number of the input.
584
+ out_channels (int): Channel number of the output.
585
+ """
586
+
587
+ def __init__(self, in_channels, out_channels, interpolation_mode='bilinear'):
588
+ super(ResBlock, self).__init__()
589
+
590
+ self.conv1 = ConvLayer(in_channels, in_channels, 3, bias=True, activate=True)
591
+ self.conv2 = ConvLayer(
592
+ in_channels,
593
+ out_channels,
594
+ 3,
595
+ downsample=True,
596
+ interpolation_mode=interpolation_mode,
597
+ bias=True,
598
+ activate=True)
599
+ self.skip = ConvLayer(
600
+ in_channels,
601
+ out_channels,
602
+ 1,
603
+ downsample=True,
604
+ interpolation_mode=interpolation_mode,
605
+ bias=False,
606
+ activate=False)
607
+
608
+ def forward(self, x):
609
+ out = self.conv1(x)
610
+ out = self.conv2(out)
611
+ skip = self.skip(x)
612
+ out = (out + skip) / math.sqrt(2)
613
+ return out
video-tetalking/third_part/GFPGAN/gfpgan/archs/stylegan2_clean_arch.py ADDED
@@ -0,0 +1,368 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import random
3
+ import torch
4
+ from basicsr.archs.arch_util import default_init_weights
5
+ from basicsr.utils.registry import ARCH_REGISTRY
6
+ from torch import nn
7
+ from torch.nn import functional as F
8
+
9
+
10
+ class NormStyleCode(nn.Module):
11
+
12
+ def forward(self, x):
13
+ """Normalize the style codes.
14
+
15
+ Args:
16
+ x (Tensor): Style codes with shape (b, c).
17
+
18
+ Returns:
19
+ Tensor: Normalized tensor.
20
+ """
21
+ return x * torch.rsqrt(torch.mean(x**2, dim=1, keepdim=True) + 1e-8)
22
+
23
+
24
+ class ModulatedConv2d(nn.Module):
25
+ """Modulated Conv2d used in StyleGAN2.
26
+
27
+ There is no bias in ModulatedConv2d.
28
+
29
+ Args:
30
+ in_channels (int): Channel number of the input.
31
+ out_channels (int): Channel number of the output.
32
+ kernel_size (int): Size of the convolving kernel.
33
+ num_style_feat (int): Channel number of style features.
34
+ demodulate (bool): Whether to demodulate in the conv layer. Default: True.
35
+ sample_mode (str | None): Indicating 'upsample', 'downsample' or None. Default: None.
36
+ eps (float): A value added to the denominator for numerical stability. Default: 1e-8.
37
+ """
38
+
39
+ def __init__(self,
40
+ in_channels,
41
+ out_channels,
42
+ kernel_size,
43
+ num_style_feat,
44
+ demodulate=True,
45
+ sample_mode=None,
46
+ eps=1e-8):
47
+ super(ModulatedConv2d, self).__init__()
48
+ self.in_channels = in_channels
49
+ self.out_channels = out_channels
50
+ self.kernel_size = kernel_size
51
+ self.demodulate = demodulate
52
+ self.sample_mode = sample_mode
53
+ self.eps = eps
54
+
55
+ # modulation inside each modulated conv
56
+ self.modulation = nn.Linear(num_style_feat, in_channels, bias=True)
57
+ # initialization
58
+ default_init_weights(self.modulation, scale=1, bias_fill=1, a=0, mode='fan_in', nonlinearity='linear')
59
+
60
+ self.weight = nn.Parameter(
61
+ torch.randn(1, out_channels, in_channels, kernel_size, kernel_size) /
62
+ math.sqrt(in_channels * kernel_size**2))
63
+ self.padding = kernel_size // 2
64
+
65
+ def forward(self, x, style):
66
+ """Forward function.
67
+
68
+ Args:
69
+ x (Tensor): Tensor with shape (b, c, h, w).
70
+ style (Tensor): Tensor with shape (b, num_style_feat).
71
+
72
+ Returns:
73
+ Tensor: Modulated tensor after convolution.
74
+ """
75
+ b, c, h, w = x.shape # c = c_in
76
+ # weight modulation
77
+ style = self.modulation(style).view(b, 1, c, 1, 1)
78
+ # self.weight: (1, c_out, c_in, k, k); style: (b, 1, c, 1, 1)
79
+ weight = self.weight * style # (b, c_out, c_in, k, k)
80
+
81
+ if self.demodulate:
82
+ demod = torch.rsqrt(weight.pow(2).sum([2, 3, 4]) + self.eps)
83
+ weight = weight * demod.view(b, self.out_channels, 1, 1, 1)
84
+
85
+ weight = weight.view(b * self.out_channels, c, self.kernel_size, self.kernel_size)
86
+
87
+ # upsample or downsample if necessary
88
+ if self.sample_mode == 'upsample':
89
+ x = F.interpolate(x, scale_factor=2, mode='bilinear', align_corners=False)
90
+ elif self.sample_mode == 'downsample':
91
+ x = F.interpolate(x, scale_factor=0.5, mode='bilinear', align_corners=False)
92
+
93
+ b, c, h, w = x.shape
94
+ x = x.view(1, b * c, h, w)
95
+ # weight: (b*c_out, c_in, k, k), groups=b
96
+ out = F.conv2d(x, weight, padding=self.padding, groups=b)
97
+ out = out.view(b, self.out_channels, *out.shape[2:4])
98
+
99
+ return out
100
+
101
+ def __repr__(self):
102
+ return (f'{self.__class__.__name__}(in_channels={self.in_channels}, out_channels={self.out_channels}, '
103
+ f'kernel_size={self.kernel_size}, demodulate={self.demodulate}, sample_mode={self.sample_mode})')
104
+
105
+
106
+ class StyleConv(nn.Module):
107
+ """Style conv used in StyleGAN2.
108
+
109
+ Args:
110
+ in_channels (int): Channel number of the input.
111
+ out_channels (int): Channel number of the output.
112
+ kernel_size (int): Size of the convolving kernel.
113
+ num_style_feat (int): Channel number of style features.
114
+ demodulate (bool): Whether demodulate in the conv layer. Default: True.
115
+ sample_mode (str | None): Indicating 'upsample', 'downsample' or None. Default: None.
116
+ """
117
+
118
+ def __init__(self, in_channels, out_channels, kernel_size, num_style_feat, demodulate=True, sample_mode=None):
119
+ super(StyleConv, self).__init__()
120
+ self.modulated_conv = ModulatedConv2d(
121
+ in_channels, out_channels, kernel_size, num_style_feat, demodulate=demodulate, sample_mode=sample_mode)
122
+ self.weight = nn.Parameter(torch.zeros(1)) # for noise injection
123
+ self.bias = nn.Parameter(torch.zeros(1, out_channels, 1, 1))
124
+ self.activate = nn.LeakyReLU(negative_slope=0.2, inplace=True)
125
+
126
+ def forward(self, x, style, noise=None):
127
+ # modulate
128
+ out = self.modulated_conv(x, style) * 2**0.5 # for conversion
129
+ # noise injection
130
+ if noise is None:
131
+ b, _, h, w = out.shape
132
+ noise = out.new_empty(b, 1, h, w).normal_()
133
+ out = out + self.weight * noise
134
+ # add bias
135
+ out = out + self.bias
136
+ # activation
137
+ out = self.activate(out)
138
+ return out
139
+
140
+
141
+ class ToRGB(nn.Module):
142
+ """To RGB (image space) from features.
143
+
144
+ Args:
145
+ in_channels (int): Channel number of input.
146
+ num_style_feat (int): Channel number of style features.
147
+ upsample (bool): Whether to upsample. Default: True.
148
+ """
149
+
150
+ def __init__(self, in_channels, num_style_feat, upsample=True):
151
+ super(ToRGB, self).__init__()
152
+ self.upsample = upsample
153
+ self.modulated_conv = ModulatedConv2d(
154
+ in_channels, 3, kernel_size=1, num_style_feat=num_style_feat, demodulate=False, sample_mode=None)
155
+ self.bias = nn.Parameter(torch.zeros(1, 3, 1, 1))
156
+
157
+ def forward(self, x, style, skip=None):
158
+ """Forward function.
159
+
160
+ Args:
161
+ x (Tensor): Feature tensor with shape (b, c, h, w).
162
+ style (Tensor): Tensor with shape (b, num_style_feat).
163
+ skip (Tensor): Base/skip tensor. Default: None.
164
+
165
+ Returns:
166
+ Tensor: RGB images.
167
+ """
168
+ out = self.modulated_conv(x, style)
169
+ out = out + self.bias
170
+ if skip is not None:
171
+ if self.upsample:
172
+ skip = F.interpolate(skip, scale_factor=2, mode='bilinear', align_corners=False)
173
+ out = out + skip
174
+ return out
175
+
176
+
177
+ class ConstantInput(nn.Module):
178
+ """Constant input.
179
+
180
+ Args:
181
+ num_channel (int): Channel number of constant input.
182
+ size (int): Spatial size of constant input.
183
+ """
184
+
185
+ def __init__(self, num_channel, size):
186
+ super(ConstantInput, self).__init__()
187
+ self.weight = nn.Parameter(torch.randn(1, num_channel, size, size))
188
+
189
+ def forward(self, batch):
190
+ out = self.weight.repeat(batch, 1, 1, 1)
191
+ return out
192
+
193
+
194
+ @ARCH_REGISTRY.register()
195
+ class StyleGAN2GeneratorClean(nn.Module):
196
+ """Clean version of StyleGAN2 Generator.
197
+
198
+ Args:
199
+ out_size (int): The spatial size of outputs.
200
+ num_style_feat (int): Channel number of style features. Default: 512.
201
+ num_mlp (int): Layer number of MLP style layers. Default: 8.
202
+ channel_multiplier (int): Channel multiplier for large networks of StyleGAN2. Default: 2.
203
+ narrow (float): Narrow ratio for channels. Default: 1.0.
204
+ """
205
+
206
+ def __init__(self, out_size, num_style_feat=512, num_mlp=8, channel_multiplier=2, narrow=1):
207
+ super(StyleGAN2GeneratorClean, self).__init__()
208
+ # Style MLP layers
209
+ self.num_style_feat = num_style_feat
210
+ style_mlp_layers = [NormStyleCode()]
211
+ for i in range(num_mlp):
212
+ style_mlp_layers.extend(
213
+ [nn.Linear(num_style_feat, num_style_feat, bias=True),
214
+ nn.LeakyReLU(negative_slope=0.2, inplace=True)])
215
+ self.style_mlp = nn.Sequential(*style_mlp_layers)
216
+ # initialization
217
+ default_init_weights(self.style_mlp, scale=1, bias_fill=0, a=0.2, mode='fan_in', nonlinearity='leaky_relu')
218
+
219
+ # channel list
220
+ channels = {
221
+ '4': int(512 * narrow),
222
+ '8': int(512 * narrow),
223
+ '16': int(512 * narrow),
224
+ '32': int(512 * narrow),
225
+ '64': int(256 * channel_multiplier * narrow),
226
+ '128': int(128 * channel_multiplier * narrow),
227
+ '256': int(64 * channel_multiplier * narrow),
228
+ '512': int(32 * channel_multiplier * narrow),
229
+ '1024': int(16 * channel_multiplier * narrow)
230
+ }
231
+ self.channels = channels
232
+
233
+ self.constant_input = ConstantInput(channels['4'], size=4)
234
+ self.style_conv1 = StyleConv(
235
+ channels['4'],
236
+ channels['4'],
237
+ kernel_size=3,
238
+ num_style_feat=num_style_feat,
239
+ demodulate=True,
240
+ sample_mode=None)
241
+ self.to_rgb1 = ToRGB(channels['4'], num_style_feat, upsample=False)
242
+
243
+ self.log_size = int(math.log(out_size, 2))
244
+ self.num_layers = (self.log_size - 2) * 2 + 1
245
+ self.num_latent = self.log_size * 2 - 2
246
+
247
+ self.style_convs = nn.ModuleList()
248
+ self.to_rgbs = nn.ModuleList()
249
+ self.noises = nn.Module()
250
+
251
+ in_channels = channels['4']
252
+ # noise
253
+ for layer_idx in range(self.num_layers):
254
+ resolution = 2**((layer_idx + 5) // 2)
255
+ shape = [1, 1, resolution, resolution]
256
+ self.noises.register_buffer(f'noise{layer_idx}', torch.randn(*shape))
257
+ # style convs and to_rgbs
258
+ for i in range(3, self.log_size + 1):
259
+ out_channels = channels[f'{2**i}']
260
+ self.style_convs.append(
261
+ StyleConv(
262
+ in_channels,
263
+ out_channels,
264
+ kernel_size=3,
265
+ num_style_feat=num_style_feat,
266
+ demodulate=True,
267
+ sample_mode='upsample'))
268
+ self.style_convs.append(
269
+ StyleConv(
270
+ out_channels,
271
+ out_channels,
272
+ kernel_size=3,
273
+ num_style_feat=num_style_feat,
274
+ demodulate=True,
275
+ sample_mode=None))
276
+ self.to_rgbs.append(ToRGB(out_channels, num_style_feat, upsample=True))
277
+ in_channels = out_channels
278
+
279
+ def make_noise(self):
280
+ """Make noise for noise injection."""
281
+ device = self.constant_input.weight.device
282
+ noises = [torch.randn(1, 1, 4, 4, device=device)]
283
+
284
+ for i in range(3, self.log_size + 1):
285
+ for _ in range(2):
286
+ noises.append(torch.randn(1, 1, 2**i, 2**i, device=device))
287
+
288
+ return noises
289
+
290
+ def get_latent(self, x):
291
+ return self.style_mlp(x)
292
+
293
+ def mean_latent(self, num_latent):
294
+ latent_in = torch.randn(num_latent, self.num_style_feat, device=self.constant_input.weight.device)
295
+ latent = self.style_mlp(latent_in).mean(0, keepdim=True)
296
+ return latent
297
+
298
+ def forward(self,
299
+ styles,
300
+ input_is_latent=False,
301
+ noise=None,
302
+ randomize_noise=True,
303
+ truncation=1,
304
+ truncation_latent=None,
305
+ inject_index=None,
306
+ return_latents=False):
307
+ """Forward function for StyleGAN2GeneratorClean.
308
+
309
+ Args:
310
+ styles (list[Tensor]): Sample codes of styles.
311
+ input_is_latent (bool): Whether input is latent style. Default: False.
312
+ noise (Tensor | None): Input noise or None. Default: None.
313
+ randomize_noise (bool): Randomize noise, used when 'noise' is False. Default: True.
314
+ truncation (float): The truncation ratio. Default: 1.
315
+ truncation_latent (Tensor | None): The truncation latent tensor. Default: None.
316
+ inject_index (int | None): The injection index for mixing noise. Default: None.
317
+ return_latents (bool): Whether to return style latents. Default: False.
318
+ """
319
+ # style codes -> latents with Style MLP layer
320
+ if not input_is_latent:
321
+ styles = [self.style_mlp(s) for s in styles]
322
+ # noises
323
+ if noise is None:
324
+ if randomize_noise:
325
+ noise = [None] * self.num_layers # for each style conv layer
326
+ else: # use the stored noise
327
+ noise = [getattr(self.noises, f'noise{i}') for i in range(self.num_layers)]
328
+ # style truncation
329
+ if truncation < 1:
330
+ style_truncation = []
331
+ for style in styles:
332
+ style_truncation.append(truncation_latent + truncation * (style - truncation_latent))
333
+ styles = style_truncation
334
+ # get style latents with injection
335
+ if len(styles) == 1:
336
+ inject_index = self.num_latent
337
+
338
+ if styles[0].ndim < 3:
339
+ # repeat latent code for all the layers
340
+ latent = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
341
+ else: # used for encoder with different latent code for each layer
342
+ latent = styles[0]
343
+ elif len(styles) == 2: # mixing noises
344
+ if inject_index is None:
345
+ inject_index = random.randint(1, self.num_latent - 1)
346
+ latent1 = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
347
+ latent2 = styles[1].unsqueeze(1).repeat(1, self.num_latent - inject_index, 1)
348
+ latent = torch.cat([latent1, latent2], 1)
349
+
350
+ # main generation
351
+ out = self.constant_input(latent.shape[0])
352
+ out = self.style_conv1(out, latent[:, 0], noise=noise[0])
353
+ skip = self.to_rgb1(out, latent[:, 1])
354
+
355
+ i = 1
356
+ for conv1, conv2, noise1, noise2, to_rgb in zip(self.style_convs[::2], self.style_convs[1::2], noise[1::2],
357
+ noise[2::2], self.to_rgbs):
358
+ out = conv1(out, latent[:, i], noise=noise1)
359
+ out = conv2(out, latent[:, i + 1], noise=noise2)
360
+ skip = to_rgb(out, latent[:, i + 2], skip) # feature back to the rgb space
361
+ i += 2
362
+
363
+ image = skip
364
+
365
+ if return_latents:
366
+ return image, latent
367
+ else:
368
+ return image, None
video-tetalking/third_part/GFPGAN/gfpgan/data/__init__.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import importlib
2
+ from basicsr.utils import scandir
3
+ from os import path as osp
4
+
5
+ # automatically scan and import dataset modules for registry
6
+ # scan all the files that end with '_dataset.py' under the data folder
7
+ data_folder = osp.dirname(osp.abspath(__file__))
8
+ dataset_filenames = [osp.splitext(osp.basename(v))[0] for v in scandir(data_folder) if v.endswith('_dataset.py')]
9
+ # import all the dataset modules
10
+ _dataset_modules = [importlib.import_module(f'gfpgan.data.{file_name}') for file_name in dataset_filenames]
video-tetalking/third_part/GFPGAN/gfpgan/data/ffhq_degradation_dataset.py ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import math
3
+ import numpy as np
4
+ import os.path as osp
5
+ import torch
6
+ import torch.utils.data as data
7
+ from basicsr.data import degradations as degradations
8
+ from basicsr.data.data_util import paths_from_folder
9
+ from basicsr.data.transforms import augment
10
+ from basicsr.utils import FileClient, get_root_logger, imfrombytes, img2tensor
11
+ from basicsr.utils.registry import DATASET_REGISTRY
12
+ from torchvision.transforms.functional import (adjust_brightness, adjust_contrast, adjust_hue, adjust_saturation,
13
+ normalize)
14
+
15
+
16
+ @DATASET_REGISTRY.register()
17
+ class FFHQDegradationDataset(data.Dataset):
18
+ """FFHQ dataset for GFPGAN.
19
+
20
+ It reads high resolution images, and then generate low-quality (LQ) images on-the-fly.
21
+
22
+ Args:
23
+ opt (dict): Config for train datasets. It contains the following keys:
24
+ dataroot_gt (str): Data root path for gt.
25
+ io_backend (dict): IO backend type and other kwarg.
26
+ mean (list | tuple): Image mean.
27
+ std (list | tuple): Image std.
28
+ use_hflip (bool): Whether to horizontally flip.
29
+ Please see more options in the codes.
30
+ """
31
+
32
+ def __init__(self, opt):
33
+ super(FFHQDegradationDataset, self).__init__()
34
+ self.opt = opt
35
+ # file client (io backend)
36
+ self.file_client = None
37
+ self.io_backend_opt = opt['io_backend']
38
+
39
+ self.gt_folder = opt['dataroot_gt']
40
+ self.mean = opt['mean']
41
+ self.std = opt['std']
42
+ self.out_size = opt['out_size']
43
+
44
+ self.crop_components = opt.get('crop_components', False) # facial components
45
+ self.eye_enlarge_ratio = opt.get('eye_enlarge_ratio', 1) # whether enlarge eye regions
46
+
47
+ if self.crop_components:
48
+ # load component list from a pre-process pth files
49
+ self.components_list = torch.load(opt.get('component_path'))
50
+
51
+ # file client (lmdb io backend)
52
+ if self.io_backend_opt['type'] == 'lmdb':
53
+ self.io_backend_opt['db_paths'] = self.gt_folder
54
+ if not self.gt_folder.endswith('.lmdb'):
55
+ raise ValueError(f"'dataroot_gt' should end with '.lmdb', but received {self.gt_folder}")
56
+ with open(osp.join(self.gt_folder, 'meta_info.txt')) as fin:
57
+ self.paths = [line.split('.')[0] for line in fin]
58
+ else:
59
+ # disk backend: scan file list from a folder
60
+ self.paths = paths_from_folder(self.gt_folder)
61
+
62
+ # degradation configurations
63
+ self.blur_kernel_size = opt['blur_kernel_size']
64
+ self.kernel_list = opt['kernel_list']
65
+ self.kernel_prob = opt['kernel_prob']
66
+ self.blur_sigma = opt['blur_sigma']
67
+ self.downsample_range = opt['downsample_range']
68
+ self.noise_range = opt['noise_range']
69
+ self.jpeg_range = opt['jpeg_range']
70
+
71
+ # color jitter
72
+ self.color_jitter_prob = opt.get('color_jitter_prob')
73
+ self.color_jitter_pt_prob = opt.get('color_jitter_pt_prob')
74
+ self.color_jitter_shift = opt.get('color_jitter_shift', 20)
75
+ # to gray
76
+ self.gray_prob = opt.get('gray_prob')
77
+
78
+ logger = get_root_logger()
79
+ logger.info(f'Blur: blur_kernel_size {self.blur_kernel_size}, sigma: [{", ".join(map(str, self.blur_sigma))}]')
80
+ logger.info(f'Downsample: downsample_range [{", ".join(map(str, self.downsample_range))}]')
81
+ logger.info(f'Noise: [{", ".join(map(str, self.noise_range))}]')
82
+ logger.info(f'JPEG compression: [{", ".join(map(str, self.jpeg_range))}]')
83
+
84
+ if self.color_jitter_prob is not None:
85
+ logger.info(f'Use random color jitter. Prob: {self.color_jitter_prob}, shift: {self.color_jitter_shift}')
86
+ if self.gray_prob is not None:
87
+ logger.info(f'Use random gray. Prob: {self.gray_prob}')
88
+ self.color_jitter_shift /= 255.
89
+
90
+ @staticmethod
91
+ def color_jitter(img, shift):
92
+ """jitter color: randomly jitter the RGB values, in numpy formats"""
93
+ jitter_val = np.random.uniform(-shift, shift, 3).astype(np.float32)
94
+ img = img + jitter_val
95
+ img = np.clip(img, 0, 1)
96
+ return img
97
+
98
+ @staticmethod
99
+ def color_jitter_pt(img, brightness, contrast, saturation, hue):
100
+ """jitter color: randomly jitter the brightness, contrast, saturation, and hue, in torch Tensor formats"""
101
+ fn_idx = torch.randperm(4)
102
+ for fn_id in fn_idx:
103
+ if fn_id == 0 and brightness is not None:
104
+ brightness_factor = torch.tensor(1.0).uniform_(brightness[0], brightness[1]).item()
105
+ img = adjust_brightness(img, brightness_factor)
106
+
107
+ if fn_id == 1 and contrast is not None:
108
+ contrast_factor = torch.tensor(1.0).uniform_(contrast[0], contrast[1]).item()
109
+ img = adjust_contrast(img, contrast_factor)
110
+
111
+ if fn_id == 2 and saturation is not None:
112
+ saturation_factor = torch.tensor(1.0).uniform_(saturation[0], saturation[1]).item()
113
+ img = adjust_saturation(img, saturation_factor)
114
+
115
+ if fn_id == 3 and hue is not None:
116
+ hue_factor = torch.tensor(1.0).uniform_(hue[0], hue[1]).item()
117
+ img = adjust_hue(img, hue_factor)
118
+ return img
119
+
120
+ def get_component_coordinates(self, index, status):
121
+ """Get facial component (left_eye, right_eye, mouth) coordinates from a pre-loaded pth file"""
122
+ components_bbox = self.components_list[f'{index:08d}']
123
+ if status[0]: # hflip
124
+ # exchange right and left eye
125
+ tmp = components_bbox['left_eye']
126
+ components_bbox['left_eye'] = components_bbox['right_eye']
127
+ components_bbox['right_eye'] = tmp
128
+ # modify the width coordinate
129
+ components_bbox['left_eye'][0] = self.out_size - components_bbox['left_eye'][0]
130
+ components_bbox['right_eye'][0] = self.out_size - components_bbox['right_eye'][0]
131
+ components_bbox['mouth'][0] = self.out_size - components_bbox['mouth'][0]
132
+
133
+ # get coordinates
134
+ locations = []
135
+ for part in ['left_eye', 'right_eye', 'mouth']:
136
+ mean = components_bbox[part][0:2]
137
+ half_len = components_bbox[part][2]
138
+ if 'eye' in part:
139
+ half_len *= self.eye_enlarge_ratio
140
+ loc = np.hstack((mean - half_len + 1, mean + half_len))
141
+ loc = torch.from_numpy(loc).float()
142
+ locations.append(loc)
143
+ return locations
144
+
145
+ def __getitem__(self, index):
146
+ if self.file_client is None:
147
+ self.file_client = FileClient(self.io_backend_opt.pop('type'), **self.io_backend_opt)
148
+
149
+ # load gt image
150
+ # Shape: (h, w, c); channel order: BGR; image range: [0, 1], float32.
151
+ gt_path = self.paths[index]
152
+ img_bytes = self.file_client.get(gt_path)
153
+ img_gt = imfrombytes(img_bytes, float32=True)
154
+
155
+ # random horizontal flip
156
+ img_gt, status = augment(img_gt, hflip=self.opt['use_hflip'], rotation=False, return_status=True)
157
+ h, w, _ = img_gt.shape
158
+
159
+ # get facial component coordinates
160
+ if self.crop_components:
161
+ locations = self.get_component_coordinates(index, status)
162
+ loc_left_eye, loc_right_eye, loc_mouth = locations
163
+
164
+ # ------------------------ generate lq image ------------------------ #
165
+ # blur
166
+ kernel = degradations.random_mixed_kernels(
167
+ self.kernel_list,
168
+ self.kernel_prob,
169
+ self.blur_kernel_size,
170
+ self.blur_sigma,
171
+ self.blur_sigma, [-math.pi, math.pi],
172
+ noise_range=None)
173
+ img_lq = cv2.filter2D(img_gt, -1, kernel)
174
+ # downsample
175
+ scale = np.random.uniform(self.downsample_range[0], self.downsample_range[1])
176
+ img_lq = cv2.resize(img_lq, (int(w // scale), int(h // scale)), interpolation=cv2.INTER_LINEAR)
177
+ # noise
178
+ if self.noise_range is not None:
179
+ img_lq = degradations.random_add_gaussian_noise(img_lq, self.noise_range)
180
+ # jpeg compression
181
+ if self.jpeg_range is not None:
182
+ img_lq = degradations.random_add_jpg_compression(img_lq, self.jpeg_range)
183
+
184
+ # resize to original size
185
+ img_lq = cv2.resize(img_lq, (w, h), interpolation=cv2.INTER_LINEAR)
186
+
187
+ # random color jitter (only for lq)
188
+ if self.color_jitter_prob is not None and (np.random.uniform() < self.color_jitter_prob):
189
+ img_lq = self.color_jitter(img_lq, self.color_jitter_shift)
190
+ # random to gray (only for lq)
191
+ if self.gray_prob and np.random.uniform() < self.gray_prob:
192
+ img_lq = cv2.cvtColor(img_lq, cv2.COLOR_BGR2GRAY)
193
+ img_lq = np.tile(img_lq[:, :, None], [1, 1, 3])
194
+ if self.opt.get('gt_gray'): # whether convert GT to gray images
195
+ img_gt = cv2.cvtColor(img_gt, cv2.COLOR_BGR2GRAY)
196
+ img_gt = np.tile(img_gt[:, :, None], [1, 1, 3]) # repeat the color channels
197
+
198
+ # BGR to RGB, HWC to CHW, numpy to tensor
199
+ img_gt, img_lq = img2tensor([img_gt, img_lq], bgr2rgb=True, float32=True)
200
+
201
+ # random color jitter (pytorch version) (only for lq)
202
+ if self.color_jitter_pt_prob is not None and (np.random.uniform() < self.color_jitter_pt_prob):
203
+ brightness = self.opt.get('brightness', (0.5, 1.5))
204
+ contrast = self.opt.get('contrast', (0.5, 1.5))
205
+ saturation = self.opt.get('saturation', (0, 1.5))
206
+ hue = self.opt.get('hue', (-0.1, 0.1))
207
+ img_lq = self.color_jitter_pt(img_lq, brightness, contrast, saturation, hue)
208
+
209
+ # round and clip
210
+ img_lq = torch.clamp((img_lq * 255.0).round(), 0, 255) / 255.
211
+
212
+ # normalize
213
+ normalize(img_gt, self.mean, self.std, inplace=True)
214
+ normalize(img_lq, self.mean, self.std, inplace=True)
215
+
216
+ if self.crop_components:
217
+ return_dict = {
218
+ 'lq': img_lq,
219
+ 'gt': img_gt,
220
+ 'gt_path': gt_path,
221
+ 'loc_left_eye': loc_left_eye,
222
+ 'loc_right_eye': loc_right_eye,
223
+ 'loc_mouth': loc_mouth
224
+ }
225
+ return return_dict
226
+ else:
227
+ return {'lq': img_lq, 'gt': img_gt, 'gt_path': gt_path}
228
+
229
+ def __len__(self):
230
+ return len(self.paths)
video-tetalking/third_part/GFPGAN/gfpgan/models/__init__.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import importlib
2
+ from basicsr.utils import scandir
3
+ from os import path as osp
4
+
5
+ # automatically scan and import model modules for registry
6
+ # scan all the files that end with '_model.py' under the model folder
7
+ model_folder = osp.dirname(osp.abspath(__file__))
8
+ model_filenames = [osp.splitext(osp.basename(v))[0] for v in scandir(model_folder) if v.endswith('_model.py')]
9
+ # import all the model modules
10
+ _model_modules = [importlib.import_module(f'gfpgan.models.{file_name}') for file_name in model_filenames]
video-tetalking/third_part/GFPGAN/gfpgan/models/gfpgan_model.py ADDED
@@ -0,0 +1,580 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import os.path as osp
3
+ import torch
4
+ from basicsr.archs import build_network
5
+ from basicsr.losses import build_loss
6
+ # from basicsr.losses.losses import r1_penalty
7
+ from basicsr.losses import r1_penalty
8
+ from basicsr.metrics import calculate_metric
9
+ from basicsr.models.base_model import BaseModel
10
+ from basicsr.utils import get_root_logger, imwrite, tensor2img
11
+ from basicsr.utils.registry import MODEL_REGISTRY
12
+ from collections import OrderedDict
13
+ from torch.nn import functional as F
14
+ from torchvision.ops import roi_align
15
+ from tqdm import tqdm
16
+
17
+
18
+ @MODEL_REGISTRY.register()
19
+ class GFPGANModel(BaseModel):
20
+ """The GFPGAN model for Towards real-world blind face restoratin with generative facial prior"""
21
+
22
+ def __init__(self, opt):
23
+ super(GFPGANModel, self).__init__(opt)
24
+ self.idx = 0 # it is used for saving data for check
25
+
26
+ # define network
27
+ self.net_g = build_network(opt['network_g'])
28
+ self.net_g = self.model_to_device(self.net_g)
29
+ self.print_network(self.net_g)
30
+
31
+ # load pretrained model
32
+ load_path = self.opt['path'].get('pretrain_network_g', None)
33
+ if load_path is not None:
34
+ param_key = self.opt['path'].get('param_key_g', 'params')
35
+ self.load_network(self.net_g, load_path, self.opt['path'].get('strict_load_g', True), param_key)
36
+
37
+ self.log_size = int(math.log(self.opt['network_g']['out_size'], 2))
38
+
39
+ if self.is_train:
40
+ self.init_training_settings()
41
+
42
+ def init_training_settings(self):
43
+ train_opt = self.opt['train']
44
+
45
+ # ----------- define net_d ----------- #
46
+ self.net_d = build_network(self.opt['network_d'])
47
+ self.net_d = self.model_to_device(self.net_d)
48
+ self.print_network(self.net_d)
49
+ # load pretrained model
50
+ load_path = self.opt['path'].get('pretrain_network_d', None)
51
+ if load_path is not None:
52
+ self.load_network(self.net_d, load_path, self.opt['path'].get('strict_load_d', True))
53
+
54
+ # ----------- define net_g with Exponential Moving Average (EMA) ----------- #
55
+ # net_g_ema only used for testing on one GPU and saving. There is no need to wrap with DistributedDataParallel
56
+ self.net_g_ema = build_network(self.opt['network_g']).to(self.device)
57
+ # load pretrained model
58
+ load_path = self.opt['path'].get('pretrain_network_g', None)
59
+ if load_path is not None:
60
+ self.load_network(self.net_g_ema, load_path, self.opt['path'].get('strict_load_g', True), 'params_ema')
61
+ else:
62
+ self.model_ema(0) # copy net_g weight
63
+
64
+ self.net_g.train()
65
+ self.net_d.train()
66
+ self.net_g_ema.eval()
67
+
68
+ # ----------- facial component networks ----------- #
69
+ if ('network_d_left_eye' in self.opt and 'network_d_right_eye' in self.opt and 'network_d_mouth' in self.opt):
70
+ self.use_facial_disc = True
71
+ else:
72
+ self.use_facial_disc = False
73
+
74
+ if self.use_facial_disc:
75
+ # left eye
76
+ self.net_d_left_eye = build_network(self.opt['network_d_left_eye'])
77
+ self.net_d_left_eye = self.model_to_device(self.net_d_left_eye)
78
+ self.print_network(self.net_d_left_eye)
79
+ load_path = self.opt['path'].get('pretrain_network_d_left_eye')
80
+ if load_path is not None:
81
+ self.load_network(self.net_d_left_eye, load_path, True, 'params')
82
+ # right eye
83
+ self.net_d_right_eye = build_network(self.opt['network_d_right_eye'])
84
+ self.net_d_right_eye = self.model_to_device(self.net_d_right_eye)
85
+ self.print_network(self.net_d_right_eye)
86
+ load_path = self.opt['path'].get('pretrain_network_d_right_eye')
87
+ if load_path is not None:
88
+ self.load_network(self.net_d_right_eye, load_path, True, 'params')
89
+ # mouth
90
+ self.net_d_mouth = build_network(self.opt['network_d_mouth'])
91
+ self.net_d_mouth = self.model_to_device(self.net_d_mouth)
92
+ self.print_network(self.net_d_mouth)
93
+ load_path = self.opt['path'].get('pretrain_network_d_mouth')
94
+ if load_path is not None:
95
+ self.load_network(self.net_d_mouth, load_path, True, 'params')
96
+
97
+ self.net_d_left_eye.train()
98
+ self.net_d_right_eye.train()
99
+ self.net_d_mouth.train()
100
+
101
+ # ----------- define facial component gan loss ----------- #
102
+ self.cri_component = build_loss(train_opt['gan_component_opt']).to(self.device)
103
+
104
+ # ----------- define losses ----------- #
105
+ # pixel loss
106
+ if train_opt.get('pixel_opt'):
107
+ self.cri_pix = build_loss(train_opt['pixel_opt']).to(self.device)
108
+ else:
109
+ self.cri_pix = None
110
+
111
+ # perceptual loss
112
+ if train_opt.get('perceptual_opt'):
113
+ self.cri_perceptual = build_loss(train_opt['perceptual_opt']).to(self.device)
114
+ else:
115
+ self.cri_perceptual = None
116
+
117
+ # L1 loss is used in pyramid loss, component style loss and identity loss
118
+ self.cri_l1 = build_loss(train_opt['L1_opt']).to(self.device)
119
+
120
+ # gan loss (wgan)
121
+ self.cri_gan = build_loss(train_opt['gan_opt']).to(self.device)
122
+
123
+ # ----------- define identity loss ----------- #
124
+ if 'network_identity' in self.opt:
125
+ self.use_identity = True
126
+ else:
127
+ self.use_identity = False
128
+
129
+ if self.use_identity:
130
+ # define identity network
131
+ self.network_identity = build_network(self.opt['network_identity'])
132
+ self.network_identity = self.model_to_device(self.network_identity)
133
+ self.print_network(self.network_identity)
134
+ load_path = self.opt['path'].get('pretrain_network_identity')
135
+ if load_path is not None:
136
+ self.load_network(self.network_identity, load_path, True, None)
137
+ self.network_identity.eval()
138
+ for param in self.network_identity.parameters():
139
+ param.requires_grad = False
140
+
141
+ # regularization weights
142
+ self.r1_reg_weight = train_opt['r1_reg_weight'] # for discriminator
143
+ self.net_d_iters = train_opt.get('net_d_iters', 1)
144
+ self.net_d_init_iters = train_opt.get('net_d_init_iters', 0)
145
+ self.net_d_reg_every = train_opt['net_d_reg_every']
146
+
147
+ # set up optimizers and schedulers
148
+ self.setup_optimizers()
149
+ self.setup_schedulers()
150
+
151
+ def setup_optimizers(self):
152
+ train_opt = self.opt['train']
153
+
154
+ # ----------- optimizer g ----------- #
155
+ net_g_reg_ratio = 1
156
+ normal_params = []
157
+ for _, param in self.net_g.named_parameters():
158
+ normal_params.append(param)
159
+ optim_params_g = [{ # add normal params first
160
+ 'params': normal_params,
161
+ 'lr': train_opt['optim_g']['lr']
162
+ }]
163
+ optim_type = train_opt['optim_g'].pop('type')
164
+ lr = train_opt['optim_g']['lr'] * net_g_reg_ratio
165
+ betas = (0**net_g_reg_ratio, 0.99**net_g_reg_ratio)
166
+ self.optimizer_g = self.get_optimizer(optim_type, optim_params_g, lr, betas=betas)
167
+ self.optimizers.append(self.optimizer_g)
168
+
169
+ # ----------- optimizer d ----------- #
170
+ net_d_reg_ratio = self.net_d_reg_every / (self.net_d_reg_every + 1)
171
+ normal_params = []
172
+ for _, param in self.net_d.named_parameters():
173
+ normal_params.append(param)
174
+ optim_params_d = [{ # add normal params first
175
+ 'params': normal_params,
176
+ 'lr': train_opt['optim_d']['lr']
177
+ }]
178
+ optim_type = train_opt['optim_d'].pop('type')
179
+ lr = train_opt['optim_d']['lr'] * net_d_reg_ratio
180
+ betas = (0**net_d_reg_ratio, 0.99**net_d_reg_ratio)
181
+ self.optimizer_d = self.get_optimizer(optim_type, optim_params_d, lr, betas=betas)
182
+ self.optimizers.append(self.optimizer_d)
183
+
184
+ # ----------- optimizers for facial component networks ----------- #
185
+ if self.use_facial_disc:
186
+ # setup optimizers for facial component discriminators
187
+ optim_type = train_opt['optim_component'].pop('type')
188
+ lr = train_opt['optim_component']['lr']
189
+ # left eye
190
+ self.optimizer_d_left_eye = self.get_optimizer(
191
+ optim_type, self.net_d_left_eye.parameters(), lr, betas=(0.9, 0.99))
192
+ self.optimizers.append(self.optimizer_d_left_eye)
193
+ # right eye
194
+ self.optimizer_d_right_eye = self.get_optimizer(
195
+ optim_type, self.net_d_right_eye.parameters(), lr, betas=(0.9, 0.99))
196
+ self.optimizers.append(self.optimizer_d_right_eye)
197
+ # mouth
198
+ self.optimizer_d_mouth = self.get_optimizer(
199
+ optim_type, self.net_d_mouth.parameters(), lr, betas=(0.9, 0.99))
200
+ self.optimizers.append(self.optimizer_d_mouth)
201
+
202
+ def feed_data(self, data):
203
+ self.lq = data['lq'].to(self.device)
204
+ if 'gt' in data:
205
+ self.gt = data['gt'].to(self.device)
206
+
207
+ if 'loc_left_eye' in data:
208
+ # get facial component locations, shape (batch, 4)
209
+ self.loc_left_eyes = data['loc_left_eye']
210
+ self.loc_right_eyes = data['loc_right_eye']
211
+ self.loc_mouths = data['loc_mouth']
212
+
213
+ # uncomment to check data
214
+ # import torchvision
215
+ # if self.opt['rank'] == 0:
216
+ # import os
217
+ # os.makedirs('tmp/gt', exist_ok=True)
218
+ # os.makedirs('tmp/lq', exist_ok=True)
219
+ # print(self.idx)
220
+ # torchvision.utils.save_image(
221
+ # self.gt, f'tmp/gt/gt_{self.idx}.png', nrow=4, padding=2, normalize=True, range=(-1, 1))
222
+ # torchvision.utils.save_image(
223
+ # self.lq, f'tmp/lq/lq{self.idx}.png', nrow=4, padding=2, normalize=True, range=(-1, 1))
224
+ # self.idx = self.idx + 1
225
+
226
+ def construct_img_pyramid(self):
227
+ """Construct image pyramid for intermediate restoration loss"""
228
+ pyramid_gt = [self.gt]
229
+ down_img = self.gt
230
+ for _ in range(0, self.log_size - 3):
231
+ down_img = F.interpolate(down_img, scale_factor=0.5, mode='bilinear', align_corners=False)
232
+ pyramid_gt.insert(0, down_img)
233
+ return pyramid_gt
234
+
235
+ def get_roi_regions(self, eye_out_size=80, mouth_out_size=120):
236
+ face_ratio = int(self.opt['network_g']['out_size'] / 512)
237
+ eye_out_size *= face_ratio
238
+ mouth_out_size *= face_ratio
239
+
240
+ rois_eyes = []
241
+ rois_mouths = []
242
+ for b in range(self.loc_left_eyes.size(0)): # loop for batch size
243
+ # left eye and right eye
244
+ img_inds = self.loc_left_eyes.new_full((2, 1), b)
245
+ bbox = torch.stack([self.loc_left_eyes[b, :], self.loc_right_eyes[b, :]], dim=0) # shape: (2, 4)
246
+ rois = torch.cat([img_inds, bbox], dim=-1) # shape: (2, 5)
247
+ rois_eyes.append(rois)
248
+ # mouse
249
+ img_inds = self.loc_left_eyes.new_full((1, 1), b)
250
+ rois = torch.cat([img_inds, self.loc_mouths[b:b + 1, :]], dim=-1) # shape: (1, 5)
251
+ rois_mouths.append(rois)
252
+
253
+ rois_eyes = torch.cat(rois_eyes, 0).to(self.device)
254
+ rois_mouths = torch.cat(rois_mouths, 0).to(self.device)
255
+
256
+ # real images
257
+ all_eyes = roi_align(self.gt, boxes=rois_eyes, output_size=eye_out_size) * face_ratio
258
+ self.left_eyes_gt = all_eyes[0::2, :, :, :]
259
+ self.right_eyes_gt = all_eyes[1::2, :, :, :]
260
+ self.mouths_gt = roi_align(self.gt, boxes=rois_mouths, output_size=mouth_out_size) * face_ratio
261
+ # output
262
+ all_eyes = roi_align(self.output, boxes=rois_eyes, output_size=eye_out_size) * face_ratio
263
+ self.left_eyes = all_eyes[0::2, :, :, :]
264
+ self.right_eyes = all_eyes[1::2, :, :, :]
265
+ self.mouths = roi_align(self.output, boxes=rois_mouths, output_size=mouth_out_size) * face_ratio
266
+
267
+ def _gram_mat(self, x):
268
+ """Calculate Gram matrix.
269
+
270
+ Args:
271
+ x (torch.Tensor): Tensor with shape of (n, c, h, w).
272
+
273
+ Returns:
274
+ torch.Tensor: Gram matrix.
275
+ """
276
+ n, c, h, w = x.size()
277
+ features = x.view(n, c, w * h)
278
+ features_t = features.transpose(1, 2)
279
+ gram = features.bmm(features_t) / (c * h * w)
280
+ return gram
281
+
282
+ def gray_resize_for_identity(self, out, size=128):
283
+ out_gray = (0.2989 * out[:, 0, :, :] + 0.5870 * out[:, 1, :, :] + 0.1140 * out[:, 2, :, :])
284
+ out_gray = out_gray.unsqueeze(1)
285
+ out_gray = F.interpolate(out_gray, (size, size), mode='bilinear', align_corners=False)
286
+ return out_gray
287
+
288
+ def optimize_parameters(self, current_iter):
289
+ # optimize net_g
290
+ for p in self.net_d.parameters():
291
+ p.requires_grad = False
292
+ self.optimizer_g.zero_grad()
293
+
294
+ # do not update facial component net_d
295
+ if self.use_facial_disc:
296
+ for p in self.net_d_left_eye.parameters():
297
+ p.requires_grad = False
298
+ for p in self.net_d_right_eye.parameters():
299
+ p.requires_grad = False
300
+ for p in self.net_d_mouth.parameters():
301
+ p.requires_grad = False
302
+
303
+ # image pyramid loss weight
304
+ pyramid_loss_weight = self.opt['train'].get('pyramid_loss_weight', 0)
305
+ if pyramid_loss_weight > 0 and current_iter > self.opt['train'].get('remove_pyramid_loss', float('inf')):
306
+ pyramid_loss_weight = 1e-12 # very small weight to avoid unused param error
307
+ if pyramid_loss_weight > 0:
308
+ self.output, out_rgbs = self.net_g(self.lq, return_rgb=True)
309
+ pyramid_gt = self.construct_img_pyramid()
310
+ else:
311
+ self.output, out_rgbs = self.net_g(self.lq, return_rgb=False)
312
+
313
+ # get roi-align regions
314
+ if self.use_facial_disc:
315
+ self.get_roi_regions(eye_out_size=80, mouth_out_size=120)
316
+
317
+ l_g_total = 0
318
+ loss_dict = OrderedDict()
319
+ if (current_iter % self.net_d_iters == 0 and current_iter > self.net_d_init_iters):
320
+ # pixel loss
321
+ if self.cri_pix:
322
+ l_g_pix = self.cri_pix(self.output, self.gt)
323
+ l_g_total += l_g_pix
324
+ loss_dict['l_g_pix'] = l_g_pix
325
+
326
+ # image pyramid loss
327
+ if pyramid_loss_weight > 0:
328
+ for i in range(0, self.log_size - 2):
329
+ l_pyramid = self.cri_l1(out_rgbs[i], pyramid_gt[i]) * pyramid_loss_weight
330
+ l_g_total += l_pyramid
331
+ loss_dict[f'l_p_{2**(i+3)}'] = l_pyramid
332
+
333
+ # perceptual loss
334
+ if self.cri_perceptual:
335
+ l_g_percep, l_g_style = self.cri_perceptual(self.output, self.gt)
336
+ if l_g_percep is not None:
337
+ l_g_total += l_g_percep
338
+ loss_dict['l_g_percep'] = l_g_percep
339
+ if l_g_style is not None:
340
+ l_g_total += l_g_style
341
+ loss_dict['l_g_style'] = l_g_style
342
+
343
+ # gan loss
344
+ fake_g_pred = self.net_d(self.output)
345
+ l_g_gan = self.cri_gan(fake_g_pred, True, is_disc=False)
346
+ l_g_total += l_g_gan
347
+ loss_dict['l_g_gan'] = l_g_gan
348
+
349
+ # facial component loss
350
+ if self.use_facial_disc:
351
+ # left eye
352
+ fake_left_eye, fake_left_eye_feats = self.net_d_left_eye(self.left_eyes, return_feats=True)
353
+ l_g_gan = self.cri_component(fake_left_eye, True, is_disc=False)
354
+ l_g_total += l_g_gan
355
+ loss_dict['l_g_gan_left_eye'] = l_g_gan
356
+ # right eye
357
+ fake_right_eye, fake_right_eye_feats = self.net_d_right_eye(self.right_eyes, return_feats=True)
358
+ l_g_gan = self.cri_component(fake_right_eye, True, is_disc=False)
359
+ l_g_total += l_g_gan
360
+ loss_dict['l_g_gan_right_eye'] = l_g_gan
361
+ # mouth
362
+ fake_mouth, fake_mouth_feats = self.net_d_mouth(self.mouths, return_feats=True)
363
+ l_g_gan = self.cri_component(fake_mouth, True, is_disc=False)
364
+ l_g_total += l_g_gan
365
+ loss_dict['l_g_gan_mouth'] = l_g_gan
366
+
367
+ if self.opt['train'].get('comp_style_weight', 0) > 0:
368
+ # get gt feat
369
+ _, real_left_eye_feats = self.net_d_left_eye(self.left_eyes_gt, return_feats=True)
370
+ _, real_right_eye_feats = self.net_d_right_eye(self.right_eyes_gt, return_feats=True)
371
+ _, real_mouth_feats = self.net_d_mouth(self.mouths_gt, return_feats=True)
372
+
373
+ def _comp_style(feat, feat_gt, criterion):
374
+ return criterion(self._gram_mat(feat[0]), self._gram_mat(
375
+ feat_gt[0].detach())) * 0.5 + criterion(
376
+ self._gram_mat(feat[1]), self._gram_mat(feat_gt[1].detach()))
377
+
378
+ # facial component style loss
379
+ comp_style_loss = 0
380
+ comp_style_loss += _comp_style(fake_left_eye_feats, real_left_eye_feats, self.cri_l1)
381
+ comp_style_loss += _comp_style(fake_right_eye_feats, real_right_eye_feats, self.cri_l1)
382
+ comp_style_loss += _comp_style(fake_mouth_feats, real_mouth_feats, self.cri_l1)
383
+ comp_style_loss = comp_style_loss * self.opt['train']['comp_style_weight']
384
+ l_g_total += comp_style_loss
385
+ loss_dict['l_g_comp_style_loss'] = comp_style_loss
386
+
387
+ # identity loss
388
+ if self.use_identity:
389
+ identity_weight = self.opt['train']['identity_weight']
390
+ # get gray images and resize
391
+ out_gray = self.gray_resize_for_identity(self.output)
392
+ gt_gray = self.gray_resize_for_identity(self.gt)
393
+
394
+ identity_gt = self.network_identity(gt_gray).detach()
395
+ identity_out = self.network_identity(out_gray)
396
+ l_identity = self.cri_l1(identity_out, identity_gt) * identity_weight
397
+ l_g_total += l_identity
398
+ loss_dict['l_identity'] = l_identity
399
+
400
+ l_g_total.backward()
401
+ self.optimizer_g.step()
402
+
403
+ # EMA
404
+ self.model_ema(decay=0.5**(32 / (10 * 1000)))
405
+
406
+ # ----------- optimize net_d ----------- #
407
+ for p in self.net_d.parameters():
408
+ p.requires_grad = True
409
+ self.optimizer_d.zero_grad()
410
+ if self.use_facial_disc:
411
+ for p in self.net_d_left_eye.parameters():
412
+ p.requires_grad = True
413
+ for p in self.net_d_right_eye.parameters():
414
+ p.requires_grad = True
415
+ for p in self.net_d_mouth.parameters():
416
+ p.requires_grad = True
417
+ self.optimizer_d_left_eye.zero_grad()
418
+ self.optimizer_d_right_eye.zero_grad()
419
+ self.optimizer_d_mouth.zero_grad()
420
+
421
+ fake_d_pred = self.net_d(self.output.detach())
422
+ real_d_pred = self.net_d(self.gt)
423
+ l_d = self.cri_gan(real_d_pred, True, is_disc=True) + self.cri_gan(fake_d_pred, False, is_disc=True)
424
+ loss_dict['l_d'] = l_d
425
+ # In WGAN, real_score should be positive and fake_score should be negative
426
+ loss_dict['real_score'] = real_d_pred.detach().mean()
427
+ loss_dict['fake_score'] = fake_d_pred.detach().mean()
428
+ l_d.backward()
429
+
430
+ # regularization loss
431
+ if current_iter % self.net_d_reg_every == 0:
432
+ self.gt.requires_grad = True
433
+ real_pred = self.net_d(self.gt)
434
+ l_d_r1 = r1_penalty(real_pred, self.gt)
435
+ l_d_r1 = (self.r1_reg_weight / 2 * l_d_r1 * self.net_d_reg_every + 0 * real_pred[0])
436
+ loss_dict['l_d_r1'] = l_d_r1.detach().mean()
437
+ l_d_r1.backward()
438
+
439
+ self.optimizer_d.step()
440
+
441
+ # optimize facial component discriminators
442
+ if self.use_facial_disc:
443
+ # left eye
444
+ fake_d_pred, _ = self.net_d_left_eye(self.left_eyes.detach())
445
+ real_d_pred, _ = self.net_d_left_eye(self.left_eyes_gt)
446
+ l_d_left_eye = self.cri_component(
447
+ real_d_pred, True, is_disc=True) + self.cri_gan(
448
+ fake_d_pred, False, is_disc=True)
449
+ loss_dict['l_d_left_eye'] = l_d_left_eye
450
+ l_d_left_eye.backward()
451
+ # right eye
452
+ fake_d_pred, _ = self.net_d_right_eye(self.right_eyes.detach())
453
+ real_d_pred, _ = self.net_d_right_eye(self.right_eyes_gt)
454
+ l_d_right_eye = self.cri_component(
455
+ real_d_pred, True, is_disc=True) + self.cri_gan(
456
+ fake_d_pred, False, is_disc=True)
457
+ loss_dict['l_d_right_eye'] = l_d_right_eye
458
+ l_d_right_eye.backward()
459
+ # mouth
460
+ fake_d_pred, _ = self.net_d_mouth(self.mouths.detach())
461
+ real_d_pred, _ = self.net_d_mouth(self.mouths_gt)
462
+ l_d_mouth = self.cri_component(
463
+ real_d_pred, True, is_disc=True) + self.cri_gan(
464
+ fake_d_pred, False, is_disc=True)
465
+ loss_dict['l_d_mouth'] = l_d_mouth
466
+ l_d_mouth.backward()
467
+
468
+ self.optimizer_d_left_eye.step()
469
+ self.optimizer_d_right_eye.step()
470
+ self.optimizer_d_mouth.step()
471
+
472
+ self.log_dict = self.reduce_loss_dict(loss_dict)
473
+
474
+ def test(self):
475
+ with torch.no_grad():
476
+ if hasattr(self, 'net_g_ema'):
477
+ self.net_g_ema.eval()
478
+ self.output, _ = self.net_g_ema(self.lq)
479
+ else:
480
+ logger = get_root_logger()
481
+ logger.warning('Do not have self.net_g_ema, use self.net_g.')
482
+ self.net_g.eval()
483
+ self.output, _ = self.net_g(self.lq)
484
+ self.net_g.train()
485
+
486
+ def dist_validation(self, dataloader, current_iter, tb_logger, save_img):
487
+ if self.opt['rank'] == 0:
488
+ self.nondist_validation(dataloader, current_iter, tb_logger, save_img)
489
+
490
+ def nondist_validation(self, dataloader, current_iter, tb_logger, save_img):
491
+ dataset_name = dataloader.dataset.opt['name']
492
+ with_metrics = self.opt['val'].get('metrics') is not None
493
+ use_pbar = self.opt['val'].get('pbar', False)
494
+
495
+ if with_metrics:
496
+ if not hasattr(self, 'metric_results'): # only execute in the first run
497
+ self.metric_results = {metric: 0 for metric in self.opt['val']['metrics'].keys()}
498
+ # initialize the best metric results for each dataset_name (supporting multiple validation datasets)
499
+ self._initialize_best_metric_results(dataset_name)
500
+ # zero self.metric_results
501
+ self.metric_results = {metric: 0 for metric in self.metric_results}
502
+
503
+ metric_data = dict()
504
+ if use_pbar:
505
+ pbar = tqdm(total=len(dataloader), unit='image')
506
+
507
+ for idx, val_data in enumerate(dataloader):
508
+ img_name = osp.splitext(osp.basename(val_data['lq_path'][0]))[0]
509
+ self.feed_data(val_data)
510
+ self.test()
511
+
512
+ sr_img = tensor2img(self.output.detach().cpu(), min_max=(-1, 1))
513
+ metric_data['img'] = sr_img
514
+ if hasattr(self, 'gt'):
515
+ gt_img = tensor2img(self.gt.detach().cpu(), min_max=(-1, 1))
516
+ metric_data['img2'] = gt_img
517
+ del self.gt
518
+
519
+ # tentative for out of GPU memory
520
+ del self.lq
521
+ del self.output
522
+ torch.cuda.empty_cache()
523
+
524
+ if save_img:
525
+ if self.opt['is_train']:
526
+ save_img_path = osp.join(self.opt['path']['visualization'], img_name,
527
+ f'{img_name}_{current_iter}.png')
528
+ else:
529
+ if self.opt['val']['suffix']:
530
+ save_img_path = osp.join(self.opt['path']['visualization'], dataset_name,
531
+ f'{img_name}_{self.opt["val"]["suffix"]}.png')
532
+ else:
533
+ save_img_path = osp.join(self.opt['path']['visualization'], dataset_name,
534
+ f'{img_name}_{self.opt["name"]}.png')
535
+ imwrite(sr_img, save_img_path)
536
+
537
+ if with_metrics:
538
+ # calculate metrics
539
+ for name, opt_ in self.opt['val']['metrics'].items():
540
+ self.metric_results[name] += calculate_metric(metric_data, opt_)
541
+ if use_pbar:
542
+ pbar.update(1)
543
+ pbar.set_description(f'Test {img_name}')
544
+ if use_pbar:
545
+ pbar.close()
546
+
547
+ if with_metrics:
548
+ for metric in self.metric_results.keys():
549
+ self.metric_results[metric] /= (idx + 1)
550
+ # update the best metric result
551
+ self._update_best_metric_result(dataset_name, metric, self.metric_results[metric], current_iter)
552
+
553
+ self._log_validation_metric_values(current_iter, dataset_name, tb_logger)
554
+
555
+ def _log_validation_metric_values(self, current_iter, dataset_name, tb_logger):
556
+ log_str = f'Validation {dataset_name}\n'
557
+ for metric, value in self.metric_results.items():
558
+ log_str += f'\t # {metric}: {value:.4f}'
559
+ if hasattr(self, 'best_metric_results'):
560
+ log_str += (f'\tBest: {self.best_metric_results[dataset_name][metric]["val"]:.4f} @ '
561
+ f'{self.best_metric_results[dataset_name][metric]["iter"]} iter')
562
+ log_str += '\n'
563
+
564
+ logger = get_root_logger()
565
+ logger.info(log_str)
566
+ if tb_logger:
567
+ for metric, value in self.metric_results.items():
568
+ tb_logger.add_scalar(f'metrics/{dataset_name}/{metric}', value, current_iter)
569
+
570
+ def save(self, epoch, current_iter):
571
+ # save net_g and net_d
572
+ self.save_network([self.net_g, self.net_g_ema], 'net_g', current_iter, param_key=['params', 'params_ema'])
573
+ self.save_network(self.net_d, 'net_d', current_iter)
574
+ # save component discriminators
575
+ if self.use_facial_disc:
576
+ self.save_network(self.net_d_left_eye, 'net_d_left_eye', current_iter)
577
+ self.save_network(self.net_d_right_eye, 'net_d_right_eye', current_iter)
578
+ self.save_network(self.net_d_mouth, 'net_d_mouth', current_iter)
579
+ # save training state
580
+ self.save_training_state(epoch, current_iter)
video-tetalking/third_part/GFPGAN/gfpgan/train.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # flake8: noqa
2
+ import os.path as osp
3
+ from basicsr.train import train_pipeline
4
+
5
+ import gfpgan.archs
6
+ import gfpgan.data
7
+ import gfpgan.models
8
+
9
+ if __name__ == '__main__':
10
+ root_path = osp.abspath(osp.join(__file__, osp.pardir, osp.pardir))
11
+ train_pipeline(root_path)
video-tetalking/third_part/GFPGAN/gfpgan/utils.py ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import os
3
+ import torch
4
+ from basicsr.utils import img2tensor, tensor2img
5
+ from basicsr.utils.download_util import load_file_from_url
6
+ from facexlib.utils.face_restoration_helper import FaceRestoreHelper
7
+ from torchvision.transforms.functional import normalize
8
+
9
+ from gfpgan.archs.gfpgan_bilinear_arch import GFPGANBilinear
10
+ from gfpgan.archs.gfpganv1_arch import GFPGANv1
11
+ from gfpgan.archs.gfpganv1_clean_arch import GFPGANv1Clean
12
+
13
+ ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
14
+
15
+
16
+ class GFPGANer():
17
+ """Helper for restoration with GFPGAN.
18
+
19
+ It will detect and crop faces, and then resize the faces to 512x512.
20
+ GFPGAN is used to restored the resized faces.
21
+ The background is upsampled with the bg_upsampler.
22
+ Finally, the faces will be pasted back to the upsample background image.
23
+
24
+ Args:
25
+ model_path (str): The path to the GFPGAN model. It can be urls (will first download it automatically).
26
+ upscale (float): The upscale of the final output. Default: 2.
27
+ arch (str): The GFPGAN architecture. Option: clean | original. Default: clean.
28
+ channel_multiplier (int): Channel multiplier for large networks of StyleGAN2. Default: 2.
29
+ bg_upsampler (nn.Module): The upsampler for the background. Default: None.
30
+ """
31
+
32
+ def __init__(self, model_path, upscale=2, arch='clean', channel_multiplier=2, bg_upsampler=None):
33
+ self.upscale = upscale
34
+ self.bg_upsampler = bg_upsampler
35
+
36
+ # initialize model
37
+ self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
38
+ # initialize the GFP-GAN
39
+ if arch == 'clean':
40
+ self.gfpgan = GFPGANv1Clean(
41
+ out_size=512,
42
+ num_style_feat=512,
43
+ channel_multiplier=channel_multiplier,
44
+ decoder_load_path=None,
45
+ fix_decoder=False,
46
+ num_mlp=8,
47
+ input_is_latent=True,
48
+ different_w=True,
49
+ narrow=1,
50
+ sft_half=True)
51
+ elif arch == 'bilinear':
52
+ self.gfpgan = GFPGANBilinear(
53
+ out_size=512,
54
+ num_style_feat=512,
55
+ channel_multiplier=channel_multiplier,
56
+ decoder_load_path=None,
57
+ fix_decoder=False,
58
+ num_mlp=8,
59
+ input_is_latent=True,
60
+ different_w=True,
61
+ narrow=1,
62
+ sft_half=True)
63
+ elif arch == 'original':
64
+ self.gfpgan = GFPGANv1(
65
+ out_size=512,
66
+ num_style_feat=512,
67
+ channel_multiplier=channel_multiplier,
68
+ decoder_load_path=None,
69
+ fix_decoder=True,
70
+ num_mlp=8,
71
+ input_is_latent=True,
72
+ different_w=True,
73
+ narrow=1,
74
+ sft_half=True)
75
+ # initialize face helper
76
+ self.face_helper = FaceRestoreHelper(
77
+ upscale,
78
+ face_size=512,
79
+ crop_ratio=(1, 1),
80
+ det_model='retinaface_resnet50',
81
+ save_ext='png',
82
+ device=self.device)
83
+
84
+ if model_path.startswith('https://'):
85
+ model_path = load_file_from_url(
86
+ url=model_path, model_dir=os.path.join(ROOT_DIR, 'gfpgan/weights'), progress=True, file_name=None)
87
+ loadnet = torch.load(model_path)
88
+ if 'params_ema' in loadnet:
89
+ keyname = 'params_ema'
90
+ else:
91
+ keyname = 'params'
92
+ self.gfpgan.load_state_dict(loadnet[keyname], strict=True)
93
+ self.gfpgan.eval()
94
+ self.gfpgan = self.gfpgan.to(self.device)
95
+
96
+ @torch.no_grad()
97
+ def enhance(self, img, has_aligned=False, only_center_face=False, paste_back=True):
98
+ self.face_helper.clean_all()
99
+
100
+ if has_aligned: # the inputs are already aligned
101
+ img = cv2.resize(img, (512, 512))
102
+ self.face_helper.cropped_faces = [img]
103
+ else:
104
+ self.face_helper.read_image(img)
105
+ # get face landmarks for each face
106
+ self.face_helper.get_face_landmarks_5(only_center_face=only_center_face, eye_dist_threshold=5)
107
+ # eye_dist_threshold=5: skip faces whose eye distance is smaller than 5 pixels
108
+ # TODO: even with eye_dist_threshold, it will still introduce wrong detections and restorations.
109
+ # align and warp each face
110
+ self.face_helper.align_warp_face()
111
+
112
+ # face restoration
113
+ for cropped_face in self.face_helper.cropped_faces:
114
+ # prepare data
115
+ cropped_face_t = img2tensor(cropped_face / 255., bgr2rgb=True, float32=True)
116
+ normalize(cropped_face_t, (0.5, 0.5, 0.5), (0.5, 0.5, 0.5), inplace=True)
117
+ cropped_face_t = cropped_face_t.unsqueeze(0).to(self.device)
118
+
119
+ try:
120
+ output = self.gfpgan(cropped_face_t, return_rgb=False)[0]
121
+ # convert to image
122
+ restored_face = tensor2img(output.squeeze(0), rgb2bgr=True, min_max=(-1, 1))
123
+ except RuntimeError as error:
124
+ print(f'\tFailed inference for GFPGAN: {error}.')
125
+ restored_face = cropped_face
126
+
127
+ restored_face = restored_face.astype('uint8')
128
+ self.face_helper.add_restored_face(restored_face)
129
+
130
+ if not has_aligned and paste_back:
131
+ # upsample the background
132
+ if self.bg_upsampler is not None:
133
+ # Now only support RealESRGAN for upsampling background
134
+ bg_img = self.bg_upsampler.enhance(img, outscale=self.upscale)[0]
135
+ else:
136
+ bg_img = None
137
+
138
+ self.face_helper.get_inverse_affine(None)
139
+ # paste each restored face to the input image
140
+ restored_img = self.face_helper.paste_faces_to_input_image(upsample_img=bg_img)
141
+ return self.face_helper.cropped_faces, self.face_helper.restored_faces, restored_img
142
+ else:
143
+ return self.face_helper.cropped_faces, self.face_helper.restored_faces, None
video-tetalking/third_part/GFPGAN/gfpgan/version.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # GENERATED VERSION FILE
2
+ # TIME: Wed Apr 20 14:43:06 2022
3
+ __version__ = '1.3.2'
4
+ __gitsha__ = '924ce47'
5
+ version_info = (1, 3, 2)
video-tetalking/third_part/GFPGAN/gfpgan/weights/README.md ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Weights
2
+
3
+ Put the downloaded weights to this folder.
video-tetalking/third_part/GFPGAN/options/train_gfpgan_v1.yml ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # general settings
2
+ name: train_GFPGANv1_512
3
+ model_type: GFPGANModel
4
+ num_gpu: auto # officially, we use 4 GPUs
5
+ manual_seed: 0
6
+
7
+ # dataset and data loader settings
8
+ datasets:
9
+ train:
10
+ name: FFHQ
11
+ type: FFHQDegradationDataset
12
+ # dataroot_gt: datasets/ffhq/ffhq_512.lmdb
13
+ dataroot_gt: datasets/ffhq/ffhq_512
14
+ io_backend:
15
+ # type: lmdb
16
+ type: disk
17
+
18
+ use_hflip: true
19
+ mean: [0.5, 0.5, 0.5]
20
+ std: [0.5, 0.5, 0.5]
21
+ out_size: 512
22
+
23
+ blur_kernel_size: 41
24
+ kernel_list: ['iso', 'aniso']
25
+ kernel_prob: [0.5, 0.5]
26
+ blur_sigma: [0.1, 10]
27
+ downsample_range: [0.8, 8]
28
+ noise_range: [0, 20]
29
+ jpeg_range: [60, 100]
30
+
31
+ # color jitter and gray
32
+ color_jitter_prob: 0.3
33
+ color_jitter_shift: 20
34
+ color_jitter_pt_prob: 0.3
35
+ gray_prob: 0.01
36
+
37
+ # If you do not want colorization, please set
38
+ # color_jitter_prob: ~
39
+ # color_jitter_pt_prob: ~
40
+ # gray_prob: 0.01
41
+ # gt_gray: True
42
+
43
+ crop_components: true
44
+ component_path: experiments/pretrained_models/FFHQ_eye_mouth_landmarks_512.pth
45
+ eye_enlarge_ratio: 1.4
46
+
47
+ # data loader
48
+ use_shuffle: true
49
+ num_worker_per_gpu: 6
50
+ batch_size_per_gpu: 3
51
+ dataset_enlarge_ratio: 1
52
+ prefetch_mode: ~
53
+
54
+ val:
55
+ # Please modify accordingly to use your own validation
56
+ # Or comment the val block if do not need validation during training
57
+ name: validation
58
+ type: PairedImageDataset
59
+ dataroot_lq: datasets/faces/validation/input
60
+ dataroot_gt: datasets/faces/validation/reference
61
+ io_backend:
62
+ type: disk
63
+ mean: [0.5, 0.5, 0.5]
64
+ std: [0.5, 0.5, 0.5]
65
+ scale: 1
66
+
67
+ # network structures
68
+ network_g:
69
+ type: GFPGANv1
70
+ out_size: 512
71
+ num_style_feat: 512
72
+ channel_multiplier: 1
73
+ resample_kernel: [1, 3, 3, 1]
74
+ decoder_load_path: experiments/pretrained_models/StyleGAN2_512_Cmul1_FFHQ_B12G4_scratch_800k.pth
75
+ fix_decoder: true
76
+ num_mlp: 8
77
+ lr_mlp: 0.01
78
+ input_is_latent: true
79
+ different_w: true
80
+ narrow: 1
81
+ sft_half: true
82
+
83
+ network_d:
84
+ type: StyleGAN2Discriminator
85
+ out_size: 512
86
+ channel_multiplier: 1
87
+ resample_kernel: [1, 3, 3, 1]
88
+
89
+ network_d_left_eye:
90
+ type: FacialComponentDiscriminator
91
+
92
+ network_d_right_eye:
93
+ type: FacialComponentDiscriminator
94
+
95
+ network_d_mouth:
96
+ type: FacialComponentDiscriminator
97
+
98
+ network_identity:
99
+ type: ResNetArcFace
100
+ block: IRBlock
101
+ layers: [2, 2, 2, 2]
102
+ use_se: False
103
+
104
+ # path
105
+ path:
106
+ pretrain_network_g: ~
107
+ param_key_g: params_ema
108
+ strict_load_g: ~
109
+ pretrain_network_d: ~
110
+ pretrain_network_d_left_eye: ~
111
+ pretrain_network_d_right_eye: ~
112
+ pretrain_network_d_mouth: ~
113
+ pretrain_network_identity: experiments/pretrained_models/arcface_resnet18.pth
114
+ # resume
115
+ resume_state: ~
116
+ ignore_resume_networks: ['network_identity']
117
+
118
+ # training settings
119
+ train:
120
+ optim_g:
121
+ type: Adam
122
+ lr: !!float 2e-3
123
+ optim_d:
124
+ type: Adam
125
+ lr: !!float 2e-3
126
+ optim_component:
127
+ type: Adam
128
+ lr: !!float 2e-3
129
+
130
+ scheduler:
131
+ type: MultiStepLR
132
+ milestones: [600000, 700000]
133
+ gamma: 0.5
134
+
135
+ total_iter: 800000
136
+ warmup_iter: -1 # no warm up
137
+
138
+ # losses
139
+ # pixel loss
140
+ pixel_opt:
141
+ type: L1Loss
142
+ loss_weight: !!float 1e-1
143
+ reduction: mean
144
+ # L1 loss used in pyramid loss, component style loss and identity loss
145
+ L1_opt:
146
+ type: L1Loss
147
+ loss_weight: 1
148
+ reduction: mean
149
+
150
+ # image pyramid loss
151
+ pyramid_loss_weight: 1
152
+ remove_pyramid_loss: 50000
153
+ # perceptual loss (content and style losses)
154
+ perceptual_opt:
155
+ type: PerceptualLoss
156
+ layer_weights:
157
+ # before relu
158
+ 'conv1_2': 0.1
159
+ 'conv2_2': 0.1
160
+ 'conv3_4': 1
161
+ 'conv4_4': 1
162
+ 'conv5_4': 1
163
+ vgg_type: vgg19
164
+ use_input_norm: true
165
+ perceptual_weight: !!float 1
166
+ style_weight: 50
167
+ range_norm: true
168
+ criterion: l1
169
+ # gan loss
170
+ gan_opt:
171
+ type: GANLoss
172
+ gan_type: wgan_softplus
173
+ loss_weight: !!float 1e-1
174
+ # r1 regularization for discriminator
175
+ r1_reg_weight: 10
176
+ # facial component loss
177
+ gan_component_opt:
178
+ type: GANLoss
179
+ gan_type: vanilla
180
+ real_label_val: 1.0
181
+ fake_label_val: 0.0
182
+ loss_weight: !!float 1
183
+ comp_style_weight: 200
184
+ # identity loss
185
+ identity_weight: 10
186
+
187
+ net_d_iters: 1
188
+ net_d_init_iters: 0
189
+ net_d_reg_every: 16
190
+
191
+ # validation settings
192
+ val:
193
+ val_freq: !!float 5e3
194
+ save_img: true
195
+
196
+ metrics:
197
+ psnr: # metric name
198
+ type: calculate_psnr
199
+ crop_border: 0
200
+ test_y_channel: false
201
+
202
+ # logging settings
203
+ logger:
204
+ print_freq: 100
205
+ save_checkpoint_freq: !!float 5e3
206
+ use_tb_logger: true
207
+ wandb:
208
+ project: ~
209
+ resume_id: ~
210
+
211
+ # dist training settings
212
+ dist_params:
213
+ backend: nccl
214
+ port: 29500
215
+
216
+ find_unused_parameters: true
video-tetalking/third_part/GFPGAN/options/train_gfpgan_v1_simple.yml ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # general settings
2
+ name: train_GFPGANv1_512_simple
3
+ model_type: GFPGANModel
4
+ num_gpu: auto # officially, we use 4 GPUs
5
+ manual_seed: 0
6
+
7
+ # dataset and data loader settings
8
+ datasets:
9
+ train:
10
+ name: FFHQ
11
+ type: FFHQDegradationDataset
12
+ # dataroot_gt: datasets/ffhq/ffhq_512.lmdb
13
+ dataroot_gt: datasets/ffhq/ffhq_512
14
+ io_backend:
15
+ # type: lmdb
16
+ type: disk
17
+
18
+ use_hflip: true
19
+ mean: [0.5, 0.5, 0.5]
20
+ std: [0.5, 0.5, 0.5]
21
+ out_size: 512
22
+
23
+ blur_kernel_size: 41
24
+ kernel_list: ['iso', 'aniso']
25
+ kernel_prob: [0.5, 0.5]
26
+ blur_sigma: [0.1, 10]
27
+ downsample_range: [0.8, 8]
28
+ noise_range: [0, 20]
29
+ jpeg_range: [60, 100]
30
+
31
+ # color jitter and gray
32
+ color_jitter_prob: 0.3
33
+ color_jitter_shift: 20
34
+ color_jitter_pt_prob: 0.3
35
+ gray_prob: 0.01
36
+
37
+ # If you do not want colorization, please set
38
+ # color_jitter_prob: ~
39
+ # color_jitter_pt_prob: ~
40
+ # gray_prob: 0.01
41
+ # gt_gray: True
42
+
43
+ # data loader
44
+ use_shuffle: true
45
+ num_worker_per_gpu: 6
46
+ batch_size_per_gpu: 3
47
+ dataset_enlarge_ratio: 1
48
+ prefetch_mode: ~
49
+
50
+ val:
51
+ # Please modify accordingly to use your own validation
52
+ # Or comment the val block if do not need validation during training
53
+ name: validation
54
+ type: PairedImageDataset
55
+ dataroot_lq: datasets/faces/validation/input
56
+ dataroot_gt: datasets/faces/validation/reference
57
+ io_backend:
58
+ type: disk
59
+ mean: [0.5, 0.5, 0.5]
60
+ std: [0.5, 0.5, 0.5]
61
+ scale: 1
62
+
63
+ # network structures
64
+ network_g:
65
+ type: GFPGANv1
66
+ out_size: 512
67
+ num_style_feat: 512
68
+ channel_multiplier: 1
69
+ resample_kernel: [1, 3, 3, 1]
70
+ decoder_load_path: experiments/pretrained_models/StyleGAN2_512_Cmul1_FFHQ_B12G4_scratch_800k.pth
71
+ fix_decoder: true
72
+ num_mlp: 8
73
+ lr_mlp: 0.01
74
+ input_is_latent: true
75
+ different_w: true
76
+ narrow: 1
77
+ sft_half: true
78
+
79
+ network_d:
80
+ type: StyleGAN2Discriminator
81
+ out_size: 512
82
+ channel_multiplier: 1
83
+ resample_kernel: [1, 3, 3, 1]
84
+
85
+
86
+ # path
87
+ path:
88
+ pretrain_network_g: ~
89
+ param_key_g: params_ema
90
+ strict_load_g: ~
91
+ pretrain_network_d: ~
92
+ resume_state: ~
93
+
94
+ # training settings
95
+ train:
96
+ optim_g:
97
+ type: Adam
98
+ lr: !!float 2e-3
99
+ optim_d:
100
+ type: Adam
101
+ lr: !!float 2e-3
102
+ optim_component:
103
+ type: Adam
104
+ lr: !!float 2e-3
105
+
106
+ scheduler:
107
+ type: MultiStepLR
108
+ milestones: [600000, 700000]
109
+ gamma: 0.5
110
+
111
+ total_iter: 800000
112
+ warmup_iter: -1 # no warm up
113
+
114
+ # losses
115
+ # pixel loss
116
+ pixel_opt:
117
+ type: L1Loss
118
+ loss_weight: !!float 1e-1
119
+ reduction: mean
120
+ # L1 loss used in pyramid loss, component style loss and identity loss
121
+ L1_opt:
122
+ type: L1Loss
123
+ loss_weight: 1
124
+ reduction: mean
125
+
126
+ # image pyramid loss
127
+ pyramid_loss_weight: 1
128
+ remove_pyramid_loss: 50000
129
+ # perceptual loss (content and style losses)
130
+ perceptual_opt:
131
+ type: PerceptualLoss
132
+ layer_weights:
133
+ # before relu
134
+ 'conv1_2': 0.1
135
+ 'conv2_2': 0.1
136
+ 'conv3_4': 1
137
+ 'conv4_4': 1
138
+ 'conv5_4': 1
139
+ vgg_type: vgg19
140
+ use_input_norm: true
141
+ perceptual_weight: !!float 1
142
+ style_weight: 50
143
+ range_norm: true
144
+ criterion: l1
145
+ # gan loss
146
+ gan_opt:
147
+ type: GANLoss
148
+ gan_type: wgan_softplus
149
+ loss_weight: !!float 1e-1
150
+ # r1 regularization for discriminator
151
+ r1_reg_weight: 10
152
+
153
+ net_d_iters: 1
154
+ net_d_init_iters: 0
155
+ net_d_reg_every: 16
156
+
157
+ # validation settings
158
+ val:
159
+ val_freq: !!float 5e3
160
+ save_img: true
161
+
162
+ metrics:
163
+ psnr: # metric name
164
+ type: calculate_psnr
165
+ crop_border: 0
166
+ test_y_channel: false
167
+
168
+ # logging settings
169
+ logger:
170
+ print_freq: 100
171
+ save_checkpoint_freq: !!float 5e3
172
+ use_tb_logger: true
173
+ wandb:
174
+ project: ~
175
+ resume_id: ~
176
+
177
+ # dist training settings
178
+ dist_params:
179
+ backend: nccl
180
+ port: 29500
181
+
182
+ find_unused_parameters: true
video-tetalking/third_part/GPEN/align_faces.py ADDED
@@ -0,0 +1,271 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on Mon Apr 24 15:43:29 2017
4
+ @author: zhaoy
5
+ """
6
+ """
7
+ @Modified by yangxy (yangtao9009@gmail.com)
8
+ """
9
+ import cv2
10
+ import numpy as np
11
+ from skimage import transform as trans
12
+
13
+ # reference facial points, a list of coordinates (x,y)
14
+ REFERENCE_FACIAL_POINTS = [
15
+ [30.29459953, 51.69630051],
16
+ [65.53179932, 51.50139999],
17
+ [48.02519989, 71.73660278],
18
+ [33.54930115, 92.3655014],
19
+ [62.72990036, 92.20410156]
20
+ ]
21
+
22
+ DEFAULT_CROP_SIZE = (96, 112)
23
+
24
+
25
+ def _umeyama(src, dst, estimate_scale=True, scale=1.0):
26
+ """Estimate N-D similarity transformation with or without scaling.
27
+ Parameters
28
+ ----------
29
+ src : (M, N) array
30
+ Source coordinates.
31
+ dst : (M, N) array
32
+ Destination coordinates.
33
+ estimate_scale : bool
34
+ Whether to estimate scaling factor.
35
+ Returns
36
+ -------
37
+ T : (N + 1, N + 1)
38
+ The homogeneous similarity transformation matrix. The matrix contains
39
+ NaN values only if the problem is not well-conditioned.
40
+ References
41
+ ----------
42
+ .. [1] "Least-squares estimation of transformation parameters between two
43
+ point patterns", Shinji Umeyama, PAMI 1991, :DOI:`10.1109/34.88573`
44
+ """
45
+
46
+ num = src.shape[0]
47
+ dim = src.shape[1]
48
+
49
+ # Compute mean of src and dst.
50
+ src_mean = src.mean(axis=0)
51
+ dst_mean = dst.mean(axis=0)
52
+
53
+ # Subtract mean from src and dst.
54
+ src_demean = src - src_mean
55
+ dst_demean = dst - dst_mean
56
+
57
+ # Eq. (38).
58
+ A = dst_demean.T @ src_demean / num
59
+
60
+ # Eq. (39).
61
+ d = np.ones((dim,), dtype=np.double)
62
+ if np.linalg.det(A) < 0:
63
+ d[dim - 1] = -1
64
+
65
+ T = np.eye(dim + 1, dtype=np.double)
66
+
67
+ U, S, V = np.linalg.svd(A)
68
+
69
+ # Eq. (40) and (43).
70
+ rank = np.linalg.matrix_rank(A)
71
+ if rank == 0:
72
+ return np.nan * T
73
+ elif rank == dim - 1:
74
+ if np.linalg.det(U) * np.linalg.det(V) > 0:
75
+ T[:dim, :dim] = U @ V
76
+ else:
77
+ s = d[dim - 1]
78
+ d[dim - 1] = -1
79
+ T[:dim, :dim] = U @ np.diag(d) @ V
80
+ d[dim - 1] = s
81
+ else:
82
+ T[:dim, :dim] = U @ np.diag(d) @ V
83
+
84
+ if estimate_scale:
85
+ # Eq. (41) and (42).
86
+ scale = 1.0 / src_demean.var(axis=0).sum() * (S @ d)
87
+ else:
88
+ scale = scale
89
+
90
+ T[:dim, dim] = dst_mean - scale * (T[:dim, :dim] @ src_mean.T)
91
+ T[:dim, :dim] *= scale
92
+
93
+ return T, scale
94
+
95
+
96
+ class FaceWarpException(Exception):
97
+ def __str__(self):
98
+ return 'In File {}:{}'.format(
99
+ __file__, super.__str__(self))
100
+
101
+
102
+ def get_reference_facial_points(output_size=None,
103
+ inner_padding_factor=0.0,
104
+ outer_padding=(0, 0),
105
+ default_square=False):
106
+ tmp_5pts = np.array(REFERENCE_FACIAL_POINTS)
107
+ tmp_crop_size = np.array(DEFAULT_CROP_SIZE)
108
+
109
+ # 0) make the inner region a square
110
+ if default_square:
111
+ size_diff = max(tmp_crop_size) - tmp_crop_size
112
+ tmp_5pts += size_diff / 2
113
+ tmp_crop_size += size_diff
114
+
115
+ if (output_size and
116
+ output_size[0] == tmp_crop_size[0] and
117
+ output_size[1] == tmp_crop_size[1]):
118
+ print('output_size == DEFAULT_CROP_SIZE {}: return default reference points'.format(tmp_crop_size))
119
+ return tmp_5pts
120
+
121
+ if (inner_padding_factor == 0 and
122
+ outer_padding == (0, 0)):
123
+ if output_size is None:
124
+ print('No paddings to do: return default reference points')
125
+ return tmp_5pts
126
+ else:
127
+ raise FaceWarpException(
128
+ 'No paddings to do, output_size must be None or {}'.format(tmp_crop_size))
129
+
130
+ # check output size
131
+ if not (0 <= inner_padding_factor <= 1.0):
132
+ raise FaceWarpException('Not (0 <= inner_padding_factor <= 1.0)')
133
+
134
+ if ((inner_padding_factor > 0 or outer_padding[0] > 0 or outer_padding[1] > 0)
135
+ and output_size is None):
136
+ output_size = tmp_crop_size * \
137
+ (1 + inner_padding_factor * 2).astype(np.int32)
138
+ output_size += np.array(outer_padding)
139
+ print(' deduced from paddings, output_size = ', output_size)
140
+
141
+ if not (outer_padding[0] < output_size[0]
142
+ and outer_padding[1] < output_size[1]):
143
+ raise FaceWarpException('Not (outer_padding[0] < output_size[0]'
144
+ 'and outer_padding[1] < output_size[1])')
145
+
146
+ # 1) pad the inner region according inner_padding_factor
147
+ # print('---> STEP1: pad the inner region according inner_padding_factor')
148
+ if inner_padding_factor > 0:
149
+ size_diff = tmp_crop_size * inner_padding_factor * 2
150
+ tmp_5pts += size_diff / 2
151
+ tmp_crop_size += np.round(size_diff).astype(np.int32)
152
+
153
+ # print(' crop_size = ', tmp_crop_size)
154
+ # print(' reference_5pts = ', tmp_5pts)
155
+
156
+ # 2) resize the padded inner region
157
+ # print('---> STEP2: resize the padded inner region')
158
+ size_bf_outer_pad = np.array(output_size) - np.array(outer_padding) * 2
159
+ # print(' crop_size = ', tmp_crop_size)
160
+ # print(' size_bf_outer_pad = ', size_bf_outer_pad)
161
+
162
+ if size_bf_outer_pad[0] * tmp_crop_size[1] != size_bf_outer_pad[1] * tmp_crop_size[0]:
163
+ raise FaceWarpException('Must have (output_size - outer_padding)'
164
+ '= some_scale * (crop_size * (1.0 + inner_padding_factor)')
165
+
166
+ scale_factor = size_bf_outer_pad[0].astype(np.float32) / tmp_crop_size[0]
167
+ # print(' resize scale_factor = ', scale_factor)
168
+ tmp_5pts = tmp_5pts * scale_factor
169
+ # size_diff = tmp_crop_size * (scale_factor - min(scale_factor))
170
+ # tmp_5pts = tmp_5pts + size_diff / 2
171
+ tmp_crop_size = size_bf_outer_pad
172
+ # print(' crop_size = ', tmp_crop_size)
173
+ # print(' reference_5pts = ', tmp_5pts)
174
+
175
+ # 3) add outer_padding to make output_size
176
+ reference_5point = tmp_5pts + np.array(outer_padding)
177
+ tmp_crop_size = output_size
178
+ # print('---> STEP3: add outer_padding to make output_size')
179
+ # print(' crop_size = ', tmp_crop_size)
180
+ # print(' reference_5pts = ', tmp_5pts)
181
+ #
182
+ # print('===> end get_reference_facial_points\n')
183
+
184
+ return reference_5point
185
+
186
+
187
+ def get_affine_transform_matrix(src_pts, dst_pts):
188
+ tfm = np.float32([[1, 0, 0], [0, 1, 0]])
189
+ n_pts = src_pts.shape[0]
190
+ ones = np.ones((n_pts, 1), src_pts.dtype)
191
+ src_pts_ = np.hstack([src_pts, ones])
192
+ dst_pts_ = np.hstack([dst_pts, ones])
193
+
194
+ A, res, rank, s = np.linalg.lstsq(src_pts_, dst_pts_)
195
+
196
+ if rank == 3:
197
+ tfm = np.float32([
198
+ [A[0, 0], A[1, 0], A[2, 0]],
199
+ [A[0, 1], A[1, 1], A[2, 1]]
200
+ ])
201
+ elif rank == 2:
202
+ tfm = np.float32([
203
+ [A[0, 0], A[1, 0], 0],
204
+ [A[0, 1], A[1, 1], 0]
205
+ ])
206
+
207
+ return tfm
208
+
209
+
210
+ def warp_and_crop_face(src_img,
211
+ facial_pts,
212
+ reference_pts=None,
213
+ crop_size=(96, 112),
214
+ align_type='smilarity'): #smilarity cv2_affine affine
215
+ if reference_pts is None:
216
+ if crop_size[0] == 96 and crop_size[1] == 112:
217
+ reference_pts = REFERENCE_FACIAL_POINTS
218
+ else:
219
+ default_square = False
220
+ inner_padding_factor = 0
221
+ outer_padding = (0, 0)
222
+ output_size = crop_size
223
+
224
+ reference_pts = get_reference_facial_points(output_size,
225
+ inner_padding_factor,
226
+ outer_padding,
227
+ default_square)
228
+
229
+ ref_pts = np.float32(reference_pts)
230
+ ref_pts_shp = ref_pts.shape
231
+ if max(ref_pts_shp) < 3: # or min(ref_pts_shp) != 2:
232
+ raise FaceWarpException(
233
+ 'reference_pts.shape must be (K,2) or (2,K) and K>2')
234
+
235
+ if ref_pts_shp[0] == 2 or ref_pts_shp[0] == 3:
236
+ ref_pts = ref_pts.T
237
+
238
+ src_pts = np.float32(facial_pts)
239
+ src_pts_shp = src_pts.shape
240
+ if max(src_pts_shp) < 3: # or min(src_pts_shp) != 2:
241
+ raise FaceWarpException(
242
+ 'facial_pts.shape must be (K,2) or (2,K) and K>2')
243
+
244
+ if src_pts_shp[0] == 2 or src_pts_shp[0] == 3:
245
+ src_pts = src_pts.T
246
+
247
+ if src_pts.shape != ref_pts.shape:
248
+ raise FaceWarpException(
249
+ 'facial_pts and reference_pts must have the same shape')
250
+
251
+ if align_type is 'cv2_affine':
252
+ tfm = cv2.getAffineTransform(src_pts[0:3], ref_pts[0:3])
253
+ tfm_inv = cv2.getAffineTransform(ref_pts[0:3], src_pts[0:3])
254
+ elif align_type is 'cv2_rigid':
255
+ tfm, _ = cv2.estimateAffinePartial2D(src_pts[0:3], ref_pts[0:3])
256
+ tfm_inv, _ = cv2.estimateAffinePartial2D(ref_pts[0:3], src_pts[0:3])
257
+ elif align_type is 'affine':
258
+ tfm = get_affine_transform_matrix(src_pts, ref_pts)
259
+ tfm_inv = get_affine_transform_matrix(ref_pts, src_pts)
260
+ else:
261
+ params, scale = _umeyama(src_pts, ref_pts)
262
+ tfm = params[:2, :]
263
+
264
+ params, _ = _umeyama(ref_pts, src_pts, False, scale=1.0/scale)
265
+ tfm_inv = params[:2, :]
266
+
267
+ # M = cv2.getPerspectiveTransform(ref_pts[0:4], src_pts[0:4])
268
+ face_img = cv2.warpAffine(src_img, tfm, (crop_size[0], crop_size[1]), flags=3)
269
+ # face_img = cv2.warpPerspective(src_img, M, (crop_size[0], crop_size[1]), flags=cv2.INTER_LINEAR )
270
+
271
+ return face_img, tfm_inv
video-tetalking/third_part/GPEN/face_detect/.DS_Store ADDED
Binary file (12.3 kB). View file
 
video-tetalking/third_part/GPEN/face_detect/data/FDDB/img_list.txt ADDED
@@ -0,0 +1,2845 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2002/08/11/big/img_591
2
+ 2002/08/26/big/img_265
3
+ 2002/07/19/big/img_423
4
+ 2002/08/24/big/img_490
5
+ 2002/08/31/big/img_17676
6
+ 2002/07/31/big/img_228
7
+ 2002/07/24/big/img_402
8
+ 2002/08/04/big/img_769
9
+ 2002/07/19/big/img_581
10
+ 2002/08/13/big/img_723
11
+ 2002/08/12/big/img_821
12
+ 2003/01/17/big/img_610
13
+ 2002/08/13/big/img_1116
14
+ 2002/08/28/big/img_19238
15
+ 2002/08/21/big/img_660
16
+ 2002/08/14/big/img_607
17
+ 2002/08/05/big/img_3708
18
+ 2002/08/19/big/img_511
19
+ 2002/08/07/big/img_1316
20
+ 2002/07/25/big/img_1047
21
+ 2002/07/23/big/img_474
22
+ 2002/07/27/big/img_970
23
+ 2002/09/02/big/img_15752
24
+ 2002/09/01/big/img_16378
25
+ 2002/09/01/big/img_16189
26
+ 2002/08/26/big/img_276
27
+ 2002/07/24/big/img_518
28
+ 2002/08/14/big/img_1027
29
+ 2002/08/24/big/img_733
30
+ 2002/08/15/big/img_249
31
+ 2003/01/15/big/img_1371
32
+ 2002/08/07/big/img_1348
33
+ 2003/01/01/big/img_331
34
+ 2002/08/23/big/img_536
35
+ 2002/07/30/big/img_224
36
+ 2002/08/10/big/img_763
37
+ 2002/08/21/big/img_293
38
+ 2002/08/15/big/img_1211
39
+ 2002/08/15/big/img_1194
40
+ 2003/01/15/big/img_390
41
+ 2002/08/06/big/img_2893
42
+ 2002/08/17/big/img_691
43
+ 2002/08/07/big/img_1695
44
+ 2002/08/16/big/img_829
45
+ 2002/07/25/big/img_201
46
+ 2002/08/23/big/img_36
47
+ 2003/01/15/big/img_763
48
+ 2003/01/15/big/img_637
49
+ 2002/08/22/big/img_592
50
+ 2002/07/25/big/img_817
51
+ 2003/01/15/big/img_1219
52
+ 2002/08/05/big/img_3508
53
+ 2002/08/15/big/img_1108
54
+ 2002/07/19/big/img_488
55
+ 2003/01/16/big/img_704
56
+ 2003/01/13/big/img_1087
57
+ 2002/08/10/big/img_670
58
+ 2002/07/24/big/img_104
59
+ 2002/08/27/big/img_19823
60
+ 2002/09/01/big/img_16229
61
+ 2003/01/13/big/img_846
62
+ 2002/08/04/big/img_412
63
+ 2002/07/22/big/img_554
64
+ 2002/08/12/big/img_331
65
+ 2002/08/02/big/img_533
66
+ 2002/08/12/big/img_259
67
+ 2002/08/18/big/img_328
68
+ 2003/01/14/big/img_630
69
+ 2002/08/05/big/img_3541
70
+ 2002/08/06/big/img_2390
71
+ 2002/08/20/big/img_150
72
+ 2002/08/02/big/img_1231
73
+ 2002/08/16/big/img_710
74
+ 2002/08/19/big/img_591
75
+ 2002/07/22/big/img_725
76
+ 2002/07/24/big/img_820
77
+ 2003/01/13/big/img_568
78
+ 2002/08/22/big/img_853
79
+ 2002/08/09/big/img_648
80
+ 2002/08/23/big/img_528
81
+ 2003/01/14/big/img_888
82
+ 2002/08/30/big/img_18201
83
+ 2002/08/13/big/img_965
84
+ 2003/01/14/big/img_660
85
+ 2002/07/19/big/img_517
86
+ 2003/01/14/big/img_406
87
+ 2002/08/30/big/img_18433
88
+ 2002/08/07/big/img_1630
89
+ 2002/08/06/big/img_2717
90
+ 2002/08/21/big/img_470
91
+ 2002/07/23/big/img_633
92
+ 2002/08/20/big/img_915
93
+ 2002/08/16/big/img_893
94
+ 2002/07/29/big/img_644
95
+ 2002/08/15/big/img_529
96
+ 2002/08/16/big/img_668
97
+ 2002/08/07/big/img_1871
98
+ 2002/07/25/big/img_192
99
+ 2002/07/31/big/img_961
100
+ 2002/08/19/big/img_738
101
+ 2002/07/31/big/img_382
102
+ 2002/08/19/big/img_298
103
+ 2003/01/17/big/img_608
104
+ 2002/08/21/big/img_514
105
+ 2002/07/23/big/img_183
106
+ 2003/01/17/big/img_536
107
+ 2002/07/24/big/img_478
108
+ 2002/08/06/big/img_2997
109
+ 2002/09/02/big/img_15380
110
+ 2002/08/07/big/img_1153
111
+ 2002/07/31/big/img_967
112
+ 2002/07/31/big/img_711
113
+ 2002/08/26/big/img_664
114
+ 2003/01/01/big/img_326
115
+ 2002/08/24/big/img_775
116
+ 2002/08/08/big/img_961
117
+ 2002/08/16/big/img_77
118
+ 2002/08/12/big/img_296
119
+ 2002/07/22/big/img_905
120
+ 2003/01/13/big/img_284
121
+ 2002/08/13/big/img_887
122
+ 2002/08/24/big/img_849
123
+ 2002/07/30/big/img_345
124
+ 2002/08/18/big/img_419
125
+ 2002/08/01/big/img_1347
126
+ 2002/08/05/big/img_3670
127
+ 2002/07/21/big/img_479
128
+ 2002/08/08/big/img_913
129
+ 2002/09/02/big/img_15828
130
+ 2002/08/30/big/img_18194
131
+ 2002/08/08/big/img_471
132
+ 2002/08/22/big/img_734
133
+ 2002/08/09/big/img_586
134
+ 2002/08/09/big/img_454
135
+ 2002/07/29/big/img_47
136
+ 2002/07/19/big/img_381
137
+ 2002/07/29/big/img_733
138
+ 2002/08/20/big/img_327
139
+ 2002/07/21/big/img_96
140
+ 2002/08/06/big/img_2680
141
+ 2002/07/25/big/img_919
142
+ 2002/07/21/big/img_158
143
+ 2002/07/22/big/img_801
144
+ 2002/07/22/big/img_567
145
+ 2002/07/24/big/img_804
146
+ 2002/07/24/big/img_690
147
+ 2003/01/15/big/img_576
148
+ 2002/08/14/big/img_335
149
+ 2003/01/13/big/img_390
150
+ 2002/08/11/big/img_258
151
+ 2002/07/23/big/img_917
152
+ 2002/08/15/big/img_525
153
+ 2003/01/15/big/img_505
154
+ 2002/07/30/big/img_886
155
+ 2003/01/16/big/img_640
156
+ 2003/01/14/big/img_642
157
+ 2003/01/17/big/img_844
158
+ 2002/08/04/big/img_571
159
+ 2002/08/29/big/img_18702
160
+ 2003/01/15/big/img_240
161
+ 2002/07/29/big/img_553
162
+ 2002/08/10/big/img_354
163
+ 2002/08/18/big/img_17
164
+ 2003/01/15/big/img_782
165
+ 2002/07/27/big/img_382
166
+ 2002/08/14/big/img_970
167
+ 2003/01/16/big/img_70
168
+ 2003/01/16/big/img_625
169
+ 2002/08/18/big/img_341
170
+ 2002/08/26/big/img_188
171
+ 2002/08/09/big/img_405
172
+ 2002/08/02/big/img_37
173
+ 2002/08/13/big/img_748
174
+ 2002/07/22/big/img_399
175
+ 2002/07/25/big/img_844
176
+ 2002/08/12/big/img_340
177
+ 2003/01/13/big/img_815
178
+ 2002/08/26/big/img_5
179
+ 2002/08/10/big/img_158
180
+ 2002/08/18/big/img_95
181
+ 2002/07/29/big/img_1297
182
+ 2003/01/13/big/img_508
183
+ 2002/09/01/big/img_16680
184
+ 2003/01/16/big/img_338
185
+ 2002/08/13/big/img_517
186
+ 2002/07/22/big/img_626
187
+ 2002/08/06/big/img_3024
188
+ 2002/07/26/big/img_499
189
+ 2003/01/13/big/img_387
190
+ 2002/08/31/big/img_18025
191
+ 2002/08/13/big/img_520
192
+ 2003/01/16/big/img_576
193
+ 2002/07/26/big/img_121
194
+ 2002/08/25/big/img_703
195
+ 2002/08/26/big/img_615
196
+ 2002/08/17/big/img_434
197
+ 2002/08/02/big/img_677
198
+ 2002/08/18/big/img_276
199
+ 2002/08/05/big/img_3672
200
+ 2002/07/26/big/img_700
201
+ 2002/07/31/big/img_277
202
+ 2003/01/14/big/img_220
203
+ 2002/08/23/big/img_232
204
+ 2002/08/31/big/img_17422
205
+ 2002/07/22/big/img_508
206
+ 2002/08/13/big/img_681
207
+ 2003/01/15/big/img_638
208
+ 2002/08/30/big/img_18408
209
+ 2003/01/14/big/img_533
210
+ 2003/01/17/big/img_12
211
+ 2002/08/28/big/img_19388
212
+ 2002/08/08/big/img_133
213
+ 2002/07/26/big/img_885
214
+ 2002/08/19/big/img_387
215
+ 2002/08/27/big/img_19976
216
+ 2002/08/26/big/img_118
217
+ 2002/08/28/big/img_19146
218
+ 2002/08/05/big/img_3259
219
+ 2002/08/15/big/img_536
220
+ 2002/07/22/big/img_279
221
+ 2002/07/22/big/img_9
222
+ 2002/08/13/big/img_301
223
+ 2002/08/15/big/img_974
224
+ 2002/08/06/big/img_2355
225
+ 2002/08/01/big/img_1526
226
+ 2002/08/03/big/img_417
227
+ 2002/08/04/big/img_407
228
+ 2002/08/15/big/img_1029
229
+ 2002/07/29/big/img_700
230
+ 2002/08/01/big/img_1463
231
+ 2002/08/31/big/img_17365
232
+ 2002/07/28/big/img_223
233
+ 2002/07/19/big/img_827
234
+ 2002/07/27/big/img_531
235
+ 2002/07/19/big/img_845
236
+ 2002/08/20/big/img_382
237
+ 2002/07/31/big/img_268
238
+ 2002/08/27/big/img_19705
239
+ 2002/08/02/big/img_830
240
+ 2002/08/23/big/img_250
241
+ 2002/07/20/big/img_777
242
+ 2002/08/21/big/img_879
243
+ 2002/08/26/big/img_20146
244
+ 2002/08/23/big/img_789
245
+ 2002/08/06/big/img_2683
246
+ 2002/08/25/big/img_576
247
+ 2002/08/09/big/img_498
248
+ 2002/08/08/big/img_384
249
+ 2002/08/26/big/img_592
250
+ 2002/07/29/big/img_1470
251
+ 2002/08/21/big/img_452
252
+ 2002/08/30/big/img_18395
253
+ 2002/08/15/big/img_215
254
+ 2002/07/21/big/img_643
255
+ 2002/07/22/big/img_209
256
+ 2003/01/17/big/img_346
257
+ 2002/08/25/big/img_658
258
+ 2002/08/21/big/img_221
259
+ 2002/08/14/big/img_60
260
+ 2003/01/17/big/img_885
261
+ 2003/01/16/big/img_482
262
+ 2002/08/19/big/img_593
263
+ 2002/08/08/big/img_233
264
+ 2002/07/30/big/img_458
265
+ 2002/07/23/big/img_384
266
+ 2003/01/15/big/img_670
267
+ 2003/01/15/big/img_267
268
+ 2002/08/26/big/img_540
269
+ 2002/07/29/big/img_552
270
+ 2002/07/30/big/img_997
271
+ 2003/01/17/big/img_377
272
+ 2002/08/21/big/img_265
273
+ 2002/08/09/big/img_561
274
+ 2002/07/31/big/img_945
275
+ 2002/09/02/big/img_15252
276
+ 2002/08/11/big/img_276
277
+ 2002/07/22/big/img_491
278
+ 2002/07/26/big/img_517
279
+ 2002/08/14/big/img_726
280
+ 2002/08/08/big/img_46
281
+ 2002/08/28/big/img_19458
282
+ 2002/08/06/big/img_2935
283
+ 2002/07/29/big/img_1392
284
+ 2002/08/13/big/img_776
285
+ 2002/08/24/big/img_616
286
+ 2002/08/14/big/img_1065
287
+ 2002/07/29/big/img_889
288
+ 2002/08/18/big/img_188
289
+ 2002/08/07/big/img_1453
290
+ 2002/08/02/big/img_760
291
+ 2002/07/28/big/img_416
292
+ 2002/08/07/big/img_1393
293
+ 2002/08/26/big/img_292
294
+ 2002/08/26/big/img_301
295
+ 2003/01/13/big/img_195
296
+ 2002/07/26/big/img_532
297
+ 2002/08/20/big/img_550
298
+ 2002/08/05/big/img_3658
299
+ 2002/08/26/big/img_738
300
+ 2002/09/02/big/img_15750
301
+ 2003/01/17/big/img_451
302
+ 2002/07/23/big/img_339
303
+ 2002/08/16/big/img_637
304
+ 2002/08/14/big/img_748
305
+ 2002/08/06/big/img_2739
306
+ 2002/07/25/big/img_482
307
+ 2002/08/19/big/img_191
308
+ 2002/08/26/big/img_537
309
+ 2003/01/15/big/img_716
310
+ 2003/01/15/big/img_767
311
+ 2002/08/02/big/img_452
312
+ 2002/08/08/big/img_1011
313
+ 2002/08/10/big/img_144
314
+ 2003/01/14/big/img_122
315
+ 2002/07/24/big/img_586
316
+ 2002/07/24/big/img_762
317
+ 2002/08/20/big/img_369
318
+ 2002/07/30/big/img_146
319
+ 2002/08/23/big/img_396
320
+ 2003/01/15/big/img_200
321
+ 2002/08/15/big/img_1183
322
+ 2003/01/14/big/img_698
323
+ 2002/08/09/big/img_792
324
+ 2002/08/06/big/img_2347
325
+ 2002/07/31/big/img_911
326
+ 2002/08/26/big/img_722
327
+ 2002/08/23/big/img_621
328
+ 2002/08/05/big/img_3790
329
+ 2003/01/13/big/img_633
330
+ 2002/08/09/big/img_224
331
+ 2002/07/24/big/img_454
332
+ 2002/07/21/big/img_202
333
+ 2002/08/02/big/img_630
334
+ 2002/08/30/big/img_18315
335
+ 2002/07/19/big/img_491
336
+ 2002/09/01/big/img_16456
337
+ 2002/08/09/big/img_242
338
+ 2002/07/25/big/img_595
339
+ 2002/07/22/big/img_522
340
+ 2002/08/01/big/img_1593
341
+ 2002/07/29/big/img_336
342
+ 2002/08/15/big/img_448
343
+ 2002/08/28/big/img_19281
344
+ 2002/07/29/big/img_342
345
+ 2002/08/12/big/img_78
346
+ 2003/01/14/big/img_525
347
+ 2002/07/28/big/img_147
348
+ 2002/08/11/big/img_353
349
+ 2002/08/22/big/img_513
350
+ 2002/08/04/big/img_721
351
+ 2002/08/17/big/img_247
352
+ 2003/01/14/big/img_891
353
+ 2002/08/20/big/img_853
354
+ 2002/07/19/big/img_414
355
+ 2002/08/01/big/img_1530
356
+ 2003/01/14/big/img_924
357
+ 2002/08/22/big/img_468
358
+ 2002/08/18/big/img_354
359
+ 2002/08/30/big/img_18193
360
+ 2002/08/23/big/img_492
361
+ 2002/08/15/big/img_871
362
+ 2002/08/12/big/img_494
363
+ 2002/08/06/big/img_2470
364
+ 2002/07/23/big/img_923
365
+ 2002/08/26/big/img_155
366
+ 2002/08/08/big/img_669
367
+ 2002/07/23/big/img_404
368
+ 2002/08/28/big/img_19421
369
+ 2002/08/29/big/img_18993
370
+ 2002/08/25/big/img_416
371
+ 2003/01/17/big/img_434
372
+ 2002/07/29/big/img_1370
373
+ 2002/07/28/big/img_483
374
+ 2002/08/11/big/img_50
375
+ 2002/08/10/big/img_404
376
+ 2002/09/02/big/img_15057
377
+ 2003/01/14/big/img_911
378
+ 2002/09/01/big/img_16697
379
+ 2003/01/16/big/img_665
380
+ 2002/09/01/big/img_16708
381
+ 2002/08/22/big/img_612
382
+ 2002/08/28/big/img_19471
383
+ 2002/08/02/big/img_198
384
+ 2003/01/16/big/img_527
385
+ 2002/08/22/big/img_209
386
+ 2002/08/30/big/img_18205
387
+ 2003/01/14/big/img_114
388
+ 2003/01/14/big/img_1028
389
+ 2003/01/16/big/img_894
390
+ 2003/01/14/big/img_837
391
+ 2002/07/30/big/img_9
392
+ 2002/08/06/big/img_2821
393
+ 2002/08/04/big/img_85
394
+ 2003/01/13/big/img_884
395
+ 2002/07/22/big/img_570
396
+ 2002/08/07/big/img_1773
397
+ 2002/07/26/big/img_208
398
+ 2003/01/17/big/img_946
399
+ 2002/07/19/big/img_930
400
+ 2003/01/01/big/img_698
401
+ 2003/01/17/big/img_612
402
+ 2002/07/19/big/img_372
403
+ 2002/07/30/big/img_721
404
+ 2003/01/14/big/img_649
405
+ 2002/08/19/big/img_4
406
+ 2002/07/25/big/img_1024
407
+ 2003/01/15/big/img_601
408
+ 2002/08/30/big/img_18470
409
+ 2002/07/22/big/img_29
410
+ 2002/08/07/big/img_1686
411
+ 2002/07/20/big/img_294
412
+ 2002/08/14/big/img_800
413
+ 2002/08/19/big/img_353
414
+ 2002/08/19/big/img_350
415
+ 2002/08/05/big/img_3392
416
+ 2002/08/09/big/img_622
417
+ 2003/01/15/big/img_236
418
+ 2002/08/11/big/img_643
419
+ 2002/08/05/big/img_3458
420
+ 2002/08/12/big/img_413
421
+ 2002/08/22/big/img_415
422
+ 2002/08/13/big/img_635
423
+ 2002/08/07/big/img_1198
424
+ 2002/08/04/big/img_873
425
+ 2002/08/12/big/img_407
426
+ 2003/01/15/big/img_346
427
+ 2002/08/02/big/img_275
428
+ 2002/08/17/big/img_997
429
+ 2002/08/21/big/img_958
430
+ 2002/08/20/big/img_579
431
+ 2002/07/29/big/img_142
432
+ 2003/01/14/big/img_1115
433
+ 2002/08/16/big/img_365
434
+ 2002/07/29/big/img_1414
435
+ 2002/08/17/big/img_489
436
+ 2002/08/13/big/img_1010
437
+ 2002/07/31/big/img_276
438
+ 2002/07/25/big/img_1000
439
+ 2002/08/23/big/img_524
440
+ 2002/08/28/big/img_19147
441
+ 2003/01/13/big/img_433
442
+ 2002/08/20/big/img_205
443
+ 2003/01/01/big/img_458
444
+ 2002/07/29/big/img_1449
445
+ 2003/01/16/big/img_696
446
+ 2002/08/28/big/img_19296
447
+ 2002/08/29/big/img_18688
448
+ 2002/08/21/big/img_767
449
+ 2002/08/20/big/img_532
450
+ 2002/08/26/big/img_187
451
+ 2002/07/26/big/img_183
452
+ 2002/07/27/big/img_890
453
+ 2003/01/13/big/img_576
454
+ 2002/07/30/big/img_15
455
+ 2002/07/31/big/img_889
456
+ 2002/08/31/big/img_17759
457
+ 2003/01/14/big/img_1114
458
+ 2002/07/19/big/img_445
459
+ 2002/08/03/big/img_593
460
+ 2002/07/24/big/img_750
461
+ 2002/07/30/big/img_133
462
+ 2002/08/25/big/img_671
463
+ 2002/07/20/big/img_351
464
+ 2002/08/31/big/img_17276
465
+ 2002/08/05/big/img_3231
466
+ 2002/09/02/big/img_15882
467
+ 2002/08/14/big/img_115
468
+ 2002/08/02/big/img_1148
469
+ 2002/07/25/big/img_936
470
+ 2002/07/31/big/img_639
471
+ 2002/08/04/big/img_427
472
+ 2002/08/22/big/img_843
473
+ 2003/01/17/big/img_17
474
+ 2003/01/13/big/img_690
475
+ 2002/08/13/big/img_472
476
+ 2002/08/09/big/img_425
477
+ 2002/08/05/big/img_3450
478
+ 2003/01/17/big/img_439
479
+ 2002/08/13/big/img_539
480
+ 2002/07/28/big/img_35
481
+ 2002/08/16/big/img_241
482
+ 2002/08/06/big/img_2898
483
+ 2003/01/16/big/img_429
484
+ 2002/08/05/big/img_3817
485
+ 2002/08/27/big/img_19919
486
+ 2002/07/19/big/img_422
487
+ 2002/08/15/big/img_560
488
+ 2002/07/23/big/img_750
489
+ 2002/07/30/big/img_353
490
+ 2002/08/05/big/img_43
491
+ 2002/08/23/big/img_305
492
+ 2002/08/01/big/img_2137
493
+ 2002/08/30/big/img_18097
494
+ 2002/08/01/big/img_1389
495
+ 2002/08/02/big/img_308
496
+ 2003/01/14/big/img_652
497
+ 2002/08/01/big/img_1798
498
+ 2003/01/14/big/img_732
499
+ 2003/01/16/big/img_294
500
+ 2002/08/26/big/img_213
501
+ 2002/07/24/big/img_842
502
+ 2003/01/13/big/img_630
503
+ 2003/01/13/big/img_634
504
+ 2002/08/06/big/img_2285
505
+ 2002/08/01/big/img_2162
506
+ 2002/08/30/big/img_18134
507
+ 2002/08/02/big/img_1045
508
+ 2002/08/01/big/img_2143
509
+ 2002/07/25/big/img_135
510
+ 2002/07/20/big/img_645
511
+ 2002/08/05/big/img_3666
512
+ 2002/08/14/big/img_523
513
+ 2002/08/04/big/img_425
514
+ 2003/01/14/big/img_137
515
+ 2003/01/01/big/img_176
516
+ 2002/08/15/big/img_505
517
+ 2002/08/24/big/img_386
518
+ 2002/08/05/big/img_3187
519
+ 2002/08/15/big/img_419
520
+ 2003/01/13/big/img_520
521
+ 2002/08/04/big/img_444
522
+ 2002/08/26/big/img_483
523
+ 2002/08/05/big/img_3449
524
+ 2002/08/30/big/img_18409
525
+ 2002/08/28/big/img_19455
526
+ 2002/08/27/big/img_20090
527
+ 2002/07/23/big/img_625
528
+ 2002/08/24/big/img_205
529
+ 2002/08/08/big/img_938
530
+ 2003/01/13/big/img_527
531
+ 2002/08/07/big/img_1712
532
+ 2002/07/24/big/img_801
533
+ 2002/08/09/big/img_579
534
+ 2003/01/14/big/img_41
535
+ 2003/01/15/big/img_1130
536
+ 2002/07/21/big/img_672
537
+ 2002/08/07/big/img_1590
538
+ 2003/01/01/big/img_532
539
+ 2002/08/02/big/img_529
540
+ 2002/08/05/big/img_3591
541
+ 2002/08/23/big/img_5
542
+ 2003/01/14/big/img_882
543
+ 2002/08/28/big/img_19234
544
+ 2002/07/24/big/img_398
545
+ 2003/01/14/big/img_592
546
+ 2002/08/22/big/img_548
547
+ 2002/08/12/big/img_761
548
+ 2003/01/16/big/img_497
549
+ 2002/08/18/big/img_133
550
+ 2002/08/08/big/img_874
551
+ 2002/07/19/big/img_247
552
+ 2002/08/15/big/img_170
553
+ 2002/08/27/big/img_19679
554
+ 2002/08/20/big/img_246
555
+ 2002/08/24/big/img_358
556
+ 2002/07/29/big/img_599
557
+ 2002/08/01/big/img_1555
558
+ 2002/07/30/big/img_491
559
+ 2002/07/30/big/img_371
560
+ 2003/01/16/big/img_682
561
+ 2002/07/25/big/img_619
562
+ 2003/01/15/big/img_587
563
+ 2002/08/02/big/img_1212
564
+ 2002/08/01/big/img_2152
565
+ 2002/07/25/big/img_668
566
+ 2003/01/16/big/img_574
567
+ 2002/08/28/big/img_19464
568
+ 2002/08/11/big/img_536
569
+ 2002/07/24/big/img_201
570
+ 2002/08/05/big/img_3488
571
+ 2002/07/25/big/img_887
572
+ 2002/07/22/big/img_789
573
+ 2002/07/30/big/img_432
574
+ 2002/08/16/big/img_166
575
+ 2002/09/01/big/img_16333
576
+ 2002/07/26/big/img_1010
577
+ 2002/07/21/big/img_793
578
+ 2002/07/22/big/img_720
579
+ 2002/07/31/big/img_337
580
+ 2002/07/27/big/img_185
581
+ 2002/08/23/big/img_440
582
+ 2002/07/31/big/img_801
583
+ 2002/07/25/big/img_478
584
+ 2003/01/14/big/img_171
585
+ 2002/08/07/big/img_1054
586
+ 2002/09/02/big/img_15659
587
+ 2002/07/29/big/img_1348
588
+ 2002/08/09/big/img_337
589
+ 2002/08/26/big/img_684
590
+ 2002/07/31/big/img_537
591
+ 2002/08/15/big/img_808
592
+ 2003/01/13/big/img_740
593
+ 2002/08/07/big/img_1667
594
+ 2002/08/03/big/img_404
595
+ 2002/08/06/big/img_2520
596
+ 2002/07/19/big/img_230
597
+ 2002/07/19/big/img_356
598
+ 2003/01/16/big/img_627
599
+ 2002/08/04/big/img_474
600
+ 2002/07/29/big/img_833
601
+ 2002/07/25/big/img_176
602
+ 2002/08/01/big/img_1684
603
+ 2002/08/21/big/img_643
604
+ 2002/08/27/big/img_19673
605
+ 2002/08/02/big/img_838
606
+ 2002/08/06/big/img_2378
607
+ 2003/01/15/big/img_48
608
+ 2002/07/30/big/img_470
609
+ 2002/08/15/big/img_963
610
+ 2002/08/24/big/img_444
611
+ 2002/08/16/big/img_662
612
+ 2002/08/15/big/img_1209
613
+ 2002/07/24/big/img_25
614
+ 2002/08/06/big/img_2740
615
+ 2002/07/29/big/img_996
616
+ 2002/08/31/big/img_18074
617
+ 2002/08/04/big/img_343
618
+ 2003/01/17/big/img_509
619
+ 2003/01/13/big/img_726
620
+ 2002/08/07/big/img_1466
621
+ 2002/07/26/big/img_307
622
+ 2002/08/10/big/img_598
623
+ 2002/08/13/big/img_890
624
+ 2002/08/14/big/img_997
625
+ 2002/07/19/big/img_392
626
+ 2002/08/02/big/img_475
627
+ 2002/08/29/big/img_19038
628
+ 2002/07/29/big/img_538
629
+ 2002/07/29/big/img_502
630
+ 2002/08/02/big/img_364
631
+ 2002/08/31/big/img_17353
632
+ 2002/08/08/big/img_539
633
+ 2002/08/01/big/img_1449
634
+ 2002/07/22/big/img_363
635
+ 2002/08/02/big/img_90
636
+ 2002/09/01/big/img_16867
637
+ 2002/08/05/big/img_3371
638
+ 2002/07/30/big/img_342
639
+ 2002/08/07/big/img_1363
640
+ 2002/08/22/big/img_790
641
+ 2003/01/15/big/img_404
642
+ 2002/08/05/big/img_3447
643
+ 2002/09/01/big/img_16167
644
+ 2003/01/13/big/img_840
645
+ 2002/08/22/big/img_1001
646
+ 2002/08/09/big/img_431
647
+ 2002/07/27/big/img_618
648
+ 2002/07/31/big/img_741
649
+ 2002/07/30/big/img_964
650
+ 2002/07/25/big/img_86
651
+ 2002/07/29/big/img_275
652
+ 2002/08/21/big/img_921
653
+ 2002/07/26/big/img_892
654
+ 2002/08/21/big/img_663
655
+ 2003/01/13/big/img_567
656
+ 2003/01/14/big/img_719
657
+ 2002/07/28/big/img_251
658
+ 2003/01/15/big/img_1123
659
+ 2002/07/29/big/img_260
660
+ 2002/08/24/big/img_337
661
+ 2002/08/01/big/img_1914
662
+ 2002/08/13/big/img_373
663
+ 2003/01/15/big/img_589
664
+ 2002/08/13/big/img_906
665
+ 2002/07/26/big/img_270
666
+ 2002/08/26/big/img_313
667
+ 2002/08/25/big/img_694
668
+ 2003/01/01/big/img_327
669
+ 2002/07/23/big/img_261
670
+ 2002/08/26/big/img_642
671
+ 2002/07/29/big/img_918
672
+ 2002/07/23/big/img_455
673
+ 2002/07/24/big/img_612
674
+ 2002/07/23/big/img_534
675
+ 2002/07/19/big/img_534
676
+ 2002/07/19/big/img_726
677
+ 2002/08/01/big/img_2146
678
+ 2002/08/02/big/img_543
679
+ 2003/01/16/big/img_777
680
+ 2002/07/30/big/img_484
681
+ 2002/08/13/big/img_1161
682
+ 2002/07/21/big/img_390
683
+ 2002/08/06/big/img_2288
684
+ 2002/08/21/big/img_677
685
+ 2002/08/13/big/img_747
686
+ 2002/08/15/big/img_1248
687
+ 2002/07/31/big/img_416
688
+ 2002/09/02/big/img_15259
689
+ 2002/08/16/big/img_781
690
+ 2002/08/24/big/img_754
691
+ 2002/07/24/big/img_803
692
+ 2002/08/20/big/img_609
693
+ 2002/08/28/big/img_19571
694
+ 2002/09/01/big/img_16140
695
+ 2002/08/26/big/img_769
696
+ 2002/07/20/big/img_588
697
+ 2002/08/02/big/img_898
698
+ 2002/07/21/big/img_466
699
+ 2002/08/14/big/img_1046
700
+ 2002/07/25/big/img_212
701
+ 2002/08/26/big/img_353
702
+ 2002/08/19/big/img_810
703
+ 2002/08/31/big/img_17824
704
+ 2002/08/12/big/img_631
705
+ 2002/07/19/big/img_828
706
+ 2002/07/24/big/img_130
707
+ 2002/08/25/big/img_580
708
+ 2002/07/31/big/img_699
709
+ 2002/07/23/big/img_808
710
+ 2002/07/31/big/img_377
711
+ 2003/01/16/big/img_570
712
+ 2002/09/01/big/img_16254
713
+ 2002/07/21/big/img_471
714
+ 2002/08/01/big/img_1548
715
+ 2002/08/18/big/img_252
716
+ 2002/08/19/big/img_576
717
+ 2002/08/20/big/img_464
718
+ 2002/07/27/big/img_735
719
+ 2002/08/21/big/img_589
720
+ 2003/01/15/big/img_1192
721
+ 2002/08/09/big/img_302
722
+ 2002/07/31/big/img_594
723
+ 2002/08/23/big/img_19
724
+ 2002/08/29/big/img_18819
725
+ 2002/08/19/big/img_293
726
+ 2002/07/30/big/img_331
727
+ 2002/08/23/big/img_607
728
+ 2002/07/30/big/img_363
729
+ 2002/08/16/big/img_766
730
+ 2003/01/13/big/img_481
731
+ 2002/08/06/big/img_2515
732
+ 2002/09/02/big/img_15913
733
+ 2002/09/02/big/img_15827
734
+ 2002/09/02/big/img_15053
735
+ 2002/08/07/big/img_1576
736
+ 2002/07/23/big/img_268
737
+ 2002/08/21/big/img_152
738
+ 2003/01/15/big/img_578
739
+ 2002/07/21/big/img_589
740
+ 2002/07/20/big/img_548
741
+ 2002/08/27/big/img_19693
742
+ 2002/08/31/big/img_17252
743
+ 2002/07/31/big/img_138
744
+ 2002/07/23/big/img_372
745
+ 2002/08/16/big/img_695
746
+ 2002/07/27/big/img_287
747
+ 2002/08/15/big/img_315
748
+ 2002/08/10/big/img_361
749
+ 2002/07/29/big/img_899
750
+ 2002/08/13/big/img_771
751
+ 2002/08/21/big/img_92
752
+ 2003/01/15/big/img_425
753
+ 2003/01/16/big/img_450
754
+ 2002/09/01/big/img_16942
755
+ 2002/08/02/big/img_51
756
+ 2002/09/02/big/img_15379
757
+ 2002/08/24/big/img_147
758
+ 2002/08/30/big/img_18122
759
+ 2002/07/26/big/img_950
760
+ 2002/08/07/big/img_1400
761
+ 2002/08/17/big/img_468
762
+ 2002/08/15/big/img_470
763
+ 2002/07/30/big/img_318
764
+ 2002/07/22/big/img_644
765
+ 2002/08/27/big/img_19732
766
+ 2002/07/23/big/img_601
767
+ 2002/08/26/big/img_398
768
+ 2002/08/21/big/img_428
769
+ 2002/08/06/big/img_2119
770
+ 2002/08/29/big/img_19103
771
+ 2003/01/14/big/img_933
772
+ 2002/08/11/big/img_674
773
+ 2002/08/28/big/img_19420
774
+ 2002/08/03/big/img_418
775
+ 2002/08/17/big/img_312
776
+ 2002/07/25/big/img_1044
777
+ 2003/01/17/big/img_671
778
+ 2002/08/30/big/img_18297
779
+ 2002/07/25/big/img_755
780
+ 2002/07/23/big/img_471
781
+ 2002/08/21/big/img_39
782
+ 2002/07/26/big/img_699
783
+ 2003/01/14/big/img_33
784
+ 2002/07/31/big/img_411
785
+ 2002/08/16/big/img_645
786
+ 2003/01/17/big/img_116
787
+ 2002/09/02/big/img_15903
788
+ 2002/08/20/big/img_120
789
+ 2002/08/22/big/img_176
790
+ 2002/07/29/big/img_1316
791
+ 2002/08/27/big/img_19914
792
+ 2002/07/22/big/img_719
793
+ 2002/08/28/big/img_19239
794
+ 2003/01/13/big/img_385
795
+ 2002/08/08/big/img_525
796
+ 2002/07/19/big/img_782
797
+ 2002/08/13/big/img_843
798
+ 2002/07/30/big/img_107
799
+ 2002/08/11/big/img_752
800
+ 2002/07/29/big/img_383
801
+ 2002/08/26/big/img_249
802
+ 2002/08/29/big/img_18860
803
+ 2002/07/30/big/img_70
804
+ 2002/07/26/big/img_194
805
+ 2002/08/15/big/img_530
806
+ 2002/08/08/big/img_816
807
+ 2002/07/31/big/img_286
808
+ 2003/01/13/big/img_294
809
+ 2002/07/31/big/img_251
810
+ 2002/07/24/big/img_13
811
+ 2002/08/31/big/img_17938
812
+ 2002/07/22/big/img_642
813
+ 2003/01/14/big/img_728
814
+ 2002/08/18/big/img_47
815
+ 2002/08/22/big/img_306
816
+ 2002/08/20/big/img_348
817
+ 2002/08/15/big/img_764
818
+ 2002/08/08/big/img_163
819
+ 2002/07/23/big/img_531
820
+ 2002/07/23/big/img_467
821
+ 2003/01/16/big/img_743
822
+ 2003/01/13/big/img_535
823
+ 2002/08/02/big/img_523
824
+ 2002/08/22/big/img_120
825
+ 2002/08/11/big/img_496
826
+ 2002/08/29/big/img_19075
827
+ 2002/08/08/big/img_465
828
+ 2002/08/09/big/img_790
829
+ 2002/08/19/big/img_588
830
+ 2002/08/23/big/img_407
831
+ 2003/01/17/big/img_435
832
+ 2002/08/24/big/img_398
833
+ 2002/08/27/big/img_19899
834
+ 2003/01/15/big/img_335
835
+ 2002/08/13/big/img_493
836
+ 2002/09/02/big/img_15460
837
+ 2002/07/31/big/img_470
838
+ 2002/08/05/big/img_3550
839
+ 2002/07/28/big/img_123
840
+ 2002/08/01/big/img_1498
841
+ 2002/08/04/big/img_504
842
+ 2003/01/17/big/img_427
843
+ 2002/08/27/big/img_19708
844
+ 2002/07/27/big/img_861
845
+ 2002/07/25/big/img_685
846
+ 2002/07/31/big/img_207
847
+ 2003/01/14/big/img_745
848
+ 2002/08/31/big/img_17756
849
+ 2002/08/24/big/img_288
850
+ 2002/08/18/big/img_181
851
+ 2002/08/10/big/img_520
852
+ 2002/08/25/big/img_705
853
+ 2002/08/23/big/img_226
854
+ 2002/08/04/big/img_727
855
+ 2002/07/24/big/img_625
856
+ 2002/08/28/big/img_19157
857
+ 2002/08/23/big/img_586
858
+ 2002/07/31/big/img_232
859
+ 2003/01/13/big/img_240
860
+ 2003/01/14/big/img_321
861
+ 2003/01/15/big/img_533
862
+ 2002/07/23/big/img_480
863
+ 2002/07/24/big/img_371
864
+ 2002/08/21/big/img_702
865
+ 2002/08/31/big/img_17075
866
+ 2002/09/02/big/img_15278
867
+ 2002/07/29/big/img_246
868
+ 2003/01/15/big/img_829
869
+ 2003/01/15/big/img_1213
870
+ 2003/01/16/big/img_441
871
+ 2002/08/14/big/img_921
872
+ 2002/07/23/big/img_425
873
+ 2002/08/15/big/img_296
874
+ 2002/07/19/big/img_135
875
+ 2002/07/26/big/img_402
876
+ 2003/01/17/big/img_88
877
+ 2002/08/20/big/img_872
878
+ 2002/08/13/big/img_1110
879
+ 2003/01/16/big/img_1040
880
+ 2002/07/23/big/img_9
881
+ 2002/08/13/big/img_700
882
+ 2002/08/16/big/img_371
883
+ 2002/08/27/big/img_19966
884
+ 2003/01/17/big/img_391
885
+ 2002/08/18/big/img_426
886
+ 2002/08/01/big/img_1618
887
+ 2002/07/21/big/img_754
888
+ 2003/01/14/big/img_1101
889
+ 2003/01/16/big/img_1022
890
+ 2002/07/22/big/img_275
891
+ 2002/08/24/big/img_86
892
+ 2002/08/17/big/img_582
893
+ 2003/01/15/big/img_765
894
+ 2003/01/17/big/img_449
895
+ 2002/07/28/big/img_265
896
+ 2003/01/13/big/img_552
897
+ 2002/07/28/big/img_115
898
+ 2003/01/16/big/img_56
899
+ 2002/08/02/big/img_1232
900
+ 2003/01/17/big/img_925
901
+ 2002/07/22/big/img_445
902
+ 2002/07/25/big/img_957
903
+ 2002/07/20/big/img_589
904
+ 2002/08/31/big/img_17107
905
+ 2002/07/29/big/img_483
906
+ 2002/08/14/big/img_1063
907
+ 2002/08/07/big/img_1545
908
+ 2002/08/14/big/img_680
909
+ 2002/09/01/big/img_16694
910
+ 2002/08/14/big/img_257
911
+ 2002/08/11/big/img_726
912
+ 2002/07/26/big/img_681
913
+ 2002/07/25/big/img_481
914
+ 2003/01/14/big/img_737
915
+ 2002/08/28/big/img_19480
916
+ 2003/01/16/big/img_362
917
+ 2002/08/27/big/img_19865
918
+ 2003/01/01/big/img_547
919
+ 2002/09/02/big/img_15074
920
+ 2002/08/01/big/img_1453
921
+ 2002/08/22/big/img_594
922
+ 2002/08/28/big/img_19263
923
+ 2002/08/13/big/img_478
924
+ 2002/07/29/big/img_1358
925
+ 2003/01/14/big/img_1022
926
+ 2002/08/16/big/img_450
927
+ 2002/08/02/big/img_159
928
+ 2002/07/26/big/img_781
929
+ 2003/01/13/big/img_601
930
+ 2002/08/20/big/img_407
931
+ 2002/08/15/big/img_468
932
+ 2002/08/31/big/img_17902
933
+ 2002/08/16/big/img_81
934
+ 2002/07/25/big/img_987
935
+ 2002/07/25/big/img_500
936
+ 2002/08/02/big/img_31
937
+ 2002/08/18/big/img_538
938
+ 2002/08/08/big/img_54
939
+ 2002/07/23/big/img_686
940
+ 2002/07/24/big/img_836
941
+ 2003/01/17/big/img_734
942
+ 2002/08/16/big/img_1055
943
+ 2003/01/16/big/img_521
944
+ 2002/07/25/big/img_612
945
+ 2002/08/22/big/img_778
946
+ 2002/08/03/big/img_251
947
+ 2002/08/12/big/img_436
948
+ 2002/08/23/big/img_705
949
+ 2002/07/28/big/img_243
950
+ 2002/07/25/big/img_1029
951
+ 2002/08/20/big/img_287
952
+ 2002/08/29/big/img_18739
953
+ 2002/08/05/big/img_3272
954
+ 2002/07/27/big/img_214
955
+ 2003/01/14/big/img_5
956
+ 2002/08/01/big/img_1380
957
+ 2002/08/29/big/img_19097
958
+ 2002/07/30/big/img_486
959
+ 2002/08/29/big/img_18707
960
+ 2002/08/10/big/img_559
961
+ 2002/08/15/big/img_365
962
+ 2002/08/09/big/img_525
963
+ 2002/08/10/big/img_689
964
+ 2002/07/25/big/img_502
965
+ 2002/08/03/big/img_667
966
+ 2002/08/10/big/img_855
967
+ 2002/08/10/big/img_706
968
+ 2002/08/18/big/img_603
969
+ 2003/01/16/big/img_1055
970
+ 2002/08/31/big/img_17890
971
+ 2002/08/15/big/img_761
972
+ 2003/01/15/big/img_489
973
+ 2002/08/26/big/img_351
974
+ 2002/08/01/big/img_1772
975
+ 2002/08/31/big/img_17729
976
+ 2002/07/25/big/img_609
977
+ 2003/01/13/big/img_539
978
+ 2002/07/27/big/img_686
979
+ 2002/07/31/big/img_311
980
+ 2002/08/22/big/img_799
981
+ 2003/01/16/big/img_936
982
+ 2002/08/31/big/img_17813
983
+ 2002/08/04/big/img_862
984
+ 2002/08/09/big/img_332
985
+ 2002/07/20/big/img_148
986
+ 2002/08/12/big/img_426
987
+ 2002/07/24/big/img_69
988
+ 2002/07/27/big/img_685
989
+ 2002/08/02/big/img_480
990
+ 2002/08/26/big/img_154
991
+ 2002/07/24/big/img_598
992
+ 2002/08/01/big/img_1881
993
+ 2002/08/20/big/img_667
994
+ 2003/01/14/big/img_495
995
+ 2002/07/21/big/img_744
996
+ 2002/07/30/big/img_150
997
+ 2002/07/23/big/img_924
998
+ 2002/08/08/big/img_272
999
+ 2002/07/23/big/img_310
1000
+ 2002/07/25/big/img_1011
1001
+ 2002/09/02/big/img_15725
1002
+ 2002/07/19/big/img_814
1003
+ 2002/08/20/big/img_936
1004
+ 2002/07/25/big/img_85
1005
+ 2002/08/24/big/img_662
1006
+ 2002/08/09/big/img_495
1007
+ 2003/01/15/big/img_196
1008
+ 2002/08/16/big/img_707
1009
+ 2002/08/28/big/img_19370
1010
+ 2002/08/06/big/img_2366
1011
+ 2002/08/06/big/img_3012
1012
+ 2002/08/01/big/img_1452
1013
+ 2002/07/31/big/img_742
1014
+ 2002/07/27/big/img_914
1015
+ 2003/01/13/big/img_290
1016
+ 2002/07/31/big/img_288
1017
+ 2002/08/02/big/img_171
1018
+ 2002/08/22/big/img_191
1019
+ 2002/07/27/big/img_1066
1020
+ 2002/08/12/big/img_383
1021
+ 2003/01/17/big/img_1018
1022
+ 2002/08/01/big/img_1785
1023
+ 2002/08/11/big/img_390
1024
+ 2002/08/27/big/img_20037
1025
+ 2002/08/12/big/img_38
1026
+ 2003/01/15/big/img_103
1027
+ 2002/08/26/big/img_31
1028
+ 2002/08/18/big/img_660
1029
+ 2002/07/22/big/img_694
1030
+ 2002/08/15/big/img_24
1031
+ 2002/07/27/big/img_1077
1032
+ 2002/08/01/big/img_1943
1033
+ 2002/07/22/big/img_292
1034
+ 2002/09/01/big/img_16857
1035
+ 2002/07/22/big/img_892
1036
+ 2003/01/14/big/img_46
1037
+ 2002/08/09/big/img_469
1038
+ 2002/08/09/big/img_414
1039
+ 2003/01/16/big/img_40
1040
+ 2002/08/28/big/img_19231
1041
+ 2002/07/27/big/img_978
1042
+ 2002/07/23/big/img_475
1043
+ 2002/07/25/big/img_92
1044
+ 2002/08/09/big/img_799
1045
+ 2002/07/25/big/img_491
1046
+ 2002/08/03/big/img_654
1047
+ 2003/01/15/big/img_687
1048
+ 2002/08/11/big/img_478
1049
+ 2002/08/07/big/img_1664
1050
+ 2002/08/20/big/img_362
1051
+ 2002/08/01/big/img_1298
1052
+ 2003/01/13/big/img_500
1053
+ 2002/08/06/big/img_2896
1054
+ 2002/08/30/big/img_18529
1055
+ 2002/08/16/big/img_1020
1056
+ 2002/07/29/big/img_892
1057
+ 2002/08/29/big/img_18726
1058
+ 2002/07/21/big/img_453
1059
+ 2002/08/17/big/img_437
1060
+ 2002/07/19/big/img_665
1061
+ 2002/07/22/big/img_440
1062
+ 2002/07/19/big/img_582
1063
+ 2002/07/21/big/img_233
1064
+ 2003/01/01/big/img_82
1065
+ 2002/07/25/big/img_341
1066
+ 2002/07/29/big/img_864
1067
+ 2002/08/02/big/img_276
1068
+ 2002/08/29/big/img_18654
1069
+ 2002/07/27/big/img_1024
1070
+ 2002/08/19/big/img_373
1071
+ 2003/01/15/big/img_241
1072
+ 2002/07/25/big/img_84
1073
+ 2002/08/13/big/img_834
1074
+ 2002/08/10/big/img_511
1075
+ 2002/08/01/big/img_1627
1076
+ 2002/08/08/big/img_607
1077
+ 2002/08/06/big/img_2083
1078
+ 2002/08/01/big/img_1486
1079
+ 2002/08/08/big/img_700
1080
+ 2002/08/01/big/img_1954
1081
+ 2002/08/21/big/img_54
1082
+ 2002/07/30/big/img_847
1083
+ 2002/08/28/big/img_19169
1084
+ 2002/07/21/big/img_549
1085
+ 2002/08/03/big/img_693
1086
+ 2002/07/31/big/img_1002
1087
+ 2003/01/14/big/img_1035
1088
+ 2003/01/16/big/img_622
1089
+ 2002/07/30/big/img_1201
1090
+ 2002/08/10/big/img_444
1091
+ 2002/07/31/big/img_374
1092
+ 2002/08/21/big/img_301
1093
+ 2002/08/13/big/img_1095
1094
+ 2003/01/13/big/img_288
1095
+ 2002/07/25/big/img_232
1096
+ 2003/01/13/big/img_967
1097
+ 2002/08/26/big/img_360
1098
+ 2002/08/05/big/img_67
1099
+ 2002/08/29/big/img_18969
1100
+ 2002/07/28/big/img_16
1101
+ 2002/08/16/big/img_515
1102
+ 2002/07/20/big/img_708
1103
+ 2002/08/18/big/img_178
1104
+ 2003/01/15/big/img_509
1105
+ 2002/07/25/big/img_430
1106
+ 2002/08/21/big/img_738
1107
+ 2002/08/16/big/img_886
1108
+ 2002/09/02/big/img_15605
1109
+ 2002/09/01/big/img_16242
1110
+ 2002/08/24/big/img_711
1111
+ 2002/07/25/big/img_90
1112
+ 2002/08/09/big/img_491
1113
+ 2002/07/30/big/img_534
1114
+ 2003/01/13/big/img_474
1115
+ 2002/08/25/big/img_510
1116
+ 2002/08/15/big/img_555
1117
+ 2002/08/02/big/img_775
1118
+ 2002/07/23/big/img_975
1119
+ 2002/08/19/big/img_229
1120
+ 2003/01/17/big/img_860
1121
+ 2003/01/02/big/img_10
1122
+ 2002/07/23/big/img_542
1123
+ 2002/08/06/big/img_2535
1124
+ 2002/07/22/big/img_37
1125
+ 2002/08/06/big/img_2342
1126
+ 2002/08/25/big/img_515
1127
+ 2002/08/25/big/img_336
1128
+ 2002/08/18/big/img_837
1129
+ 2002/08/21/big/img_616
1130
+ 2003/01/17/big/img_24
1131
+ 2002/07/26/big/img_936
1132
+ 2002/08/14/big/img_896
1133
+ 2002/07/29/big/img_465
1134
+ 2002/07/31/big/img_543
1135
+ 2002/08/01/big/img_1411
1136
+ 2002/08/02/big/img_423
1137
+ 2002/08/21/big/img_44
1138
+ 2002/07/31/big/img_11
1139
+ 2003/01/15/big/img_628
1140
+ 2003/01/15/big/img_605
1141
+ 2002/07/30/big/img_571
1142
+ 2002/07/23/big/img_428
1143
+ 2002/08/15/big/img_942
1144
+ 2002/07/26/big/img_531
1145
+ 2003/01/16/big/img_59
1146
+ 2002/08/02/big/img_410
1147
+ 2002/07/31/big/img_230
1148
+ 2002/08/19/big/img_806
1149
+ 2003/01/14/big/img_462
1150
+ 2002/08/16/big/img_370
1151
+ 2002/08/13/big/img_380
1152
+ 2002/08/16/big/img_932
1153
+ 2002/07/19/big/img_393
1154
+ 2002/08/20/big/img_764
1155
+ 2002/08/15/big/img_616
1156
+ 2002/07/26/big/img_267
1157
+ 2002/07/27/big/img_1069
1158
+ 2002/08/14/big/img_1041
1159
+ 2003/01/13/big/img_594
1160
+ 2002/09/01/big/img_16845
1161
+ 2002/08/09/big/img_229
1162
+ 2003/01/16/big/img_639
1163
+ 2002/08/19/big/img_398
1164
+ 2002/08/18/big/img_978
1165
+ 2002/08/24/big/img_296
1166
+ 2002/07/29/big/img_415
1167
+ 2002/07/30/big/img_923
1168
+ 2002/08/18/big/img_575
1169
+ 2002/08/22/big/img_182
1170
+ 2002/07/25/big/img_806
1171
+ 2002/07/22/big/img_49
1172
+ 2002/07/29/big/img_989
1173
+ 2003/01/17/big/img_789
1174
+ 2003/01/15/big/img_503
1175
+ 2002/09/01/big/img_16062
1176
+ 2003/01/17/big/img_794
1177
+ 2002/08/15/big/img_564
1178
+ 2003/01/15/big/img_222
1179
+ 2002/08/01/big/img_1656
1180
+ 2003/01/13/big/img_432
1181
+ 2002/07/19/big/img_426
1182
+ 2002/08/17/big/img_244
1183
+ 2002/08/13/big/img_805
1184
+ 2002/09/02/big/img_15067
1185
+ 2002/08/11/big/img_58
1186
+ 2002/08/22/big/img_636
1187
+ 2002/07/22/big/img_416
1188
+ 2002/08/13/big/img_836
1189
+ 2002/08/26/big/img_363
1190
+ 2002/07/30/big/img_917
1191
+ 2003/01/14/big/img_206
1192
+ 2002/08/12/big/img_311
1193
+ 2002/08/31/big/img_17623
1194
+ 2002/07/29/big/img_661
1195
+ 2003/01/13/big/img_417
1196
+ 2002/08/02/big/img_463
1197
+ 2002/08/02/big/img_669
1198
+ 2002/08/26/big/img_670
1199
+ 2002/08/02/big/img_375
1200
+ 2002/07/19/big/img_209
1201
+ 2002/08/08/big/img_115
1202
+ 2002/08/21/big/img_399
1203
+ 2002/08/20/big/img_911
1204
+ 2002/08/07/big/img_1212
1205
+ 2002/08/20/big/img_578
1206
+ 2002/08/22/big/img_554
1207
+ 2002/08/21/big/img_484
1208
+ 2002/07/25/big/img_450
1209
+ 2002/08/03/big/img_542
1210
+ 2002/08/15/big/img_561
1211
+ 2002/07/23/big/img_360
1212
+ 2002/08/30/big/img_18137
1213
+ 2002/07/25/big/img_250
1214
+ 2002/08/03/big/img_647
1215
+ 2002/08/20/big/img_375
1216
+ 2002/08/14/big/img_387
1217
+ 2002/09/01/big/img_16990
1218
+ 2002/08/28/big/img_19341
1219
+ 2003/01/15/big/img_239
1220
+ 2002/08/20/big/img_528
1221
+ 2002/08/12/big/img_130
1222
+ 2002/09/02/big/img_15108
1223
+ 2003/01/15/big/img_372
1224
+ 2002/08/16/big/img_678
1225
+ 2002/08/04/big/img_623
1226
+ 2002/07/23/big/img_477
1227
+ 2002/08/28/big/img_19590
1228
+ 2003/01/17/big/img_978
1229
+ 2002/09/01/big/img_16692
1230
+ 2002/07/20/big/img_109
1231
+ 2002/08/06/big/img_2660
1232
+ 2003/01/14/big/img_464
1233
+ 2002/08/09/big/img_618
1234
+ 2002/07/22/big/img_722
1235
+ 2002/08/25/big/img_419
1236
+ 2002/08/03/big/img_314
1237
+ 2002/08/25/big/img_40
1238
+ 2002/07/27/big/img_430
1239
+ 2002/08/10/big/img_569
1240
+ 2002/08/23/big/img_398
1241
+ 2002/07/23/big/img_893
1242
+ 2002/08/16/big/img_261
1243
+ 2002/08/06/big/img_2668
1244
+ 2002/07/22/big/img_835
1245
+ 2002/09/02/big/img_15093
1246
+ 2003/01/16/big/img_65
1247
+ 2002/08/21/big/img_448
1248
+ 2003/01/14/big/img_351
1249
+ 2003/01/17/big/img_133
1250
+ 2002/07/28/big/img_493
1251
+ 2003/01/15/big/img_640
1252
+ 2002/09/01/big/img_16880
1253
+ 2002/08/15/big/img_350
1254
+ 2002/08/20/big/img_624
1255
+ 2002/08/25/big/img_604
1256
+ 2002/08/06/big/img_2200
1257
+ 2002/08/23/big/img_290
1258
+ 2002/08/13/big/img_1152
1259
+ 2003/01/14/big/img_251
1260
+ 2002/08/02/big/img_538
1261
+ 2002/08/22/big/img_613
1262
+ 2003/01/13/big/img_351
1263
+ 2002/08/18/big/img_368
1264
+ 2002/07/23/big/img_392
1265
+ 2002/07/25/big/img_198
1266
+ 2002/07/25/big/img_418
1267
+ 2002/08/26/big/img_614
1268
+ 2002/07/23/big/img_405
1269
+ 2003/01/14/big/img_445
1270
+ 2002/07/25/big/img_326
1271
+ 2002/08/10/big/img_734
1272
+ 2003/01/14/big/img_530
1273
+ 2002/08/08/big/img_561
1274
+ 2002/08/29/big/img_18990
1275
+ 2002/08/10/big/img_576
1276
+ 2002/07/29/big/img_1494
1277
+ 2002/07/19/big/img_198
1278
+ 2002/08/10/big/img_562
1279
+ 2002/07/22/big/img_901
1280
+ 2003/01/14/big/img_37
1281
+ 2002/09/02/big/img_15629
1282
+ 2003/01/14/big/img_58
1283
+ 2002/08/01/big/img_1364
1284
+ 2002/07/27/big/img_636
1285
+ 2003/01/13/big/img_241
1286
+ 2002/09/01/big/img_16988
1287
+ 2003/01/13/big/img_560
1288
+ 2002/08/09/big/img_533
1289
+ 2002/07/31/big/img_249
1290
+ 2003/01/17/big/img_1007
1291
+ 2002/07/21/big/img_64
1292
+ 2003/01/13/big/img_537
1293
+ 2003/01/15/big/img_606
1294
+ 2002/08/18/big/img_651
1295
+ 2002/08/24/big/img_405
1296
+ 2002/07/26/big/img_837
1297
+ 2002/08/09/big/img_562
1298
+ 2002/08/01/big/img_1983
1299
+ 2002/08/03/big/img_514
1300
+ 2002/07/29/big/img_314
1301
+ 2002/08/12/big/img_493
1302
+ 2003/01/14/big/img_121
1303
+ 2003/01/14/big/img_479
1304
+ 2002/08/04/big/img_410
1305
+ 2002/07/22/big/img_607
1306
+ 2003/01/17/big/img_417
1307
+ 2002/07/20/big/img_547
1308
+ 2002/08/13/big/img_396
1309
+ 2002/08/31/big/img_17538
1310
+ 2002/08/13/big/img_187
1311
+ 2002/08/12/big/img_328
1312
+ 2003/01/14/big/img_569
1313
+ 2002/07/27/big/img_1081
1314
+ 2002/08/14/big/img_504
1315
+ 2002/08/23/big/img_785
1316
+ 2002/07/26/big/img_339
1317
+ 2002/08/07/big/img_1156
1318
+ 2002/08/07/big/img_1456
1319
+ 2002/08/23/big/img_378
1320
+ 2002/08/27/big/img_19719
1321
+ 2002/07/31/big/img_39
1322
+ 2002/07/31/big/img_883
1323
+ 2003/01/14/big/img_676
1324
+ 2002/07/29/big/img_214
1325
+ 2002/07/26/big/img_669
1326
+ 2002/07/25/big/img_202
1327
+ 2002/08/08/big/img_259
1328
+ 2003/01/17/big/img_943
1329
+ 2003/01/15/big/img_512
1330
+ 2002/08/05/big/img_3295
1331
+ 2002/08/27/big/img_19685
1332
+ 2002/08/08/big/img_277
1333
+ 2002/08/30/big/img_18154
1334
+ 2002/07/22/big/img_663
1335
+ 2002/08/29/big/img_18914
1336
+ 2002/07/31/big/img_908
1337
+ 2002/08/27/big/img_19926
1338
+ 2003/01/13/big/img_791
1339
+ 2003/01/15/big/img_827
1340
+ 2002/08/18/big/img_878
1341
+ 2002/08/14/big/img_670
1342
+ 2002/07/20/big/img_182
1343
+ 2002/08/15/big/img_291
1344
+ 2002/08/06/big/img_2600
1345
+ 2002/07/23/big/img_587
1346
+ 2002/08/14/big/img_577
1347
+ 2003/01/15/big/img_585
1348
+ 2002/07/30/big/img_310
1349
+ 2002/08/03/big/img_658
1350
+ 2002/08/10/big/img_157
1351
+ 2002/08/19/big/img_811
1352
+ 2002/07/29/big/img_1318
1353
+ 2002/08/04/big/img_104
1354
+ 2002/07/30/big/img_332
1355
+ 2002/07/24/big/img_789
1356
+ 2002/07/29/big/img_516
1357
+ 2002/07/23/big/img_843
1358
+ 2002/08/01/big/img_1528
1359
+ 2002/08/13/big/img_798
1360
+ 2002/08/07/big/img_1729
1361
+ 2002/08/28/big/img_19448
1362
+ 2003/01/16/big/img_95
1363
+ 2002/08/12/big/img_473
1364
+ 2002/07/27/big/img_269
1365
+ 2003/01/16/big/img_621
1366
+ 2002/07/29/big/img_772
1367
+ 2002/07/24/big/img_171
1368
+ 2002/07/19/big/img_429
1369
+ 2002/08/07/big/img_1933
1370
+ 2002/08/27/big/img_19629
1371
+ 2002/08/05/big/img_3688
1372
+ 2002/08/07/big/img_1691
1373
+ 2002/07/23/big/img_600
1374
+ 2002/07/29/big/img_666
1375
+ 2002/08/25/big/img_566
1376
+ 2002/08/06/big/img_2659
1377
+ 2002/08/29/big/img_18929
1378
+ 2002/08/16/big/img_407
1379
+ 2002/08/18/big/img_774
1380
+ 2002/08/19/big/img_249
1381
+ 2002/08/06/big/img_2427
1382
+ 2002/08/29/big/img_18899
1383
+ 2002/08/01/big/img_1818
1384
+ 2002/07/31/big/img_108
1385
+ 2002/07/29/big/img_500
1386
+ 2002/08/11/big/img_115
1387
+ 2002/07/19/big/img_521
1388
+ 2002/08/02/big/img_1163
1389
+ 2002/07/22/big/img_62
1390
+ 2002/08/13/big/img_466
1391
+ 2002/08/21/big/img_956
1392
+ 2002/08/23/big/img_602
1393
+ 2002/08/20/big/img_858
1394
+ 2002/07/25/big/img_690
1395
+ 2002/07/19/big/img_130
1396
+ 2002/08/04/big/img_874
1397
+ 2002/07/26/big/img_489
1398
+ 2002/07/22/big/img_548
1399
+ 2002/08/10/big/img_191
1400
+ 2002/07/25/big/img_1051
1401
+ 2002/08/18/big/img_473
1402
+ 2002/08/12/big/img_755
1403
+ 2002/08/18/big/img_413
1404
+ 2002/08/08/big/img_1044
1405
+ 2002/08/17/big/img_680
1406
+ 2002/08/26/big/img_235
1407
+ 2002/08/20/big/img_330
1408
+ 2002/08/22/big/img_344
1409
+ 2002/08/09/big/img_593
1410
+ 2002/07/31/big/img_1006
1411
+ 2002/08/14/big/img_337
1412
+ 2002/08/16/big/img_728
1413
+ 2002/07/24/big/img_834
1414
+ 2002/08/04/big/img_552
1415
+ 2002/09/02/big/img_15213
1416
+ 2002/07/25/big/img_725
1417
+ 2002/08/30/big/img_18290
1418
+ 2003/01/01/big/img_475
1419
+ 2002/07/27/big/img_1083
1420
+ 2002/08/29/big/img_18955
1421
+ 2002/08/31/big/img_17232
1422
+ 2002/08/08/big/img_480
1423
+ 2002/08/01/big/img_1311
1424
+ 2002/07/30/big/img_745
1425
+ 2002/08/03/big/img_649
1426
+ 2002/08/12/big/img_193
1427
+ 2002/07/29/big/img_228
1428
+ 2002/07/25/big/img_836
1429
+ 2002/08/20/big/img_400
1430
+ 2002/07/30/big/img_507
1431
+ 2002/09/02/big/img_15072
1432
+ 2002/07/26/big/img_658
1433
+ 2002/07/28/big/img_503
1434
+ 2002/08/05/big/img_3814
1435
+ 2002/08/24/big/img_745
1436
+ 2003/01/13/big/img_817
1437
+ 2002/08/08/big/img_579
1438
+ 2002/07/22/big/img_251
1439
+ 2003/01/13/big/img_689
1440
+ 2002/07/25/big/img_407
1441
+ 2002/08/13/big/img_1050
1442
+ 2002/08/14/big/img_733
1443
+ 2002/07/24/big/img_82
1444
+ 2003/01/17/big/img_288
1445
+ 2003/01/15/big/img_475
1446
+ 2002/08/14/big/img_620
1447
+ 2002/08/21/big/img_167
1448
+ 2002/07/19/big/img_300
1449
+ 2002/07/26/big/img_219
1450
+ 2002/08/01/big/img_1468
1451
+ 2002/07/23/big/img_260
1452
+ 2002/08/09/big/img_555
1453
+ 2002/07/19/big/img_160
1454
+ 2002/08/02/big/img_1060
1455
+ 2003/01/14/big/img_149
1456
+ 2002/08/15/big/img_346
1457
+ 2002/08/24/big/img_597
1458
+ 2002/08/22/big/img_502
1459
+ 2002/08/30/big/img_18228
1460
+ 2002/07/21/big/img_766
1461
+ 2003/01/15/big/img_841
1462
+ 2002/07/24/big/img_516
1463
+ 2002/08/02/big/img_265
1464
+ 2002/08/15/big/img_1243
1465
+ 2003/01/15/big/img_223
1466
+ 2002/08/04/big/img_236
1467
+ 2002/07/22/big/img_309
1468
+ 2002/07/20/big/img_656
1469
+ 2002/07/31/big/img_412
1470
+ 2002/09/01/big/img_16462
1471
+ 2003/01/16/big/img_431
1472
+ 2002/07/22/big/img_793
1473
+ 2002/08/15/big/img_877
1474
+ 2002/07/26/big/img_282
1475
+ 2002/07/25/big/img_529
1476
+ 2002/08/24/big/img_613
1477
+ 2003/01/17/big/img_700
1478
+ 2002/08/06/big/img_2526
1479
+ 2002/08/24/big/img_394
1480
+ 2002/08/21/big/img_521
1481
+ 2002/08/25/big/img_560
1482
+ 2002/07/29/big/img_966
1483
+ 2002/07/25/big/img_448
1484
+ 2003/01/13/big/img_782
1485
+ 2002/08/21/big/img_296
1486
+ 2002/09/01/big/img_16755
1487
+ 2002/08/05/big/img_3552
1488
+ 2002/09/02/big/img_15823
1489
+ 2003/01/14/big/img_193
1490
+ 2002/07/21/big/img_159
1491
+ 2002/08/02/big/img_564
1492
+ 2002/08/16/big/img_300
1493
+ 2002/07/19/big/img_269
1494
+ 2002/08/13/big/img_676
1495
+ 2002/07/28/big/img_57
1496
+ 2002/08/05/big/img_3318
1497
+ 2002/07/31/big/img_218
1498
+ 2002/08/21/big/img_898
1499
+ 2002/07/29/big/img_109
1500
+ 2002/07/19/big/img_854
1501
+ 2002/08/23/big/img_311
1502
+ 2002/08/14/big/img_318
1503
+ 2002/07/25/big/img_523
1504
+ 2002/07/21/big/img_678
1505
+ 2003/01/17/big/img_690
1506
+ 2002/08/28/big/img_19503
1507
+ 2002/08/18/big/img_251
1508
+ 2002/08/22/big/img_672
1509
+ 2002/08/20/big/img_663
1510
+ 2002/08/02/big/img_148
1511
+ 2002/09/02/big/img_15580
1512
+ 2002/07/25/big/img_778
1513
+ 2002/08/14/big/img_565
1514
+ 2002/08/12/big/img_374
1515
+ 2002/08/13/big/img_1018
1516
+ 2002/08/20/big/img_474
1517
+ 2002/08/25/big/img_33
1518
+ 2002/08/02/big/img_1190
1519
+ 2002/08/08/big/img_864
1520
+ 2002/08/14/big/img_1071
1521
+ 2002/08/30/big/img_18103
1522
+ 2002/08/18/big/img_533
1523
+ 2003/01/16/big/img_650
1524
+ 2002/07/25/big/img_108
1525
+ 2002/07/26/big/img_81
1526
+ 2002/07/27/big/img_543
1527
+ 2002/07/29/big/img_521
1528
+ 2003/01/13/big/img_434
1529
+ 2002/08/26/big/img_674
1530
+ 2002/08/06/big/img_2932
1531
+ 2002/08/07/big/img_1262
1532
+ 2003/01/15/big/img_201
1533
+ 2003/01/16/big/img_673
1534
+ 2002/09/02/big/img_15988
1535
+ 2002/07/29/big/img_1306
1536
+ 2003/01/14/big/img_1072
1537
+ 2002/08/30/big/img_18232
1538
+ 2002/08/05/big/img_3711
1539
+ 2002/07/23/big/img_775
1540
+ 2002/08/01/big/img_16
1541
+ 2003/01/16/big/img_630
1542
+ 2002/08/22/big/img_695
1543
+ 2002/08/14/big/img_51
1544
+ 2002/08/14/big/img_782
1545
+ 2002/08/24/big/img_742
1546
+ 2003/01/14/big/img_512
1547
+ 2003/01/15/big/img_1183
1548
+ 2003/01/15/big/img_714
1549
+ 2002/08/01/big/img_2078
1550
+ 2002/07/31/big/img_682
1551
+ 2002/09/02/big/img_15687
1552
+ 2002/07/26/big/img_518
1553
+ 2002/08/27/big/img_19676
1554
+ 2002/09/02/big/img_15969
1555
+ 2002/08/02/big/img_931
1556
+ 2002/08/25/big/img_508
1557
+ 2002/08/29/big/img_18616
1558
+ 2002/07/22/big/img_839
1559
+ 2002/07/28/big/img_313
1560
+ 2003/01/14/big/img_155
1561
+ 2002/08/02/big/img_1105
1562
+ 2002/08/09/big/img_53
1563
+ 2002/08/16/big/img_469
1564
+ 2002/08/15/big/img_502
1565
+ 2002/08/20/big/img_575
1566
+ 2002/07/25/big/img_138
1567
+ 2003/01/16/big/img_579
1568
+ 2002/07/19/big/img_352
1569
+ 2003/01/14/big/img_762
1570
+ 2003/01/01/big/img_588
1571
+ 2002/08/02/big/img_981
1572
+ 2002/08/21/big/img_447
1573
+ 2002/09/01/big/img_16151
1574
+ 2003/01/14/big/img_769
1575
+ 2002/08/23/big/img_461
1576
+ 2002/08/17/big/img_240
1577
+ 2002/09/02/big/img_15220
1578
+ 2002/07/19/big/img_408
1579
+ 2002/09/02/big/img_15496
1580
+ 2002/07/29/big/img_758
1581
+ 2002/08/28/big/img_19392
1582
+ 2002/08/06/big/img_2723
1583
+ 2002/08/31/big/img_17752
1584
+ 2002/08/23/big/img_469
1585
+ 2002/08/13/big/img_515
1586
+ 2002/09/02/big/img_15551
1587
+ 2002/08/03/big/img_462
1588
+ 2002/07/24/big/img_613
1589
+ 2002/07/22/big/img_61
1590
+ 2002/08/08/big/img_171
1591
+ 2002/08/21/big/img_177
1592
+ 2003/01/14/big/img_105
1593
+ 2002/08/02/big/img_1017
1594
+ 2002/08/22/big/img_106
1595
+ 2002/07/27/big/img_542
1596
+ 2002/07/21/big/img_665
1597
+ 2002/07/23/big/img_595
1598
+ 2002/08/04/big/img_657
1599
+ 2002/08/29/big/img_19002
1600
+ 2003/01/15/big/img_550
1601
+ 2002/08/14/big/img_662
1602
+ 2002/07/20/big/img_425
1603
+ 2002/08/30/big/img_18528
1604
+ 2002/07/26/big/img_611
1605
+ 2002/07/22/big/img_849
1606
+ 2002/08/07/big/img_1655
1607
+ 2002/08/21/big/img_638
1608
+ 2003/01/17/big/img_732
1609
+ 2003/01/01/big/img_496
1610
+ 2002/08/18/big/img_713
1611
+ 2002/08/08/big/img_109
1612
+ 2002/07/27/big/img_1008
1613
+ 2002/07/20/big/img_559
1614
+ 2002/08/16/big/img_699
1615
+ 2002/08/31/big/img_17702
1616
+ 2002/07/31/big/img_1013
1617
+ 2002/08/01/big/img_2027
1618
+ 2002/08/02/big/img_1001
1619
+ 2002/08/03/big/img_210
1620
+ 2002/08/01/big/img_2087
1621
+ 2003/01/14/big/img_199
1622
+ 2002/07/29/big/img_48
1623
+ 2002/07/19/big/img_727
1624
+ 2002/08/09/big/img_249
1625
+ 2002/08/04/big/img_632
1626
+ 2002/08/22/big/img_620
1627
+ 2003/01/01/big/img_457
1628
+ 2002/08/05/big/img_3223
1629
+ 2002/07/27/big/img_240
1630
+ 2002/07/25/big/img_797
1631
+ 2002/08/13/big/img_430
1632
+ 2002/07/25/big/img_615
1633
+ 2002/08/12/big/img_28
1634
+ 2002/07/30/big/img_220
1635
+ 2002/07/24/big/img_89
1636
+ 2002/08/21/big/img_357
1637
+ 2002/08/09/big/img_590
1638
+ 2003/01/13/big/img_525
1639
+ 2002/08/17/big/img_818
1640
+ 2003/01/02/big/img_7
1641
+ 2002/07/26/big/img_636
1642
+ 2003/01/13/big/img_1122
1643
+ 2002/07/23/big/img_810
1644
+ 2002/08/20/big/img_888
1645
+ 2002/07/27/big/img_3
1646
+ 2002/08/15/big/img_451
1647
+ 2002/09/02/big/img_15787
1648
+ 2002/07/31/big/img_281
1649
+ 2002/08/05/big/img_3274
1650
+ 2002/08/07/big/img_1254
1651
+ 2002/07/31/big/img_27
1652
+ 2002/08/01/big/img_1366
1653
+ 2002/07/30/big/img_182
1654
+ 2002/08/27/big/img_19690
1655
+ 2002/07/29/big/img_68
1656
+ 2002/08/23/big/img_754
1657
+ 2002/07/30/big/img_540
1658
+ 2002/08/27/big/img_20063
1659
+ 2002/08/14/big/img_471
1660
+ 2002/08/02/big/img_615
1661
+ 2002/07/30/big/img_186
1662
+ 2002/08/25/big/img_150
1663
+ 2002/07/27/big/img_626
1664
+ 2002/07/20/big/img_225
1665
+ 2003/01/15/big/img_1252
1666
+ 2002/07/19/big/img_367
1667
+ 2003/01/15/big/img_582
1668
+ 2002/08/09/big/img_572
1669
+ 2002/08/08/big/img_428
1670
+ 2003/01/15/big/img_639
1671
+ 2002/08/28/big/img_19245
1672
+ 2002/07/24/big/img_321
1673
+ 2002/08/02/big/img_662
1674
+ 2002/08/08/big/img_1033
1675
+ 2003/01/17/big/img_867
1676
+ 2002/07/22/big/img_652
1677
+ 2003/01/14/big/img_224
1678
+ 2002/08/18/big/img_49
1679
+ 2002/07/26/big/img_46
1680
+ 2002/08/31/big/img_18021
1681
+ 2002/07/25/big/img_151
1682
+ 2002/08/23/big/img_540
1683
+ 2002/08/25/big/img_693
1684
+ 2002/07/23/big/img_340
1685
+ 2002/07/28/big/img_117
1686
+ 2002/09/02/big/img_15768
1687
+ 2002/08/26/big/img_562
1688
+ 2002/07/24/big/img_480
1689
+ 2003/01/15/big/img_341
1690
+ 2002/08/10/big/img_783
1691
+ 2002/08/20/big/img_132
1692
+ 2003/01/14/big/img_370
1693
+ 2002/07/20/big/img_720
1694
+ 2002/08/03/big/img_144
1695
+ 2002/08/20/big/img_538
1696
+ 2002/08/01/big/img_1745
1697
+ 2002/08/11/big/img_683
1698
+ 2002/08/03/big/img_328
1699
+ 2002/08/10/big/img_793
1700
+ 2002/08/14/big/img_689
1701
+ 2002/08/02/big/img_162
1702
+ 2003/01/17/big/img_411
1703
+ 2002/07/31/big/img_361
1704
+ 2002/08/15/big/img_289
1705
+ 2002/08/08/big/img_254
1706
+ 2002/08/15/big/img_996
1707
+ 2002/08/20/big/img_785
1708
+ 2002/07/24/big/img_511
1709
+ 2002/08/06/big/img_2614
1710
+ 2002/08/29/big/img_18733
1711
+ 2002/08/17/big/img_78
1712
+ 2002/07/30/big/img_378
1713
+ 2002/08/31/big/img_17947
1714
+ 2002/08/26/big/img_88
1715
+ 2002/07/30/big/img_558
1716
+ 2002/08/02/big/img_67
1717
+ 2003/01/14/big/img_325
1718
+ 2002/07/29/big/img_1357
1719
+ 2002/07/19/big/img_391
1720
+ 2002/07/30/big/img_307
1721
+ 2003/01/13/big/img_219
1722
+ 2002/07/24/big/img_807
1723
+ 2002/08/23/big/img_543
1724
+ 2002/08/29/big/img_18620
1725
+ 2002/07/22/big/img_769
1726
+ 2002/08/26/big/img_503
1727
+ 2002/07/30/big/img_78
1728
+ 2002/08/14/big/img_1036
1729
+ 2002/08/09/big/img_58
1730
+ 2002/07/24/big/img_616
1731
+ 2002/08/02/big/img_464
1732
+ 2002/07/26/big/img_576
1733
+ 2002/07/22/big/img_273
1734
+ 2003/01/16/big/img_470
1735
+ 2002/07/29/big/img_329
1736
+ 2002/07/30/big/img_1086
1737
+ 2002/07/31/big/img_353
1738
+ 2002/09/02/big/img_15275
1739
+ 2003/01/17/big/img_555
1740
+ 2002/08/26/big/img_212
1741
+ 2002/08/01/big/img_1692
1742
+ 2003/01/15/big/img_600
1743
+ 2002/07/29/big/img_825
1744
+ 2002/08/08/big/img_68
1745
+ 2002/08/10/big/img_719
1746
+ 2002/07/31/big/img_636
1747
+ 2002/07/29/big/img_325
1748
+ 2002/07/21/big/img_515
1749
+ 2002/07/22/big/img_705
1750
+ 2003/01/13/big/img_818
1751
+ 2002/08/09/big/img_486
1752
+ 2002/08/22/big/img_141
1753
+ 2002/07/22/big/img_303
1754
+ 2002/08/09/big/img_393
1755
+ 2002/07/29/big/img_963
1756
+ 2002/08/02/big/img_1215
1757
+ 2002/08/19/big/img_674
1758
+ 2002/08/12/big/img_690
1759
+ 2002/08/21/big/img_637
1760
+ 2002/08/21/big/img_841
1761
+ 2002/08/24/big/img_71
1762
+ 2002/07/25/big/img_596
1763
+ 2002/07/24/big/img_864
1764
+ 2002/08/18/big/img_293
1765
+ 2003/01/14/big/img_657
1766
+ 2002/08/15/big/img_411
1767
+ 2002/08/16/big/img_348
1768
+ 2002/08/05/big/img_3157
1769
+ 2002/07/20/big/img_663
1770
+ 2003/01/13/big/img_654
1771
+ 2003/01/16/big/img_433
1772
+ 2002/08/30/big/img_18200
1773
+ 2002/08/12/big/img_226
1774
+ 2003/01/16/big/img_491
1775
+ 2002/08/08/big/img_666
1776
+ 2002/07/19/big/img_576
1777
+ 2003/01/15/big/img_776
1778
+ 2003/01/16/big/img_899
1779
+ 2002/07/19/big/img_397
1780
+ 2002/08/14/big/img_44
1781
+ 2003/01/15/big/img_762
1782
+ 2002/08/02/big/img_982
1783
+ 2002/09/02/big/img_15234
1784
+ 2002/08/17/big/img_556
1785
+ 2002/08/21/big/img_410
1786
+ 2002/08/21/big/img_386
1787
+ 2002/07/19/big/img_690
1788
+ 2002/08/05/big/img_3052
1789
+ 2002/08/14/big/img_219
1790
+ 2002/08/16/big/img_273
1791
+ 2003/01/15/big/img_752
1792
+ 2002/08/08/big/img_184
1793
+ 2002/07/31/big/img_743
1794
+ 2002/08/23/big/img_338
1795
+ 2003/01/14/big/img_1055
1796
+ 2002/08/05/big/img_3405
1797
+ 2003/01/15/big/img_17
1798
+ 2002/08/03/big/img_141
1799
+ 2002/08/14/big/img_549
1800
+ 2002/07/27/big/img_1034
1801
+ 2002/07/31/big/img_932
1802
+ 2002/08/30/big/img_18487
1803
+ 2002/09/02/big/img_15814
1804
+ 2002/08/01/big/img_2086
1805
+ 2002/09/01/big/img_16535
1806
+ 2002/07/22/big/img_500
1807
+ 2003/01/13/big/img_400
1808
+ 2002/08/25/big/img_607
1809
+ 2002/08/30/big/img_18384
1810
+ 2003/01/14/big/img_951
1811
+ 2002/08/13/big/img_1150
1812
+ 2002/08/08/big/img_1022
1813
+ 2002/08/10/big/img_428
1814
+ 2002/08/28/big/img_19242
1815
+ 2002/08/05/big/img_3098
1816
+ 2002/07/23/big/img_400
1817
+ 2002/08/26/big/img_365
1818
+ 2002/07/20/big/img_318
1819
+ 2002/08/13/big/img_740
1820
+ 2003/01/16/big/img_37
1821
+ 2002/08/26/big/img_274
1822
+ 2002/08/02/big/img_205
1823
+ 2002/08/21/big/img_695
1824
+ 2002/08/06/big/img_2289
1825
+ 2002/08/20/big/img_794
1826
+ 2002/08/18/big/img_438
1827
+ 2002/08/07/big/img_1380
1828
+ 2002/08/02/big/img_737
1829
+ 2002/08/07/big/img_1651
1830
+ 2002/08/15/big/img_1238
1831
+ 2002/08/01/big/img_1681
1832
+ 2002/08/06/big/img_3017
1833
+ 2002/07/23/big/img_706
1834
+ 2002/07/31/big/img_392
1835
+ 2002/08/09/big/img_539
1836
+ 2002/07/29/big/img_835
1837
+ 2002/08/26/big/img_723
1838
+ 2002/08/28/big/img_19235
1839
+ 2003/01/16/big/img_353
1840
+ 2002/08/10/big/img_150
1841
+ 2002/08/29/big/img_19025
1842
+ 2002/08/21/big/img_310
1843
+ 2002/08/10/big/img_823
1844
+ 2002/07/26/big/img_981
1845
+ 2002/08/11/big/img_288
1846
+ 2002/08/19/big/img_534
1847
+ 2002/08/21/big/img_300
1848
+ 2002/07/31/big/img_49
1849
+ 2002/07/30/big/img_469
1850
+ 2002/08/28/big/img_19197
1851
+ 2002/08/25/big/img_205
1852
+ 2002/08/10/big/img_390
1853
+ 2002/08/23/big/img_291
1854
+ 2002/08/26/big/img_230
1855
+ 2002/08/18/big/img_76
1856
+ 2002/07/23/big/img_409
1857
+ 2002/08/14/big/img_1053
1858
+ 2003/01/14/big/img_291
1859
+ 2002/08/10/big/img_503
1860
+ 2002/08/27/big/img_19928
1861
+ 2002/08/03/big/img_563
1862
+ 2002/08/17/big/img_250
1863
+ 2002/08/06/big/img_2381
1864
+ 2002/08/17/big/img_948
1865
+ 2002/08/06/big/img_2710
1866
+ 2002/07/22/big/img_696
1867
+ 2002/07/31/big/img_670
1868
+ 2002/08/12/big/img_594
1869
+ 2002/07/29/big/img_624
1870
+ 2003/01/17/big/img_934
1871
+ 2002/08/03/big/img_584
1872
+ 2002/08/22/big/img_1003
1873
+ 2002/08/05/big/img_3396
1874
+ 2003/01/13/big/img_570
1875
+ 2002/08/02/big/img_219
1876
+ 2002/09/02/big/img_15774
1877
+ 2002/08/16/big/img_818
1878
+ 2002/08/23/big/img_402
1879
+ 2003/01/14/big/img_552
1880
+ 2002/07/29/big/img_71
1881
+ 2002/08/05/big/img_3592
1882
+ 2002/08/16/big/img_80
1883
+ 2002/07/27/big/img_672
1884
+ 2003/01/13/big/img_470
1885
+ 2003/01/16/big/img_702
1886
+ 2002/09/01/big/img_16130
1887
+ 2002/08/08/big/img_240
1888
+ 2002/09/01/big/img_16338
1889
+ 2002/07/26/big/img_312
1890
+ 2003/01/14/big/img_538
1891
+ 2002/07/20/big/img_695
1892
+ 2002/08/30/big/img_18098
1893
+ 2002/08/25/big/img_259
1894
+ 2002/08/16/big/img_1042
1895
+ 2002/08/09/big/img_837
1896
+ 2002/08/31/big/img_17760
1897
+ 2002/07/31/big/img_14
1898
+ 2002/08/09/big/img_361
1899
+ 2003/01/16/big/img_107
1900
+ 2002/08/14/big/img_124
1901
+ 2002/07/19/big/img_463
1902
+ 2003/01/15/big/img_275
1903
+ 2002/07/25/big/img_1151
1904
+ 2002/07/29/big/img_1501
1905
+ 2002/08/27/big/img_19889
1906
+ 2002/08/29/big/img_18603
1907
+ 2003/01/17/big/img_601
1908
+ 2002/08/25/big/img_355
1909
+ 2002/08/08/big/img_297
1910
+ 2002/08/20/big/img_290
1911
+ 2002/07/31/big/img_195
1912
+ 2003/01/01/big/img_336
1913
+ 2002/08/18/big/img_369
1914
+ 2002/07/25/big/img_621
1915
+ 2002/08/11/big/img_508
1916
+ 2003/01/14/big/img_458
1917
+ 2003/01/15/big/img_795
1918
+ 2002/08/12/big/img_498
1919
+ 2002/08/01/big/img_1734
1920
+ 2002/08/02/big/img_246
1921
+ 2002/08/16/big/img_565
1922
+ 2002/08/11/big/img_475
1923
+ 2002/08/22/big/img_408
1924
+ 2002/07/28/big/img_78
1925
+ 2002/07/21/big/img_81
1926
+ 2003/01/14/big/img_697
1927
+ 2002/08/14/big/img_661
1928
+ 2002/08/15/big/img_507
1929
+ 2002/08/19/big/img_55
1930
+ 2002/07/22/big/img_152
1931
+ 2003/01/14/big/img_470
1932
+ 2002/08/03/big/img_379
1933
+ 2002/08/22/big/img_506
1934
+ 2003/01/16/big/img_966
1935
+ 2002/08/18/big/img_698
1936
+ 2002/08/24/big/img_528
1937
+ 2002/08/23/big/img_10
1938
+ 2002/08/01/big/img_1655
1939
+ 2002/08/22/big/img_953
1940
+ 2002/07/19/big/img_630
1941
+ 2002/07/22/big/img_889
1942
+ 2002/08/16/big/img_351
1943
+ 2003/01/16/big/img_83
1944
+ 2002/07/19/big/img_805
1945
+ 2002/08/14/big/img_704
1946
+ 2002/07/19/big/img_389
1947
+ 2002/08/31/big/img_17765
1948
+ 2002/07/29/big/img_606
1949
+ 2003/01/17/big/img_939
1950
+ 2002/09/02/big/img_15081
1951
+ 2002/08/21/big/img_181
1952
+ 2002/07/29/big/img_1321
1953
+ 2002/07/21/big/img_497
1954
+ 2002/07/20/big/img_539
1955
+ 2002/08/24/big/img_119
1956
+ 2002/08/01/big/img_1281
1957
+ 2002/07/26/big/img_207
1958
+ 2002/07/26/big/img_432
1959
+ 2002/07/27/big/img_1006
1960
+ 2002/08/05/big/img_3087
1961
+ 2002/08/14/big/img_252
1962
+ 2002/08/14/big/img_798
1963
+ 2002/07/24/big/img_538
1964
+ 2002/09/02/big/img_15507
1965
+ 2002/08/08/big/img_901
1966
+ 2003/01/14/big/img_557
1967
+ 2002/08/07/big/img_1819
1968
+ 2002/08/04/big/img_470
1969
+ 2002/08/01/big/img_1504
1970
+ 2002/08/16/big/img_1070
1971
+ 2002/08/16/big/img_372
1972
+ 2002/08/23/big/img_416
1973
+ 2002/08/30/big/img_18208
1974
+ 2002/08/01/big/img_2043
1975
+ 2002/07/22/big/img_385
1976
+ 2002/08/22/big/img_466
1977
+ 2002/08/21/big/img_869
1978
+ 2002/08/28/big/img_19429
1979
+ 2002/08/02/big/img_770
1980
+ 2002/07/23/big/img_433
1981
+ 2003/01/14/big/img_13
1982
+ 2002/07/27/big/img_953
1983
+ 2002/09/02/big/img_15728
1984
+ 2002/08/01/big/img_1361
1985
+ 2002/08/29/big/img_18897
1986
+ 2002/08/26/big/img_534
1987
+ 2002/08/11/big/img_121
1988
+ 2002/08/26/big/img_20130
1989
+ 2002/07/31/big/img_363
1990
+ 2002/08/13/big/img_978
1991
+ 2002/07/25/big/img_835
1992
+ 2002/08/02/big/img_906
1993
+ 2003/01/14/big/img_548
1994
+ 2002/07/30/big/img_80
1995
+ 2002/07/26/big/img_982
1996
+ 2003/01/16/big/img_99
1997
+ 2002/08/19/big/img_362
1998
+ 2002/08/24/big/img_376
1999
+ 2002/08/07/big/img_1264
2000
+ 2002/07/27/big/img_938
2001
+ 2003/01/17/big/img_535
2002
+ 2002/07/26/big/img_457
2003
+ 2002/08/08/big/img_848
2004
+ 2003/01/15/big/img_859
2005
+ 2003/01/15/big/img_622
2006
+ 2002/07/30/big/img_403
2007
+ 2002/07/29/big/img_217
2008
+ 2002/07/26/big/img_891
2009
+ 2002/07/24/big/img_70
2010
+ 2002/08/25/big/img_619
2011
+ 2002/08/05/big/img_3375
2012
+ 2002/08/01/big/img_2160
2013
+ 2002/08/06/big/img_2227
2014
+ 2003/01/14/big/img_117
2015
+ 2002/08/14/big/img_227
2016
+ 2002/08/13/big/img_565
2017
+ 2002/08/19/big/img_625
2018
+ 2002/08/03/big/img_812
2019
+ 2002/07/24/big/img_41
2020
+ 2002/08/16/big/img_235
2021
+ 2002/07/29/big/img_759
2022
+ 2002/07/21/big/img_433
2023
+ 2002/07/29/big/img_190
2024
+ 2003/01/16/big/img_435
2025
+ 2003/01/13/big/img_708
2026
+ 2002/07/30/big/img_57
2027
+ 2002/08/22/big/img_162
2028
+ 2003/01/01/big/img_558
2029
+ 2003/01/15/big/img_604
2030
+ 2002/08/16/big/img_935
2031
+ 2002/08/20/big/img_394
2032
+ 2002/07/28/big/img_465
2033
+ 2002/09/02/big/img_15534
2034
+ 2002/08/16/big/img_87
2035
+ 2002/07/22/big/img_469
2036
+ 2002/08/12/big/img_245
2037
+ 2003/01/13/big/img_236
2038
+ 2002/08/06/big/img_2736
2039
+ 2002/08/03/big/img_348
2040
+ 2003/01/14/big/img_218
2041
+ 2002/07/26/big/img_232
2042
+ 2003/01/15/big/img_244
2043
+ 2002/07/25/big/img_1121
2044
+ 2002/08/01/big/img_1484
2045
+ 2002/07/26/big/img_541
2046
+ 2002/08/07/big/img_1244
2047
+ 2002/07/31/big/img_3
2048
+ 2002/08/30/big/img_18437
2049
+ 2002/08/29/big/img_19094
2050
+ 2002/08/01/big/img_1355
2051
+ 2002/08/19/big/img_338
2052
+ 2002/07/19/big/img_255
2053
+ 2002/07/21/big/img_76
2054
+ 2002/08/25/big/img_199
2055
+ 2002/08/12/big/img_740
2056
+ 2002/07/30/big/img_852
2057
+ 2002/08/15/big/img_599
2058
+ 2002/08/23/big/img_254
2059
+ 2002/08/19/big/img_125
2060
+ 2002/07/24/big/img_2
2061
+ 2002/08/04/big/img_145
2062
+ 2002/08/05/big/img_3137
2063
+ 2002/07/28/big/img_463
2064
+ 2003/01/14/big/img_801
2065
+ 2002/07/23/big/img_366
2066
+ 2002/08/26/big/img_600
2067
+ 2002/08/26/big/img_649
2068
+ 2002/09/02/big/img_15849
2069
+ 2002/07/26/big/img_248
2070
+ 2003/01/13/big/img_200
2071
+ 2002/08/07/big/img_1794
2072
+ 2002/08/31/big/img_17270
2073
+ 2002/08/23/big/img_608
2074
+ 2003/01/13/big/img_837
2075
+ 2002/08/23/big/img_581
2076
+ 2002/08/20/big/img_754
2077
+ 2002/08/18/big/img_183
2078
+ 2002/08/20/big/img_328
2079
+ 2002/07/22/big/img_494
2080
+ 2002/07/29/big/img_399
2081
+ 2002/08/28/big/img_19284
2082
+ 2002/08/08/big/img_566
2083
+ 2002/07/25/big/img_376
2084
+ 2002/07/23/big/img_138
2085
+ 2002/07/25/big/img_435
2086
+ 2002/08/17/big/img_685
2087
+ 2002/07/19/big/img_90
2088
+ 2002/07/20/big/img_716
2089
+ 2002/08/31/big/img_17458
2090
+ 2002/08/26/big/img_461
2091
+ 2002/07/25/big/img_355
2092
+ 2002/08/06/big/img_2152
2093
+ 2002/07/27/big/img_932
2094
+ 2002/07/23/big/img_232
2095
+ 2002/08/08/big/img_1020
2096
+ 2002/07/31/big/img_366
2097
+ 2002/08/06/big/img_2667
2098
+ 2002/08/21/big/img_465
2099
+ 2002/08/15/big/img_305
2100
+ 2002/08/02/big/img_247
2101
+ 2002/07/28/big/img_46
2102
+ 2002/08/27/big/img_19922
2103
+ 2002/08/23/big/img_643
2104
+ 2003/01/13/big/img_624
2105
+ 2002/08/23/big/img_625
2106
+ 2002/08/05/big/img_3787
2107
+ 2003/01/13/big/img_627
2108
+ 2002/09/01/big/img_16381
2109
+ 2002/08/05/big/img_3668
2110
+ 2002/07/21/big/img_535
2111
+ 2002/08/27/big/img_19680
2112
+ 2002/07/22/big/img_413
2113
+ 2002/07/29/big/img_481
2114
+ 2003/01/15/big/img_496
2115
+ 2002/07/23/big/img_701
2116
+ 2002/08/29/big/img_18670
2117
+ 2002/07/28/big/img_319
2118
+ 2003/01/14/big/img_517
2119
+ 2002/07/26/big/img_256
2120
+ 2003/01/16/big/img_593
2121
+ 2002/07/30/big/img_956
2122
+ 2002/07/30/big/img_667
2123
+ 2002/07/25/big/img_100
2124
+ 2002/08/11/big/img_570
2125
+ 2002/07/26/big/img_745
2126
+ 2002/08/04/big/img_834
2127
+ 2002/08/25/big/img_521
2128
+ 2002/08/01/big/img_2148
2129
+ 2002/09/02/big/img_15183
2130
+ 2002/08/22/big/img_514
2131
+ 2002/08/23/big/img_477
2132
+ 2002/07/23/big/img_336
2133
+ 2002/07/26/big/img_481
2134
+ 2002/08/20/big/img_409
2135
+ 2002/07/23/big/img_918
2136
+ 2002/08/09/big/img_474
2137
+ 2002/08/02/big/img_929
2138
+ 2002/08/31/big/img_17932
2139
+ 2002/08/19/big/img_161
2140
+ 2002/08/09/big/img_667
2141
+ 2002/07/31/big/img_805
2142
+ 2002/09/02/big/img_15678
2143
+ 2002/08/31/big/img_17509
2144
+ 2002/08/29/big/img_18998
2145
+ 2002/07/23/big/img_301
2146
+ 2002/08/07/big/img_1612
2147
+ 2002/08/06/big/img_2472
2148
+ 2002/07/23/big/img_466
2149
+ 2002/08/27/big/img_19634
2150
+ 2003/01/16/big/img_16
2151
+ 2002/08/14/big/img_193
2152
+ 2002/08/21/big/img_340
2153
+ 2002/08/27/big/img_19799
2154
+ 2002/08/01/big/img_1345
2155
+ 2002/08/07/big/img_1448
2156
+ 2002/08/11/big/img_324
2157
+ 2003/01/16/big/img_754
2158
+ 2002/08/13/big/img_418
2159
+ 2003/01/16/big/img_544
2160
+ 2002/08/19/big/img_135
2161
+ 2002/08/10/big/img_455
2162
+ 2002/08/10/big/img_693
2163
+ 2002/08/31/big/img_17967
2164
+ 2002/08/28/big/img_19229
2165
+ 2002/08/04/big/img_811
2166
+ 2002/09/01/big/img_16225
2167
+ 2003/01/16/big/img_428
2168
+ 2002/09/02/big/img_15295
2169
+ 2002/07/26/big/img_108
2170
+ 2002/07/21/big/img_477
2171
+ 2002/08/07/big/img_1354
2172
+ 2002/08/23/big/img_246
2173
+ 2002/08/16/big/img_652
2174
+ 2002/07/27/big/img_553
2175
+ 2002/07/31/big/img_346
2176
+ 2002/08/04/big/img_537
2177
+ 2002/08/08/big/img_498
2178
+ 2002/08/29/big/img_18956
2179
+ 2003/01/13/big/img_922
2180
+ 2002/08/31/big/img_17425
2181
+ 2002/07/26/big/img_438
2182
+ 2002/08/19/big/img_185
2183
+ 2003/01/16/big/img_33
2184
+ 2002/08/10/big/img_252
2185
+ 2002/07/29/big/img_598
2186
+ 2002/08/27/big/img_19820
2187
+ 2002/08/06/big/img_2664
2188
+ 2002/08/20/big/img_705
2189
+ 2003/01/14/big/img_816
2190
+ 2002/08/03/big/img_552
2191
+ 2002/07/25/big/img_561
2192
+ 2002/07/25/big/img_934
2193
+ 2002/08/01/big/img_1893
2194
+ 2003/01/14/big/img_746
2195
+ 2003/01/16/big/img_519
2196
+ 2002/08/03/big/img_681
2197
+ 2002/07/24/big/img_808
2198
+ 2002/08/14/big/img_803
2199
+ 2002/08/25/big/img_155
2200
+ 2002/07/30/big/img_1107
2201
+ 2002/08/29/big/img_18882
2202
+ 2003/01/15/big/img_598
2203
+ 2002/08/19/big/img_122
2204
+ 2002/07/30/big/img_428
2205
+ 2002/07/24/big/img_684
2206
+ 2002/08/22/big/img_192
2207
+ 2002/08/22/big/img_543
2208
+ 2002/08/07/big/img_1318
2209
+ 2002/08/18/big/img_25
2210
+ 2002/07/26/big/img_583
2211
+ 2002/07/20/big/img_464
2212
+ 2002/08/19/big/img_664
2213
+ 2002/08/24/big/img_861
2214
+ 2002/09/01/big/img_16136
2215
+ 2002/08/22/big/img_400
2216
+ 2002/08/12/big/img_445
2217
+ 2003/01/14/big/img_174
2218
+ 2002/08/27/big/img_19677
2219
+ 2002/08/31/big/img_17214
2220
+ 2002/08/30/big/img_18175
2221
+ 2003/01/17/big/img_402
2222
+ 2002/08/06/big/img_2396
2223
+ 2002/08/18/big/img_448
2224
+ 2002/08/21/big/img_165
2225
+ 2002/08/31/big/img_17609
2226
+ 2003/01/01/big/img_151
2227
+ 2002/08/26/big/img_372
2228
+ 2002/09/02/big/img_15994
2229
+ 2002/07/26/big/img_660
2230
+ 2002/09/02/big/img_15197
2231
+ 2002/07/29/big/img_258
2232
+ 2002/08/30/big/img_18525
2233
+ 2003/01/13/big/img_368
2234
+ 2002/07/29/big/img_1538
2235
+ 2002/07/21/big/img_787
2236
+ 2002/08/18/big/img_152
2237
+ 2002/08/06/big/img_2379
2238
+ 2003/01/17/big/img_864
2239
+ 2002/08/27/big/img_19998
2240
+ 2002/08/01/big/img_1634
2241
+ 2002/07/25/big/img_414
2242
+ 2002/08/22/big/img_627
2243
+ 2002/08/07/big/img_1669
2244
+ 2002/08/16/big/img_1052
2245
+ 2002/08/31/big/img_17796
2246
+ 2002/08/18/big/img_199
2247
+ 2002/09/02/big/img_15147
2248
+ 2002/08/09/big/img_460
2249
+ 2002/08/14/big/img_581
2250
+ 2002/08/30/big/img_18286
2251
+ 2002/07/26/big/img_337
2252
+ 2002/08/18/big/img_589
2253
+ 2003/01/14/big/img_866
2254
+ 2002/07/20/big/img_624
2255
+ 2002/08/01/big/img_1801
2256
+ 2002/07/24/big/img_683
2257
+ 2002/08/09/big/img_725
2258
+ 2003/01/14/big/img_34
2259
+ 2002/07/30/big/img_144
2260
+ 2002/07/30/big/img_706
2261
+ 2002/08/08/big/img_394
2262
+ 2002/08/19/big/img_619
2263
+ 2002/08/06/big/img_2703
2264
+ 2002/08/29/big/img_19034
2265
+ 2002/07/24/big/img_67
2266
+ 2002/08/27/big/img_19841
2267
+ 2002/08/19/big/img_427
2268
+ 2003/01/14/big/img_333
2269
+ 2002/09/01/big/img_16406
2270
+ 2002/07/19/big/img_882
2271
+ 2002/08/17/big/img_238
2272
+ 2003/01/14/big/img_739
2273
+ 2002/07/22/big/img_151
2274
+ 2002/08/21/big/img_743
2275
+ 2002/07/25/big/img_1048
2276
+ 2002/07/30/big/img_395
2277
+ 2003/01/13/big/img_584
2278
+ 2002/08/13/big/img_742
2279
+ 2002/08/13/big/img_1168
2280
+ 2003/01/14/big/img_147
2281
+ 2002/07/26/big/img_803
2282
+ 2002/08/05/big/img_3298
2283
+ 2002/08/07/big/img_1451
2284
+ 2002/08/16/big/img_424
2285
+ 2002/07/29/big/img_1069
2286
+ 2002/09/01/big/img_16735
2287
+ 2002/07/21/big/img_637
2288
+ 2003/01/14/big/img_585
2289
+ 2002/08/02/big/img_358
2290
+ 2003/01/13/big/img_358
2291
+ 2002/08/14/big/img_198
2292
+ 2002/08/17/big/img_935
2293
+ 2002/08/04/big/img_42
2294
+ 2002/08/30/big/img_18245
2295
+ 2002/07/25/big/img_158
2296
+ 2002/08/22/big/img_744
2297
+ 2002/08/06/big/img_2291
2298
+ 2002/08/05/big/img_3044
2299
+ 2002/07/30/big/img_272
2300
+ 2002/08/23/big/img_641
2301
+ 2002/07/24/big/img_797
2302
+ 2002/07/30/big/img_392
2303
+ 2003/01/14/big/img_447
2304
+ 2002/07/31/big/img_898
2305
+ 2002/08/06/big/img_2812
2306
+ 2002/08/13/big/img_564
2307
+ 2002/07/22/big/img_43
2308
+ 2002/07/26/big/img_634
2309
+ 2002/07/19/big/img_843
2310
+ 2002/08/26/big/img_58
2311
+ 2002/07/21/big/img_375
2312
+ 2002/08/25/big/img_729
2313
+ 2002/07/19/big/img_561
2314
+ 2003/01/15/big/img_884
2315
+ 2002/07/25/big/img_891
2316
+ 2002/08/09/big/img_558
2317
+ 2002/08/26/big/img_587
2318
+ 2002/08/13/big/img_1146
2319
+ 2002/09/02/big/img_15153
2320
+ 2002/07/26/big/img_316
2321
+ 2002/08/01/big/img_1940
2322
+ 2002/08/26/big/img_90
2323
+ 2003/01/13/big/img_347
2324
+ 2002/07/25/big/img_520
2325
+ 2002/08/29/big/img_18718
2326
+ 2002/08/28/big/img_19219
2327
+ 2002/08/13/big/img_375
2328
+ 2002/07/20/big/img_719
2329
+ 2002/08/31/big/img_17431
2330
+ 2002/07/28/big/img_192
2331
+ 2002/08/26/big/img_259
2332
+ 2002/08/18/big/img_484
2333
+ 2002/07/29/big/img_580
2334
+ 2002/07/26/big/img_84
2335
+ 2002/08/02/big/img_302
2336
+ 2002/08/31/big/img_17007
2337
+ 2003/01/15/big/img_543
2338
+ 2002/09/01/big/img_16488
2339
+ 2002/08/22/big/img_798
2340
+ 2002/07/30/big/img_383
2341
+ 2002/08/04/big/img_668
2342
+ 2002/08/13/big/img_156
2343
+ 2002/08/07/big/img_1353
2344
+ 2002/07/25/big/img_281
2345
+ 2003/01/14/big/img_587
2346
+ 2003/01/15/big/img_524
2347
+ 2002/08/19/big/img_726
2348
+ 2002/08/21/big/img_709
2349
+ 2002/08/26/big/img_465
2350
+ 2002/07/31/big/img_658
2351
+ 2002/08/28/big/img_19148
2352
+ 2002/07/23/big/img_423
2353
+ 2002/08/16/big/img_758
2354
+ 2002/08/22/big/img_523
2355
+ 2002/08/16/big/img_591
2356
+ 2002/08/23/big/img_845
2357
+ 2002/07/26/big/img_678
2358
+ 2002/08/09/big/img_806
2359
+ 2002/08/06/big/img_2369
2360
+ 2002/07/29/big/img_457
2361
+ 2002/07/19/big/img_278
2362
+ 2002/08/30/big/img_18107
2363
+ 2002/07/26/big/img_444
2364
+ 2002/08/20/big/img_278
2365
+ 2002/08/26/big/img_92
2366
+ 2002/08/26/big/img_257
2367
+ 2002/07/25/big/img_266
2368
+ 2002/08/05/big/img_3829
2369
+ 2002/07/26/big/img_757
2370
+ 2002/07/29/big/img_1536
2371
+ 2002/08/09/big/img_472
2372
+ 2003/01/17/big/img_480
2373
+ 2002/08/28/big/img_19355
2374
+ 2002/07/26/big/img_97
2375
+ 2002/08/06/big/img_2503
2376
+ 2002/07/19/big/img_254
2377
+ 2002/08/01/big/img_1470
2378
+ 2002/08/21/big/img_42
2379
+ 2002/08/20/big/img_217
2380
+ 2002/08/06/big/img_2459
2381
+ 2002/07/19/big/img_552
2382
+ 2002/08/13/big/img_717
2383
+ 2002/08/12/big/img_586
2384
+ 2002/08/20/big/img_411
2385
+ 2003/01/13/big/img_768
2386
+ 2002/08/07/big/img_1747
2387
+ 2002/08/15/big/img_385
2388
+ 2002/08/01/big/img_1648
2389
+ 2002/08/15/big/img_311
2390
+ 2002/08/21/big/img_95
2391
+ 2002/08/09/big/img_108
2392
+ 2002/08/21/big/img_398
2393
+ 2002/08/17/big/img_340
2394
+ 2002/08/14/big/img_474
2395
+ 2002/08/13/big/img_294
2396
+ 2002/08/24/big/img_840
2397
+ 2002/08/09/big/img_808
2398
+ 2002/08/23/big/img_491
2399
+ 2002/07/28/big/img_33
2400
+ 2003/01/13/big/img_664
2401
+ 2002/08/02/big/img_261
2402
+ 2002/08/09/big/img_591
2403
+ 2002/07/26/big/img_309
2404
+ 2003/01/14/big/img_372
2405
+ 2002/08/19/big/img_581
2406
+ 2002/08/19/big/img_168
2407
+ 2002/08/26/big/img_422
2408
+ 2002/07/24/big/img_106
2409
+ 2002/08/01/big/img_1936
2410
+ 2002/08/05/big/img_3764
2411
+ 2002/08/21/big/img_266
2412
+ 2002/08/31/big/img_17968
2413
+ 2002/08/01/big/img_1941
2414
+ 2002/08/15/big/img_550
2415
+ 2002/08/14/big/img_13
2416
+ 2002/07/30/big/img_171
2417
+ 2003/01/13/big/img_490
2418
+ 2002/07/25/big/img_427
2419
+ 2002/07/19/big/img_770
2420
+ 2002/08/12/big/img_759
2421
+ 2003/01/15/big/img_1360
2422
+ 2002/08/05/big/img_3692
2423
+ 2003/01/16/big/img_30
2424
+ 2002/07/25/big/img_1026
2425
+ 2002/07/22/big/img_288
2426
+ 2002/08/29/big/img_18801
2427
+ 2002/07/24/big/img_793
2428
+ 2002/08/13/big/img_178
2429
+ 2002/08/06/big/img_2322
2430
+ 2003/01/14/big/img_560
2431
+ 2002/08/18/big/img_408
2432
+ 2003/01/16/big/img_915
2433
+ 2003/01/16/big/img_679
2434
+ 2002/08/07/big/img_1552
2435
+ 2002/08/29/big/img_19050
2436
+ 2002/08/01/big/img_2172
2437
+ 2002/07/31/big/img_30
2438
+ 2002/07/30/big/img_1019
2439
+ 2002/07/30/big/img_587
2440
+ 2003/01/13/big/img_773
2441
+ 2002/07/30/big/img_410
2442
+ 2002/07/28/big/img_65
2443
+ 2002/08/05/big/img_3138
2444
+ 2002/07/23/big/img_541
2445
+ 2002/08/22/big/img_963
2446
+ 2002/07/27/big/img_657
2447
+ 2002/07/30/big/img_1051
2448
+ 2003/01/16/big/img_150
2449
+ 2002/07/31/big/img_519
2450
+ 2002/08/01/big/img_1961
2451
+ 2002/08/05/big/img_3752
2452
+ 2002/07/23/big/img_631
2453
+ 2003/01/14/big/img_237
2454
+ 2002/07/28/big/img_21
2455
+ 2002/07/22/big/img_813
2456
+ 2002/08/05/big/img_3563
2457
+ 2003/01/17/big/img_620
2458
+ 2002/07/19/big/img_523
2459
+ 2002/07/30/big/img_904
2460
+ 2002/08/29/big/img_18642
2461
+ 2002/08/11/big/img_492
2462
+ 2002/08/01/big/img_2130
2463
+ 2002/07/25/big/img_618
2464
+ 2002/08/17/big/img_305
2465
+ 2003/01/16/big/img_520
2466
+ 2002/07/26/big/img_495
2467
+ 2002/08/17/big/img_164
2468
+ 2002/08/03/big/img_440
2469
+ 2002/07/24/big/img_441
2470
+ 2002/08/06/big/img_2146
2471
+ 2002/08/11/big/img_558
2472
+ 2002/08/02/big/img_545
2473
+ 2002/08/31/big/img_18090
2474
+ 2003/01/01/big/img_136
2475
+ 2002/07/25/big/img_1099
2476
+ 2003/01/13/big/img_728
2477
+ 2003/01/16/big/img_197
2478
+ 2002/07/26/big/img_651
2479
+ 2002/08/11/big/img_676
2480
+ 2003/01/15/big/img_10
2481
+ 2002/08/21/big/img_250
2482
+ 2002/08/14/big/img_325
2483
+ 2002/08/04/big/img_390
2484
+ 2002/07/24/big/img_554
2485
+ 2003/01/16/big/img_333
2486
+ 2002/07/31/big/img_922
2487
+ 2002/09/02/big/img_15586
2488
+ 2003/01/16/big/img_184
2489
+ 2002/07/22/big/img_766
2490
+ 2002/07/21/big/img_608
2491
+ 2002/08/07/big/img_1578
2492
+ 2002/08/17/big/img_961
2493
+ 2002/07/27/big/img_324
2494
+ 2002/08/05/big/img_3765
2495
+ 2002/08/23/big/img_462
2496
+ 2003/01/16/big/img_382
2497
+ 2002/08/27/big/img_19838
2498
+ 2002/08/01/big/img_1505
2499
+ 2002/08/21/big/img_662
2500
+ 2002/08/14/big/img_605
2501
+ 2002/08/19/big/img_816
2502
+ 2002/07/29/big/img_136
2503
+ 2002/08/20/big/img_719
2504
+ 2002/08/06/big/img_2826
2505
+ 2002/08/10/big/img_630
2506
+ 2003/01/17/big/img_973
2507
+ 2002/08/14/big/img_116
2508
+ 2002/08/02/big/img_666
2509
+ 2002/08/21/big/img_710
2510
+ 2002/08/05/big/img_55
2511
+ 2002/07/31/big/img_229
2512
+ 2002/08/01/big/img_1549
2513
+ 2002/07/23/big/img_432
2514
+ 2002/07/21/big/img_430
2515
+ 2002/08/21/big/img_549
2516
+ 2002/08/08/big/img_985
2517
+ 2002/07/20/big/img_610
2518
+ 2002/07/23/big/img_978
2519
+ 2002/08/23/big/img_219
2520
+ 2002/07/25/big/img_175
2521
+ 2003/01/15/big/img_230
2522
+ 2002/08/23/big/img_385
2523
+ 2002/07/31/big/img_879
2524
+ 2002/08/12/big/img_495
2525
+ 2002/08/22/big/img_499
2526
+ 2002/08/30/big/img_18322
2527
+ 2002/08/15/big/img_795
2528
+ 2002/08/13/big/img_835
2529
+ 2003/01/17/big/img_930
2530
+ 2002/07/30/big/img_873
2531
+ 2002/08/11/big/img_257
2532
+ 2002/07/31/big/img_593
2533
+ 2002/08/21/big/img_916
2534
+ 2003/01/13/big/img_814
2535
+ 2002/07/25/big/img_722
2536
+ 2002/08/16/big/img_379
2537
+ 2002/07/31/big/img_497
2538
+ 2002/07/22/big/img_602
2539
+ 2002/08/21/big/img_642
2540
+ 2002/08/21/big/img_614
2541
+ 2002/08/23/big/img_482
2542
+ 2002/07/29/big/img_603
2543
+ 2002/08/13/big/img_705
2544
+ 2002/07/23/big/img_833
2545
+ 2003/01/14/big/img_511
2546
+ 2002/07/24/big/img_376
2547
+ 2002/08/17/big/img_1030
2548
+ 2002/08/05/big/img_3576
2549
+ 2002/08/16/big/img_540
2550
+ 2002/07/22/big/img_630
2551
+ 2002/08/10/big/img_180
2552
+ 2002/08/14/big/img_905
2553
+ 2002/08/29/big/img_18777
2554
+ 2002/08/22/big/img_693
2555
+ 2003/01/16/big/img_933
2556
+ 2002/08/20/big/img_555
2557
+ 2002/08/15/big/img_549
2558
+ 2003/01/14/big/img_830
2559
+ 2003/01/16/big/img_64
2560
+ 2002/08/27/big/img_19670
2561
+ 2002/08/22/big/img_729
2562
+ 2002/07/27/big/img_981
2563
+ 2002/08/09/big/img_458
2564
+ 2003/01/17/big/img_884
2565
+ 2002/07/25/big/img_639
2566
+ 2002/08/31/big/img_18008
2567
+ 2002/08/22/big/img_249
2568
+ 2002/08/17/big/img_971
2569
+ 2002/08/04/big/img_308
2570
+ 2002/07/28/big/img_362
2571
+ 2002/08/12/big/img_142
2572
+ 2002/08/26/big/img_61
2573
+ 2002/08/14/big/img_422
2574
+ 2002/07/19/big/img_607
2575
+ 2003/01/15/big/img_717
2576
+ 2002/08/01/big/img_1475
2577
+ 2002/08/29/big/img_19061
2578
+ 2003/01/01/big/img_346
2579
+ 2002/07/20/big/img_315
2580
+ 2003/01/15/big/img_756
2581
+ 2002/08/15/big/img_879
2582
+ 2002/08/08/big/img_615
2583
+ 2003/01/13/big/img_431
2584
+ 2002/08/05/big/img_3233
2585
+ 2002/08/24/big/img_526
2586
+ 2003/01/13/big/img_717
2587
+ 2002/09/01/big/img_16408
2588
+ 2002/07/22/big/img_217
2589
+ 2002/07/31/big/img_960
2590
+ 2002/08/21/big/img_610
2591
+ 2002/08/05/big/img_3753
2592
+ 2002/08/03/big/img_151
2593
+ 2002/08/21/big/img_267
2594
+ 2002/08/01/big/img_2175
2595
+ 2002/08/04/big/img_556
2596
+ 2002/08/21/big/img_527
2597
+ 2002/09/02/big/img_15800
2598
+ 2002/07/27/big/img_156
2599
+ 2002/07/20/big/img_590
2600
+ 2002/08/15/big/img_700
2601
+ 2002/08/08/big/img_444
2602
+ 2002/07/25/big/img_94
2603
+ 2002/07/24/big/img_778
2604
+ 2002/08/14/big/img_694
2605
+ 2002/07/20/big/img_666
2606
+ 2002/08/02/big/img_200
2607
+ 2002/08/02/big/img_578
2608
+ 2003/01/17/big/img_332
2609
+ 2002/09/01/big/img_16352
2610
+ 2002/08/27/big/img_19668
2611
+ 2002/07/23/big/img_823
2612
+ 2002/08/13/big/img_431
2613
+ 2003/01/16/big/img_463
2614
+ 2002/08/27/big/img_19711
2615
+ 2002/08/23/big/img_154
2616
+ 2002/07/31/big/img_360
2617
+ 2002/08/23/big/img_555
2618
+ 2002/08/10/big/img_561
2619
+ 2003/01/14/big/img_550
2620
+ 2002/08/07/big/img_1370
2621
+ 2002/07/30/big/img_1184
2622
+ 2002/08/01/big/img_1445
2623
+ 2002/08/23/big/img_22
2624
+ 2002/07/30/big/img_606
2625
+ 2003/01/17/big/img_271
2626
+ 2002/08/31/big/img_17316
2627
+ 2002/08/16/big/img_973
2628
+ 2002/07/26/big/img_77
2629
+ 2002/07/20/big/img_788
2630
+ 2002/08/06/big/img_2426
2631
+ 2002/08/07/big/img_1498
2632
+ 2002/08/16/big/img_358
2633
+ 2002/08/06/big/img_2851
2634
+ 2002/08/12/big/img_359
2635
+ 2002/08/01/big/img_1521
2636
+ 2002/08/02/big/img_709
2637
+ 2002/08/20/big/img_935
2638
+ 2002/08/12/big/img_188
2639
+ 2002/08/24/big/img_411
2640
+ 2002/08/22/big/img_680
2641
+ 2002/08/06/big/img_2480
2642
+ 2002/07/20/big/img_627
2643
+ 2002/07/30/big/img_214
2644
+ 2002/07/25/big/img_354
2645
+ 2002/08/02/big/img_636
2646
+ 2003/01/15/big/img_661
2647
+ 2002/08/07/big/img_1327
2648
+ 2002/08/01/big/img_2108
2649
+ 2002/08/31/big/img_17919
2650
+ 2002/08/29/big/img_18768
2651
+ 2002/08/05/big/img_3840
2652
+ 2002/07/26/big/img_242
2653
+ 2003/01/14/big/img_451
2654
+ 2002/08/20/big/img_923
2655
+ 2002/08/27/big/img_19908
2656
+ 2002/08/16/big/img_282
2657
+ 2002/08/19/big/img_440
2658
+ 2003/01/01/big/img_230
2659
+ 2002/08/08/big/img_212
2660
+ 2002/07/20/big/img_443
2661
+ 2002/08/25/big/img_635
2662
+ 2003/01/13/big/img_1169
2663
+ 2002/07/26/big/img_998
2664
+ 2002/08/15/big/img_995
2665
+ 2002/08/06/big/img_3002
2666
+ 2002/07/29/big/img_460
2667
+ 2003/01/14/big/img_925
2668
+ 2002/07/23/big/img_539
2669
+ 2002/08/16/big/img_694
2670
+ 2003/01/13/big/img_459
2671
+ 2002/07/23/big/img_249
2672
+ 2002/08/20/big/img_539
2673
+ 2002/08/04/big/img_186
2674
+ 2002/08/26/big/img_264
2675
+ 2002/07/22/big/img_704
2676
+ 2002/08/25/big/img_277
2677
+ 2002/08/22/big/img_988
2678
+ 2002/07/29/big/img_504
2679
+ 2002/08/05/big/img_3600
2680
+ 2002/08/30/big/img_18380
2681
+ 2003/01/14/big/img_937
2682
+ 2002/08/21/big/img_254
2683
+ 2002/08/10/big/img_130
2684
+ 2002/08/20/big/img_339
2685
+ 2003/01/14/big/img_428
2686
+ 2002/08/20/big/img_889
2687
+ 2002/08/31/big/img_17637
2688
+ 2002/07/26/big/img_644
2689
+ 2002/09/01/big/img_16776
2690
+ 2002/08/06/big/img_2239
2691
+ 2002/08/06/big/img_2646
2692
+ 2003/01/13/big/img_491
2693
+ 2002/08/10/big/img_579
2694
+ 2002/08/21/big/img_713
2695
+ 2002/08/22/big/img_482
2696
+ 2002/07/22/big/img_167
2697
+ 2002/07/24/big/img_539
2698
+ 2002/08/14/big/img_721
2699
+ 2002/07/25/big/img_389
2700
+ 2002/09/01/big/img_16591
2701
+ 2002/08/13/big/img_543
2702
+ 2003/01/14/big/img_432
2703
+ 2002/08/09/big/img_287
2704
+ 2002/07/26/big/img_126
2705
+ 2002/08/23/big/img_412
2706
+ 2002/08/15/big/img_1034
2707
+ 2002/08/28/big/img_19485
2708
+ 2002/07/31/big/img_236
2709
+ 2002/07/30/big/img_523
2710
+ 2002/07/19/big/img_141
2711
+ 2003/01/17/big/img_957
2712
+ 2002/08/04/big/img_81
2713
+ 2002/07/25/big/img_206
2714
+ 2002/08/15/big/img_716
2715
+ 2002/08/13/big/img_403
2716
+ 2002/08/15/big/img_685
2717
+ 2002/07/26/big/img_884
2718
+ 2002/07/19/big/img_499
2719
+ 2002/07/23/big/img_772
2720
+ 2002/07/27/big/img_752
2721
+ 2003/01/14/big/img_493
2722
+ 2002/08/25/big/img_664
2723
+ 2002/07/31/big/img_334
2724
+ 2002/08/26/big/img_678
2725
+ 2002/09/01/big/img_16541
2726
+ 2003/01/14/big/img_347
2727
+ 2002/07/23/big/img_187
2728
+ 2002/07/30/big/img_1163
2729
+ 2002/08/05/big/img_35
2730
+ 2002/08/22/big/img_944
2731
+ 2002/08/07/big/img_1239
2732
+ 2002/07/29/big/img_1215
2733
+ 2002/08/03/big/img_312
2734
+ 2002/08/05/big/img_3523
2735
+ 2002/07/29/big/img_218
2736
+ 2002/08/13/big/img_672
2737
+ 2002/08/16/big/img_205
2738
+ 2002/08/17/big/img_594
2739
+ 2002/07/29/big/img_1411
2740
+ 2002/07/30/big/img_942
2741
+ 2003/01/16/big/img_312
2742
+ 2002/08/08/big/img_312
2743
+ 2002/07/25/big/img_15
2744
+ 2002/08/09/big/img_839
2745
+ 2002/08/01/big/img_2069
2746
+ 2002/08/31/big/img_17512
2747
+ 2002/08/01/big/img_3
2748
+ 2002/07/31/big/img_320
2749
+ 2003/01/15/big/img_1265
2750
+ 2002/08/14/big/img_563
2751
+ 2002/07/31/big/img_167
2752
+ 2002/08/20/big/img_374
2753
+ 2002/08/13/big/img_406
2754
+ 2002/08/08/big/img_625
2755
+ 2002/08/02/big/img_314
2756
+ 2002/08/27/big/img_19964
2757
+ 2002/09/01/big/img_16670
2758
+ 2002/07/31/big/img_599
2759
+ 2002/08/29/big/img_18906
2760
+ 2002/07/24/big/img_373
2761
+ 2002/07/26/big/img_513
2762
+ 2002/09/02/big/img_15497
2763
+ 2002/08/19/big/img_117
2764
+ 2003/01/01/big/img_158
2765
+ 2002/08/24/big/img_178
2766
+ 2003/01/13/big/img_935
2767
+ 2002/08/13/big/img_609
2768
+ 2002/08/30/big/img_18341
2769
+ 2002/08/25/big/img_674
2770
+ 2003/01/13/big/img_209
2771
+ 2002/08/13/big/img_258
2772
+ 2002/08/05/big/img_3543
2773
+ 2002/08/07/big/img_1970
2774
+ 2002/08/06/big/img_3004
2775
+ 2003/01/17/big/img_487
2776
+ 2002/08/24/big/img_873
2777
+ 2002/08/29/big/img_18730
2778
+ 2002/08/09/big/img_375
2779
+ 2003/01/16/big/img_751
2780
+ 2002/08/02/big/img_603
2781
+ 2002/08/19/big/img_325
2782
+ 2002/09/01/big/img_16420
2783
+ 2002/08/05/big/img_3633
2784
+ 2002/08/21/big/img_516
2785
+ 2002/07/19/big/img_501
2786
+ 2002/07/26/big/img_688
2787
+ 2002/07/24/big/img_256
2788
+ 2002/07/25/big/img_438
2789
+ 2002/07/31/big/img_1017
2790
+ 2002/08/22/big/img_512
2791
+ 2002/07/21/big/img_543
2792
+ 2002/08/08/big/img_223
2793
+ 2002/08/19/big/img_189
2794
+ 2002/08/12/big/img_630
2795
+ 2002/07/30/big/img_958
2796
+ 2002/07/28/big/img_208
2797
+ 2002/08/31/big/img_17691
2798
+ 2002/07/22/big/img_542
2799
+ 2002/07/19/big/img_741
2800
+ 2002/07/19/big/img_158
2801
+ 2002/08/15/big/img_399
2802
+ 2002/08/01/big/img_2159
2803
+ 2002/08/14/big/img_455
2804
+ 2002/08/17/big/img_1011
2805
+ 2002/08/26/big/img_744
2806
+ 2002/08/12/big/img_624
2807
+ 2003/01/17/big/img_821
2808
+ 2002/08/16/big/img_980
2809
+ 2002/07/28/big/img_281
2810
+ 2002/07/25/big/img_171
2811
+ 2002/08/03/big/img_116
2812
+ 2002/07/22/big/img_467
2813
+ 2002/07/31/big/img_750
2814
+ 2002/07/26/big/img_435
2815
+ 2002/07/19/big/img_822
2816
+ 2002/08/13/big/img_626
2817
+ 2002/08/11/big/img_344
2818
+ 2002/08/02/big/img_473
2819
+ 2002/09/01/big/img_16817
2820
+ 2002/08/01/big/img_1275
2821
+ 2002/08/28/big/img_19270
2822
+ 2002/07/23/big/img_607
2823
+ 2002/08/09/big/img_316
2824
+ 2002/07/29/big/img_626
2825
+ 2002/07/24/big/img_824
2826
+ 2002/07/22/big/img_342
2827
+ 2002/08/08/big/img_794
2828
+ 2002/08/07/big/img_1209
2829
+ 2002/07/19/big/img_18
2830
+ 2002/08/25/big/img_634
2831
+ 2002/07/24/big/img_730
2832
+ 2003/01/17/big/img_356
2833
+ 2002/07/23/big/img_305
2834
+ 2002/07/30/big/img_453
2835
+ 2003/01/13/big/img_972
2836
+ 2002/08/06/big/img_2610
2837
+ 2002/08/29/big/img_18920
2838
+ 2002/07/31/big/img_123
2839
+ 2002/07/26/big/img_979
2840
+ 2002/08/24/big/img_635
2841
+ 2002/08/05/big/img_3704
2842
+ 2002/08/07/big/img_1358
2843
+ 2002/07/22/big/img_306
2844
+ 2002/08/13/big/img_619
2845
+ 2002/08/02/big/img_366
video-tetalking/third_part/GPEN/face_detect/data/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from .wider_face import WiderFaceDetection, detection_collate
2
+ from .data_augment import *
3
+ from .config import *
video-tetalking/third_part/GPEN/face_detect/data/config.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # config.py
2
+
3
+ cfg_mnet = {
4
+ 'name': 'mobilenet0.25',
5
+ 'min_sizes': [[16, 32], [64, 128], [256, 512]],
6
+ 'steps': [8, 16, 32],
7
+ 'variance': [0.1, 0.2],
8
+ 'clip': False,
9
+ 'loc_weight': 2.0,
10
+ 'gpu_train': True,
11
+ 'batch_size': 32,
12
+ 'ngpu': 1,
13
+ 'epoch': 250,
14
+ 'decay1': 190,
15
+ 'decay2': 220,
16
+ 'image_size': 640,
17
+ 'pretrain': False,
18
+ 'return_layers': {'stage1': 1, 'stage2': 2, 'stage3': 3},
19
+ 'in_channel': 32,
20
+ 'out_channel': 64
21
+ }
22
+
23
+ cfg_re50 = {
24
+ 'name': 'Resnet50',
25
+ 'min_sizes': [[16, 32], [64, 128], [256, 512]],
26
+ 'steps': [8, 16, 32],
27
+ 'variance': [0.1, 0.2],
28
+ 'clip': False,
29
+ 'loc_weight': 2.0,
30
+ 'gpu_train': True,
31
+ 'batch_size': 24,
32
+ 'ngpu': 4,
33
+ 'epoch': 100,
34
+ 'decay1': 70,
35
+ 'decay2': 90,
36
+ 'image_size': 840,
37
+ 'pretrain': False,
38
+ 'return_layers': {'layer2': 1, 'layer3': 2, 'layer4': 3},
39
+ 'in_channel': 256,
40
+ 'out_channel': 256
41
+ }
42
+
video-tetalking/third_part/GPEN/face_detect/data/data_augment.py ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import random
4
+ from face_detect.utils.box_utils import matrix_iof
5
+
6
+
7
+ def _crop(image, boxes, labels, landm, img_dim):
8
+ height, width, _ = image.shape
9
+ pad_image_flag = True
10
+
11
+ for _ in range(250):
12
+ """
13
+ if random.uniform(0, 1) <= 0.2:
14
+ scale = 1.0
15
+ else:
16
+ scale = random.uniform(0.3, 1.0)
17
+ """
18
+ PRE_SCALES = [0.3, 0.45, 0.6, 0.8, 1.0]
19
+ scale = random.choice(PRE_SCALES)
20
+ short_side = min(width, height)
21
+ w = int(scale * short_side)
22
+ h = w
23
+
24
+ if width == w:
25
+ l = 0
26
+ else:
27
+ l = random.randrange(width - w)
28
+ if height == h:
29
+ t = 0
30
+ else:
31
+ t = random.randrange(height - h)
32
+ roi = np.array((l, t, l + w, t + h))
33
+
34
+ value = matrix_iof(boxes, roi[np.newaxis])
35
+ flag = (value >= 1)
36
+ if not flag.any():
37
+ continue
38
+
39
+ centers = (boxes[:, :2] + boxes[:, 2:]) / 2
40
+ mask_a = np.logical_and(roi[:2] < centers, centers < roi[2:]).all(axis=1)
41
+ boxes_t = boxes[mask_a].copy()
42
+ labels_t = labels[mask_a].copy()
43
+ landms_t = landm[mask_a].copy()
44
+ landms_t = landms_t.reshape([-1, 5, 2])
45
+
46
+ if boxes_t.shape[0] == 0:
47
+ continue
48
+
49
+ image_t = image[roi[1]:roi[3], roi[0]:roi[2]]
50
+
51
+ boxes_t[:, :2] = np.maximum(boxes_t[:, :2], roi[:2])
52
+ boxes_t[:, :2] -= roi[:2]
53
+ boxes_t[:, 2:] = np.minimum(boxes_t[:, 2:], roi[2:])
54
+ boxes_t[:, 2:] -= roi[:2]
55
+
56
+ # landm
57
+ landms_t[:, :, :2] = landms_t[:, :, :2] - roi[:2]
58
+ landms_t[:, :, :2] = np.maximum(landms_t[:, :, :2], np.array([0, 0]))
59
+ landms_t[:, :, :2] = np.minimum(landms_t[:, :, :2], roi[2:] - roi[:2])
60
+ landms_t = landms_t.reshape([-1, 10])
61
+
62
+
63
+ # make sure that the cropped image contains at least one face > 16 pixel at training image scale
64
+ b_w_t = (boxes_t[:, 2] - boxes_t[:, 0] + 1) / w * img_dim
65
+ b_h_t = (boxes_t[:, 3] - boxes_t[:, 1] + 1) / h * img_dim
66
+ mask_b = np.minimum(b_w_t, b_h_t) > 0.0
67
+ boxes_t = boxes_t[mask_b]
68
+ labels_t = labels_t[mask_b]
69
+ landms_t = landms_t[mask_b]
70
+
71
+ if boxes_t.shape[0] == 0:
72
+ continue
73
+
74
+ pad_image_flag = False
75
+
76
+ return image_t, boxes_t, labels_t, landms_t, pad_image_flag
77
+ return image, boxes, labels, landm, pad_image_flag
78
+
79
+
80
+ def _distort(image):
81
+
82
+ def _convert(image, alpha=1, beta=0):
83
+ tmp = image.astype(float) * alpha + beta
84
+ tmp[tmp < 0] = 0
85
+ tmp[tmp > 255] = 255
86
+ image[:] = tmp
87
+
88
+ image = image.copy()
89
+
90
+ if random.randrange(2):
91
+
92
+ #brightness distortion
93
+ if random.randrange(2):
94
+ _convert(image, beta=random.uniform(-32, 32))
95
+
96
+ #contrast distortion
97
+ if random.randrange(2):
98
+ _convert(image, alpha=random.uniform(0.5, 1.5))
99
+
100
+ image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
101
+
102
+ #saturation distortion
103
+ if random.randrange(2):
104
+ _convert(image[:, :, 1], alpha=random.uniform(0.5, 1.5))
105
+
106
+ #hue distortion
107
+ if random.randrange(2):
108
+ tmp = image[:, :, 0].astype(int) + random.randint(-18, 18)
109
+ tmp %= 180
110
+ image[:, :, 0] = tmp
111
+
112
+ image = cv2.cvtColor(image, cv2.COLOR_HSV2BGR)
113
+
114
+ else:
115
+
116
+ #brightness distortion
117
+ if random.randrange(2):
118
+ _convert(image, beta=random.uniform(-32, 32))
119
+
120
+ image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
121
+
122
+ #saturation distortion
123
+ if random.randrange(2):
124
+ _convert(image[:, :, 1], alpha=random.uniform(0.5, 1.5))
125
+
126
+ #hue distortion
127
+ if random.randrange(2):
128
+ tmp = image[:, :, 0].astype(int) + random.randint(-18, 18)
129
+ tmp %= 180
130
+ image[:, :, 0] = tmp
131
+
132
+ image = cv2.cvtColor(image, cv2.COLOR_HSV2BGR)
133
+
134
+ #contrast distortion
135
+ if random.randrange(2):
136
+ _convert(image, alpha=random.uniform(0.5, 1.5))
137
+
138
+ return image
139
+
140
+
141
+ def _expand(image, boxes, fill, p):
142
+ if random.randrange(2):
143
+ return image, boxes
144
+
145
+ height, width, depth = image.shape
146
+
147
+ scale = random.uniform(1, p)
148
+ w = int(scale * width)
149
+ h = int(scale * height)
150
+
151
+ left = random.randint(0, w - width)
152
+ top = random.randint(0, h - height)
153
+
154
+ boxes_t = boxes.copy()
155
+ boxes_t[:, :2] += (left, top)
156
+ boxes_t[:, 2:] += (left, top)
157
+ expand_image = np.empty(
158
+ (h, w, depth),
159
+ dtype=image.dtype)
160
+ expand_image[:, :] = fill
161
+ expand_image[top:top + height, left:left + width] = image
162
+ image = expand_image
163
+
164
+ return image, boxes_t
165
+
166
+
167
+ def _mirror(image, boxes, landms):
168
+ _, width, _ = image.shape
169
+ if random.randrange(2):
170
+ image = image[:, ::-1]
171
+ boxes = boxes.copy()
172
+ boxes[:, 0::2] = width - boxes[:, 2::-2]
173
+
174
+ # landm
175
+ landms = landms.copy()
176
+ landms = landms.reshape([-1, 5, 2])
177
+ landms[:, :, 0] = width - landms[:, :, 0]
178
+ tmp = landms[:, 1, :].copy()
179
+ landms[:, 1, :] = landms[:, 0, :]
180
+ landms[:, 0, :] = tmp
181
+ tmp1 = landms[:, 4, :].copy()
182
+ landms[:, 4, :] = landms[:, 3, :]
183
+ landms[:, 3, :] = tmp1
184
+ landms = landms.reshape([-1, 10])
185
+
186
+ return image, boxes, landms
187
+
188
+
189
+ def _pad_to_square(image, rgb_mean, pad_image_flag):
190
+ if not pad_image_flag:
191
+ return image
192
+ height, width, _ = image.shape
193
+ long_side = max(width, height)
194
+ image_t = np.empty((long_side, long_side, 3), dtype=image.dtype)
195
+ image_t[:, :] = rgb_mean
196
+ image_t[0:0 + height, 0:0 + width] = image
197
+ return image_t
198
+
199
+
200
+ def _resize_subtract_mean(image, insize, rgb_mean):
201
+ interp_methods = [cv2.INTER_LINEAR, cv2.INTER_CUBIC, cv2.INTER_AREA, cv2.INTER_NEAREST, cv2.INTER_LANCZOS4]
202
+ interp_method = interp_methods[random.randrange(5)]
203
+ image = cv2.resize(image, (insize, insize), interpolation=interp_method)
204
+ image = image.astype(np.float32)
205
+ image -= rgb_mean
206
+ return image.transpose(2, 0, 1)
207
+
208
+
209
+ class preproc(object):
210
+
211
+ def __init__(self, img_dim, rgb_means):
212
+ self.img_dim = img_dim
213
+ self.rgb_means = rgb_means
214
+
215
+ def __call__(self, image, targets):
216
+ assert targets.shape[0] > 0, "this image does not have gt"
217
+
218
+ boxes = targets[:, :4].copy()
219
+ labels = targets[:, -1].copy()
220
+ landm = targets[:, 4:-1].copy()
221
+
222
+ image_t, boxes_t, labels_t, landm_t, pad_image_flag = _crop(image, boxes, labels, landm, self.img_dim)
223
+ image_t = _distort(image_t)
224
+ image_t = _pad_to_square(image_t,self.rgb_means, pad_image_flag)
225
+ image_t, boxes_t, landm_t = _mirror(image_t, boxes_t, landm_t)
226
+ height, width, _ = image_t.shape
227
+ image_t = _resize_subtract_mean(image_t, self.img_dim, self.rgb_means)
228
+ boxes_t[:, 0::2] /= width
229
+ boxes_t[:, 1::2] /= height
230
+
231
+ landm_t[:, 0::2] /= width
232
+ landm_t[:, 1::2] /= height
233
+
234
+ labels_t = np.expand_dims(labels_t, 1)
235
+ targets_t = np.hstack((boxes_t, landm_t, labels_t))
236
+
237
+ return image_t, targets_t
video-tetalking/third_part/GPEN/face_detect/data/wider_face.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import os.path
3
+ import sys
4
+ import torch
5
+ import torch.utils.data as data
6
+ import cv2
7
+ import numpy as np
8
+
9
+ class WiderFaceDetection(data.Dataset):
10
+ def __init__(self, txt_path, preproc=None):
11
+ self.preproc = preproc
12
+ self.imgs_path = []
13
+ self.words = []
14
+ f = open(txt_path,'r')
15
+ lines = f.readlines()
16
+ isFirst = True
17
+ labels = []
18
+ for line in lines:
19
+ line = line.rstrip()
20
+ if line.startswith('#'):
21
+ if isFirst is True:
22
+ isFirst = False
23
+ else:
24
+ labels_copy = labels.copy()
25
+ self.words.append(labels_copy)
26
+ labels.clear()
27
+ path = line[2:]
28
+ path = txt_path.replace('label.txt','images/') + path
29
+ self.imgs_path.append(path)
30
+ else:
31
+ line = line.split(' ')
32
+ label = [float(x) for x in line]
33
+ labels.append(label)
34
+
35
+ self.words.append(labels)
36
+
37
+ def __len__(self):
38
+ return len(self.imgs_path)
39
+
40
+ def __getitem__(self, index):
41
+ img = cv2.imread(self.imgs_path[index])
42
+ height, width, _ = img.shape
43
+
44
+ labels = self.words[index]
45
+ annotations = np.zeros((0, 15))
46
+ if len(labels) == 0:
47
+ return annotations
48
+ for idx, label in enumerate(labels):
49
+ annotation = np.zeros((1, 15))
50
+ # bbox
51
+ annotation[0, 0] = label[0] # x1
52
+ annotation[0, 1] = label[1] # y1
53
+ annotation[0, 2] = label[0] + label[2] # x2
54
+ annotation[0, 3] = label[1] + label[3] # y2
55
+
56
+ # landmarks
57
+ annotation[0, 4] = label[4] # l0_x
58
+ annotation[0, 5] = label[5] # l0_y
59
+ annotation[0, 6] = label[7] # l1_x
60
+ annotation[0, 7] = label[8] # l1_y
61
+ annotation[0, 8] = label[10] # l2_x
62
+ annotation[0, 9] = label[11] # l2_y
63
+ annotation[0, 10] = label[13] # l3_x
64
+ annotation[0, 11] = label[14] # l3_y
65
+ annotation[0, 12] = label[16] # l4_x
66
+ annotation[0, 13] = label[17] # l4_y
67
+ if (annotation[0, 4]<0):
68
+ annotation[0, 14] = -1
69
+ else:
70
+ annotation[0, 14] = 1
71
+
72
+ annotations = np.append(annotations, annotation, axis=0)
73
+ target = np.array(annotations)
74
+ if self.preproc is not None:
75
+ img, target = self.preproc(img, target)
76
+
77
+ return torch.from_numpy(img), target
78
+
79
+ def detection_collate(batch):
80
+ """Custom collate fn for dealing with batches of images that have a different
81
+ number of associated object annotations (bounding boxes).
82
+
83
+ Arguments:
84
+ batch: (tuple) A tuple of tensor images and lists of annotations
85
+
86
+ Return:
87
+ A tuple containing:
88
+ 1) (tensor) batch of images stacked on their 0 dim
89
+ 2) (list of tensors) annotations for a given image are stacked on 0 dim
90
+ """
91
+ targets = []
92
+ imgs = []
93
+ for _, sample in enumerate(batch):
94
+ for _, tup in enumerate(sample):
95
+ if torch.is_tensor(tup):
96
+ imgs.append(tup)
97
+ elif isinstance(tup, type(np.empty(0))):
98
+ annos = torch.from_numpy(tup).float()
99
+ targets.append(annos)
100
+
101
+ return (torch.stack(imgs, 0), targets)
video-tetalking/third_part/GPEN/face_detect/facemodels/__init__.py ADDED
File without changes
video-tetalking/third_part/GPEN/face_detect/facemodels/net.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import torch
3
+ import torch.nn as nn
4
+ import torchvision.models._utils as _utils
5
+ import torchvision.models as models
6
+ import torch.nn.functional as F
7
+ from torch.autograd import Variable
8
+
9
+ def conv_bn(inp, oup, stride = 1, leaky = 0):
10
+ return nn.Sequential(
11
+ nn.Conv2d(inp, oup, 3, stride, 1, bias=False),
12
+ nn.BatchNorm2d(oup),
13
+ nn.LeakyReLU(negative_slope=leaky, inplace=True)
14
+ )
15
+
16
+ def conv_bn_no_relu(inp, oup, stride):
17
+ return nn.Sequential(
18
+ nn.Conv2d(inp, oup, 3, stride, 1, bias=False),
19
+ nn.BatchNorm2d(oup),
20
+ )
21
+
22
+ def conv_bn1X1(inp, oup, stride, leaky=0):
23
+ return nn.Sequential(
24
+ nn.Conv2d(inp, oup, 1, stride, padding=0, bias=False),
25
+ nn.BatchNorm2d(oup),
26
+ nn.LeakyReLU(negative_slope=leaky, inplace=True)
27
+ )
28
+
29
+ def conv_dw(inp, oup, stride, leaky=0.1):
30
+ return nn.Sequential(
31
+ nn.Conv2d(inp, inp, 3, stride, 1, groups=inp, bias=False),
32
+ nn.BatchNorm2d(inp),
33
+ nn.LeakyReLU(negative_slope= leaky,inplace=True),
34
+
35
+ nn.Conv2d(inp, oup, 1, 1, 0, bias=False),
36
+ nn.BatchNorm2d(oup),
37
+ nn.LeakyReLU(negative_slope= leaky,inplace=True),
38
+ )
39
+
40
+ class SSH(nn.Module):
41
+ def __init__(self, in_channel, out_channel):
42
+ super(SSH, self).__init__()
43
+ assert out_channel % 4 == 0
44
+ leaky = 0
45
+ if (out_channel <= 64):
46
+ leaky = 0.1
47
+ self.conv3X3 = conv_bn_no_relu(in_channel, out_channel//2, stride=1)
48
+
49
+ self.conv5X5_1 = conv_bn(in_channel, out_channel//4, stride=1, leaky = leaky)
50
+ self.conv5X5_2 = conv_bn_no_relu(out_channel//4, out_channel//4, stride=1)
51
+
52
+ self.conv7X7_2 = conv_bn(out_channel//4, out_channel//4, stride=1, leaky = leaky)
53
+ self.conv7x7_3 = conv_bn_no_relu(out_channel//4, out_channel//4, stride=1)
54
+
55
+ def forward(self, input):
56
+ conv3X3 = self.conv3X3(input)
57
+
58
+ conv5X5_1 = self.conv5X5_1(input)
59
+ conv5X5 = self.conv5X5_2(conv5X5_1)
60
+
61
+ conv7X7_2 = self.conv7X7_2(conv5X5_1)
62
+ conv7X7 = self.conv7x7_3(conv7X7_2)
63
+
64
+ out = torch.cat([conv3X3, conv5X5, conv7X7], dim=1)
65
+ out = F.relu(out)
66
+ return out
67
+
68
+ class FPN(nn.Module):
69
+ def __init__(self,in_channels_list,out_channels):
70
+ super(FPN,self).__init__()
71
+ leaky = 0
72
+ if (out_channels <= 64):
73
+ leaky = 0.1
74
+ self.output1 = conv_bn1X1(in_channels_list[0], out_channels, stride = 1, leaky = leaky)
75
+ self.output2 = conv_bn1X1(in_channels_list[1], out_channels, stride = 1, leaky = leaky)
76
+ self.output3 = conv_bn1X1(in_channels_list[2], out_channels, stride = 1, leaky = leaky)
77
+
78
+ self.merge1 = conv_bn(out_channels, out_channels, leaky = leaky)
79
+ self.merge2 = conv_bn(out_channels, out_channels, leaky = leaky)
80
+
81
+ def forward(self, input):
82
+ # names = list(input.keys())
83
+ input = list(input.values())
84
+
85
+ output1 = self.output1(input[0])
86
+ output2 = self.output2(input[1])
87
+ output3 = self.output3(input[2])
88
+
89
+ up3 = F.interpolate(output3, size=[output2.size(2), output2.size(3)], mode="nearest")
90
+ output2 = output2 + up3
91
+ output2 = self.merge2(output2)
92
+
93
+ up2 = F.interpolate(output2, size=[output1.size(2), output1.size(3)], mode="nearest")
94
+ output1 = output1 + up2
95
+ output1 = self.merge1(output1)
96
+
97
+ out = [output1, output2, output3]
98
+ return out
99
+
100
+
101
+
102
+ class MobileNetV1(nn.Module):
103
+ def __init__(self):
104
+ super(MobileNetV1, self).__init__()
105
+ self.stage1 = nn.Sequential(
106
+ conv_bn(3, 8, 2, leaky = 0.1), # 3
107
+ conv_dw(8, 16, 1), # 7
108
+ conv_dw(16, 32, 2), # 11
109
+ conv_dw(32, 32, 1), # 19
110
+ conv_dw(32, 64, 2), # 27
111
+ conv_dw(64, 64, 1), # 43
112
+ )
113
+ self.stage2 = nn.Sequential(
114
+ conv_dw(64, 128, 2), # 43 + 16 = 59
115
+ conv_dw(128, 128, 1), # 59 + 32 = 91
116
+ conv_dw(128, 128, 1), # 91 + 32 = 123
117
+ conv_dw(128, 128, 1), # 123 + 32 = 155
118
+ conv_dw(128, 128, 1), # 155 + 32 = 187
119
+ conv_dw(128, 128, 1), # 187 + 32 = 219
120
+ )
121
+ self.stage3 = nn.Sequential(
122
+ conv_dw(128, 256, 2), # 219 +3 2 = 241
123
+ conv_dw(256, 256, 1), # 241 + 64 = 301
124
+ )
125
+ self.avg = nn.AdaptiveAvgPool2d((1,1))
126
+ self.fc = nn.Linear(256, 1000)
127
+
128
+ def forward(self, x):
129
+ x = self.stage1(x)
130
+ x = self.stage2(x)
131
+ x = self.stage3(x)
132
+ x = self.avg(x)
133
+ # x = self.model(x)
134
+ x = x.view(-1, 256)
135
+ x = self.fc(x)
136
+ return x
137
+
video-tetalking/third_part/GPEN/face_detect/facemodels/retinaface.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torchvision.models.detection.backbone_utils as backbone_utils
4
+ import torchvision.models._utils as _utils
5
+ import torch.nn.functional as F
6
+ from collections import OrderedDict
7
+
8
+ from face_detect.facemodels.net import MobileNetV1 as MobileNetV1
9
+ from face_detect.facemodels.net import FPN as FPN
10
+ from face_detect.facemodels.net import SSH as SSH
11
+
12
+
13
+
14
+ class ClassHead(nn.Module):
15
+ def __init__(self,inchannels=512,num_anchors=3):
16
+ super(ClassHead,self).__init__()
17
+ self.num_anchors = num_anchors
18
+ self.conv1x1 = nn.Conv2d(inchannels,self.num_anchors*2,kernel_size=(1,1),stride=1,padding=0)
19
+
20
+ def forward(self,x):
21
+ out = self.conv1x1(x)
22
+ out = out.permute(0,2,3,1).contiguous()
23
+
24
+ return out.view(out.shape[0], -1, 2)
25
+
26
+ class BboxHead(nn.Module):
27
+ def __init__(self,inchannels=512,num_anchors=3):
28
+ super(BboxHead,self).__init__()
29
+ self.conv1x1 = nn.Conv2d(inchannels,num_anchors*4,kernel_size=(1,1),stride=1,padding=0)
30
+
31
+ def forward(self,x):
32
+ out = self.conv1x1(x)
33
+ out = out.permute(0,2,3,1).contiguous()
34
+
35
+ return out.view(out.shape[0], -1, 4)
36
+
37
+ class LandmarkHead(nn.Module):
38
+ def __init__(self,inchannels=512,num_anchors=3):
39
+ super(LandmarkHead,self).__init__()
40
+ self.conv1x1 = nn.Conv2d(inchannels,num_anchors*10,kernel_size=(1,1),stride=1,padding=0)
41
+
42
+ def forward(self,x):
43
+ out = self.conv1x1(x)
44
+ out = out.permute(0,2,3,1).contiguous()
45
+
46
+ return out.view(out.shape[0], -1, 10)
47
+
48
+ class RetinaFace(nn.Module):
49
+ def __init__(self, cfg = None, phase = 'train'):
50
+ """
51
+ :param cfg: Network related settings.
52
+ :param phase: train or test.
53
+ """
54
+ super(RetinaFace,self).__init__()
55
+ self.phase = phase
56
+ backbone = None
57
+ if cfg['name'] == 'mobilenet0.25':
58
+ backbone = MobileNetV1()
59
+ if cfg['pretrain']:
60
+ checkpoint = torch.load("./weights/mobilenetV1X0.25_pretrain.tar", map_location=torch.device('cpu'))
61
+ from collections import OrderedDict
62
+ new_state_dict = OrderedDict()
63
+ for k, v in checkpoint['state_dict'].items():
64
+ name = k[7:] # remove module.
65
+ new_state_dict[name] = v
66
+ # load params
67
+ backbone.load_state_dict(new_state_dict)
68
+ elif cfg['name'] == 'Resnet50':
69
+ import torchvision.models as models
70
+ backbone = models.resnet50(pretrained=cfg['pretrain'])
71
+
72
+ self.body = _utils.IntermediateLayerGetter(backbone, cfg['return_layers'])
73
+ in_channels_stage2 = cfg['in_channel']
74
+ in_channels_list = [
75
+ in_channels_stage2 * 2,
76
+ in_channels_stage2 * 4,
77
+ in_channels_stage2 * 8,
78
+ ]
79
+ out_channels = cfg['out_channel']
80
+ self.fpn = FPN(in_channels_list,out_channels)
81
+ self.ssh1 = SSH(out_channels, out_channels)
82
+ self.ssh2 = SSH(out_channels, out_channels)
83
+ self.ssh3 = SSH(out_channels, out_channels)
84
+
85
+ self.ClassHead = self._make_class_head(fpn_num=3, inchannels=cfg['out_channel'])
86
+ self.BboxHead = self._make_bbox_head(fpn_num=3, inchannels=cfg['out_channel'])
87
+ self.LandmarkHead = self._make_landmark_head(fpn_num=3, inchannels=cfg['out_channel'])
88
+
89
+ def _make_class_head(self,fpn_num=3,inchannels=64,anchor_num=2):
90
+ classhead = nn.ModuleList()
91
+ for i in range(fpn_num):
92
+ classhead.append(ClassHead(inchannels,anchor_num))
93
+ return classhead
94
+
95
+ def _make_bbox_head(self,fpn_num=3,inchannels=64,anchor_num=2):
96
+ bboxhead = nn.ModuleList()
97
+ for i in range(fpn_num):
98
+ bboxhead.append(BboxHead(inchannels,anchor_num))
99
+ return bboxhead
100
+
101
+ def _make_landmark_head(self,fpn_num=3,inchannels=64,anchor_num=2):
102
+ landmarkhead = nn.ModuleList()
103
+ for i in range(fpn_num):
104
+ landmarkhead.append(LandmarkHead(inchannels,anchor_num))
105
+ return landmarkhead
106
+
107
+ def forward(self,inputs):
108
+ out = self.body(inputs)
109
+
110
+ # FPN
111
+ fpn = self.fpn(out)
112
+
113
+ # SSH
114
+ feature1 = self.ssh1(fpn[0])
115
+ feature2 = self.ssh2(fpn[1])
116
+ feature3 = self.ssh3(fpn[2])
117
+ features = [feature1, feature2, feature3]
118
+
119
+ bbox_regressions = torch.cat([self.BboxHead[i](feature) for i, feature in enumerate(features)], dim=1)
120
+ classifications = torch.cat([self.ClassHead[i](feature) for i, feature in enumerate(features)],dim=1)
121
+ ldm_regressions = torch.cat([self.LandmarkHead[i](feature) for i, feature in enumerate(features)], dim=1)
122
+
123
+ if self.phase == 'train':
124
+ output = (bbox_regressions, classifications, ldm_regressions)
125
+ else:
126
+ output = (bbox_regressions, F.softmax(classifications, dim=-1), ldm_regressions)
127
+ return output
video-tetalking/third_part/GPEN/face_detect/layers/__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ from .functions import *
2
+ from .modules import *
video-tetalking/third_part/GPEN/face_detect/layers/functions/prior_box.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from itertools import product as product
3
+ import numpy as np
4
+ from math import ceil
5
+
6
+
7
+ class PriorBox(object):
8
+ def __init__(self, cfg, image_size=None, phase='train'):
9
+ super(PriorBox, self).__init__()
10
+ self.min_sizes = cfg['min_sizes']
11
+ self.steps = cfg['steps']
12
+ self.clip = cfg['clip']
13
+ self.image_size = image_size
14
+ self.feature_maps = [[ceil(self.image_size[0]/step), ceil(self.image_size[1]/step)] for step in self.steps]
15
+ self.name = "s"
16
+
17
+ def forward(self):
18
+ anchors = []
19
+ for k, f in enumerate(self.feature_maps):
20
+ min_sizes = self.min_sizes[k]
21
+ for i, j in product(range(f[0]), range(f[1])):
22
+ for min_size in min_sizes:
23
+ s_kx = min_size / self.image_size[1]
24
+ s_ky = min_size / self.image_size[0]
25
+ dense_cx = [x * self.steps[k] / self.image_size[1] for x in [j + 0.5]]
26
+ dense_cy = [y * self.steps[k] / self.image_size[0] for y in [i + 0.5]]
27
+ for cy, cx in product(dense_cy, dense_cx):
28
+ anchors += [cx, cy, s_kx, s_ky]
29
+
30
+ # back to torch land
31
+ output = torch.Tensor(anchors).view(-1, 4)
32
+ if self.clip:
33
+ output.clamp_(max=1, min=0)
34
+ return output
video-tetalking/third_part/GPEN/face_detect/layers/modules/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from .multibox_loss import MultiBoxLoss
2
+
3
+ __all__ = ['MultiBoxLoss']
video-tetalking/third_part/GPEN/face_detect/layers/modules/multibox_loss.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.nn.functional as F
4
+ from torch.autograd import Variable
5
+ from face_detect.utils.box_utils import match, log_sum_exp
6
+ from face_detect.data import cfg_mnet
7
+ GPU = cfg_mnet['gpu_train']
8
+
9
+ class MultiBoxLoss(nn.Module):
10
+ """SSD Weighted Loss Function
11
+ Compute Targets:
12
+ 1) Produce Confidence Target Indices by matching ground truth boxes
13
+ with (default) 'priorboxes' that have jaccard index > threshold parameter
14
+ (default threshold: 0.5).
15
+ 2) Produce localization target by 'encoding' variance into offsets of ground
16
+ truth boxes and their matched 'priorboxes'.
17
+ 3) Hard negative mining to filter the excessive number of negative examples
18
+ that comes with using a large number of default bounding boxes.
19
+ (default negative:positive ratio 3:1)
20
+ Objective Loss:
21
+ L(x,c,l,g) = (Lconf(x, c) + αLloc(x,l,g)) / N
22
+ Where, Lconf is the CrossEntropy Loss and Lloc is the SmoothL1 Loss
23
+ weighted by α which is set to 1 by cross val.
24
+ Args:
25
+ c: class confidences,
26
+ l: predicted boxes,
27
+ g: ground truth boxes
28
+ N: number of matched default boxes
29
+ See: https://arxiv.org/pdf/1512.02325.pdf for more details.
30
+ """
31
+
32
+ def __init__(self, num_classes, overlap_thresh, prior_for_matching, bkg_label, neg_mining, neg_pos, neg_overlap, encode_target):
33
+ super(MultiBoxLoss, self).__init__()
34
+ self.num_classes = num_classes
35
+ self.threshold = overlap_thresh
36
+ self.background_label = bkg_label
37
+ self.encode_target = encode_target
38
+ self.use_prior_for_matching = prior_for_matching
39
+ self.do_neg_mining = neg_mining
40
+ self.negpos_ratio = neg_pos
41
+ self.neg_overlap = neg_overlap
42
+ self.variance = [0.1, 0.2]
43
+
44
+ def forward(self, predictions, priors, targets):
45
+ """Multibox Loss
46
+ Args:
47
+ predictions (tuple): A tuple containing loc preds, conf preds,
48
+ and prior boxes from SSD net.
49
+ conf shape: torch.size(batch_size,num_priors,num_classes)
50
+ loc shape: torch.size(batch_size,num_priors,4)
51
+ priors shape: torch.size(num_priors,4)
52
+
53
+ ground_truth (tensor): Ground truth boxes and labels for a batch,
54
+ shape: [batch_size,num_objs,5] (last idx is the label).
55
+ """
56
+
57
+ loc_data, conf_data, landm_data = predictions
58
+ priors = priors
59
+ num = loc_data.size(0)
60
+ num_priors = (priors.size(0))
61
+
62
+ # match priors (default boxes) and ground truth boxes
63
+ loc_t = torch.Tensor(num, num_priors, 4)
64
+ landm_t = torch.Tensor(num, num_priors, 10)
65
+ conf_t = torch.LongTensor(num, num_priors)
66
+ for idx in range(num):
67
+ truths = targets[idx][:, :4].data
68
+ labels = targets[idx][:, -1].data
69
+ landms = targets[idx][:, 4:14].data
70
+ defaults = priors.data
71
+ match(self.threshold, truths, defaults, self.variance, labels, landms, loc_t, conf_t, landm_t, idx)
72
+ if GPU:
73
+ loc_t = loc_t.cuda()
74
+ conf_t = conf_t.cuda()
75
+ landm_t = landm_t.cuda()
76
+
77
+ zeros = torch.tensor(0).cuda()
78
+ # landm Loss (Smooth L1)
79
+ # Shape: [batch,num_priors,10]
80
+ pos1 = conf_t > zeros
81
+ num_pos_landm = pos1.long().sum(1, keepdim=True)
82
+ N1 = max(num_pos_landm.data.sum().float(), 1)
83
+ pos_idx1 = pos1.unsqueeze(pos1.dim()).expand_as(landm_data)
84
+ landm_p = landm_data[pos_idx1].view(-1, 10)
85
+ landm_t = landm_t[pos_idx1].view(-1, 10)
86
+ loss_landm = F.smooth_l1_loss(landm_p, landm_t, reduction='sum')
87
+
88
+
89
+ pos = conf_t != zeros
90
+ conf_t[pos] = 1
91
+
92
+ # Localization Loss (Smooth L1)
93
+ # Shape: [batch,num_priors,4]
94
+ pos_idx = pos.unsqueeze(pos.dim()).expand_as(loc_data)
95
+ loc_p = loc_data[pos_idx].view(-1, 4)
96
+ loc_t = loc_t[pos_idx].view(-1, 4)
97
+ loss_l = F.smooth_l1_loss(loc_p, loc_t, reduction='sum')
98
+
99
+ # Compute max conf across batch for hard negative mining
100
+ batch_conf = conf_data.view(-1, self.num_classes)
101
+ loss_c = log_sum_exp(batch_conf) - batch_conf.gather(1, conf_t.view(-1, 1))
102
+
103
+ # Hard Negative Mining
104
+ loss_c[pos.view(-1, 1)] = 0 # filter out pos boxes for now
105
+ loss_c = loss_c.view(num, -1)
106
+ _, loss_idx = loss_c.sort(1, descending=True)
107
+ _, idx_rank = loss_idx.sort(1)
108
+ num_pos = pos.long().sum(1, keepdim=True)
109
+ num_neg = torch.clamp(self.negpos_ratio*num_pos, max=pos.size(1)-1)
110
+ neg = idx_rank < num_neg.expand_as(idx_rank)
111
+
112
+ # Confidence Loss Including Positive and Negative Examples
113
+ pos_idx = pos.unsqueeze(2).expand_as(conf_data)
114
+ neg_idx = neg.unsqueeze(2).expand_as(conf_data)
115
+ conf_p = conf_data[(pos_idx+neg_idx).gt(0)].view(-1,self.num_classes)
116
+ targets_weighted = conf_t[(pos+neg).gt(0)]
117
+ loss_c = F.cross_entropy(conf_p, targets_weighted, reduction='sum')
118
+
119
+ # Sum of losses: L(x,c,l,g) = (Lconf(x, c) + αLloc(x,l,g)) / N
120
+ N = max(num_pos.data.sum().float(), 1)
121
+ loss_l /= N
122
+ loss_c /= N
123
+ loss_landm /= N1
124
+
125
+ return loss_l, loss_c, loss_landm
video-tetalking/third_part/GPEN/face_detect/retinaface_detection.py ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ '''
2
+ @paper: GAN Prior Embedded Network for Blind Face Restoration in the Wild (CVPR2021)
3
+ @author: yangxy (yangtao9009@gmail.com)
4
+ '''
5
+ import os
6
+ import torch
7
+ import torch.backends.cudnn as cudnn
8
+ import numpy as np
9
+ from face_detect.data import cfg_re50
10
+ from face_detect.layers.functions.prior_box import PriorBox
11
+ from face_detect.utils.nms.py_cpu_nms import py_cpu_nms
12
+ import cv2
13
+ from face_detect.facemodels.retinaface import RetinaFace
14
+ from face_detect.utils.box_utils import decode, decode_landm
15
+ import time
16
+ import torch.nn.functional as F
17
+
18
+
19
+ class RetinaFaceDetection(object):
20
+ def __init__(self, base_dir, device='cuda', network='RetinaFace-R50'):
21
+ torch.set_grad_enabled(False)
22
+ cudnn.benchmark = True
23
+ self.pretrained_path = os.path.join(base_dir, network+'.pth')
24
+ self.device = device #torch.cuda.current_device()
25
+ self.cfg = cfg_re50
26
+ self.net = RetinaFace(cfg=self.cfg, phase='test')
27
+ self.load_model()
28
+ self.net = self.net.to(device)
29
+
30
+ self.mean = torch.tensor([[[[104]], [[117]], [[123]]]]).to(device)
31
+
32
+ def check_keys(self, pretrained_state_dict):
33
+ ckpt_keys = set(pretrained_state_dict.keys())
34
+ model_keys = set(self.net.state_dict().keys())
35
+ used_pretrained_keys = model_keys & ckpt_keys
36
+ unused_pretrained_keys = ckpt_keys - model_keys
37
+ missing_keys = model_keys - ckpt_keys
38
+ assert len(used_pretrained_keys) > 0, 'load NONE from pretrained checkpoint'
39
+ return True
40
+
41
+ def remove_prefix(self, state_dict, prefix):
42
+ ''' Old style model is stored with all names of parameters sharing common prefix 'module.' '''
43
+ f = lambda x: x.split(prefix, 1)[-1] if x.startswith(prefix) else x
44
+ return {f(key): value for key, value in state_dict.items()}
45
+
46
+ def load_model(self, load_to_cpu=False):
47
+ #if load_to_cpu:
48
+ # pretrained_dict = torch.load(self.pretrained_path, map_location=lambda storage, loc: storage)
49
+ #else:
50
+ # pretrained_dict = torch.load(self.pretrained_path, map_location=lambda storage, loc: storage.cuda())
51
+ pretrained_dict = torch.load(self.pretrained_path, map_location=torch.device('cpu'))
52
+ if "state_dict" in pretrained_dict.keys():
53
+ pretrained_dict = self.remove_prefix(pretrained_dict['state_dict'], 'module.')
54
+ else:
55
+ pretrained_dict = self.remove_prefix(pretrained_dict, 'module.')
56
+ self.check_keys(pretrained_dict)
57
+ self.net.load_state_dict(pretrained_dict, strict=False)
58
+ self.net.eval()
59
+
60
+ def detect(self, img_raw, resize=1, confidence_threshold=0.9, nms_threshold=0.4, top_k=5000, keep_top_k=750, save_image=False):
61
+ img = np.float32(img_raw)
62
+
63
+ im_height, im_width = img.shape[:2]
64
+ ss = 1.0
65
+ # tricky
66
+ if max(im_height, im_width) > 1500:
67
+ ss = 1000.0/max(im_height, im_width)
68
+ img = cv2.resize(img, (0,0), fx=ss, fy=ss)
69
+ im_height, im_width = img.shape[:2]
70
+
71
+ scale = torch.Tensor([img.shape[1], img.shape[0], img.shape[1], img.shape[0]])
72
+ img -= (104, 117, 123)
73
+ img = img.transpose(2, 0, 1)
74
+ img = torch.from_numpy(img).unsqueeze(0)
75
+ img = img.to(self.device)
76
+ scale = scale.to(self.device)
77
+
78
+ with torch.no_grad():
79
+ loc, conf, landms = self.net(img) # forward pass
80
+
81
+ priorbox = PriorBox(self.cfg, image_size=(im_height, im_width))
82
+ priors = priorbox.forward()
83
+ priors = priors.to(self.device)
84
+ prior_data = priors.data
85
+ boxes = decode(loc.data.squeeze(0), prior_data, self.cfg['variance'])
86
+ boxes = boxes * scale / resize
87
+ boxes = boxes.cpu().numpy()
88
+ scores = conf.squeeze(0).data.cpu().numpy()[:, 1]
89
+ landms = decode_landm(landms.data.squeeze(0), prior_data, self.cfg['variance'])
90
+ scale1 = torch.Tensor([img.shape[3], img.shape[2], img.shape[3], img.shape[2],
91
+ img.shape[3], img.shape[2], img.shape[3], img.shape[2],
92
+ img.shape[3], img.shape[2]])
93
+ scale1 = scale1.to(self.device)
94
+ landms = landms * scale1 / resize
95
+ landms = landms.cpu().numpy()
96
+
97
+ # ignore low scores
98
+ inds = np.where(scores > confidence_threshold)[0]
99
+ boxes = boxes[inds]
100
+ landms = landms[inds]
101
+ scores = scores[inds]
102
+
103
+ # keep top-K before NMS
104
+ order = scores.argsort()[::-1][:top_k]
105
+ boxes = boxes[order]
106
+ landms = landms[order]
107
+ scores = scores[order]
108
+
109
+ # do NMS
110
+ dets = np.hstack((boxes, scores[:, np.newaxis])).astype(np.float32, copy=False)
111
+ keep = py_cpu_nms(dets, nms_threshold)
112
+ # keep = nms(dets, nms_threshold,force_cpu=args.cpu)
113
+ dets = dets[keep, :]
114
+ landms = landms[keep]
115
+
116
+ # keep top-K faster NMS
117
+ dets = dets[:keep_top_k, :]
118
+ landms = landms[:keep_top_k, :]
119
+
120
+ # sort faces(delete)
121
+ '''
122
+ fscores = [det[4] for det in dets]
123
+ sorted_idx = sorted(range(len(fscores)), key=lambda k:fscores[k], reverse=False) # sort index
124
+ tmp = [landms[idx] for idx in sorted_idx]
125
+ landms = np.asarray(tmp)
126
+ '''
127
+
128
+ landms = landms.reshape((-1, 5, 2))
129
+ landms = landms.transpose((0, 2, 1))
130
+ landms = landms.reshape(-1, 10, )
131
+ return dets/ss, landms/ss
132
+
133
+ def detect_tensor(self, img, resize=1, confidence_threshold=0.9, nms_threshold=0.4, top_k=5000, keep_top_k=750, save_image=False):
134
+ im_height, im_width = img.shape[-2:]
135
+ ss = 1000/max(im_height, im_width)
136
+ img = F.interpolate(img, scale_factor=ss)
137
+ im_height, im_width = img.shape[-2:]
138
+ scale = torch.Tensor([im_width, im_height, im_width, im_height]).to(self.device)
139
+ img -= self.mean
140
+
141
+ loc, conf, landms = self.net(img) # forward pass
142
+
143
+ priorbox = PriorBox(self.cfg, image_size=(im_height, im_width))
144
+ priors = priorbox.forward()
145
+ priors = priors.to(self.device)
146
+ prior_data = priors.data
147
+ boxes = decode(loc.data.squeeze(0), prior_data, self.cfg['variance'])
148
+ boxes = boxes * scale / resize
149
+ boxes = boxes.cpu().numpy()
150
+ scores = conf.squeeze(0).data.cpu().numpy()[:, 1]
151
+ landms = decode_landm(landms.data.squeeze(0), prior_data, self.cfg['variance'])
152
+ scale1 = torch.Tensor([img.shape[3], img.shape[2], img.shape[3], img.shape[2],
153
+ img.shape[3], img.shape[2], img.shape[3], img.shape[2],
154
+ img.shape[3], img.shape[2]])
155
+ scale1 = scale1.to(self.device)
156
+ landms = landms * scale1 / resize
157
+ landms = landms.cpu().numpy()
158
+
159
+ # ignore low scores
160
+ inds = np.where(scores > confidence_threshold)[0]
161
+ boxes = boxes[inds]
162
+ landms = landms[inds]
163
+ scores = scores[inds]
164
+
165
+ # keep top-K before NMS
166
+ order = scores.argsort()[::-1][:top_k]
167
+ boxes = boxes[order]
168
+ landms = landms[order]
169
+ scores = scores[order]
170
+
171
+ # do NMS
172
+ dets = np.hstack((boxes, scores[:, np.newaxis])).astype(np.float32, copy=False)
173
+ keep = py_cpu_nms(dets, nms_threshold)
174
+ # keep = nms(dets, nms_threshold,force_cpu=args.cpu)
175
+ dets = dets[keep, :]
176
+ landms = landms[keep]
177
+
178
+ # keep top-K faster NMS
179
+ dets = dets[:keep_top_k, :]
180
+ landms = landms[:keep_top_k, :]
181
+
182
+ # sort faces(delete)
183
+ '''
184
+ fscores = [det[4] for det in dets]
185
+ sorted_idx = sorted(range(len(fscores)), key=lambda k:fscores[k], reverse=False) # sort index
186
+ tmp = [landms[idx] for idx in sorted_idx]
187
+ landms = np.asarray(tmp)
188
+ '''
189
+
190
+ landms = landms.reshape((-1, 5, 2))
191
+ landms = landms.transpose((0, 2, 1))
192
+ landms = landms.reshape(-1, 10, )
193
+ return dets/ss, landms/ss
video-tetalking/third_part/GPEN/face_detect/utils/__init__.py ADDED
File without changes
video-tetalking/third_part/GPEN/face_detect/utils/box_utils.py ADDED
@@ -0,0 +1,330 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import numpy as np
3
+
4
+
5
+ def point_form(boxes):
6
+ """ Convert prior_boxes to (xmin, ymin, xmax, ymax)
7
+ representation for comparison to point form ground truth data.
8
+ Args:
9
+ boxes: (tensor) center-size default boxes from priorbox layers.
10
+ Return:
11
+ boxes: (tensor) Converted xmin, ymin, xmax, ymax form of boxes.
12
+ """
13
+ return torch.cat((boxes[:, :2] - boxes[:, 2:]/2, # xmin, ymin
14
+ boxes[:, :2] + boxes[:, 2:]/2), 1) # xmax, ymax
15
+
16
+
17
+ def center_size(boxes):
18
+ """ Convert prior_boxes to (cx, cy, w, h)
19
+ representation for comparison to center-size form ground truth data.
20
+ Args:
21
+ boxes: (tensor) point_form boxes
22
+ Return:
23
+ boxes: (tensor) Converted xmin, ymin, xmax, ymax form of boxes.
24
+ """
25
+ return torch.cat((boxes[:, 2:] + boxes[:, :2])/2, # cx, cy
26
+ boxes[:, 2:] - boxes[:, :2], 1) # w, h
27
+
28
+
29
+ def intersect(box_a, box_b):
30
+ """ We resize both tensors to [A,B,2] without new malloc:
31
+ [A,2] -> [A,1,2] -> [A,B,2]
32
+ [B,2] -> [1,B,2] -> [A,B,2]
33
+ Then we compute the area of intersect between box_a and box_b.
34
+ Args:
35
+ box_a: (tensor) bounding boxes, Shape: [A,4].
36
+ box_b: (tensor) bounding boxes, Shape: [B,4].
37
+ Return:
38
+ (tensor) intersection area, Shape: [A,B].
39
+ """
40
+ A = box_a.size(0)
41
+ B = box_b.size(0)
42
+ max_xy = torch.min(box_a[:, 2:].unsqueeze(1).expand(A, B, 2),
43
+ box_b[:, 2:].unsqueeze(0).expand(A, B, 2))
44
+ min_xy = torch.max(box_a[:, :2].unsqueeze(1).expand(A, B, 2),
45
+ box_b[:, :2].unsqueeze(0).expand(A, B, 2))
46
+ inter = torch.clamp((max_xy - min_xy), min=0)
47
+ return inter[:, :, 0] * inter[:, :, 1]
48
+
49
+
50
+ def jaccard(box_a, box_b):
51
+ """Compute the jaccard overlap of two sets of boxes. The jaccard overlap
52
+ is simply the intersection over union of two boxes. Here we operate on
53
+ ground truth boxes and default boxes.
54
+ E.g.:
55
+ A ∩ B / A ∪ B = A ∩ B / (area(A) + area(B) - A ∩ B)
56
+ Args:
57
+ box_a: (tensor) Ground truth bounding boxes, Shape: [num_objects,4]
58
+ box_b: (tensor) Prior boxes from priorbox layers, Shape: [num_priors,4]
59
+ Return:
60
+ jaccard overlap: (tensor) Shape: [box_a.size(0), box_b.size(0)]
61
+ """
62
+ inter = intersect(box_a, box_b)
63
+ area_a = ((box_a[:, 2]-box_a[:, 0]) *
64
+ (box_a[:, 3]-box_a[:, 1])).unsqueeze(1).expand_as(inter) # [A,B]
65
+ area_b = ((box_b[:, 2]-box_b[:, 0]) *
66
+ (box_b[:, 3]-box_b[:, 1])).unsqueeze(0).expand_as(inter) # [A,B]
67
+ union = area_a + area_b - inter
68
+ return inter / union # [A,B]
69
+
70
+
71
+ def matrix_iou(a, b):
72
+ """
73
+ return iou of a and b, numpy version for data augenmentation
74
+ """
75
+ lt = np.maximum(a[:, np.newaxis, :2], b[:, :2])
76
+ rb = np.minimum(a[:, np.newaxis, 2:], b[:, 2:])
77
+
78
+ area_i = np.prod(rb - lt, axis=2) * (lt < rb).all(axis=2)
79
+ area_a = np.prod(a[:, 2:] - a[:, :2], axis=1)
80
+ area_b = np.prod(b[:, 2:] - b[:, :2], axis=1)
81
+ return area_i / (area_a[:, np.newaxis] + area_b - area_i)
82
+
83
+
84
+ def matrix_iof(a, b):
85
+ """
86
+ return iof of a and b, numpy version for data augenmentation
87
+ """
88
+ lt = np.maximum(a[:, np.newaxis, :2], b[:, :2])
89
+ rb = np.minimum(a[:, np.newaxis, 2:], b[:, 2:])
90
+
91
+ area_i = np.prod(rb - lt, axis=2) * (lt < rb).all(axis=2)
92
+ area_a = np.prod(a[:, 2:] - a[:, :2], axis=1)
93
+ return area_i / np.maximum(area_a[:, np.newaxis], 1)
94
+
95
+
96
+ def match(threshold, truths, priors, variances, labels, landms, loc_t, conf_t, landm_t, idx):
97
+ """Match each prior box with the ground truth box of the highest jaccard
98
+ overlap, encode the bounding boxes, then return the matched indices
99
+ corresponding to both confidence and location preds.
100
+ Args:
101
+ threshold: (float) The overlap threshold used when mathing boxes.
102
+ truths: (tensor) Ground truth boxes, Shape: [num_obj, 4].
103
+ priors: (tensor) Prior boxes from priorbox layers, Shape: [n_priors,4].
104
+ variances: (tensor) Variances corresponding to each prior coord,
105
+ Shape: [num_priors, 4].
106
+ labels: (tensor) All the class labels for the image, Shape: [num_obj].
107
+ landms: (tensor) Ground truth landms, Shape [num_obj, 10].
108
+ loc_t: (tensor) Tensor to be filled w/ endcoded location targets.
109
+ conf_t: (tensor) Tensor to be filled w/ matched indices for conf preds.
110
+ landm_t: (tensor) Tensor to be filled w/ endcoded landm targets.
111
+ idx: (int) current batch index
112
+ Return:
113
+ The matched indices corresponding to 1)location 2)confidence 3)landm preds.
114
+ """
115
+ # jaccard index
116
+ overlaps = jaccard(
117
+ truths,
118
+ point_form(priors)
119
+ )
120
+ # (Bipartite Matching)
121
+ # [1,num_objects] best prior for each ground truth
122
+ best_prior_overlap, best_prior_idx = overlaps.max(1, keepdim=True)
123
+
124
+ # ignore hard gt
125
+ valid_gt_idx = best_prior_overlap[:, 0] >= 0.2
126
+ best_prior_idx_filter = best_prior_idx[valid_gt_idx, :]
127
+ if best_prior_idx_filter.shape[0] <= 0:
128
+ loc_t[idx] = 0
129
+ conf_t[idx] = 0
130
+ return
131
+
132
+ # [1,num_priors] best ground truth for each prior
133
+ best_truth_overlap, best_truth_idx = overlaps.max(0, keepdim=True)
134
+ best_truth_idx.squeeze_(0)
135
+ best_truth_overlap.squeeze_(0)
136
+ best_prior_idx.squeeze_(1)
137
+ best_prior_idx_filter.squeeze_(1)
138
+ best_prior_overlap.squeeze_(1)
139
+ best_truth_overlap.index_fill_(0, best_prior_idx_filter, 2) # ensure best prior
140
+ # TODO refactor: index best_prior_idx with long tensor
141
+ # ensure every gt matches with its prior of max overlap
142
+ for j in range(best_prior_idx.size(0)): # 判别此anchor是预测哪一个boxes
143
+ best_truth_idx[best_prior_idx[j]] = j
144
+ matches = truths[best_truth_idx] # Shape: [num_priors,4] 此处为每一个anchor对应的bbox取出来
145
+ conf = labels[best_truth_idx] # Shape: [num_priors] 此处为每一个anchor对应的label取出来
146
+ conf[best_truth_overlap < threshold] = 0 # label as background overlap<0.35的全部作为负样本
147
+ loc = encode(matches, priors, variances)
148
+
149
+ matches_landm = landms[best_truth_idx]
150
+ landm = encode_landm(matches_landm, priors, variances)
151
+ loc_t[idx] = loc # [num_priors,4] encoded offsets to learn
152
+ conf_t[idx] = conf # [num_priors] top class label for each prior
153
+ landm_t[idx] = landm
154
+
155
+
156
+ def encode(matched, priors, variances):
157
+ """Encode the variances from the priorbox layers into the ground truth boxes
158
+ we have matched (based on jaccard overlap) with the prior boxes.
159
+ Args:
160
+ matched: (tensor) Coords of ground truth for each prior in point-form
161
+ Shape: [num_priors, 4].
162
+ priors: (tensor) Prior boxes in center-offset form
163
+ Shape: [num_priors,4].
164
+ variances: (list[float]) Variances of priorboxes
165
+ Return:
166
+ encoded boxes (tensor), Shape: [num_priors, 4]
167
+ """
168
+
169
+ # dist b/t match center and prior's center
170
+ g_cxcy = (matched[:, :2] + matched[:, 2:])/2 - priors[:, :2]
171
+ # encode variance
172
+ g_cxcy /= (variances[0] * priors[:, 2:])
173
+ # match wh / prior wh
174
+ g_wh = (matched[:, 2:] - matched[:, :2]) / priors[:, 2:]
175
+ g_wh = torch.log(g_wh) / variances[1]
176
+ # return target for smooth_l1_loss
177
+ return torch.cat([g_cxcy, g_wh], 1) # [num_priors,4]
178
+
179
+ def encode_landm(matched, priors, variances):
180
+ """Encode the variances from the priorbox layers into the ground truth boxes
181
+ we have matched (based on jaccard overlap) with the prior boxes.
182
+ Args:
183
+ matched: (tensor) Coords of ground truth for each prior in point-form
184
+ Shape: [num_priors, 10].
185
+ priors: (tensor) Prior boxes in center-offset form
186
+ Shape: [num_priors,4].
187
+ variances: (list[float]) Variances of priorboxes
188
+ Return:
189
+ encoded landm (tensor), Shape: [num_priors, 10]
190
+ """
191
+
192
+ # dist b/t match center and prior's center
193
+ matched = torch.reshape(matched, (matched.size(0), 5, 2))
194
+ priors_cx = priors[:, 0].unsqueeze(1).expand(matched.size(0), 5).unsqueeze(2)
195
+ priors_cy = priors[:, 1].unsqueeze(1).expand(matched.size(0), 5).unsqueeze(2)
196
+ priors_w = priors[:, 2].unsqueeze(1).expand(matched.size(0), 5).unsqueeze(2)
197
+ priors_h = priors[:, 3].unsqueeze(1).expand(matched.size(0), 5).unsqueeze(2)
198
+ priors = torch.cat([priors_cx, priors_cy, priors_w, priors_h], dim=2)
199
+ g_cxcy = matched[:, :, :2] - priors[:, :, :2]
200
+ # encode variance
201
+ g_cxcy /= (variances[0] * priors[:, :, 2:])
202
+ # g_cxcy /= priors[:, :, 2:]
203
+ g_cxcy = g_cxcy.reshape(g_cxcy.size(0), -1)
204
+ # return target for smooth_l1_loss
205
+ return g_cxcy
206
+
207
+
208
+ # Adapted from https://github.com/Hakuyume/chainer-ssd
209
+ def decode(loc, priors, variances):
210
+ """Decode locations from predictions using priors to undo
211
+ the encoding we did for offset regression at train time.
212
+ Args:
213
+ loc (tensor): location predictions for loc layers,
214
+ Shape: [num_priors,4]
215
+ priors (tensor): Prior boxes in center-offset form.
216
+ Shape: [num_priors,4].
217
+ variances: (list[float]) Variances of priorboxes
218
+ Return:
219
+ decoded bounding box predictions
220
+ """
221
+
222
+ boxes = torch.cat((
223
+ priors[:, :2] + loc[:, :2] * variances[0] * priors[:, 2:],
224
+ priors[:, 2:] * torch.exp(loc[:, 2:] * variances[1])), 1)
225
+ boxes[:, :2] -= boxes[:, 2:] / 2
226
+ boxes[:, 2:] += boxes[:, :2]
227
+ return boxes
228
+
229
+ def decode_landm(pre, priors, variances):
230
+ """Decode landm from predictions using priors to undo
231
+ the encoding we did for offset regression at train time.
232
+ Args:
233
+ pre (tensor): landm predictions for loc layers,
234
+ Shape: [num_priors,10]
235
+ priors (tensor): Prior boxes in center-offset form.
236
+ Shape: [num_priors,4].
237
+ variances: (list[float]) Variances of priorboxes
238
+ Return:
239
+ decoded landm predictions
240
+ """
241
+ landms = torch.cat((priors[:, :2] + pre[:, :2] * variances[0] * priors[:, 2:],
242
+ priors[:, :2] + pre[:, 2:4] * variances[0] * priors[:, 2:],
243
+ priors[:, :2] + pre[:, 4:6] * variances[0] * priors[:, 2:],
244
+ priors[:, :2] + pre[:, 6:8] * variances[0] * priors[:, 2:],
245
+ priors[:, :2] + pre[:, 8:10] * variances[0] * priors[:, 2:],
246
+ ), dim=1)
247
+ return landms
248
+
249
+
250
+ def log_sum_exp(x):
251
+ """Utility function for computing log_sum_exp while determining
252
+ This will be used to determine unaveraged confidence loss across
253
+ all examples in a batch.
254
+ Args:
255
+ x (Variable(tensor)): conf_preds from conf layers
256
+ """
257
+ x_max = x.data.max()
258
+ return torch.log(torch.sum(torch.exp(x-x_max), 1, keepdim=True)) + x_max
259
+
260
+
261
+ # Original author: Francisco Massa:
262
+ # https://github.com/fmassa/object-detection.torch
263
+ # Ported to PyTorch by Max deGroot (02/01/2017)
264
+ def nms(boxes, scores, overlap=0.5, top_k=200):
265
+ """Apply non-maximum suppression at test time to avoid detecting too many
266
+ overlapping bounding boxes for a given object.
267
+ Args:
268
+ boxes: (tensor) The location preds for the img, Shape: [num_priors,4].
269
+ scores: (tensor) The class predscores for the img, Shape:[num_priors].
270
+ overlap: (float) The overlap thresh for suppressing unnecessary boxes.
271
+ top_k: (int) The Maximum number of box preds to consider.
272
+ Return:
273
+ The indices of the kept boxes with respect to num_priors.
274
+ """
275
+
276
+ keep = torch.Tensor(scores.size(0)).fill_(0).long()
277
+ if boxes.numel() == 0:
278
+ return keep
279
+ x1 = boxes[:, 0]
280
+ y1 = boxes[:, 1]
281
+ x2 = boxes[:, 2]
282
+ y2 = boxes[:, 3]
283
+ area = torch.mul(x2 - x1, y2 - y1)
284
+ v, idx = scores.sort(0) # sort in ascending order
285
+ # I = I[v >= 0.01]
286
+ idx = idx[-top_k:] # indices of the top-k largest vals
287
+ xx1 = boxes.new()
288
+ yy1 = boxes.new()
289
+ xx2 = boxes.new()
290
+ yy2 = boxes.new()
291
+ w = boxes.new()
292
+ h = boxes.new()
293
+
294
+ # keep = torch.Tensor()
295
+ count = 0
296
+ while idx.numel() > 0:
297
+ i = idx[-1] # index of current largest val
298
+ # keep.append(i)
299
+ keep[count] = i
300
+ count += 1
301
+ if idx.size(0) == 1:
302
+ break
303
+ idx = idx[:-1] # remove kept element from view
304
+ # load bboxes of next highest vals
305
+ torch.index_select(x1, 0, idx, out=xx1)
306
+ torch.index_select(y1, 0, idx, out=yy1)
307
+ torch.index_select(x2, 0, idx, out=xx2)
308
+ torch.index_select(y2, 0, idx, out=yy2)
309
+ # store element-wise max with next highest score
310
+ xx1 = torch.clamp(xx1, min=x1[i])
311
+ yy1 = torch.clamp(yy1, min=y1[i])
312
+ xx2 = torch.clamp(xx2, max=x2[i])
313
+ yy2 = torch.clamp(yy2, max=y2[i])
314
+ w.resize_as_(xx2)
315
+ h.resize_as_(yy2)
316
+ w = xx2 - xx1
317
+ h = yy2 - yy1
318
+ # check sizes of xx1 and xx2.. after each iteration
319
+ w = torch.clamp(w, min=0.0)
320
+ h = torch.clamp(h, min=0.0)
321
+ inter = w*h
322
+ # IoU = i / (area(a) + area(b) - i)
323
+ rem_areas = torch.index_select(area, 0, idx) # load remaining areas)
324
+ union = (rem_areas - inter) + area[i]
325
+ IoU = inter/union # store result in iou
326
+ # keep only elements with an IoU <= overlap
327
+ idx = idx[IoU.le(overlap)]
328
+ return keep, count
329
+
330
+