MyNiuuu commited on
Commit
4e42a1b
1 Parent(s): 8ce91a1
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .DS_Store +0 -0
  2. .gitattributes +2 -0
  3. README.md +36 -0
  4. aniportrait/.DS_Store +0 -0
  5. aniportrait/audio2ldmk.py +310 -0
  6. aniportrait/configs/config.yaml +12 -0
  7. aniportrait/configs/inference_audio.yaml +17 -0
  8. aniportrait/configs/inference_v2.yaml +35 -0
  9. aniportrait/src/.DS_Store +0 -0
  10. aniportrait/src/audio_models/mish.py +51 -0
  11. aniportrait/src/audio_models/model.py +71 -0
  12. aniportrait/src/audio_models/pose_model.py +125 -0
  13. aniportrait/src/audio_models/torch_utils.py +25 -0
  14. aniportrait/src/audio_models/wav2vec2.py +125 -0
  15. aniportrait/src/utils/audio_util.py +30 -0
  16. aniportrait/src/utils/draw_util.py +149 -0
  17. aniportrait/src/utils/face_landmark.py +3305 -0
  18. aniportrait/src/utils/frame_interpolation.py +69 -0
  19. aniportrait/src/utils/mp_models/blaze_face_short_range.tflite +3 -0
  20. aniportrait/src/utils/mp_models/face_landmarker_v2_with_blendshapes.task +3 -0
  21. aniportrait/src/utils/mp_models/pose_landmarker_heavy.task +3 -0
  22. aniportrait/src/utils/mp_utils.py +95 -0
  23. aniportrait/src/utils/pose_util.py +89 -0
  24. aniportrait/src/utils/util.py +181 -0
  25. ckpt_tree.md +108 -0
  26. ckpts/.DS_Store +0 -0
  27. ckpts/aniportrait/.DS_Store +0 -0
  28. ckpts/aniportrait/audio2mesh.pt +3 -0
  29. ckpts/aniportrait/audio2pose.pt +3 -0
  30. ckpts/aniportrait/denoising_unet.pth +3 -0
  31. ckpts/aniportrait/film_net_fp16.pt +3 -0
  32. ckpts/aniportrait/image_encoder/config.json +23 -0
  33. ckpts/aniportrait/image_encoder/pytorch_model.bin +3 -0
  34. ckpts/aniportrait/motion_module.pth +3 -0
  35. ckpts/aniportrait/pose_guider.pth +3 -0
  36. ckpts/aniportrait/reference_unet.pth +3 -0
  37. ckpts/aniportrait/sd-image-variations-diffusers/README.md +226 -0
  38. ckpts/aniportrait/sd-image-variations-diffusers/alias-montage.jpg +0 -0
  39. ckpts/aniportrait/sd-image-variations-diffusers/default-montage.jpg +0 -0
  40. ckpts/aniportrait/sd-image-variations-diffusers/earring.jpg +0 -0
  41. ckpts/aniportrait/sd-image-variations-diffusers/feature_extractor/preprocessor_config.json +28 -0
  42. ckpts/aniportrait/sd-image-variations-diffusers/inputs.jpg +0 -0
  43. ckpts/aniportrait/sd-image-variations-diffusers/model_index.json +29 -0
  44. ckpts/aniportrait/sd-image-variations-diffusers/safety_checker/config.json +181 -0
  45. ckpts/aniportrait/sd-image-variations-diffusers/safety_checker/pytorch_model.bin +3 -0
  46. ckpts/aniportrait/sd-image-variations-diffusers/scheduler/scheduler_config.json +13 -0
  47. ckpts/aniportrait/sd-image-variations-diffusers/unet/config.json +40 -0
  48. ckpts/aniportrait/sd-image-variations-diffusers/unet/diffusion_pytorch_model.bin +3 -0
  49. ckpts/aniportrait/sd-image-variations-diffusers/v1-montage.jpg +0 -0
  50. ckpts/aniportrait/sd-image-variations-diffusers/v2-montage.jpg +0 -0
.DS_Store ADDED
Binary file (8.2 kB). View file
 
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ *.task filter=lfs diff=lfs merge=lfs -text
37
+ *.mat filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ ## Introduction
3
+
4
+ This repo provides the inference Gradio demo for **Hybrid (Trajectory + Landmark)** Control of MOFA-Video.
5
+
6
+ ## Environment Setup
7
+
8
+ ```
9
+ cd MOFA-Hybrid
10
+ conda create -n mofa python==3.10
11
+ conda activate mofa
12
+ pip install -r requirements.txt
13
+ pip install opencv-python-headless
14
+ pip install "git+https://github.com/facebookresearch/pytorch3d.git"
15
+ ```
16
+
17
+ **IMPORTANT:** Gradio Version of **4.5.0** should be used since other versions may cause errors.
18
+
19
+
20
+ ## Checkpoints Download
21
+ 1. Download the checkpoint of CMP from [here](https://huggingface.co/MyNiuuu/MOFA-Video-Hybrid/blob/main/models/cmp/experiments/semiauto_annot/resnet50_vip%2Bmpii_liteflow/checkpoints/ckpt_iter_42000.pth.tar) and put it into `./models/cmp/experiments/semiauto_annot/resnet50_vip+mpii_liteflow/checkpoints`.
22
+
23
+ 2. Downloading the necessary pretrained checkpoints from [huggingface](https://huggingface.co/MyNiuuu/MOFA-Video-Hybrid). It is recommended to directly using git lfs to clone the [huggingface repo](https://huggingface.co/MyNiuuu/MOFA-Video-Hybrid). The checkpoints should be orgnized as `./ckpt_tree.md` (they will be automatically organized if you use git lfs to clone the [huggingface repo](https://huggingface.co/MyNiuuu/MOFA-Video-Hybrid)).
24
+
25
+
26
+ ## Run Gradio Demo
27
+
28
+ ### Using audio to animate the facial part
29
+
30
+ `python run_gradio_audio_driven.py`
31
+
32
+ ### Using refernce video to animate the facial part
33
+
34
+ `python run_gradio_audio_driven.py`
35
+
36
+ **IMPORTANT:** Please refer to the instructions on the gradio interface during the inference process.
aniportrait/.DS_Store ADDED
Binary file (6.15 kB). View file
 
aniportrait/audio2ldmk.py ADDED
@@ -0,0 +1,310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+ import os
3
+ # import ffmpeg
4
+ import random
5
+ import numpy as np
6
+ import cv2
7
+ import torch
8
+ import torchvision
9
+ from omegaconf import OmegaConf
10
+ from PIL import Image
11
+
12
+ from src.audio_models.model import Audio2MeshModel
13
+ from src.audio_models.pose_model import Audio2PoseModel
14
+ from src.utils.audio_util import prepare_audio_feature
15
+ from src.utils.mp_utils import LMKExtractor
16
+ from src.utils.pose_util import project_points, smooth_pose_seq
17
+
18
+
19
+ PARTS = [
20
+ ('FACE', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], (10, 200, 10)),
21
+ ('LEFT_EYE', [43, 44, 45, 46, 47, 48, 43], (180, 200, 10)),
22
+ ('LEFT_EYEBROW', [23, 24, 25, 26, 27], (180, 220, 10)),
23
+ ('RIGHT_EYE', [37, 38, 39, 40, 41, 42, 37], (10, 200, 180)),
24
+ ('RIGHT_EYEBROW', [18, 19, 20, 21, 22], (10, 220, 180)),
25
+ ('NOSE_UP', [28, 29, 30, 31], (10, 200, 250)),
26
+ ('NOSE_DOWN', [32, 33, 34, 35, 36], (250, 200, 10)),
27
+ ('LIPS_OUTER_BOTTOM_LEFT', [55, 56, 57, 58], (10, 180, 20)),
28
+ ('LIPS_OUTER_BOTTOM_RIGHT', [49, 60, 59, 58], (20, 10, 180)),
29
+ ('LIPS_INNER_BOTTOM_LEFT', [65, 66, 67], (100, 100, 30)),
30
+ ('LIPS_INNER_BOTTOM_RIGHT', [61, 68, 67], (100, 150, 50)),
31
+ ('LIPS_OUTER_TOP_LEFT', [52, 53, 54, 55], (20, 80, 100)),
32
+ ('LIPS_OUTER_TOP_RIGHT', [52, 51, 50, 49], (80, 100, 20)),
33
+ ('LIPS_INNER_TOP_LEFT', [63, 64, 65], (120, 100, 200)),
34
+ ('LIPS_INNER_TOP_RIGHT', [63, 62, 61], (150, 120, 100)),
35
+ ]
36
+
37
+
38
+ def draw_landmarks(keypoints, h, w):
39
+
40
+ image = np.zeros((h, w, 3))
41
+
42
+ for name, indices, color in PARTS:
43
+ # 选择当前部分的关键点
44
+ indices = np.array(indices) - 1
45
+ current_part_keypoints = keypoints[indices]
46
+
47
+ # 绘制关键点
48
+ # for point in current_part_keypoints:
49
+ # x, y = point
50
+ # image[y, x, :] = color
51
+
52
+ # 绘制连接线
53
+ for i in range(len(indices) - 1):
54
+ x1, y1 = current_part_keypoints[i]
55
+ x2, y2 = current_part_keypoints[i + 1]
56
+ cv2.line(image, (int(x1), int(y1)), (int(x2), int(y2)), color, thickness=2)
57
+
58
+ return image
59
+
60
+
61
+
62
+ def convert_ldmk_to_68(mediapipe_ldmk):
63
+ return np.stack([
64
+ # face coutour
65
+ mediapipe_ldmk[:, 234],
66
+ mediapipe_ldmk[:, 93],
67
+ mediapipe_ldmk[:, 132],
68
+ mediapipe_ldmk[:, 58],
69
+ mediapipe_ldmk[:, 172],
70
+ mediapipe_ldmk[:, 136],
71
+ mediapipe_ldmk[:, 150],
72
+ mediapipe_ldmk[:, 176],
73
+ mediapipe_ldmk[:, 152],
74
+ mediapipe_ldmk[:, 400],
75
+ mediapipe_ldmk[:, 379],
76
+ mediapipe_ldmk[:, 365],
77
+ mediapipe_ldmk[:, 397],
78
+ mediapipe_ldmk[:, 288],
79
+ mediapipe_ldmk[:, 361],
80
+ mediapipe_ldmk[:, 323],
81
+ mediapipe_ldmk[:, 454],
82
+ # right eyebrow
83
+ mediapipe_ldmk[:, 70],
84
+ mediapipe_ldmk[:, 63],
85
+ mediapipe_ldmk[:, 105],
86
+ mediapipe_ldmk[:, 66],
87
+ mediapipe_ldmk[:, 107],
88
+ # left eyebrow
89
+ mediapipe_ldmk[:, 336],
90
+ mediapipe_ldmk[:, 296],
91
+ mediapipe_ldmk[:, 334],
92
+ mediapipe_ldmk[:, 293],
93
+ mediapipe_ldmk[:, 300],
94
+ # nose
95
+ mediapipe_ldmk[:, 168],
96
+ mediapipe_ldmk[:, 6],
97
+ mediapipe_ldmk[:, 195],
98
+ mediapipe_ldmk[:, 4],
99
+ # nose down
100
+ mediapipe_ldmk[:, 239],
101
+ mediapipe_ldmk[:, 241],
102
+ mediapipe_ldmk[:, 19],
103
+ mediapipe_ldmk[:, 461],
104
+ mediapipe_ldmk[:, 459],
105
+ # right eye
106
+ mediapipe_ldmk[:, 33],
107
+ mediapipe_ldmk[:, 160],
108
+ mediapipe_ldmk[:, 158],
109
+ mediapipe_ldmk[:, 133],
110
+ mediapipe_ldmk[:, 153],
111
+ mediapipe_ldmk[:, 144],
112
+ # left eye
113
+ mediapipe_ldmk[:, 362],
114
+ mediapipe_ldmk[:, 385],
115
+ mediapipe_ldmk[:, 387],
116
+ mediapipe_ldmk[:, 263],
117
+ mediapipe_ldmk[:, 373],
118
+ mediapipe_ldmk[:, 380],
119
+ # outer lips
120
+ mediapipe_ldmk[:, 61],
121
+ mediapipe_ldmk[:, 40],
122
+ mediapipe_ldmk[:, 37],
123
+ mediapipe_ldmk[:, 0],
124
+ mediapipe_ldmk[:, 267],
125
+ mediapipe_ldmk[:, 270],
126
+ mediapipe_ldmk[:, 291],
127
+ mediapipe_ldmk[:, 321],
128
+ mediapipe_ldmk[:, 314],
129
+ mediapipe_ldmk[:, 17],
130
+ mediapipe_ldmk[:, 84],
131
+ mediapipe_ldmk[:, 91],
132
+ # inner lips
133
+ mediapipe_ldmk[:, 78],
134
+ mediapipe_ldmk[:, 81],
135
+ mediapipe_ldmk[:, 13],
136
+ mediapipe_ldmk[:, 311],
137
+ mediapipe_ldmk[:, 308],
138
+ mediapipe_ldmk[:, 402],
139
+ mediapipe_ldmk[:, 14],
140
+ mediapipe_ldmk[:, 178],
141
+ ], axis=1)
142
+
143
+
144
+
145
+ # def parse_args():
146
+ # parser = argparse.ArgumentParser()
147
+ # parser.add_argument("--config", type=str, default='./configs/prompts/animation_audio.yaml')
148
+ # parser.add_argument("-W", type=int, default=512)
149
+ # parser.add_argument("-H", type=int, default=512)
150
+ # parser.add_argument("-L", type=int)
151
+ # parser.add_argument("--seed", type=int, default=42)
152
+ # parser.add_argument("--cfg", type=float, default=3.5)
153
+ # parser.add_argument("--steps", type=int, default=25)
154
+ # parser.add_argument("--fps", type=int, default=30)
155
+ # parser.add_argument("-acc", "--accelerate", action='store_true')
156
+ # parser.add_argument("--fi_step", type=int, default=3)
157
+ # args = parser.parse_args()
158
+
159
+ # return args
160
+
161
+
162
+ def parse_args():
163
+ parser = argparse.ArgumentParser()
164
+ parser.add_argument("--ref_image_path", type=str, required=True)
165
+ parser.add_argument("--audio_path", type=str, required=True)
166
+ parser.add_argument("--save_dir", type=str, required=True)
167
+ parser.add_argument("--fps", type=int, default=25)
168
+ parser.add_argument("--sr", type=int, default=16000)
169
+ args = parser.parse_args()
170
+
171
+ return args
172
+
173
+
174
+ def set_seed(seed):
175
+ random.seed(seed)
176
+ np.random.seed(seed)
177
+ torch.manual_seed(seed)
178
+ if torch.cuda.is_available():
179
+ torch.cuda.manual_seed(seed)
180
+ torch.cuda.manual_seed_all(seed)
181
+ torch.backends.cudnn.deterministic = True
182
+
183
+
184
+ def main():
185
+ args = parse_args()
186
+
187
+ config = OmegaConf.load('aniportrait/configs/config.yaml')
188
+
189
+ set_seed(42)
190
+
191
+ # if config.weight_dtype == "fp16":
192
+ # weight_dtype = torch.float16
193
+ # else:
194
+ # weight_dtype = torch.float32
195
+
196
+ audio_infer_config = OmegaConf.load(config.audio_inference_config)
197
+ # prepare model
198
+ a2m_model = Audio2MeshModel(audio_infer_config['a2m_model'])
199
+ a2m_model.load_state_dict(torch.load(audio_infer_config['pretrained_model']['a2m_ckpt']), strict=False)
200
+ a2m_model.cuda().eval()
201
+
202
+ a2p_model = Audio2PoseModel(audio_infer_config['a2p_model'])
203
+ a2p_model.load_state_dict(torch.load(audio_infer_config['pretrained_model']['a2p_ckpt']), strict=False)
204
+ a2p_model.cuda().eval()
205
+
206
+ lmk_extractor = LMKExtractor()
207
+
208
+ ref_image_path = args.ref_image_path
209
+ audio_path = args.audio_path
210
+ save_dir = args.save_dir
211
+
212
+ ref_image_pil = Image.open(ref_image_path).convert("RGB")
213
+ ref_image_np = cv2.cvtColor(np.array(ref_image_pil), cv2.COLOR_RGB2BGR)
214
+ height, width, _ = ref_image_np.shape
215
+
216
+ face_result = lmk_extractor(ref_image_np)
217
+ assert face_result is not None, "No face detected."
218
+ lmks = face_result['lmks'].astype(np.float32)
219
+ lmks[:, 0] *= width
220
+ lmks[:, 1] *= height
221
+
222
+ # print(lmks.shape)
223
+
224
+ # assert False
225
+
226
+ sample = prepare_audio_feature(audio_path, fps=args.fps, wav2vec_model_path=audio_infer_config['a2m_model']['model_path'])
227
+ sample['audio_feature'] = torch.from_numpy(sample['audio_feature']).float().cuda()
228
+ sample['audio_feature'] = sample['audio_feature'].unsqueeze(0)
229
+
230
+ # print(sample['audio_feature'].shape)
231
+
232
+ # inference
233
+ pred = a2m_model.infer(sample['audio_feature'], sample['seq_len'])
234
+ pred = pred.squeeze().detach().cpu().numpy()
235
+ pred = pred.reshape(pred.shape[0], -1, 3)
236
+
237
+ pred = pred + face_result['lmks3d']
238
+
239
+ # print(pred.shape)
240
+
241
+ # assert False
242
+
243
+ id_seed = 42
244
+ id_seed = torch.LongTensor([id_seed]).cuda()
245
+
246
+ # Currently, only inference up to a maximum length of 10 seconds is supported.
247
+ chunk_duration = 5 # 5 seconds
248
+ chunk_size = args.sr * chunk_duration
249
+
250
+
251
+ audio_chunks = list(sample['audio_feature'].split(chunk_size, dim=1))
252
+ seq_len_list = [chunk_duration*args.fps] * (len(audio_chunks) - 1) + [sample['seq_len'] % (chunk_duration*args.fps)]
253
+ audio_chunks[-2] = torch.cat((audio_chunks[-2], audio_chunks[-1]), dim=1)
254
+ seq_len_list[-2] = seq_len_list[-2] + seq_len_list[-1]
255
+ del audio_chunks[-1]
256
+ del seq_len_list[-1]
257
+
258
+ # assert False
259
+
260
+ pose_seq = []
261
+ for audio, seq_len in zip(audio_chunks, seq_len_list):
262
+ pose_seq_chunk = a2p_model.infer(audio, seq_len, id_seed)
263
+ pose_seq_chunk = pose_seq_chunk.squeeze().detach().cpu().numpy()
264
+ pose_seq_chunk[:, :3] *= 0.5
265
+ pose_seq.append(pose_seq_chunk)
266
+
267
+ pose_seq = np.concatenate(pose_seq, 0)
268
+ pose_seq = smooth_pose_seq(pose_seq, 7)
269
+
270
+ # project 3D mesh to 2D landmark
271
+ projected_vertices = project_points(pred, face_result['trans_mat'], pose_seq, [height, width])
272
+ projected_vertices = np.concatenate([lmks[:468, :2][None, :], projected_vertices], axis=0)
273
+ projected_vertices = convert_ldmk_to_68(projected_vertices)
274
+
275
+ # print(projected_vertices.shape)
276
+
277
+ pose_images = []
278
+ for i in range(projected_vertices.shape[0]):
279
+ pose_img = draw_landmarks(projected_vertices[i], height, width)
280
+ pose_images.append(pose_img)
281
+ pose_images = np.array(pose_images)
282
+
283
+ # print(pose_images.shape)
284
+
285
+ ref_image_np = cv2.cvtColor(ref_image_np, cv2.COLOR_BGR2RGB)
286
+ ref_imgs = np.stack([ref_image_np]*(pose_images.shape[0]), axis=0)
287
+
288
+ all_np = np.concatenate([ref_imgs, pose_images], axis=2)
289
+
290
+ # print(projected_vertices.shape)
291
+
292
+ os.makedirs(save_dir, exist_ok=True)
293
+
294
+ np.save(os.path.join(save_dir, 'landmarks.npy'), projected_vertices)
295
+
296
+ torchvision.io.write_video(os.path.join(save_dir, 'landmarks.mp4'), all_np, fps=args.fps, video_codec='h264', options={'crf': '10'})
297
+
298
+ # stream = ffmpeg.input(os.path.join(save_dir, 'landmarks.mp4'))
299
+ # audio = ffmpeg.input(args.audio_path)
300
+ # ffmpeg.output(stream.video, audio.audio, os.path.join(save_dir, 'landmarks_audio.mp4'), vcodec='copy', acodec='aac').run()
301
+
302
+
303
+
304
+
305
+
306
+
307
+
308
+ if __name__ == "__main__":
309
+ main()
310
+
aniportrait/configs/config.yaml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ pretrained_base_model_path: 'ckpts/aniportrait/stable-diffusion-v1-5'
2
+ pretrained_vae_path: 'ckpts/aniportrait/sd-vae-ft-mse'
3
+ image_encoder_path: 'ckpts/aniportrait/image_encoder'
4
+
5
+ denoising_unet_path: "ckpts/aniportrait/denoising_unet.pth"
6
+ reference_unet_path: "ckpts/aniportrait/reference_unet.pth"
7
+ pose_guider_path: "ckpts/aniportrait/pose_guider.pth"
8
+ motion_module_path: "ckpts/aniportrait/motion_module.pth"
9
+
10
+ audio_inference_config: "aniportrait/configs/inference_audio.yaml"
11
+ inference_config: "aniportrait/configs/inference_v2.yaml"
12
+ weight_dtype: 'fp16'
aniportrait/configs/inference_audio.yaml ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ a2m_model:
2
+ out_dim: 1404
3
+ latent_dim: 512
4
+ model_path: ckpts/aniportrait/wav2vec2-base-960h
5
+ only_last_fetures: True
6
+ from_pretrained: True
7
+
8
+ a2p_model:
9
+ out_dim: 6
10
+ latent_dim: 512
11
+ model_path: ckpts/aniportrait/wav2vec2-base-960h
12
+ only_last_fetures: True
13
+ from_pretrained: True
14
+
15
+ pretrained_model:
16
+ a2m_ckpt: ckpts/aniportrait/audio2mesh.pt
17
+ a2p_ckpt: ckpts/aniportrait/audio2pose.pt
aniportrait/configs/inference_v2.yaml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ unet_additional_kwargs:
2
+ use_inflated_groupnorm: true
3
+ unet_use_cross_frame_attention: false
4
+ unet_use_temporal_attention: false
5
+ use_motion_module: true
6
+ motion_module_resolutions:
7
+ - 1
8
+ - 2
9
+ - 4
10
+ - 8
11
+ motion_module_mid_block: true
12
+ motion_module_decoder_only: false
13
+ motion_module_type: Vanilla
14
+ motion_module_kwargs:
15
+ num_attention_heads: 8
16
+ num_transformer_block: 1
17
+ attention_block_types:
18
+ - Temporal_Self
19
+ - Temporal_Self
20
+ temporal_position_encoding: true
21
+ temporal_position_encoding_max_len: 32
22
+ temporal_attention_dim_div: 1
23
+
24
+ noise_scheduler_kwargs:
25
+ beta_start: 0.00085
26
+ beta_end: 0.012
27
+ beta_schedule: "linear"
28
+ clip_sample: false
29
+ steps_offset: 1
30
+ ### Zero-SNR params
31
+ prediction_type: "v_prediction"
32
+ rescale_betas_zero_snr: True
33
+ timestep_spacing: "trailing"
34
+
35
+ sampler: DDIM
aniportrait/src/.DS_Store ADDED
Binary file (6.15 kB). View file
 
aniportrait/src/audio_models/mish.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Applies the mish function element-wise:
3
+ mish(x) = x * tanh(softplus(x)) = x * tanh(ln(1 + exp(x)))
4
+ """
5
+
6
+ # import pytorch
7
+ import torch
8
+ import torch.nn.functional as F
9
+ from torch import nn
10
+
11
+ @torch.jit.script
12
+ def mish(input):
13
+ """
14
+ Applies the mish function element-wise:
15
+ mish(x) = x * tanh(softplus(x)) = x * tanh(ln(1 + exp(x)))
16
+ See additional documentation for mish class.
17
+ """
18
+ return input * torch.tanh(F.softplus(input))
19
+
20
+ class Mish(nn.Module):
21
+ """
22
+ Applies the mish function element-wise:
23
+ mish(x) = x * tanh(softplus(x)) = x * tanh(ln(1 + exp(x)))
24
+
25
+ Shape:
26
+ - Input: (N, *) where * means, any number of additional
27
+ dimensions
28
+ - Output: (N, *), same shape as the input
29
+
30
+ Examples:
31
+ >>> m = Mish()
32
+ >>> input = torch.randn(2)
33
+ >>> output = m(input)
34
+
35
+ Reference: https://pytorch.org/docs/stable/generated/torch.nn.Mish.html
36
+ """
37
+
38
+ def __init__(self):
39
+ """
40
+ Init method.
41
+ """
42
+ super().__init__()
43
+
44
+ def forward(self, input):
45
+ """
46
+ Forward pass of the function.
47
+ """
48
+ if torch.__version__ >= "1.9":
49
+ return F.mish(input)
50
+ else:
51
+ return mish(input)
aniportrait/src/audio_models/model.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.nn.functional as F
5
+ from transformers import Wav2Vec2Config
6
+
7
+ from .torch_utils import get_mask_from_lengths
8
+ from .wav2vec2 import Wav2Vec2Model
9
+
10
+
11
+ class Audio2MeshModel(nn.Module):
12
+ def __init__(
13
+ self,
14
+ config
15
+ ):
16
+ super().__init__()
17
+ out_dim = config['out_dim']
18
+ latent_dim = config['latent_dim']
19
+ model_path = config['model_path']
20
+ only_last_fetures = config['only_last_fetures']
21
+ from_pretrained = config['from_pretrained']
22
+
23
+ self._only_last_features = only_last_fetures
24
+
25
+ self.audio_encoder_config = Wav2Vec2Config.from_pretrained(model_path, local_files_only=True)
26
+ if from_pretrained:
27
+ self.audio_encoder = Wav2Vec2Model.from_pretrained(model_path, local_files_only=True)
28
+ else:
29
+ self.audio_encoder = Wav2Vec2Model(self.audio_encoder_config)
30
+ self.audio_encoder.feature_extractor._freeze_parameters()
31
+
32
+ hidden_size = self.audio_encoder_config.hidden_size
33
+
34
+ self.in_fn = nn.Linear(hidden_size, latent_dim)
35
+
36
+ self.out_fn = nn.Linear(latent_dim, out_dim)
37
+ nn.init.constant_(self.out_fn.weight, 0)
38
+ nn.init.constant_(self.out_fn.bias, 0)
39
+
40
+ def forward(self, audio, label, audio_len=None):
41
+ attention_mask = ~get_mask_from_lengths(audio_len) if audio_len else None
42
+
43
+ seq_len = label.shape[1]
44
+
45
+ embeddings = self.audio_encoder(audio, seq_len=seq_len, output_hidden_states=True,
46
+ attention_mask=attention_mask)
47
+
48
+ if self._only_last_features:
49
+ hidden_states = embeddings.last_hidden_state
50
+ else:
51
+ hidden_states = sum(embeddings.hidden_states) / len(embeddings.hidden_states)
52
+
53
+ layer_in = self.in_fn(hidden_states)
54
+ out = self.out_fn(layer_in)
55
+
56
+ return out, None
57
+
58
+ def infer(self, input_value, seq_len):
59
+ embeddings = self.audio_encoder(input_value, seq_len=seq_len, output_hidden_states=True)
60
+
61
+ if self._only_last_features:
62
+ hidden_states = embeddings.last_hidden_state
63
+ else:
64
+ hidden_states = sum(embeddings.hidden_states) / len(embeddings.hidden_states)
65
+
66
+ layer_in = self.in_fn(hidden_states)
67
+ out = self.out_fn(layer_in)
68
+
69
+ return out
70
+
71
+
aniportrait/src/audio_models/pose_model.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import math
3
+ import torch
4
+ import torch.nn as nn
5
+ from transformers import Wav2Vec2Config
6
+
7
+ from .torch_utils import get_mask_from_lengths
8
+ from .wav2vec2 import Wav2Vec2Model
9
+
10
+
11
+ def init_biased_mask(n_head, max_seq_len, period):
12
+ def get_slopes(n):
13
+ def get_slopes_power_of_2(n):
14
+ start = (2**(-2**-(math.log2(n)-3)))
15
+ ratio = start
16
+ return [start*ratio**i for i in range(n)]
17
+ if math.log2(n).is_integer():
18
+ return get_slopes_power_of_2(n)
19
+ else:
20
+ closest_power_of_2 = 2**math.floor(math.log2(n))
21
+ return get_slopes_power_of_2(closest_power_of_2) + get_slopes(2*closest_power_of_2)[0::2][:n-closest_power_of_2]
22
+ slopes = torch.Tensor(get_slopes(n_head))
23
+ bias = torch.arange(start=0, end=max_seq_len, step=period).unsqueeze(1).repeat(1,period).view(-1)//(period)
24
+ bias = - torch.flip(bias,dims=[0])
25
+ alibi = torch.zeros(max_seq_len, max_seq_len)
26
+ for i in range(max_seq_len):
27
+ alibi[i, :i+1] = bias[-(i+1):]
28
+ alibi = slopes.unsqueeze(1).unsqueeze(1) * alibi.unsqueeze(0)
29
+ mask = (torch.triu(torch.ones(max_seq_len, max_seq_len)) == 1).transpose(0, 1)
30
+ mask = mask.float().masked_fill(mask == 0, float('-inf')).masked_fill(mask == 1, float(0.0))
31
+ mask = mask.unsqueeze(0) + alibi
32
+ return mask
33
+
34
+
35
+ def enc_dec_mask(device, T, S):
36
+ mask = torch.ones(T, S)
37
+ for i in range(T):
38
+ mask[i, i] = 0
39
+ return (mask==1).to(device=device)
40
+
41
+
42
+ class PositionalEncoding(nn.Module):
43
+ def __init__(self, d_model, max_len=600):
44
+ super(PositionalEncoding, self).__init__()
45
+ pe = torch.zeros(max_len, d_model)
46
+ position = torch.arange(0, max_len).unsqueeze(1).float()
47
+ div_term = torch.exp(torch.arange(0, d_model, 2).float() * -(math.log(10000.0) / d_model))
48
+ pe[:, 0::2] = torch.sin(position * div_term)
49
+ pe[:, 1::2] = torch.cos(position * div_term)
50
+ pe = pe.unsqueeze(0)
51
+ self.register_buffer('pe', pe)
52
+
53
+ def forward(self, x):
54
+ x = x + self.pe[:, :x.size(1)]
55
+ return x
56
+
57
+
58
+ class Audio2PoseModel(nn.Module):
59
+ def __init__(
60
+ self,
61
+ config
62
+ ):
63
+
64
+ super().__init__()
65
+
66
+ latent_dim = config['latent_dim']
67
+ model_path = config['model_path']
68
+ only_last_fetures = config['only_last_fetures']
69
+ from_pretrained = config['from_pretrained']
70
+ out_dim = config['out_dim']
71
+
72
+ self.out_dim = out_dim
73
+
74
+ self._only_last_features = only_last_fetures
75
+
76
+ self.audio_encoder_config = Wav2Vec2Config.from_pretrained(model_path, local_files_only=True)
77
+ if from_pretrained:
78
+ self.audio_encoder = Wav2Vec2Model.from_pretrained(model_path, local_files_only=True)
79
+ else:
80
+ self.audio_encoder = Wav2Vec2Model(self.audio_encoder_config)
81
+ self.audio_encoder.feature_extractor._freeze_parameters()
82
+
83
+ hidden_size = self.audio_encoder_config.hidden_size
84
+
85
+ self.pose_map = nn.Linear(out_dim, latent_dim)
86
+ self.in_fn = nn.Linear(hidden_size, latent_dim)
87
+
88
+ self.PPE = PositionalEncoding(latent_dim)
89
+ self.biased_mask = init_biased_mask(n_head = 8, max_seq_len = 600, period=1)
90
+ decoder_layer = nn.TransformerDecoderLayer(d_model=latent_dim, nhead=8, dim_feedforward=2*latent_dim, batch_first=True)
91
+ self.transformer_decoder = nn.TransformerDecoder(decoder_layer, num_layers=8)
92
+ self.pose_map_r = nn.Linear(latent_dim, out_dim)
93
+
94
+ self.id_embed = nn.Embedding(100, latent_dim) # 100 ids
95
+
96
+
97
+ def infer(self, input_value, seq_len, id_seed=None):
98
+ embeddings = self.audio_encoder(input_value, seq_len=seq_len, output_hidden_states=True)
99
+
100
+ if self._only_last_features:
101
+ hidden_states = embeddings.last_hidden_state
102
+ else:
103
+ hidden_states = sum(embeddings.hidden_states) / len(embeddings.hidden_states)
104
+
105
+ hidden_states = self.in_fn(hidden_states)
106
+
107
+ id_embedding = self.id_embed(id_seed).unsqueeze(1)
108
+
109
+ init_pose = torch.zeros([hidden_states.shape[0], 1, self.out_dim]).to(hidden_states.device)
110
+ for i in range(seq_len):
111
+ if i==0:
112
+ pose_emb = self.pose_map(init_pose)
113
+ pose_input = self.PPE(pose_emb)
114
+ else:
115
+ pose_input = self.PPE(pose_emb)
116
+
117
+ pose_input = pose_input + id_embedding
118
+ tgt_mask = self.biased_mask[:, :pose_input.shape[1], :pose_input.shape[1]].clone().detach().to(hidden_states.device)
119
+ memory_mask = enc_dec_mask(hidden_states.device, pose_input.shape[1], hidden_states.shape[1])
120
+ pose_out = self.transformer_decoder(pose_input, hidden_states, tgt_mask=tgt_mask, memory_mask=memory_mask)
121
+ pose_out = self.pose_map_r(pose_out)
122
+ new_output = self.pose_map(pose_out[:,-1,:]).unsqueeze(1)
123
+ pose_emb = torch.cat((pose_emb, new_output), 1)
124
+ return pose_out
125
+
aniportrait/src/audio_models/torch_utils.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn.functional as F
3
+
4
+
5
+ def get_mask_from_lengths(lengths, max_len=None):
6
+ lengths = lengths.to(torch.long)
7
+ if max_len is None:
8
+ max_len = torch.max(lengths).item()
9
+
10
+ ids = torch.arange(0, max_len).unsqueeze(0).expand(lengths.shape[0], -1).to(lengths.device)
11
+ mask = ids < lengths.unsqueeze(1).expand(-1, max_len)
12
+
13
+ return mask
14
+
15
+
16
+ def linear_interpolation(features, seq_len):
17
+ features = features.transpose(1, 2)
18
+ output_features = F.interpolate(features, size=seq_len, align_corners=True, mode='linear')
19
+ return output_features.transpose(1, 2)
20
+
21
+
22
+ if __name__ == "__main__":
23
+ import numpy as np
24
+ mask = ~get_mask_from_lengths(torch.from_numpy(np.array([4,6])))
25
+ import pdb; pdb.set_trace()
aniportrait/src/audio_models/wav2vec2.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import Wav2Vec2Config, Wav2Vec2Model
2
+ from transformers.modeling_outputs import BaseModelOutput
3
+
4
+ from .torch_utils import linear_interpolation
5
+
6
+ # the implementation of Wav2Vec2Model is borrowed from
7
+ # https://github.com/huggingface/transformers/blob/HEAD/src/transformers/models/wav2vec2/modeling_wav2vec2.py
8
+ # initialize our encoder with the pre-trained wav2vec 2.0 weights.
9
+ class Wav2Vec2Model(Wav2Vec2Model):
10
+ def __init__(self, config: Wav2Vec2Config):
11
+ super().__init__(config)
12
+
13
+ def forward(
14
+ self,
15
+ input_values,
16
+ seq_len,
17
+ attention_mask=None,
18
+ mask_time_indices=None,
19
+ output_attentions=None,
20
+ output_hidden_states=None,
21
+ return_dict=None,
22
+ ):
23
+ self.config.output_attentions = True
24
+
25
+ output_hidden_states = (
26
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
27
+ )
28
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
29
+
30
+ extract_features = self.feature_extractor(input_values)
31
+ extract_features = extract_features.transpose(1, 2)
32
+ extract_features = linear_interpolation(extract_features, seq_len=seq_len)
33
+
34
+ if attention_mask is not None:
35
+ # compute reduced attention_mask corresponding to feature vectors
36
+ attention_mask = self._get_feature_vector_attention_mask(
37
+ extract_features.shape[1], attention_mask, add_adapter=False
38
+ )
39
+
40
+ hidden_states, extract_features = self.feature_projection(extract_features)
41
+ hidden_states = self._mask_hidden_states(
42
+ hidden_states, mask_time_indices=mask_time_indices, attention_mask=attention_mask
43
+ )
44
+
45
+ encoder_outputs = self.encoder(
46
+ hidden_states,
47
+ attention_mask=attention_mask,
48
+ output_attentions=output_attentions,
49
+ output_hidden_states=output_hidden_states,
50
+ return_dict=return_dict,
51
+ )
52
+
53
+ hidden_states = encoder_outputs[0]
54
+
55
+ if self.adapter is not None:
56
+ hidden_states = self.adapter(hidden_states)
57
+
58
+ if not return_dict:
59
+ return (hidden_states, ) + encoder_outputs[1:]
60
+ return BaseModelOutput(
61
+ last_hidden_state=hidden_states,
62
+ hidden_states=encoder_outputs.hidden_states,
63
+ attentions=encoder_outputs.attentions,
64
+ )
65
+
66
+
67
+ def feature_extract(
68
+ self,
69
+ input_values,
70
+ seq_len,
71
+ ):
72
+ extract_features = self.feature_extractor(input_values)
73
+ extract_features = extract_features.transpose(1, 2)
74
+ extract_features = linear_interpolation(extract_features, seq_len=seq_len)
75
+
76
+ return extract_features
77
+
78
+ def encode(
79
+ self,
80
+ extract_features,
81
+ attention_mask=None,
82
+ mask_time_indices=None,
83
+ output_attentions=None,
84
+ output_hidden_states=None,
85
+ return_dict=None,
86
+ ):
87
+ self.config.output_attentions = True
88
+
89
+ output_hidden_states = (
90
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
91
+ )
92
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
93
+
94
+ if attention_mask is not None:
95
+ # compute reduced attention_mask corresponding to feature vectors
96
+ attention_mask = self._get_feature_vector_attention_mask(
97
+ extract_features.shape[1], attention_mask, add_adapter=False
98
+ )
99
+
100
+
101
+ hidden_states, extract_features = self.feature_projection(extract_features)
102
+ hidden_states = self._mask_hidden_states(
103
+ hidden_states, mask_time_indices=mask_time_indices, attention_mask=attention_mask
104
+ )
105
+
106
+ encoder_outputs = self.encoder(
107
+ hidden_states,
108
+ attention_mask=attention_mask,
109
+ output_attentions=output_attentions,
110
+ output_hidden_states=output_hidden_states,
111
+ return_dict=return_dict,
112
+ )
113
+
114
+ hidden_states = encoder_outputs[0]
115
+
116
+ if self.adapter is not None:
117
+ hidden_states = self.adapter(hidden_states)
118
+
119
+ if not return_dict:
120
+ return (hidden_states, ) + encoder_outputs[1:]
121
+ return BaseModelOutput(
122
+ last_hidden_state=hidden_states,
123
+ hidden_states=encoder_outputs.hidden_states,
124
+ attentions=encoder_outputs.attentions,
125
+ )
aniportrait/src/utils/audio_util.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import math
3
+
4
+ import librosa
5
+ import numpy as np
6
+ from transformers import Wav2Vec2FeatureExtractor
7
+
8
+
9
+ class DataProcessor:
10
+ def __init__(self, sampling_rate, wav2vec_model_path):
11
+ self._processor = Wav2Vec2FeatureExtractor.from_pretrained(wav2vec_model_path, local_files_only=True)
12
+ self._sampling_rate = sampling_rate
13
+
14
+ def extract_feature(self, audio_path):
15
+ speech_array, sampling_rate = librosa.load(audio_path, sr=self._sampling_rate)
16
+ input_value = np.squeeze(self._processor(speech_array, sampling_rate=sampling_rate).input_values)
17
+ return input_value
18
+
19
+
20
+ def prepare_audio_feature(wav_file, fps=25, sampling_rate=16000, wav2vec_model_path=None):
21
+ data_preprocessor = DataProcessor(sampling_rate, wav2vec_model_path)
22
+
23
+ input_value = data_preprocessor.extract_feature(wav_file)
24
+ seq_len = math.ceil(len(input_value)/sampling_rate*fps)
25
+ return {
26
+ "audio_feature": input_value,
27
+ "seq_len": seq_len
28
+ }
29
+
30
+
aniportrait/src/utils/draw_util.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import mediapipe as mp
3
+ import numpy as np
4
+ from mediapipe.framework.formats import landmark_pb2
5
+
6
+ class FaceMeshVisualizer:
7
+ def __init__(self, forehead_edge=False):
8
+ self.mp_drawing = mp.solutions.drawing_utils
9
+ mp_face_mesh = mp.solutions.face_mesh
10
+ self.mp_face_mesh = mp_face_mesh
11
+ self.forehead_edge = forehead_edge
12
+
13
+ DrawingSpec = mp.solutions.drawing_styles.DrawingSpec
14
+ f_thick = 2
15
+ f_rad = 1
16
+ right_iris_draw = DrawingSpec(color=(10, 200, 250), thickness=f_thick, circle_radius=f_rad)
17
+ right_eye_draw = DrawingSpec(color=(10, 200, 180), thickness=f_thick, circle_radius=f_rad)
18
+ right_eyebrow_draw = DrawingSpec(color=(10, 220, 180), thickness=f_thick, circle_radius=f_rad)
19
+ left_iris_draw = DrawingSpec(color=(250, 200, 10), thickness=f_thick, circle_radius=f_rad)
20
+ left_eye_draw = DrawingSpec(color=(180, 200, 10), thickness=f_thick, circle_radius=f_rad)
21
+ left_eyebrow_draw = DrawingSpec(color=(180, 220, 10), thickness=f_thick, circle_radius=f_rad)
22
+ head_draw = DrawingSpec(color=(10, 200, 10), thickness=f_thick, circle_radius=f_rad)
23
+
24
+ mouth_draw_obl = DrawingSpec(color=(10, 180, 20), thickness=f_thick, circle_radius=f_rad)
25
+ mouth_draw_obr = DrawingSpec(color=(20, 10, 180), thickness=f_thick, circle_radius=f_rad)
26
+
27
+ mouth_draw_ibl = DrawingSpec(color=(100, 100, 30), thickness=f_thick, circle_radius=f_rad)
28
+ mouth_draw_ibr = DrawingSpec(color=(100, 150, 50), thickness=f_thick, circle_radius=f_rad)
29
+
30
+ mouth_draw_otl = DrawingSpec(color=(20, 80, 100), thickness=f_thick, circle_radius=f_rad)
31
+ mouth_draw_otr = DrawingSpec(color=(80, 100, 20), thickness=f_thick, circle_radius=f_rad)
32
+
33
+ mouth_draw_itl = DrawingSpec(color=(120, 100, 200), thickness=f_thick, circle_radius=f_rad)
34
+ mouth_draw_itr = DrawingSpec(color=(150 ,120, 100), thickness=f_thick, circle_radius=f_rad)
35
+
36
+ FACEMESH_LIPS_OUTER_BOTTOM_LEFT = [(61,146),(146,91),(91,181),(181,84),(84,17)]
37
+ FACEMESH_LIPS_OUTER_BOTTOM_RIGHT = [(17,314),(314,405),(405,321),(321,375),(375,291)]
38
+
39
+ FACEMESH_LIPS_INNER_BOTTOM_LEFT = [(78,95),(95,88),(88,178),(178,87),(87,14)]
40
+ FACEMESH_LIPS_INNER_BOTTOM_RIGHT = [(14,317),(317,402),(402,318),(318,324),(324,308)]
41
+
42
+ FACEMESH_LIPS_OUTER_TOP_LEFT = [(61,185),(185,40),(40,39),(39,37),(37,0)]
43
+ FACEMESH_LIPS_OUTER_TOP_RIGHT = [(0,267),(267,269),(269,270),(270,409),(409,291)]
44
+
45
+ FACEMESH_LIPS_INNER_TOP_LEFT = [(78,191),(191,80),(80,81),(81,82),(82,13)]
46
+ FACEMESH_LIPS_INNER_TOP_RIGHT = [(13,312),(312,311),(311,310),(310,415),(415,308)]
47
+
48
+ FACEMESH_CUSTOM_FACE_OVAL = [(176, 149), (150, 136), (356, 454), (58, 132), (152, 148), (361, 288), (251, 389), (132, 93), (389, 356), (400, 377), (136, 172), (377, 152), (323, 361), (172, 58), (454, 323), (365, 379), (379, 378), (148, 176), (93, 234), (397, 365), (149, 150), (288, 397), (234, 127), (378, 400), (127, 162), (162, 21)]
49
+
50
+ # mp_face_mesh.FACEMESH_CONTOURS has all the items we care about.
51
+ face_connection_spec = {}
52
+ if self.forehead_edge:
53
+ for edge in mp_face_mesh.FACEMESH_FACE_OVAL:
54
+ face_connection_spec[edge] = head_draw
55
+ else:
56
+ for edge in FACEMESH_CUSTOM_FACE_OVAL:
57
+ face_connection_spec[edge] = head_draw
58
+ for edge in mp_face_mesh.FACEMESH_LEFT_EYE:
59
+ face_connection_spec[edge] = left_eye_draw
60
+ for edge in mp_face_mesh.FACEMESH_LEFT_EYEBROW:
61
+ face_connection_spec[edge] = left_eyebrow_draw
62
+ # for edge in mp_face_mesh.FACEMESH_LEFT_IRIS:
63
+ # face_connection_spec[edge] = left_iris_draw
64
+ for edge in mp_face_mesh.FACEMESH_RIGHT_EYE:
65
+ face_connection_spec[edge] = right_eye_draw
66
+ for edge in mp_face_mesh.FACEMESH_RIGHT_EYEBROW:
67
+ face_connection_spec[edge] = right_eyebrow_draw
68
+ # for edge in mp_face_mesh.FACEMESH_RIGHT_IRIS:
69
+ # face_connection_spec[edge] = right_iris_draw
70
+ # for edge in mp_face_mesh.FACEMESH_LIPS:
71
+ # face_connection_spec[edge] = mouth_draw
72
+
73
+ for edge in FACEMESH_LIPS_OUTER_BOTTOM_LEFT:
74
+ face_connection_spec[edge] = mouth_draw_obl
75
+ for edge in FACEMESH_LIPS_OUTER_BOTTOM_RIGHT:
76
+ face_connection_spec[edge] = mouth_draw_obr
77
+ for edge in FACEMESH_LIPS_INNER_BOTTOM_LEFT:
78
+ face_connection_spec[edge] = mouth_draw_ibl
79
+ for edge in FACEMESH_LIPS_INNER_BOTTOM_RIGHT:
80
+ face_connection_spec[edge] = mouth_draw_ibr
81
+ for edge in FACEMESH_LIPS_OUTER_TOP_LEFT:
82
+ face_connection_spec[edge] = mouth_draw_otl
83
+ for edge in FACEMESH_LIPS_OUTER_TOP_RIGHT:
84
+ face_connection_spec[edge] = mouth_draw_otr
85
+ for edge in FACEMESH_LIPS_INNER_TOP_LEFT:
86
+ face_connection_spec[edge] = mouth_draw_itl
87
+ for edge in FACEMESH_LIPS_INNER_TOP_RIGHT:
88
+ face_connection_spec[edge] = mouth_draw_itr
89
+
90
+
91
+ iris_landmark_spec = {468: right_iris_draw, 473: left_iris_draw}
92
+
93
+ self.face_connection_spec = face_connection_spec
94
+ def draw_pupils(self, image, landmark_list, drawing_spec, halfwidth: int = 2):
95
+ """We have a custom function to draw the pupils because the mp.draw_landmarks method requires a parameter for all
96
+ landmarks. Until our PR is merged into mediapipe, we need this separate method."""
97
+ if len(image.shape) != 3:
98
+ raise ValueError("Input image must be H,W,C.")
99
+ image_rows, image_cols, image_channels = image.shape
100
+ if image_channels != 3: # BGR channels
101
+ raise ValueError('Input image must contain three channel bgr data.')
102
+ for idx, landmark in enumerate(landmark_list.landmark):
103
+ if (
104
+ (landmark.HasField('visibility') and landmark.visibility < 0.9) or
105
+ (landmark.HasField('presence') and landmark.presence < 0.5)
106
+ ):
107
+ continue
108
+ if landmark.x >= 1.0 or landmark.x < 0 or landmark.y >= 1.0 or landmark.y < 0:
109
+ continue
110
+ image_x = int(image_cols*landmark.x)
111
+ image_y = int(image_rows*landmark.y)
112
+ draw_color = None
113
+ if isinstance(drawing_spec, Mapping):
114
+ if drawing_spec.get(idx) is None:
115
+ continue
116
+ else:
117
+ draw_color = drawing_spec[idx].color
118
+ elif isinstance(drawing_spec, DrawingSpec):
119
+ draw_color = drawing_spec.color
120
+ image[image_y-halfwidth:image_y+halfwidth, image_x-halfwidth:image_x+halfwidth, :] = draw_color
121
+
122
+
123
+
124
+ def draw_landmarks(self, image_size, keypoints, normed=False):
125
+ ini_size = [512, 512]
126
+ image = np.zeros([ini_size[1], ini_size[0], 3], dtype=np.uint8)
127
+ new_landmarks = landmark_pb2.NormalizedLandmarkList()
128
+ for i in range(keypoints.shape[0]):
129
+ landmark = new_landmarks.landmark.add()
130
+ if normed:
131
+ landmark.x = keypoints[i, 0]
132
+ landmark.y = keypoints[i, 1]
133
+ else:
134
+ landmark.x = keypoints[i, 0] / image_size[0]
135
+ landmark.y = keypoints[i, 1] / image_size[1]
136
+ landmark.z = 1.0
137
+
138
+ self.mp_drawing.draw_landmarks(
139
+ image=image,
140
+ landmark_list=new_landmarks,
141
+ connections=self.face_connection_spec.keys(),
142
+ landmark_drawing_spec=None,
143
+ connection_drawing_spec=self.face_connection_spec
144
+ )
145
+ # draw_pupils(image, face_landmarks, iris_landmark_spec, 2)
146
+ image = cv2.resize(image, (image_size[0], image_size[1]))
147
+
148
+ return image
149
+
aniportrait/src/utils/face_landmark.py ADDED
@@ -0,0 +1,3305 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 The MediaPipe Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """MediaPipe face landmarker task."""
15
+
16
+ import dataclasses
17
+ import enum
18
+ from typing import Callable, Mapping, Optional, List
19
+
20
+ import numpy as np
21
+
22
+ from mediapipe.framework.formats import classification_pb2
23
+ from mediapipe.framework.formats import landmark_pb2
24
+ from mediapipe.framework.formats import matrix_data_pb2
25
+ from mediapipe.python import packet_creator
26
+ from mediapipe.python import packet_getter
27
+ from mediapipe.python._framework_bindings import image as image_module
28
+ from mediapipe.python._framework_bindings import packet as packet_module
29
+ # pylint: disable=unused-import
30
+ from mediapipe.tasks.cc.vision.face_geometry.proto import face_geometry_pb2
31
+ # pylint: enable=unused-import
32
+ from mediapipe.tasks.cc.vision.face_landmarker.proto import face_landmarker_graph_options_pb2
33
+ from mediapipe.tasks.python.components.containers import category as category_module
34
+ from mediapipe.tasks.python.components.containers import landmark as landmark_module
35
+ from mediapipe.tasks.python.core import base_options as base_options_module
36
+ from mediapipe.tasks.python.core import task_info as task_info_module
37
+ from mediapipe.tasks.python.core.optional_dependencies import doc_controls
38
+ from mediapipe.tasks.python.vision.core import base_vision_task_api
39
+ from mediapipe.tasks.python.vision.core import image_processing_options as image_processing_options_module
40
+ from mediapipe.tasks.python.vision.core import vision_task_running_mode as running_mode_module
41
+
42
+ _BaseOptions = base_options_module.BaseOptions
43
+ _FaceLandmarkerGraphOptionsProto = (
44
+ face_landmarker_graph_options_pb2.FaceLandmarkerGraphOptions
45
+ )
46
+ _LayoutEnum = matrix_data_pb2.MatrixData.Layout
47
+ _RunningMode = running_mode_module.VisionTaskRunningMode
48
+ _ImageProcessingOptions = image_processing_options_module.ImageProcessingOptions
49
+ _TaskInfo = task_info_module.TaskInfo
50
+
51
+ _IMAGE_IN_STREAM_NAME = 'image_in'
52
+ _IMAGE_OUT_STREAM_NAME = 'image_out'
53
+ _IMAGE_TAG = 'IMAGE'
54
+ _NORM_RECT_STREAM_NAME = 'norm_rect_in'
55
+ _NORM_RECT_TAG = 'NORM_RECT'
56
+ _NORM_LANDMARKS_STREAM_NAME = 'norm_landmarks'
57
+ _NORM_LANDMARKS_TAG = 'NORM_LANDMARKS'
58
+ _BLENDSHAPES_STREAM_NAME = 'blendshapes'
59
+ _BLENDSHAPES_TAG = 'BLENDSHAPES'
60
+ _FACE_GEOMETRY_STREAM_NAME = 'face_geometry'
61
+ _FACE_GEOMETRY_TAG = 'FACE_GEOMETRY'
62
+ _TASK_GRAPH_NAME = 'mediapipe.tasks.vision.face_landmarker.FaceLandmarkerGraph'
63
+ _MICRO_SECONDS_PER_MILLISECOND = 1000
64
+
65
+
66
+ class Blendshapes(enum.IntEnum):
67
+ """The 52 blendshape coefficients."""
68
+
69
+ NEUTRAL = 0
70
+ BROW_DOWN_LEFT = 1
71
+ BROW_DOWN_RIGHT = 2
72
+ BROW_INNER_UP = 3
73
+ BROW_OUTER_UP_LEFT = 4
74
+ BROW_OUTER_UP_RIGHT = 5
75
+ CHEEK_PUFF = 6
76
+ CHEEK_SQUINT_LEFT = 7
77
+ CHEEK_SQUINT_RIGHT = 8
78
+ EYE_BLINK_LEFT = 9
79
+ EYE_BLINK_RIGHT = 10
80
+ EYE_LOOK_DOWN_LEFT = 11
81
+ EYE_LOOK_DOWN_RIGHT = 12
82
+ EYE_LOOK_IN_LEFT = 13
83
+ EYE_LOOK_IN_RIGHT = 14
84
+ EYE_LOOK_OUT_LEFT = 15
85
+ EYE_LOOK_OUT_RIGHT = 16
86
+ EYE_LOOK_UP_LEFT = 17
87
+ EYE_LOOK_UP_RIGHT = 18
88
+ EYE_SQUINT_LEFT = 19
89
+ EYE_SQUINT_RIGHT = 20
90
+ EYE_WIDE_LEFT = 21
91
+ EYE_WIDE_RIGHT = 22
92
+ JAW_FORWARD = 23
93
+ JAW_LEFT = 24
94
+ JAW_OPEN = 25
95
+ JAW_RIGHT = 26
96
+ MOUTH_CLOSE = 27
97
+ MOUTH_DIMPLE_LEFT = 28
98
+ MOUTH_DIMPLE_RIGHT = 29
99
+ MOUTH_FROWN_LEFT = 30
100
+ MOUTH_FROWN_RIGHT = 31
101
+ MOUTH_FUNNEL = 32
102
+ MOUTH_LEFT = 33
103
+ MOUTH_LOWER_DOWN_LEFT = 34
104
+ MOUTH_LOWER_DOWN_RIGHT = 35
105
+ MOUTH_PRESS_LEFT = 36
106
+ MOUTH_PRESS_RIGHT = 37
107
+ MOUTH_PUCKER = 38
108
+ MOUTH_RIGHT = 39
109
+ MOUTH_ROLL_LOWER = 40
110
+ MOUTH_ROLL_UPPER = 41
111
+ MOUTH_SHRUG_LOWER = 42
112
+ MOUTH_SHRUG_UPPER = 43
113
+ MOUTH_SMILE_LEFT = 44
114
+ MOUTH_SMILE_RIGHT = 45
115
+ MOUTH_STRETCH_LEFT = 46
116
+ MOUTH_STRETCH_RIGHT = 47
117
+ MOUTH_UPPER_UP_LEFT = 48
118
+ MOUTH_UPPER_UP_RIGHT = 49
119
+ NOSE_SNEER_LEFT = 50
120
+ NOSE_SNEER_RIGHT = 51
121
+
122
+
123
+ class FaceLandmarksConnections:
124
+ """The connections between face landmarks."""
125
+
126
+ @dataclasses.dataclass
127
+ class Connection:
128
+ """The connection class for face landmarks."""
129
+
130
+ start: int
131
+ end: int
132
+
133
+ FACE_LANDMARKS_LIPS: List[Connection] = [
134
+ Connection(61, 146),
135
+ Connection(146, 91),
136
+ Connection(91, 181),
137
+ Connection(181, 84),
138
+ Connection(84, 17),
139
+ Connection(17, 314),
140
+ Connection(314, 405),
141
+ Connection(405, 321),
142
+ Connection(321, 375),
143
+ Connection(375, 291),
144
+ Connection(61, 185),
145
+ Connection(185, 40),
146
+ Connection(40, 39),
147
+ Connection(39, 37),
148
+ Connection(37, 0),
149
+ Connection(0, 267),
150
+ Connection(267, 269),
151
+ Connection(269, 270),
152
+ Connection(270, 409),
153
+ Connection(409, 291),
154
+ Connection(78, 95),
155
+ Connection(95, 88),
156
+ Connection(88, 178),
157
+ Connection(178, 87),
158
+ Connection(87, 14),
159
+ Connection(14, 317),
160
+ Connection(317, 402),
161
+ Connection(402, 318),
162
+ Connection(318, 324),
163
+ Connection(324, 308),
164
+ Connection(78, 191),
165
+ Connection(191, 80),
166
+ Connection(80, 81),
167
+ Connection(81, 82),
168
+ Connection(82, 13),
169
+ Connection(13, 312),
170
+ Connection(312, 311),
171
+ Connection(311, 310),
172
+ Connection(310, 415),
173
+ Connection(415, 308),
174
+ ]
175
+
176
+ FACE_LANDMARKS_LEFT_EYE: List[Connection] = [
177
+ Connection(263, 249),
178
+ Connection(249, 390),
179
+ Connection(390, 373),
180
+ Connection(373, 374),
181
+ Connection(374, 380),
182
+ Connection(380, 381),
183
+ Connection(381, 382),
184
+ Connection(382, 362),
185
+ Connection(263, 466),
186
+ Connection(466, 388),
187
+ Connection(388, 387),
188
+ Connection(387, 386),
189
+ Connection(386, 385),
190
+ Connection(385, 384),
191
+ Connection(384, 398),
192
+ Connection(398, 362),
193
+ ]
194
+
195
+ FACE_LANDMARKS_LEFT_EYEBROW: List[Connection] = [
196
+ Connection(276, 283),
197
+ Connection(283, 282),
198
+ Connection(282, 295),
199
+ Connection(295, 285),
200
+ Connection(300, 293),
201
+ Connection(293, 334),
202
+ Connection(334, 296),
203
+ Connection(296, 336),
204
+ ]
205
+
206
+ FACE_LANDMARKS_LEFT_IRIS: List[Connection] = [
207
+ Connection(474, 475),
208
+ Connection(475, 476),
209
+ Connection(476, 477),
210
+ Connection(477, 474),
211
+ ]
212
+
213
+ FACE_LANDMARKS_RIGHT_EYE: List[Connection] = [
214
+ Connection(33, 7),
215
+ Connection(7, 163),
216
+ Connection(163, 144),
217
+ Connection(144, 145),
218
+ Connection(145, 153),
219
+ Connection(153, 154),
220
+ Connection(154, 155),
221
+ Connection(155, 133),
222
+ Connection(33, 246),
223
+ Connection(246, 161),
224
+ Connection(161, 160),
225
+ Connection(160, 159),
226
+ Connection(159, 158),
227
+ Connection(158, 157),
228
+ Connection(157, 173),
229
+ Connection(173, 133),
230
+ ]
231
+
232
+ FACE_LANDMARKS_RIGHT_EYEBROW: List[Connection] = [
233
+ Connection(46, 53),
234
+ Connection(53, 52),
235
+ Connection(52, 65),
236
+ Connection(65, 55),
237
+ Connection(70, 63),
238
+ Connection(63, 105),
239
+ Connection(105, 66),
240
+ Connection(66, 107),
241
+ ]
242
+
243
+ FACE_LANDMARKS_RIGHT_IRIS: List[Connection] = [
244
+ Connection(469, 470),
245
+ Connection(470, 471),
246
+ Connection(471, 472),
247
+ Connection(472, 469),
248
+ ]
249
+
250
+ FACE_LANDMARKS_FACE_OVAL: List[Connection] = [
251
+ Connection(10, 338),
252
+ Connection(338, 297),
253
+ Connection(297, 332),
254
+ Connection(332, 284),
255
+ Connection(284, 251),
256
+ Connection(251, 389),
257
+ Connection(389, 356),
258
+ Connection(356, 454),
259
+ Connection(454, 323),
260
+ Connection(323, 361),
261
+ Connection(361, 288),
262
+ Connection(288, 397),
263
+ Connection(397, 365),
264
+ Connection(365, 379),
265
+ Connection(379, 378),
266
+ Connection(378, 400),
267
+ Connection(400, 377),
268
+ Connection(377, 152),
269
+ Connection(152, 148),
270
+ Connection(148, 176),
271
+ Connection(176, 149),
272
+ Connection(149, 150),
273
+ Connection(150, 136),
274
+ Connection(136, 172),
275
+ Connection(172, 58),
276
+ Connection(58, 132),
277
+ Connection(132, 93),
278
+ Connection(93, 234),
279
+ Connection(234, 127),
280
+ Connection(127, 162),
281
+ Connection(162, 21),
282
+ Connection(21, 54),
283
+ Connection(54, 103),
284
+ Connection(103, 67),
285
+ Connection(67, 109),
286
+ Connection(109, 10),
287
+ ]
288
+
289
+ FACE_LANDMARKS_CONTOURS: List[Connection] = (
290
+ FACE_LANDMARKS_LIPS
291
+ + FACE_LANDMARKS_LEFT_EYE
292
+ + FACE_LANDMARKS_LEFT_EYEBROW
293
+ + FACE_LANDMARKS_RIGHT_EYE
294
+ + FACE_LANDMARKS_RIGHT_EYEBROW
295
+ + FACE_LANDMARKS_FACE_OVAL
296
+ )
297
+
298
+ FACE_LANDMARKS_TESSELATION: List[Connection] = [
299
+ Connection(127, 34),
300
+ Connection(34, 139),
301
+ Connection(139, 127),
302
+ Connection(11, 0),
303
+ Connection(0, 37),
304
+ Connection(37, 11),
305
+ Connection(232, 231),
306
+ Connection(231, 120),
307
+ Connection(120, 232),
308
+ Connection(72, 37),
309
+ Connection(37, 39),
310
+ Connection(39, 72),
311
+ Connection(128, 121),
312
+ Connection(121, 47),
313
+ Connection(47, 128),
314
+ Connection(232, 121),
315
+ Connection(121, 128),
316
+ Connection(128, 232),
317
+ Connection(104, 69),
318
+ Connection(69, 67),
319
+ Connection(67, 104),
320
+ Connection(175, 171),
321
+ Connection(171, 148),
322
+ Connection(148, 175),
323
+ Connection(118, 50),
324
+ Connection(50, 101),
325
+ Connection(101, 118),
326
+ Connection(73, 39),
327
+ Connection(39, 40),
328
+ Connection(40, 73),
329
+ Connection(9, 151),
330
+ Connection(151, 108),
331
+ Connection(108, 9),
332
+ Connection(48, 115),
333
+ Connection(115, 131),
334
+ Connection(131, 48),
335
+ Connection(194, 204),
336
+ Connection(204, 211),
337
+ Connection(211, 194),
338
+ Connection(74, 40),
339
+ Connection(40, 185),
340
+ Connection(185, 74),
341
+ Connection(80, 42),
342
+ Connection(42, 183),
343
+ Connection(183, 80),
344
+ Connection(40, 92),
345
+ Connection(92, 186),
346
+ Connection(186, 40),
347
+ Connection(230, 229),
348
+ Connection(229, 118),
349
+ Connection(118, 230),
350
+ Connection(202, 212),
351
+ Connection(212, 214),
352
+ Connection(214, 202),
353
+ Connection(83, 18),
354
+ Connection(18, 17),
355
+ Connection(17, 83),
356
+ Connection(76, 61),
357
+ Connection(61, 146),
358
+ Connection(146, 76),
359
+ Connection(160, 29),
360
+ Connection(29, 30),
361
+ Connection(30, 160),
362
+ Connection(56, 157),
363
+ Connection(157, 173),
364
+ Connection(173, 56),
365
+ Connection(106, 204),
366
+ Connection(204, 194),
367
+ Connection(194, 106),
368
+ Connection(135, 214),
369
+ Connection(214, 192),
370
+ Connection(192, 135),
371
+ Connection(203, 165),
372
+ Connection(165, 98),
373
+ Connection(98, 203),
374
+ Connection(21, 71),
375
+ Connection(71, 68),
376
+ Connection(68, 21),
377
+ Connection(51, 45),
378
+ Connection(45, 4),
379
+ Connection(4, 51),
380
+ Connection(144, 24),
381
+ Connection(24, 23),
382
+ Connection(23, 144),
383
+ Connection(77, 146),
384
+ Connection(146, 91),
385
+ Connection(91, 77),
386
+ Connection(205, 50),
387
+ Connection(50, 187),
388
+ Connection(187, 205),
389
+ Connection(201, 200),
390
+ Connection(200, 18),
391
+ Connection(18, 201),
392
+ Connection(91, 106),
393
+ Connection(106, 182),
394
+ Connection(182, 91),
395
+ Connection(90, 91),
396
+ Connection(91, 181),
397
+ Connection(181, 90),
398
+ Connection(85, 84),
399
+ Connection(84, 17),
400
+ Connection(17, 85),
401
+ Connection(206, 203),
402
+ Connection(203, 36),
403
+ Connection(36, 206),
404
+ Connection(148, 171),
405
+ Connection(171, 140),
406
+ Connection(140, 148),
407
+ Connection(92, 40),
408
+ Connection(40, 39),
409
+ Connection(39, 92),
410
+ Connection(193, 189),
411
+ Connection(189, 244),
412
+ Connection(244, 193),
413
+ Connection(159, 158),
414
+ Connection(158, 28),
415
+ Connection(28, 159),
416
+ Connection(247, 246),
417
+ Connection(246, 161),
418
+ Connection(161, 247),
419
+ Connection(236, 3),
420
+ Connection(3, 196),
421
+ Connection(196, 236),
422
+ Connection(54, 68),
423
+ Connection(68, 104),
424
+ Connection(104, 54),
425
+ Connection(193, 168),
426
+ Connection(168, 8),
427
+ Connection(8, 193),
428
+ Connection(117, 228),
429
+ Connection(228, 31),
430
+ Connection(31, 117),
431
+ Connection(189, 193),
432
+ Connection(193, 55),
433
+ Connection(55, 189),
434
+ Connection(98, 97),
435
+ Connection(97, 99),
436
+ Connection(99, 98),
437
+ Connection(126, 47),
438
+ Connection(47, 100),
439
+ Connection(100, 126),
440
+ Connection(166, 79),
441
+ Connection(79, 218),
442
+ Connection(218, 166),
443
+ Connection(155, 154),
444
+ Connection(154, 26),
445
+ Connection(26, 155),
446
+ Connection(209, 49),
447
+ Connection(49, 131),
448
+ Connection(131, 209),
449
+ Connection(135, 136),
450
+ Connection(136, 150),
451
+ Connection(150, 135),
452
+ Connection(47, 126),
453
+ Connection(126, 217),
454
+ Connection(217, 47),
455
+ Connection(223, 52),
456
+ Connection(52, 53),
457
+ Connection(53, 223),
458
+ Connection(45, 51),
459
+ Connection(51, 134),
460
+ Connection(134, 45),
461
+ Connection(211, 170),
462
+ Connection(170, 140),
463
+ Connection(140, 211),
464
+ Connection(67, 69),
465
+ Connection(69, 108),
466
+ Connection(108, 67),
467
+ Connection(43, 106),
468
+ Connection(106, 91),
469
+ Connection(91, 43),
470
+ Connection(230, 119),
471
+ Connection(119, 120),
472
+ Connection(120, 230),
473
+ Connection(226, 130),
474
+ Connection(130, 247),
475
+ Connection(247, 226),
476
+ Connection(63, 53),
477
+ Connection(53, 52),
478
+ Connection(52, 63),
479
+ Connection(238, 20),
480
+ Connection(20, 242),
481
+ Connection(242, 238),
482
+ Connection(46, 70),
483
+ Connection(70, 156),
484
+ Connection(156, 46),
485
+ Connection(78, 62),
486
+ Connection(62, 96),
487
+ Connection(96, 78),
488
+ Connection(46, 53),
489
+ Connection(53, 63),
490
+ Connection(63, 46),
491
+ Connection(143, 34),
492
+ Connection(34, 227),
493
+ Connection(227, 143),
494
+ Connection(123, 117),
495
+ Connection(117, 111),
496
+ Connection(111, 123),
497
+ Connection(44, 125),
498
+ Connection(125, 19),
499
+ Connection(19, 44),
500
+ Connection(236, 134),
501
+ Connection(134, 51),
502
+ Connection(51, 236),
503
+ Connection(216, 206),
504
+ Connection(206, 205),
505
+ Connection(205, 216),
506
+ Connection(154, 153),
507
+ Connection(153, 22),
508
+ Connection(22, 154),
509
+ Connection(39, 37),
510
+ Connection(37, 167),
511
+ Connection(167, 39),
512
+ Connection(200, 201),
513
+ Connection(201, 208),
514
+ Connection(208, 200),
515
+ Connection(36, 142),
516
+ Connection(142, 100),
517
+ Connection(100, 36),
518
+ Connection(57, 212),
519
+ Connection(212, 202),
520
+ Connection(202, 57),
521
+ Connection(20, 60),
522
+ Connection(60, 99),
523
+ Connection(99, 20),
524
+ Connection(28, 158),
525
+ Connection(158, 157),
526
+ Connection(157, 28),
527
+ Connection(35, 226),
528
+ Connection(226, 113),
529
+ Connection(113, 35),
530
+ Connection(160, 159),
531
+ Connection(159, 27),
532
+ Connection(27, 160),
533
+ Connection(204, 202),
534
+ Connection(202, 210),
535
+ Connection(210, 204),
536
+ Connection(113, 225),
537
+ Connection(225, 46),
538
+ Connection(46, 113),
539
+ Connection(43, 202),
540
+ Connection(202, 204),
541
+ Connection(204, 43),
542
+ Connection(62, 76),
543
+ Connection(76, 77),
544
+ Connection(77, 62),
545
+ Connection(137, 123),
546
+ Connection(123, 116),
547
+ Connection(116, 137),
548
+ Connection(41, 38),
549
+ Connection(38, 72),
550
+ Connection(72, 41),
551
+ Connection(203, 129),
552
+ Connection(129, 142),
553
+ Connection(142, 203),
554
+ Connection(64, 98),
555
+ Connection(98, 240),
556
+ Connection(240, 64),
557
+ Connection(49, 102),
558
+ Connection(102, 64),
559
+ Connection(64, 49),
560
+ Connection(41, 73),
561
+ Connection(73, 74),
562
+ Connection(74, 41),
563
+ Connection(212, 216),
564
+ Connection(216, 207),
565
+ Connection(207, 212),
566
+ Connection(42, 74),
567
+ Connection(74, 184),
568
+ Connection(184, 42),
569
+ Connection(169, 170),
570
+ Connection(170, 211),
571
+ Connection(211, 169),
572
+ Connection(170, 149),
573
+ Connection(149, 176),
574
+ Connection(176, 170),
575
+ Connection(105, 66),
576
+ Connection(66, 69),
577
+ Connection(69, 105),
578
+ Connection(122, 6),
579
+ Connection(6, 168),
580
+ Connection(168, 122),
581
+ Connection(123, 147),
582
+ Connection(147, 187),
583
+ Connection(187, 123),
584
+ Connection(96, 77),
585
+ Connection(77, 90),
586
+ Connection(90, 96),
587
+ Connection(65, 55),
588
+ Connection(55, 107),
589
+ Connection(107, 65),
590
+ Connection(89, 90),
591
+ Connection(90, 180),
592
+ Connection(180, 89),
593
+ Connection(101, 100),
594
+ Connection(100, 120),
595
+ Connection(120, 101),
596
+ Connection(63, 105),
597
+ Connection(105, 104),
598
+ Connection(104, 63),
599
+ Connection(93, 137),
600
+ Connection(137, 227),
601
+ Connection(227, 93),
602
+ Connection(15, 86),
603
+ Connection(86, 85),
604
+ Connection(85, 15),
605
+ Connection(129, 102),
606
+ Connection(102, 49),
607
+ Connection(49, 129),
608
+ Connection(14, 87),
609
+ Connection(87, 86),
610
+ Connection(86, 14),
611
+ Connection(55, 8),
612
+ Connection(8, 9),
613
+ Connection(9, 55),
614
+ Connection(100, 47),
615
+ Connection(47, 121),
616
+ Connection(121, 100),
617
+ Connection(145, 23),
618
+ Connection(23, 22),
619
+ Connection(22, 145),
620
+ Connection(88, 89),
621
+ Connection(89, 179),
622
+ Connection(179, 88),
623
+ Connection(6, 122),
624
+ Connection(122, 196),
625
+ Connection(196, 6),
626
+ Connection(88, 95),
627
+ Connection(95, 96),
628
+ Connection(96, 88),
629
+ Connection(138, 172),
630
+ Connection(172, 136),
631
+ Connection(136, 138),
632
+ Connection(215, 58),
633
+ Connection(58, 172),
634
+ Connection(172, 215),
635
+ Connection(115, 48),
636
+ Connection(48, 219),
637
+ Connection(219, 115),
638
+ Connection(42, 80),
639
+ Connection(80, 81),
640
+ Connection(81, 42),
641
+ Connection(195, 3),
642
+ Connection(3, 51),
643
+ Connection(51, 195),
644
+ Connection(43, 146),
645
+ Connection(146, 61),
646
+ Connection(61, 43),
647
+ Connection(171, 175),
648
+ Connection(175, 199),
649
+ Connection(199, 171),
650
+ Connection(81, 82),
651
+ Connection(82, 38),
652
+ Connection(38, 81),
653
+ Connection(53, 46),
654
+ Connection(46, 225),
655
+ Connection(225, 53),
656
+ Connection(144, 163),
657
+ Connection(163, 110),
658
+ Connection(110, 144),
659
+ Connection(52, 65),
660
+ Connection(65, 66),
661
+ Connection(66, 52),
662
+ Connection(229, 228),
663
+ Connection(228, 117),
664
+ Connection(117, 229),
665
+ Connection(34, 127),
666
+ Connection(127, 234),
667
+ Connection(234, 34),
668
+ Connection(107, 108),
669
+ Connection(108, 69),
670
+ Connection(69, 107),
671
+ Connection(109, 108),
672
+ Connection(108, 151),
673
+ Connection(151, 109),
674
+ Connection(48, 64),
675
+ Connection(64, 235),
676
+ Connection(235, 48),
677
+ Connection(62, 78),
678
+ Connection(78, 191),
679
+ Connection(191, 62),
680
+ Connection(129, 209),
681
+ Connection(209, 126),
682
+ Connection(126, 129),
683
+ Connection(111, 35),
684
+ Connection(35, 143),
685
+ Connection(143, 111),
686
+ Connection(117, 123),
687
+ Connection(123, 50),
688
+ Connection(50, 117),
689
+ Connection(222, 65),
690
+ Connection(65, 52),
691
+ Connection(52, 222),
692
+ Connection(19, 125),
693
+ Connection(125, 141),
694
+ Connection(141, 19),
695
+ Connection(221, 55),
696
+ Connection(55, 65),
697
+ Connection(65, 221),
698
+ Connection(3, 195),
699
+ Connection(195, 197),
700
+ Connection(197, 3),
701
+ Connection(25, 7),
702
+ Connection(7, 33),
703
+ Connection(33, 25),
704
+ Connection(220, 237),
705
+ Connection(237, 44),
706
+ Connection(44, 220),
707
+ Connection(70, 71),
708
+ Connection(71, 139),
709
+ Connection(139, 70),
710
+ Connection(122, 193),
711
+ Connection(193, 245),
712
+ Connection(245, 122),
713
+ Connection(247, 130),
714
+ Connection(130, 33),
715
+ Connection(33, 247),
716
+ Connection(71, 21),
717
+ Connection(21, 162),
718
+ Connection(162, 71),
719
+ Connection(170, 169),
720
+ Connection(169, 150),
721
+ Connection(150, 170),
722
+ Connection(188, 174),
723
+ Connection(174, 196),
724
+ Connection(196, 188),
725
+ Connection(216, 186),
726
+ Connection(186, 92),
727
+ Connection(92, 216),
728
+ Connection(2, 97),
729
+ Connection(97, 167),
730
+ Connection(167, 2),
731
+ Connection(141, 125),
732
+ Connection(125, 241),
733
+ Connection(241, 141),
734
+ Connection(164, 167),
735
+ Connection(167, 37),
736
+ Connection(37, 164),
737
+ Connection(72, 38),
738
+ Connection(38, 12),
739
+ Connection(12, 72),
740
+ Connection(38, 82),
741
+ Connection(82, 13),
742
+ Connection(13, 38),
743
+ Connection(63, 68),
744
+ Connection(68, 71),
745
+ Connection(71, 63),
746
+ Connection(226, 35),
747
+ Connection(35, 111),
748
+ Connection(111, 226),
749
+ Connection(101, 50),
750
+ Connection(50, 205),
751
+ Connection(205, 101),
752
+ Connection(206, 92),
753
+ Connection(92, 165),
754
+ Connection(165, 206),
755
+ Connection(209, 198),
756
+ Connection(198, 217),
757
+ Connection(217, 209),
758
+ Connection(165, 167),
759
+ Connection(167, 97),
760
+ Connection(97, 165),
761
+ Connection(220, 115),
762
+ Connection(115, 218),
763
+ Connection(218, 220),
764
+ Connection(133, 112),
765
+ Connection(112, 243),
766
+ Connection(243, 133),
767
+ Connection(239, 238),
768
+ Connection(238, 241),
769
+ Connection(241, 239),
770
+ Connection(214, 135),
771
+ Connection(135, 169),
772
+ Connection(169, 214),
773
+ Connection(190, 173),
774
+ Connection(173, 133),
775
+ Connection(133, 190),
776
+ Connection(171, 208),
777
+ Connection(208, 32),
778
+ Connection(32, 171),
779
+ Connection(125, 44),
780
+ Connection(44, 237),
781
+ Connection(237, 125),
782
+ Connection(86, 87),
783
+ Connection(87, 178),
784
+ Connection(178, 86),
785
+ Connection(85, 86),
786
+ Connection(86, 179),
787
+ Connection(179, 85),
788
+ Connection(84, 85),
789
+ Connection(85, 180),
790
+ Connection(180, 84),
791
+ Connection(83, 84),
792
+ Connection(84, 181),
793
+ Connection(181, 83),
794
+ Connection(201, 83),
795
+ Connection(83, 182),
796
+ Connection(182, 201),
797
+ Connection(137, 93),
798
+ Connection(93, 132),
799
+ Connection(132, 137),
800
+ Connection(76, 62),
801
+ Connection(62, 183),
802
+ Connection(183, 76),
803
+ Connection(61, 76),
804
+ Connection(76, 184),
805
+ Connection(184, 61),
806
+ Connection(57, 61),
807
+ Connection(61, 185),
808
+ Connection(185, 57),
809
+ Connection(212, 57),
810
+ Connection(57, 186),
811
+ Connection(186, 212),
812
+ Connection(214, 207),
813
+ Connection(207, 187),
814
+ Connection(187, 214),
815
+ Connection(34, 143),
816
+ Connection(143, 156),
817
+ Connection(156, 34),
818
+ Connection(79, 239),
819
+ Connection(239, 237),
820
+ Connection(237, 79),
821
+ Connection(123, 137),
822
+ Connection(137, 177),
823
+ Connection(177, 123),
824
+ Connection(44, 1),
825
+ Connection(1, 4),
826
+ Connection(4, 44),
827
+ Connection(201, 194),
828
+ Connection(194, 32),
829
+ Connection(32, 201),
830
+ Connection(64, 102),
831
+ Connection(102, 129),
832
+ Connection(129, 64),
833
+ Connection(213, 215),
834
+ Connection(215, 138),
835
+ Connection(138, 213),
836
+ Connection(59, 166),
837
+ Connection(166, 219),
838
+ Connection(219, 59),
839
+ Connection(242, 99),
840
+ Connection(99, 97),
841
+ Connection(97, 242),
842
+ Connection(2, 94),
843
+ Connection(94, 141),
844
+ Connection(141, 2),
845
+ Connection(75, 59),
846
+ Connection(59, 235),
847
+ Connection(235, 75),
848
+ Connection(24, 110),
849
+ Connection(110, 228),
850
+ Connection(228, 24),
851
+ Connection(25, 130),
852
+ Connection(130, 226),
853
+ Connection(226, 25),
854
+ Connection(23, 24),
855
+ Connection(24, 229),
856
+ Connection(229, 23),
857
+ Connection(22, 23),
858
+ Connection(23, 230),
859
+ Connection(230, 22),
860
+ Connection(26, 22),
861
+ Connection(22, 231),
862
+ Connection(231, 26),
863
+ Connection(112, 26),
864
+ Connection(26, 232),
865
+ Connection(232, 112),
866
+ Connection(189, 190),
867
+ Connection(190, 243),
868
+ Connection(243, 189),
869
+ Connection(221, 56),
870
+ Connection(56, 190),
871
+ Connection(190, 221),
872
+ Connection(28, 56),
873
+ Connection(56, 221),
874
+ Connection(221, 28),
875
+ Connection(27, 28),
876
+ Connection(28, 222),
877
+ Connection(222, 27),
878
+ Connection(29, 27),
879
+ Connection(27, 223),
880
+ Connection(223, 29),
881
+ Connection(30, 29),
882
+ Connection(29, 224),
883
+ Connection(224, 30),
884
+ Connection(247, 30),
885
+ Connection(30, 225),
886
+ Connection(225, 247),
887
+ Connection(238, 79),
888
+ Connection(79, 20),
889
+ Connection(20, 238),
890
+ Connection(166, 59),
891
+ Connection(59, 75),
892
+ Connection(75, 166),
893
+ Connection(60, 75),
894
+ Connection(75, 240),
895
+ Connection(240, 60),
896
+ Connection(147, 177),
897
+ Connection(177, 215),
898
+ Connection(215, 147),
899
+ Connection(20, 79),
900
+ Connection(79, 166),
901
+ Connection(166, 20),
902
+ Connection(187, 147),
903
+ Connection(147, 213),
904
+ Connection(213, 187),
905
+ Connection(112, 233),
906
+ Connection(233, 244),
907
+ Connection(244, 112),
908
+ Connection(233, 128),
909
+ Connection(128, 245),
910
+ Connection(245, 233),
911
+ Connection(128, 114),
912
+ Connection(114, 188),
913
+ Connection(188, 128),
914
+ Connection(114, 217),
915
+ Connection(217, 174),
916
+ Connection(174, 114),
917
+ Connection(131, 115),
918
+ Connection(115, 220),
919
+ Connection(220, 131),
920
+ Connection(217, 198),
921
+ Connection(198, 236),
922
+ Connection(236, 217),
923
+ Connection(198, 131),
924
+ Connection(131, 134),
925
+ Connection(134, 198),
926
+ Connection(177, 132),
927
+ Connection(132, 58),
928
+ Connection(58, 177),
929
+ Connection(143, 35),
930
+ Connection(35, 124),
931
+ Connection(124, 143),
932
+ Connection(110, 163),
933
+ Connection(163, 7),
934
+ Connection(7, 110),
935
+ Connection(228, 110),
936
+ Connection(110, 25),
937
+ Connection(25, 228),
938
+ Connection(356, 389),
939
+ Connection(389, 368),
940
+ Connection(368, 356),
941
+ Connection(11, 302),
942
+ Connection(302, 267),
943
+ Connection(267, 11),
944
+ Connection(452, 350),
945
+ Connection(350, 349),
946
+ Connection(349, 452),
947
+ Connection(302, 303),
948
+ Connection(303, 269),
949
+ Connection(269, 302),
950
+ Connection(357, 343),
951
+ Connection(343, 277),
952
+ Connection(277, 357),
953
+ Connection(452, 453),
954
+ Connection(453, 357),
955
+ Connection(357, 452),
956
+ Connection(333, 332),
957
+ Connection(332, 297),
958
+ Connection(297, 333),
959
+ Connection(175, 152),
960
+ Connection(152, 377),
961
+ Connection(377, 175),
962
+ Connection(347, 348),
963
+ Connection(348, 330),
964
+ Connection(330, 347),
965
+ Connection(303, 304),
966
+ Connection(304, 270),
967
+ Connection(270, 303),
968
+ Connection(9, 336),
969
+ Connection(336, 337),
970
+ Connection(337, 9),
971
+ Connection(278, 279),
972
+ Connection(279, 360),
973
+ Connection(360, 278),
974
+ Connection(418, 262),
975
+ Connection(262, 431),
976
+ Connection(431, 418),
977
+ Connection(304, 408),
978
+ Connection(408, 409),
979
+ Connection(409, 304),
980
+ Connection(310, 415),
981
+ Connection(415, 407),
982
+ Connection(407, 310),
983
+ Connection(270, 409),
984
+ Connection(409, 410),
985
+ Connection(410, 270),
986
+ Connection(450, 348),
987
+ Connection(348, 347),
988
+ Connection(347, 450),
989
+ Connection(422, 430),
990
+ Connection(430, 434),
991
+ Connection(434, 422),
992
+ Connection(313, 314),
993
+ Connection(314, 17),
994
+ Connection(17, 313),
995
+ Connection(306, 307),
996
+ Connection(307, 375),
997
+ Connection(375, 306),
998
+ Connection(387, 388),
999
+ Connection(388, 260),
1000
+ Connection(260, 387),
1001
+ Connection(286, 414),
1002
+ Connection(414, 398),
1003
+ Connection(398, 286),
1004
+ Connection(335, 406),
1005
+ Connection(406, 418),
1006
+ Connection(418, 335),
1007
+ Connection(364, 367),
1008
+ Connection(367, 416),
1009
+ Connection(416, 364),
1010
+ Connection(423, 358),
1011
+ Connection(358, 327),
1012
+ Connection(327, 423),
1013
+ Connection(251, 284),
1014
+ Connection(284, 298),
1015
+ Connection(298, 251),
1016
+ Connection(281, 5),
1017
+ Connection(5, 4),
1018
+ Connection(4, 281),
1019
+ Connection(373, 374),
1020
+ Connection(374, 253),
1021
+ Connection(253, 373),
1022
+ Connection(307, 320),
1023
+ Connection(320, 321),
1024
+ Connection(321, 307),
1025
+ Connection(425, 427),
1026
+ Connection(427, 411),
1027
+ Connection(411, 425),
1028
+ Connection(421, 313),
1029
+ Connection(313, 18),
1030
+ Connection(18, 421),
1031
+ Connection(321, 405),
1032
+ Connection(405, 406),
1033
+ Connection(406, 321),
1034
+ Connection(320, 404),
1035
+ Connection(404, 405),
1036
+ Connection(405, 320),
1037
+ Connection(315, 16),
1038
+ Connection(16, 17),
1039
+ Connection(17, 315),
1040
+ Connection(426, 425),
1041
+ Connection(425, 266),
1042
+ Connection(266, 426),
1043
+ Connection(377, 400),
1044
+ Connection(400, 369),
1045
+ Connection(369, 377),
1046
+ Connection(322, 391),
1047
+ Connection(391, 269),
1048
+ Connection(269, 322),
1049
+ Connection(417, 465),
1050
+ Connection(465, 464),
1051
+ Connection(464, 417),
1052
+ Connection(386, 257),
1053
+ Connection(257, 258),
1054
+ Connection(258, 386),
1055
+ Connection(466, 260),
1056
+ Connection(260, 388),
1057
+ Connection(388, 466),
1058
+ Connection(456, 399),
1059
+ Connection(399, 419),
1060
+ Connection(419, 456),
1061
+ Connection(284, 332),
1062
+ Connection(332, 333),
1063
+ Connection(333, 284),
1064
+ Connection(417, 285),
1065
+ Connection(285, 8),
1066
+ Connection(8, 417),
1067
+ Connection(346, 340),
1068
+ Connection(340, 261),
1069
+ Connection(261, 346),
1070
+ Connection(413, 441),
1071
+ Connection(441, 285),
1072
+ Connection(285, 413),
1073
+ Connection(327, 460),
1074
+ Connection(460, 328),
1075
+ Connection(328, 327),
1076
+ Connection(355, 371),
1077
+ Connection(371, 329),
1078
+ Connection(329, 355),
1079
+ Connection(392, 439),
1080
+ Connection(439, 438),
1081
+ Connection(438, 392),
1082
+ Connection(382, 341),
1083
+ Connection(341, 256),
1084
+ Connection(256, 382),
1085
+ Connection(429, 420),
1086
+ Connection(420, 360),
1087
+ Connection(360, 429),
1088
+ Connection(364, 394),
1089
+ Connection(394, 379),
1090
+ Connection(379, 364),
1091
+ Connection(277, 343),
1092
+ Connection(343, 437),
1093
+ Connection(437, 277),
1094
+ Connection(443, 444),
1095
+ Connection(444, 283),
1096
+ Connection(283, 443),
1097
+ Connection(275, 440),
1098
+ Connection(440, 363),
1099
+ Connection(363, 275),
1100
+ Connection(431, 262),
1101
+ Connection(262, 369),
1102
+ Connection(369, 431),
1103
+ Connection(297, 338),
1104
+ Connection(338, 337),
1105
+ Connection(337, 297),
1106
+ Connection(273, 375),
1107
+ Connection(375, 321),
1108
+ Connection(321, 273),
1109
+ Connection(450, 451),
1110
+ Connection(451, 349),
1111
+ Connection(349, 450),
1112
+ Connection(446, 342),
1113
+ Connection(342, 467),
1114
+ Connection(467, 446),
1115
+ Connection(293, 334),
1116
+ Connection(334, 282),
1117
+ Connection(282, 293),
1118
+ Connection(458, 461),
1119
+ Connection(461, 462),
1120
+ Connection(462, 458),
1121
+ Connection(276, 353),
1122
+ Connection(353, 383),
1123
+ Connection(383, 276),
1124
+ Connection(308, 324),
1125
+ Connection(324, 325),
1126
+ Connection(325, 308),
1127
+ Connection(276, 300),
1128
+ Connection(300, 293),
1129
+ Connection(293, 276),
1130
+ Connection(372, 345),
1131
+ Connection(345, 447),
1132
+ Connection(447, 372),
1133
+ Connection(352, 345),
1134
+ Connection(345, 340),
1135
+ Connection(340, 352),
1136
+ Connection(274, 1),
1137
+ Connection(1, 19),
1138
+ Connection(19, 274),
1139
+ Connection(456, 248),
1140
+ Connection(248, 281),
1141
+ Connection(281, 456),
1142
+ Connection(436, 427),
1143
+ Connection(427, 425),
1144
+ Connection(425, 436),
1145
+ Connection(381, 256),
1146
+ Connection(256, 252),
1147
+ Connection(252, 381),
1148
+ Connection(269, 391),
1149
+ Connection(391, 393),
1150
+ Connection(393, 269),
1151
+ Connection(200, 199),
1152
+ Connection(199, 428),
1153
+ Connection(428, 200),
1154
+ Connection(266, 330),
1155
+ Connection(330, 329),
1156
+ Connection(329, 266),
1157
+ Connection(287, 273),
1158
+ Connection(273, 422),
1159
+ Connection(422, 287),
1160
+ Connection(250, 462),
1161
+ Connection(462, 328),
1162
+ Connection(328, 250),
1163
+ Connection(258, 286),
1164
+ Connection(286, 384),
1165
+ Connection(384, 258),
1166
+ Connection(265, 353),
1167
+ Connection(353, 342),
1168
+ Connection(342, 265),
1169
+ Connection(387, 259),
1170
+ Connection(259, 257),
1171
+ Connection(257, 387),
1172
+ Connection(424, 431),
1173
+ Connection(431, 430),
1174
+ Connection(430, 424),
1175
+ Connection(342, 353),
1176
+ Connection(353, 276),
1177
+ Connection(276, 342),
1178
+ Connection(273, 335),
1179
+ Connection(335, 424),
1180
+ Connection(424, 273),
1181
+ Connection(292, 325),
1182
+ Connection(325, 307),
1183
+ Connection(307, 292),
1184
+ Connection(366, 447),
1185
+ Connection(447, 345),
1186
+ Connection(345, 366),
1187
+ Connection(271, 303),
1188
+ Connection(303, 302),
1189
+ Connection(302, 271),
1190
+ Connection(423, 266),
1191
+ Connection(266, 371),
1192
+ Connection(371, 423),
1193
+ Connection(294, 455),
1194
+ Connection(455, 460),
1195
+ Connection(460, 294),
1196
+ Connection(279, 278),
1197
+ Connection(278, 294),
1198
+ Connection(294, 279),
1199
+ Connection(271, 272),
1200
+ Connection(272, 304),
1201
+ Connection(304, 271),
1202
+ Connection(432, 434),
1203
+ Connection(434, 427),
1204
+ Connection(427, 432),
1205
+ Connection(272, 407),
1206
+ Connection(407, 408),
1207
+ Connection(408, 272),
1208
+ Connection(394, 430),
1209
+ Connection(430, 431),
1210
+ Connection(431, 394),
1211
+ Connection(395, 369),
1212
+ Connection(369, 400),
1213
+ Connection(400, 395),
1214
+ Connection(334, 333),
1215
+ Connection(333, 299),
1216
+ Connection(299, 334),
1217
+ Connection(351, 417),
1218
+ Connection(417, 168),
1219
+ Connection(168, 351),
1220
+ Connection(352, 280),
1221
+ Connection(280, 411),
1222
+ Connection(411, 352),
1223
+ Connection(325, 319),
1224
+ Connection(319, 320),
1225
+ Connection(320, 325),
1226
+ Connection(295, 296),
1227
+ Connection(296, 336),
1228
+ Connection(336, 295),
1229
+ Connection(319, 403),
1230
+ Connection(403, 404),
1231
+ Connection(404, 319),
1232
+ Connection(330, 348),
1233
+ Connection(348, 349),
1234
+ Connection(349, 330),
1235
+ Connection(293, 298),
1236
+ Connection(298, 333),
1237
+ Connection(333, 293),
1238
+ Connection(323, 454),
1239
+ Connection(454, 447),
1240
+ Connection(447, 323),
1241
+ Connection(15, 16),
1242
+ Connection(16, 315),
1243
+ Connection(315, 15),
1244
+ Connection(358, 429),
1245
+ Connection(429, 279),
1246
+ Connection(279, 358),
1247
+ Connection(14, 15),
1248
+ Connection(15, 316),
1249
+ Connection(316, 14),
1250
+ Connection(285, 336),
1251
+ Connection(336, 9),
1252
+ Connection(9, 285),
1253
+ Connection(329, 349),
1254
+ Connection(349, 350),
1255
+ Connection(350, 329),
1256
+ Connection(374, 380),
1257
+ Connection(380, 252),
1258
+ Connection(252, 374),
1259
+ Connection(318, 402),
1260
+ Connection(402, 403),
1261
+ Connection(403, 318),
1262
+ Connection(6, 197),
1263
+ Connection(197, 419),
1264
+ Connection(419, 6),
1265
+ Connection(318, 319),
1266
+ Connection(319, 325),
1267
+ Connection(325, 318),
1268
+ Connection(367, 364),
1269
+ Connection(364, 365),
1270
+ Connection(365, 367),
1271
+ Connection(435, 367),
1272
+ Connection(367, 397),
1273
+ Connection(397, 435),
1274
+ Connection(344, 438),
1275
+ Connection(438, 439),
1276
+ Connection(439, 344),
1277
+ Connection(272, 271),
1278
+ Connection(271, 311),
1279
+ Connection(311, 272),
1280
+ Connection(195, 5),
1281
+ Connection(5, 281),
1282
+ Connection(281, 195),
1283
+ Connection(273, 287),
1284
+ Connection(287, 291),
1285
+ Connection(291, 273),
1286
+ Connection(396, 428),
1287
+ Connection(428, 199),
1288
+ Connection(199, 396),
1289
+ Connection(311, 271),
1290
+ Connection(271, 268),
1291
+ Connection(268, 311),
1292
+ Connection(283, 444),
1293
+ Connection(444, 445),
1294
+ Connection(445, 283),
1295
+ Connection(373, 254),
1296
+ Connection(254, 339),
1297
+ Connection(339, 373),
1298
+ Connection(282, 334),
1299
+ Connection(334, 296),
1300
+ Connection(296, 282),
1301
+ Connection(449, 347),
1302
+ Connection(347, 346),
1303
+ Connection(346, 449),
1304
+ Connection(264, 447),
1305
+ Connection(447, 454),
1306
+ Connection(454, 264),
1307
+ Connection(336, 296),
1308
+ Connection(296, 299),
1309
+ Connection(299, 336),
1310
+ Connection(338, 10),
1311
+ Connection(10, 151),
1312
+ Connection(151, 338),
1313
+ Connection(278, 439),
1314
+ Connection(439, 455),
1315
+ Connection(455, 278),
1316
+ Connection(292, 407),
1317
+ Connection(407, 415),
1318
+ Connection(415, 292),
1319
+ Connection(358, 371),
1320
+ Connection(371, 355),
1321
+ Connection(355, 358),
1322
+ Connection(340, 345),
1323
+ Connection(345, 372),
1324
+ Connection(372, 340),
1325
+ Connection(346, 347),
1326
+ Connection(347, 280),
1327
+ Connection(280, 346),
1328
+ Connection(442, 443),
1329
+ Connection(443, 282),
1330
+ Connection(282, 442),
1331
+ Connection(19, 94),
1332
+ Connection(94, 370),
1333
+ Connection(370, 19),
1334
+ Connection(441, 442),
1335
+ Connection(442, 295),
1336
+ Connection(295, 441),
1337
+ Connection(248, 419),
1338
+ Connection(419, 197),
1339
+ Connection(197, 248),
1340
+ Connection(263, 255),
1341
+ Connection(255, 359),
1342
+ Connection(359, 263),
1343
+ Connection(440, 275),
1344
+ Connection(275, 274),
1345
+ Connection(274, 440),
1346
+ Connection(300, 383),
1347
+ Connection(383, 368),
1348
+ Connection(368, 300),
1349
+ Connection(351, 412),
1350
+ Connection(412, 465),
1351
+ Connection(465, 351),
1352
+ Connection(263, 467),
1353
+ Connection(467, 466),
1354
+ Connection(466, 263),
1355
+ Connection(301, 368),
1356
+ Connection(368, 389),
1357
+ Connection(389, 301),
1358
+ Connection(395, 378),
1359
+ Connection(378, 379),
1360
+ Connection(379, 395),
1361
+ Connection(412, 351),
1362
+ Connection(351, 419),
1363
+ Connection(419, 412),
1364
+ Connection(436, 426),
1365
+ Connection(426, 322),
1366
+ Connection(322, 436),
1367
+ Connection(2, 164),
1368
+ Connection(164, 393),
1369
+ Connection(393, 2),
1370
+ Connection(370, 462),
1371
+ Connection(462, 461),
1372
+ Connection(461, 370),
1373
+ Connection(164, 0),
1374
+ Connection(0, 267),
1375
+ Connection(267, 164),
1376
+ Connection(302, 11),
1377
+ Connection(11, 12),
1378
+ Connection(12, 302),
1379
+ Connection(268, 12),
1380
+ Connection(12, 13),
1381
+ Connection(13, 268),
1382
+ Connection(293, 300),
1383
+ Connection(300, 301),
1384
+ Connection(301, 293),
1385
+ Connection(446, 261),
1386
+ Connection(261, 340),
1387
+ Connection(340, 446),
1388
+ Connection(330, 266),
1389
+ Connection(266, 425),
1390
+ Connection(425, 330),
1391
+ Connection(426, 423),
1392
+ Connection(423, 391),
1393
+ Connection(391, 426),
1394
+ Connection(429, 355),
1395
+ Connection(355, 437),
1396
+ Connection(437, 429),
1397
+ Connection(391, 327),
1398
+ Connection(327, 326),
1399
+ Connection(326, 391),
1400
+ Connection(440, 457),
1401
+ Connection(457, 438),
1402
+ Connection(438, 440),
1403
+ Connection(341, 382),
1404
+ Connection(382, 362),
1405
+ Connection(362, 341),
1406
+ Connection(459, 457),
1407
+ Connection(457, 461),
1408
+ Connection(461, 459),
1409
+ Connection(434, 430),
1410
+ Connection(430, 394),
1411
+ Connection(394, 434),
1412
+ Connection(414, 463),
1413
+ Connection(463, 362),
1414
+ Connection(362, 414),
1415
+ Connection(396, 369),
1416
+ Connection(369, 262),
1417
+ Connection(262, 396),
1418
+ Connection(354, 461),
1419
+ Connection(461, 457),
1420
+ Connection(457, 354),
1421
+ Connection(316, 403),
1422
+ Connection(403, 402),
1423
+ Connection(402, 316),
1424
+ Connection(315, 404),
1425
+ Connection(404, 403),
1426
+ Connection(403, 315),
1427
+ Connection(314, 405),
1428
+ Connection(405, 404),
1429
+ Connection(404, 314),
1430
+ Connection(313, 406),
1431
+ Connection(406, 405),
1432
+ Connection(405, 313),
1433
+ Connection(421, 418),
1434
+ Connection(418, 406),
1435
+ Connection(406, 421),
1436
+ Connection(366, 401),
1437
+ Connection(401, 361),
1438
+ Connection(361, 366),
1439
+ Connection(306, 408),
1440
+ Connection(408, 407),
1441
+ Connection(407, 306),
1442
+ Connection(291, 409),
1443
+ Connection(409, 408),
1444
+ Connection(408, 291),
1445
+ Connection(287, 410),
1446
+ Connection(410, 409),
1447
+ Connection(409, 287),
1448
+ Connection(432, 436),
1449
+ Connection(436, 410),
1450
+ Connection(410, 432),
1451
+ Connection(434, 416),
1452
+ Connection(416, 411),
1453
+ Connection(411, 434),
1454
+ Connection(264, 368),
1455
+ Connection(368, 383),
1456
+ Connection(383, 264),
1457
+ Connection(309, 438),
1458
+ Connection(438, 457),
1459
+ Connection(457, 309),
1460
+ Connection(352, 376),
1461
+ Connection(376, 401),
1462
+ Connection(401, 352),
1463
+ Connection(274, 275),
1464
+ Connection(275, 4),
1465
+ Connection(4, 274),
1466
+ Connection(421, 428),
1467
+ Connection(428, 262),
1468
+ Connection(262, 421),
1469
+ Connection(294, 327),
1470
+ Connection(327, 358),
1471
+ Connection(358, 294),
1472
+ Connection(433, 416),
1473
+ Connection(416, 367),
1474
+ Connection(367, 433),
1475
+ Connection(289, 455),
1476
+ Connection(455, 439),
1477
+ Connection(439, 289),
1478
+ Connection(462, 370),
1479
+ Connection(370, 326),
1480
+ Connection(326, 462),
1481
+ Connection(2, 326),
1482
+ Connection(326, 370),
1483
+ Connection(370, 2),
1484
+ Connection(305, 460),
1485
+ Connection(460, 455),
1486
+ Connection(455, 305),
1487
+ Connection(254, 449),
1488
+ Connection(449, 448),
1489
+ Connection(448, 254),
1490
+ Connection(255, 261),
1491
+ Connection(261, 446),
1492
+ Connection(446, 255),
1493
+ Connection(253, 450),
1494
+ Connection(450, 449),
1495
+ Connection(449, 253),
1496
+ Connection(252, 451),
1497
+ Connection(451, 450),
1498
+ Connection(450, 252),
1499
+ Connection(256, 452),
1500
+ Connection(452, 451),
1501
+ Connection(451, 256),
1502
+ Connection(341, 453),
1503
+ Connection(453, 452),
1504
+ Connection(452, 341),
1505
+ Connection(413, 464),
1506
+ Connection(464, 463),
1507
+ Connection(463, 413),
1508
+ Connection(441, 413),
1509
+ Connection(413, 414),
1510
+ Connection(414, 441),
1511
+ Connection(258, 442),
1512
+ Connection(442, 441),
1513
+ Connection(441, 258),
1514
+ Connection(257, 443),
1515
+ Connection(443, 442),
1516
+ Connection(442, 257),
1517
+ Connection(259, 444),
1518
+ Connection(444, 443),
1519
+ Connection(443, 259),
1520
+ Connection(260, 445),
1521
+ Connection(445, 444),
1522
+ Connection(444, 260),
1523
+ Connection(467, 342),
1524
+ Connection(342, 445),
1525
+ Connection(445, 467),
1526
+ Connection(459, 458),
1527
+ Connection(458, 250),
1528
+ Connection(250, 459),
1529
+ Connection(289, 392),
1530
+ Connection(392, 290),
1531
+ Connection(290, 289),
1532
+ Connection(290, 328),
1533
+ Connection(328, 460),
1534
+ Connection(460, 290),
1535
+ Connection(376, 433),
1536
+ Connection(433, 435),
1537
+ Connection(435, 376),
1538
+ Connection(250, 290),
1539
+ Connection(290, 392),
1540
+ Connection(392, 250),
1541
+ Connection(411, 416),
1542
+ Connection(416, 433),
1543
+ Connection(433, 411),
1544
+ Connection(341, 463),
1545
+ Connection(463, 464),
1546
+ Connection(464, 341),
1547
+ Connection(453, 464),
1548
+ Connection(464, 465),
1549
+ Connection(465, 453),
1550
+ Connection(357, 465),
1551
+ Connection(465, 412),
1552
+ Connection(412, 357),
1553
+ Connection(343, 412),
1554
+ Connection(412, 399),
1555
+ Connection(399, 343),
1556
+ Connection(360, 363),
1557
+ Connection(363, 440),
1558
+ Connection(440, 360),
1559
+ Connection(437, 399),
1560
+ Connection(399, 456),
1561
+ Connection(456, 437),
1562
+ Connection(420, 456),
1563
+ Connection(456, 363),
1564
+ Connection(363, 420),
1565
+ Connection(401, 435),
1566
+ Connection(435, 288),
1567
+ Connection(288, 401),
1568
+ Connection(372, 383),
1569
+ Connection(383, 353),
1570
+ Connection(353, 372),
1571
+ Connection(339, 255),
1572
+ Connection(255, 249),
1573
+ Connection(249, 339),
1574
+ Connection(448, 261),
1575
+ Connection(261, 255),
1576
+ Connection(255, 448),
1577
+ Connection(133, 243),
1578
+ Connection(243, 190),
1579
+ Connection(190, 133),
1580
+ Connection(133, 155),
1581
+ Connection(155, 112),
1582
+ Connection(112, 133),
1583
+ Connection(33, 246),
1584
+ Connection(246, 247),
1585
+ Connection(247, 33),
1586
+ Connection(33, 130),
1587
+ Connection(130, 25),
1588
+ Connection(25, 33),
1589
+ Connection(398, 384),
1590
+ Connection(384, 286),
1591
+ Connection(286, 398),
1592
+ Connection(362, 398),
1593
+ Connection(398, 414),
1594
+ Connection(414, 362),
1595
+ Connection(362, 463),
1596
+ Connection(463, 341),
1597
+ Connection(341, 362),
1598
+ Connection(263, 359),
1599
+ Connection(359, 467),
1600
+ Connection(467, 263),
1601
+ Connection(263, 249),
1602
+ Connection(249, 255),
1603
+ Connection(255, 263),
1604
+ Connection(466, 467),
1605
+ Connection(467, 260),
1606
+ Connection(260, 466),
1607
+ Connection(75, 60),
1608
+ Connection(60, 166),
1609
+ Connection(166, 75),
1610
+ Connection(238, 239),
1611
+ Connection(239, 79),
1612
+ Connection(79, 238),
1613
+ Connection(162, 127),
1614
+ Connection(127, 139),
1615
+ Connection(139, 162),
1616
+ Connection(72, 11),
1617
+ Connection(11, 37),
1618
+ Connection(37, 72),
1619
+ Connection(121, 232),
1620
+ Connection(232, 120),
1621
+ Connection(120, 121),
1622
+ Connection(73, 72),
1623
+ Connection(72, 39),
1624
+ Connection(39, 73),
1625
+ Connection(114, 128),
1626
+ Connection(128, 47),
1627
+ Connection(47, 114),
1628
+ Connection(233, 232),
1629
+ Connection(232, 128),
1630
+ Connection(128, 233),
1631
+ Connection(103, 104),
1632
+ Connection(104, 67),
1633
+ Connection(67, 103),
1634
+ Connection(152, 175),
1635
+ Connection(175, 148),
1636
+ Connection(148, 152),
1637
+ Connection(119, 118),
1638
+ Connection(118, 101),
1639
+ Connection(101, 119),
1640
+ Connection(74, 73),
1641
+ Connection(73, 40),
1642
+ Connection(40, 74),
1643
+ Connection(107, 9),
1644
+ Connection(9, 108),
1645
+ Connection(108, 107),
1646
+ Connection(49, 48),
1647
+ Connection(48, 131),
1648
+ Connection(131, 49),
1649
+ Connection(32, 194),
1650
+ Connection(194, 211),
1651
+ Connection(211, 32),
1652
+ Connection(184, 74),
1653
+ Connection(74, 185),
1654
+ Connection(185, 184),
1655
+ Connection(191, 80),
1656
+ Connection(80, 183),
1657
+ Connection(183, 191),
1658
+ Connection(185, 40),
1659
+ Connection(40, 186),
1660
+ Connection(186, 185),
1661
+ Connection(119, 230),
1662
+ Connection(230, 118),
1663
+ Connection(118, 119),
1664
+ Connection(210, 202),
1665
+ Connection(202, 214),
1666
+ Connection(214, 210),
1667
+ Connection(84, 83),
1668
+ Connection(83, 17),
1669
+ Connection(17, 84),
1670
+ Connection(77, 76),
1671
+ Connection(76, 146),
1672
+ Connection(146, 77),
1673
+ Connection(161, 160),
1674
+ Connection(160, 30),
1675
+ Connection(30, 161),
1676
+ Connection(190, 56),
1677
+ Connection(56, 173),
1678
+ Connection(173, 190),
1679
+ Connection(182, 106),
1680
+ Connection(106, 194),
1681
+ Connection(194, 182),
1682
+ Connection(138, 135),
1683
+ Connection(135, 192),
1684
+ Connection(192, 138),
1685
+ Connection(129, 203),
1686
+ Connection(203, 98),
1687
+ Connection(98, 129),
1688
+ Connection(54, 21),
1689
+ Connection(21, 68),
1690
+ Connection(68, 54),
1691
+ Connection(5, 51),
1692
+ Connection(51, 4),
1693
+ Connection(4, 5),
1694
+ Connection(145, 144),
1695
+ Connection(144, 23),
1696
+ Connection(23, 145),
1697
+ Connection(90, 77),
1698
+ Connection(77, 91),
1699
+ Connection(91, 90),
1700
+ Connection(207, 205),
1701
+ Connection(205, 187),
1702
+ Connection(187, 207),
1703
+ Connection(83, 201),
1704
+ Connection(201, 18),
1705
+ Connection(18, 83),
1706
+ Connection(181, 91),
1707
+ Connection(91, 182),
1708
+ Connection(182, 181),
1709
+ Connection(180, 90),
1710
+ Connection(90, 181),
1711
+ Connection(181, 180),
1712
+ Connection(16, 85),
1713
+ Connection(85, 17),
1714
+ Connection(17, 16),
1715
+ Connection(205, 206),
1716
+ Connection(206, 36),
1717
+ Connection(36, 205),
1718
+ Connection(176, 148),
1719
+ Connection(148, 140),
1720
+ Connection(140, 176),
1721
+ Connection(165, 92),
1722
+ Connection(92, 39),
1723
+ Connection(39, 165),
1724
+ Connection(245, 193),
1725
+ Connection(193, 244),
1726
+ Connection(244, 245),
1727
+ Connection(27, 159),
1728
+ Connection(159, 28),
1729
+ Connection(28, 27),
1730
+ Connection(30, 247),
1731
+ Connection(247, 161),
1732
+ Connection(161, 30),
1733
+ Connection(174, 236),
1734
+ Connection(236, 196),
1735
+ Connection(196, 174),
1736
+ Connection(103, 54),
1737
+ Connection(54, 104),
1738
+ Connection(104, 103),
1739
+ Connection(55, 193),
1740
+ Connection(193, 8),
1741
+ Connection(8, 55),
1742
+ Connection(111, 117),
1743
+ Connection(117, 31),
1744
+ Connection(31, 111),
1745
+ Connection(221, 189),
1746
+ Connection(189, 55),
1747
+ Connection(55, 221),
1748
+ Connection(240, 98),
1749
+ Connection(98, 99),
1750
+ Connection(99, 240),
1751
+ Connection(142, 126),
1752
+ Connection(126, 100),
1753
+ Connection(100, 142),
1754
+ Connection(219, 166),
1755
+ Connection(166, 218),
1756
+ Connection(218, 219),
1757
+ Connection(112, 155),
1758
+ Connection(155, 26),
1759
+ Connection(26, 112),
1760
+ Connection(198, 209),
1761
+ Connection(209, 131),
1762
+ Connection(131, 198),
1763
+ Connection(169, 135),
1764
+ Connection(135, 150),
1765
+ Connection(150, 169),
1766
+ Connection(114, 47),
1767
+ Connection(47, 217),
1768
+ Connection(217, 114),
1769
+ Connection(224, 223),
1770
+ Connection(223, 53),
1771
+ Connection(53, 224),
1772
+ Connection(220, 45),
1773
+ Connection(45, 134),
1774
+ Connection(134, 220),
1775
+ Connection(32, 211),
1776
+ Connection(211, 140),
1777
+ Connection(140, 32),
1778
+ Connection(109, 67),
1779
+ Connection(67, 108),
1780
+ Connection(108, 109),
1781
+ Connection(146, 43),
1782
+ Connection(43, 91),
1783
+ Connection(91, 146),
1784
+ Connection(231, 230),
1785
+ Connection(230, 120),
1786
+ Connection(120, 231),
1787
+ Connection(113, 226),
1788
+ Connection(226, 247),
1789
+ Connection(247, 113),
1790
+ Connection(105, 63),
1791
+ Connection(63, 52),
1792
+ Connection(52, 105),
1793
+ Connection(241, 238),
1794
+ Connection(238, 242),
1795
+ Connection(242, 241),
1796
+ Connection(124, 46),
1797
+ Connection(46, 156),
1798
+ Connection(156, 124),
1799
+ Connection(95, 78),
1800
+ Connection(78, 96),
1801
+ Connection(96, 95),
1802
+ Connection(70, 46),
1803
+ Connection(46, 63),
1804
+ Connection(63, 70),
1805
+ Connection(116, 143),
1806
+ Connection(143, 227),
1807
+ Connection(227, 116),
1808
+ Connection(116, 123),
1809
+ Connection(123, 111),
1810
+ Connection(111, 116),
1811
+ Connection(1, 44),
1812
+ Connection(44, 19),
1813
+ Connection(19, 1),
1814
+ Connection(3, 236),
1815
+ Connection(236, 51),
1816
+ Connection(51, 3),
1817
+ Connection(207, 216),
1818
+ Connection(216, 205),
1819
+ Connection(205, 207),
1820
+ Connection(26, 154),
1821
+ Connection(154, 22),
1822
+ Connection(22, 26),
1823
+ Connection(165, 39),
1824
+ Connection(39, 167),
1825
+ Connection(167, 165),
1826
+ Connection(199, 200),
1827
+ Connection(200, 208),
1828
+ Connection(208, 199),
1829
+ Connection(101, 36),
1830
+ Connection(36, 100),
1831
+ Connection(100, 101),
1832
+ Connection(43, 57),
1833
+ Connection(57, 202),
1834
+ Connection(202, 43),
1835
+ Connection(242, 20),
1836
+ Connection(20, 99),
1837
+ Connection(99, 242),
1838
+ Connection(56, 28),
1839
+ Connection(28, 157),
1840
+ Connection(157, 56),
1841
+ Connection(124, 35),
1842
+ Connection(35, 113),
1843
+ Connection(113, 124),
1844
+ Connection(29, 160),
1845
+ Connection(160, 27),
1846
+ Connection(27, 29),
1847
+ Connection(211, 204),
1848
+ Connection(204, 210),
1849
+ Connection(210, 211),
1850
+ Connection(124, 113),
1851
+ Connection(113, 46),
1852
+ Connection(46, 124),
1853
+ Connection(106, 43),
1854
+ Connection(43, 204),
1855
+ Connection(204, 106),
1856
+ Connection(96, 62),
1857
+ Connection(62, 77),
1858
+ Connection(77, 96),
1859
+ Connection(227, 137),
1860
+ Connection(137, 116),
1861
+ Connection(116, 227),
1862
+ Connection(73, 41),
1863
+ Connection(41, 72),
1864
+ Connection(72, 73),
1865
+ Connection(36, 203),
1866
+ Connection(203, 142),
1867
+ Connection(142, 36),
1868
+ Connection(235, 64),
1869
+ Connection(64, 240),
1870
+ Connection(240, 235),
1871
+ Connection(48, 49),
1872
+ Connection(49, 64),
1873
+ Connection(64, 48),
1874
+ Connection(42, 41),
1875
+ Connection(41, 74),
1876
+ Connection(74, 42),
1877
+ Connection(214, 212),
1878
+ Connection(212, 207),
1879
+ Connection(207, 214),
1880
+ Connection(183, 42),
1881
+ Connection(42, 184),
1882
+ Connection(184, 183),
1883
+ Connection(210, 169),
1884
+ Connection(169, 211),
1885
+ Connection(211, 210),
1886
+ Connection(140, 170),
1887
+ Connection(170, 176),
1888
+ Connection(176, 140),
1889
+ Connection(104, 105),
1890
+ Connection(105, 69),
1891
+ Connection(69, 104),
1892
+ Connection(193, 122),
1893
+ Connection(122, 168),
1894
+ Connection(168, 193),
1895
+ Connection(50, 123),
1896
+ Connection(123, 187),
1897
+ Connection(187, 50),
1898
+ Connection(89, 96),
1899
+ Connection(96, 90),
1900
+ Connection(90, 89),
1901
+ Connection(66, 65),
1902
+ Connection(65, 107),
1903
+ Connection(107, 66),
1904
+ Connection(179, 89),
1905
+ Connection(89, 180),
1906
+ Connection(180, 179),
1907
+ Connection(119, 101),
1908
+ Connection(101, 120),
1909
+ Connection(120, 119),
1910
+ Connection(68, 63),
1911
+ Connection(63, 104),
1912
+ Connection(104, 68),
1913
+ Connection(234, 93),
1914
+ Connection(93, 227),
1915
+ Connection(227, 234),
1916
+ Connection(16, 15),
1917
+ Connection(15, 85),
1918
+ Connection(85, 16),
1919
+ Connection(209, 129),
1920
+ Connection(129, 49),
1921
+ Connection(49, 209),
1922
+ Connection(15, 14),
1923
+ Connection(14, 86),
1924
+ Connection(86, 15),
1925
+ Connection(107, 55),
1926
+ Connection(55, 9),
1927
+ Connection(9, 107),
1928
+ Connection(120, 100),
1929
+ Connection(100, 121),
1930
+ Connection(121, 120),
1931
+ Connection(153, 145),
1932
+ Connection(145, 22),
1933
+ Connection(22, 153),
1934
+ Connection(178, 88),
1935
+ Connection(88, 179),
1936
+ Connection(179, 178),
1937
+ Connection(197, 6),
1938
+ Connection(6, 196),
1939
+ Connection(196, 197),
1940
+ Connection(89, 88),
1941
+ Connection(88, 96),
1942
+ Connection(96, 89),
1943
+ Connection(135, 138),
1944
+ Connection(138, 136),
1945
+ Connection(136, 135),
1946
+ Connection(138, 215),
1947
+ Connection(215, 172),
1948
+ Connection(172, 138),
1949
+ Connection(218, 115),
1950
+ Connection(115, 219),
1951
+ Connection(219, 218),
1952
+ Connection(41, 42),
1953
+ Connection(42, 81),
1954
+ Connection(81, 41),
1955
+ Connection(5, 195),
1956
+ Connection(195, 51),
1957
+ Connection(51, 5),
1958
+ Connection(57, 43),
1959
+ Connection(43, 61),
1960
+ Connection(61, 57),
1961
+ Connection(208, 171),
1962
+ Connection(171, 199),
1963
+ Connection(199, 208),
1964
+ Connection(41, 81),
1965
+ Connection(81, 38),
1966
+ Connection(38, 41),
1967
+ Connection(224, 53),
1968
+ Connection(53, 225),
1969
+ Connection(225, 224),
1970
+ Connection(24, 144),
1971
+ Connection(144, 110),
1972
+ Connection(110, 24),
1973
+ Connection(105, 52),
1974
+ Connection(52, 66),
1975
+ Connection(66, 105),
1976
+ Connection(118, 229),
1977
+ Connection(229, 117),
1978
+ Connection(117, 118),
1979
+ Connection(227, 34),
1980
+ Connection(34, 234),
1981
+ Connection(234, 227),
1982
+ Connection(66, 107),
1983
+ Connection(107, 69),
1984
+ Connection(69, 66),
1985
+ Connection(10, 109),
1986
+ Connection(109, 151),
1987
+ Connection(151, 10),
1988
+ Connection(219, 48),
1989
+ Connection(48, 235),
1990
+ Connection(235, 219),
1991
+ Connection(183, 62),
1992
+ Connection(62, 191),
1993
+ Connection(191, 183),
1994
+ Connection(142, 129),
1995
+ Connection(129, 126),
1996
+ Connection(126, 142),
1997
+ Connection(116, 111),
1998
+ Connection(111, 143),
1999
+ Connection(143, 116),
2000
+ Connection(118, 117),
2001
+ Connection(117, 50),
2002
+ Connection(50, 118),
2003
+ Connection(223, 222),
2004
+ Connection(222, 52),
2005
+ Connection(52, 223),
2006
+ Connection(94, 19),
2007
+ Connection(19, 141),
2008
+ Connection(141, 94),
2009
+ Connection(222, 221),
2010
+ Connection(221, 65),
2011
+ Connection(65, 222),
2012
+ Connection(196, 3),
2013
+ Connection(3, 197),
2014
+ Connection(197, 196),
2015
+ Connection(45, 220),
2016
+ Connection(220, 44),
2017
+ Connection(44, 45),
2018
+ Connection(156, 70),
2019
+ Connection(70, 139),
2020
+ Connection(139, 156),
2021
+ Connection(188, 122),
2022
+ Connection(122, 245),
2023
+ Connection(245, 188),
2024
+ Connection(139, 71),
2025
+ Connection(71, 162),
2026
+ Connection(162, 139),
2027
+ Connection(149, 170),
2028
+ Connection(170, 150),
2029
+ Connection(150, 149),
2030
+ Connection(122, 188),
2031
+ Connection(188, 196),
2032
+ Connection(196, 122),
2033
+ Connection(206, 216),
2034
+ Connection(216, 92),
2035
+ Connection(92, 206),
2036
+ Connection(164, 2),
2037
+ Connection(2, 167),
2038
+ Connection(167, 164),
2039
+ Connection(242, 141),
2040
+ Connection(141, 241),
2041
+ Connection(241, 242),
2042
+ Connection(0, 164),
2043
+ Connection(164, 37),
2044
+ Connection(37, 0),
2045
+ Connection(11, 72),
2046
+ Connection(72, 12),
2047
+ Connection(12, 11),
2048
+ Connection(12, 38),
2049
+ Connection(38, 13),
2050
+ Connection(13, 12),
2051
+ Connection(70, 63),
2052
+ Connection(63, 71),
2053
+ Connection(71, 70),
2054
+ Connection(31, 226),
2055
+ Connection(226, 111),
2056
+ Connection(111, 31),
2057
+ Connection(36, 101),
2058
+ Connection(101, 205),
2059
+ Connection(205, 36),
2060
+ Connection(203, 206),
2061
+ Connection(206, 165),
2062
+ Connection(165, 203),
2063
+ Connection(126, 209),
2064
+ Connection(209, 217),
2065
+ Connection(217, 126),
2066
+ Connection(98, 165),
2067
+ Connection(165, 97),
2068
+ Connection(97, 98),
2069
+ Connection(237, 220),
2070
+ Connection(220, 218),
2071
+ Connection(218, 237),
2072
+ Connection(237, 239),
2073
+ Connection(239, 241),
2074
+ Connection(241, 237),
2075
+ Connection(210, 214),
2076
+ Connection(214, 169),
2077
+ Connection(169, 210),
2078
+ Connection(140, 171),
2079
+ Connection(171, 32),
2080
+ Connection(32, 140),
2081
+ Connection(241, 125),
2082
+ Connection(125, 237),
2083
+ Connection(237, 241),
2084
+ Connection(179, 86),
2085
+ Connection(86, 178),
2086
+ Connection(178, 179),
2087
+ Connection(180, 85),
2088
+ Connection(85, 179),
2089
+ Connection(179, 180),
2090
+ Connection(181, 84),
2091
+ Connection(84, 180),
2092
+ Connection(180, 181),
2093
+ Connection(182, 83),
2094
+ Connection(83, 181),
2095
+ Connection(181, 182),
2096
+ Connection(194, 201),
2097
+ Connection(201, 182),
2098
+ Connection(182, 194),
2099
+ Connection(177, 137),
2100
+ Connection(137, 132),
2101
+ Connection(132, 177),
2102
+ Connection(184, 76),
2103
+ Connection(76, 183),
2104
+ Connection(183, 184),
2105
+ Connection(185, 61),
2106
+ Connection(61, 184),
2107
+ Connection(184, 185),
2108
+ Connection(186, 57),
2109
+ Connection(57, 185),
2110
+ Connection(185, 186),
2111
+ Connection(216, 212),
2112
+ Connection(212, 186),
2113
+ Connection(186, 216),
2114
+ Connection(192, 214),
2115
+ Connection(214, 187),
2116
+ Connection(187, 192),
2117
+ Connection(139, 34),
2118
+ Connection(34, 156),
2119
+ Connection(156, 139),
2120
+ Connection(218, 79),
2121
+ Connection(79, 237),
2122
+ Connection(237, 218),
2123
+ Connection(147, 123),
2124
+ Connection(123, 177),
2125
+ Connection(177, 147),
2126
+ Connection(45, 44),
2127
+ Connection(44, 4),
2128
+ Connection(4, 45),
2129
+ Connection(208, 201),
2130
+ Connection(201, 32),
2131
+ Connection(32, 208),
2132
+ Connection(98, 64),
2133
+ Connection(64, 129),
2134
+ Connection(129, 98),
2135
+ Connection(192, 213),
2136
+ Connection(213, 138),
2137
+ Connection(138, 192),
2138
+ Connection(235, 59),
2139
+ Connection(59, 219),
2140
+ Connection(219, 235),
2141
+ Connection(141, 242),
2142
+ Connection(242, 97),
2143
+ Connection(97, 141),
2144
+ Connection(97, 2),
2145
+ Connection(2, 141),
2146
+ Connection(141, 97),
2147
+ Connection(240, 75),
2148
+ Connection(75, 235),
2149
+ Connection(235, 240),
2150
+ Connection(229, 24),
2151
+ Connection(24, 228),
2152
+ Connection(228, 229),
2153
+ Connection(31, 25),
2154
+ Connection(25, 226),
2155
+ Connection(226, 31),
2156
+ Connection(230, 23),
2157
+ Connection(23, 229),
2158
+ Connection(229, 230),
2159
+ Connection(231, 22),
2160
+ Connection(22, 230),
2161
+ Connection(230, 231),
2162
+ Connection(232, 26),
2163
+ Connection(26, 231),
2164
+ Connection(231, 232),
2165
+ Connection(233, 112),
2166
+ Connection(112, 232),
2167
+ Connection(232, 233),
2168
+ Connection(244, 189),
2169
+ Connection(189, 243),
2170
+ Connection(243, 244),
2171
+ Connection(189, 221),
2172
+ Connection(221, 190),
2173
+ Connection(190, 189),
2174
+ Connection(222, 28),
2175
+ Connection(28, 221),
2176
+ Connection(221, 222),
2177
+ Connection(223, 27),
2178
+ Connection(27, 222),
2179
+ Connection(222, 223),
2180
+ Connection(224, 29),
2181
+ Connection(29, 223),
2182
+ Connection(223, 224),
2183
+ Connection(225, 30),
2184
+ Connection(30, 224),
2185
+ Connection(224, 225),
2186
+ Connection(113, 247),
2187
+ Connection(247, 225),
2188
+ Connection(225, 113),
2189
+ Connection(99, 60),
2190
+ Connection(60, 240),
2191
+ Connection(240, 99),
2192
+ Connection(213, 147),
2193
+ Connection(147, 215),
2194
+ Connection(215, 213),
2195
+ Connection(60, 20),
2196
+ Connection(20, 166),
2197
+ Connection(166, 60),
2198
+ Connection(192, 187),
2199
+ Connection(187, 213),
2200
+ Connection(213, 192),
2201
+ Connection(243, 112),
2202
+ Connection(112, 244),
2203
+ Connection(244, 243),
2204
+ Connection(244, 233),
2205
+ Connection(233, 245),
2206
+ Connection(245, 244),
2207
+ Connection(245, 128),
2208
+ Connection(128, 188),
2209
+ Connection(188, 245),
2210
+ Connection(188, 114),
2211
+ Connection(114, 174),
2212
+ Connection(174, 188),
2213
+ Connection(134, 131),
2214
+ Connection(131, 220),
2215
+ Connection(220, 134),
2216
+ Connection(174, 217),
2217
+ Connection(217, 236),
2218
+ Connection(236, 174),
2219
+ Connection(236, 198),
2220
+ Connection(198, 134),
2221
+ Connection(134, 236),
2222
+ Connection(215, 177),
2223
+ Connection(177, 58),
2224
+ Connection(58, 215),
2225
+ Connection(156, 143),
2226
+ Connection(143, 124),
2227
+ Connection(124, 156),
2228
+ Connection(25, 110),
2229
+ Connection(110, 7),
2230
+ Connection(7, 25),
2231
+ Connection(31, 228),
2232
+ Connection(228, 25),
2233
+ Connection(25, 31),
2234
+ Connection(264, 356),
2235
+ Connection(356, 368),
2236
+ Connection(368, 264),
2237
+ Connection(0, 11),
2238
+ Connection(11, 267),
2239
+ Connection(267, 0),
2240
+ Connection(451, 452),
2241
+ Connection(452, 349),
2242
+ Connection(349, 451),
2243
+ Connection(267, 302),
2244
+ Connection(302, 269),
2245
+ Connection(269, 267),
2246
+ Connection(350, 357),
2247
+ Connection(357, 277),
2248
+ Connection(277, 350),
2249
+ Connection(350, 452),
2250
+ Connection(452, 357),
2251
+ Connection(357, 350),
2252
+ Connection(299, 333),
2253
+ Connection(333, 297),
2254
+ Connection(297, 299),
2255
+ Connection(396, 175),
2256
+ Connection(175, 377),
2257
+ Connection(377, 396),
2258
+ Connection(280, 347),
2259
+ Connection(347, 330),
2260
+ Connection(330, 280),
2261
+ Connection(269, 303),
2262
+ Connection(303, 270),
2263
+ Connection(270, 269),
2264
+ Connection(151, 9),
2265
+ Connection(9, 337),
2266
+ Connection(337, 151),
2267
+ Connection(344, 278),
2268
+ Connection(278, 360),
2269
+ Connection(360, 344),
2270
+ Connection(424, 418),
2271
+ Connection(418, 431),
2272
+ Connection(431, 424),
2273
+ Connection(270, 304),
2274
+ Connection(304, 409),
2275
+ Connection(409, 270),
2276
+ Connection(272, 310),
2277
+ Connection(310, 407),
2278
+ Connection(407, 272),
2279
+ Connection(322, 270),
2280
+ Connection(270, 410),
2281
+ Connection(410, 322),
2282
+ Connection(449, 450),
2283
+ Connection(450, 347),
2284
+ Connection(347, 449),
2285
+ Connection(432, 422),
2286
+ Connection(422, 434),
2287
+ Connection(434, 432),
2288
+ Connection(18, 313),
2289
+ Connection(313, 17),
2290
+ Connection(17, 18),
2291
+ Connection(291, 306),
2292
+ Connection(306, 375),
2293
+ Connection(375, 291),
2294
+ Connection(259, 387),
2295
+ Connection(387, 260),
2296
+ Connection(260, 259),
2297
+ Connection(424, 335),
2298
+ Connection(335, 418),
2299
+ Connection(418, 424),
2300
+ Connection(434, 364),
2301
+ Connection(364, 416),
2302
+ Connection(416, 434),
2303
+ Connection(391, 423),
2304
+ Connection(423, 327),
2305
+ Connection(327, 391),
2306
+ Connection(301, 251),
2307
+ Connection(251, 298),
2308
+ Connection(298, 301),
2309
+ Connection(275, 281),
2310
+ Connection(281, 4),
2311
+ Connection(4, 275),
2312
+ Connection(254, 373),
2313
+ Connection(373, 253),
2314
+ Connection(253, 254),
2315
+ Connection(375, 307),
2316
+ Connection(307, 321),
2317
+ Connection(321, 375),
2318
+ Connection(280, 425),
2319
+ Connection(425, 411),
2320
+ Connection(411, 280),
2321
+ Connection(200, 421),
2322
+ Connection(421, 18),
2323
+ Connection(18, 200),
2324
+ Connection(335, 321),
2325
+ Connection(321, 406),
2326
+ Connection(406, 335),
2327
+ Connection(321, 320),
2328
+ Connection(320, 405),
2329
+ Connection(405, 321),
2330
+ Connection(314, 315),
2331
+ Connection(315, 17),
2332
+ Connection(17, 314),
2333
+ Connection(423, 426),
2334
+ Connection(426, 266),
2335
+ Connection(266, 423),
2336
+ Connection(396, 377),
2337
+ Connection(377, 369),
2338
+ Connection(369, 396),
2339
+ Connection(270, 322),
2340
+ Connection(322, 269),
2341
+ Connection(269, 270),
2342
+ Connection(413, 417),
2343
+ Connection(417, 464),
2344
+ Connection(464, 413),
2345
+ Connection(385, 386),
2346
+ Connection(386, 258),
2347
+ Connection(258, 385),
2348
+ Connection(248, 456),
2349
+ Connection(456, 419),
2350
+ Connection(419, 248),
2351
+ Connection(298, 284),
2352
+ Connection(284, 333),
2353
+ Connection(333, 298),
2354
+ Connection(168, 417),
2355
+ Connection(417, 8),
2356
+ Connection(8, 168),
2357
+ Connection(448, 346),
2358
+ Connection(346, 261),
2359
+ Connection(261, 448),
2360
+ Connection(417, 413),
2361
+ Connection(413, 285),
2362
+ Connection(285, 417),
2363
+ Connection(326, 327),
2364
+ Connection(327, 328),
2365
+ Connection(328, 326),
2366
+ Connection(277, 355),
2367
+ Connection(355, 329),
2368
+ Connection(329, 277),
2369
+ Connection(309, 392),
2370
+ Connection(392, 438),
2371
+ Connection(438, 309),
2372
+ Connection(381, 382),
2373
+ Connection(382, 256),
2374
+ Connection(256, 381),
2375
+ Connection(279, 429),
2376
+ Connection(429, 360),
2377
+ Connection(360, 279),
2378
+ Connection(365, 364),
2379
+ Connection(364, 379),
2380
+ Connection(379, 365),
2381
+ Connection(355, 277),
2382
+ Connection(277, 437),
2383
+ Connection(437, 355),
2384
+ Connection(282, 443),
2385
+ Connection(443, 283),
2386
+ Connection(283, 282),
2387
+ Connection(281, 275),
2388
+ Connection(275, 363),
2389
+ Connection(363, 281),
2390
+ Connection(395, 431),
2391
+ Connection(431, 369),
2392
+ Connection(369, 395),
2393
+ Connection(299, 297),
2394
+ Connection(297, 337),
2395
+ Connection(337, 299),
2396
+ Connection(335, 273),
2397
+ Connection(273, 321),
2398
+ Connection(321, 335),
2399
+ Connection(348, 450),
2400
+ Connection(450, 349),
2401
+ Connection(349, 348),
2402
+ Connection(359, 446),
2403
+ Connection(446, 467),
2404
+ Connection(467, 359),
2405
+ Connection(283, 293),
2406
+ Connection(293, 282),
2407
+ Connection(282, 283),
2408
+ Connection(250, 458),
2409
+ Connection(458, 462),
2410
+ Connection(462, 250),
2411
+ Connection(300, 276),
2412
+ Connection(276, 383),
2413
+ Connection(383, 300),
2414
+ Connection(292, 308),
2415
+ Connection(308, 325),
2416
+ Connection(325, 292),
2417
+ Connection(283, 276),
2418
+ Connection(276, 293),
2419
+ Connection(293, 283),
2420
+ Connection(264, 372),
2421
+ Connection(372, 447),
2422
+ Connection(447, 264),
2423
+ Connection(346, 352),
2424
+ Connection(352, 340),
2425
+ Connection(340, 346),
2426
+ Connection(354, 274),
2427
+ Connection(274, 19),
2428
+ Connection(19, 354),
2429
+ Connection(363, 456),
2430
+ Connection(456, 281),
2431
+ Connection(281, 363),
2432
+ Connection(426, 436),
2433
+ Connection(436, 425),
2434
+ Connection(425, 426),
2435
+ Connection(380, 381),
2436
+ Connection(381, 252),
2437
+ Connection(252, 380),
2438
+ Connection(267, 269),
2439
+ Connection(269, 393),
2440
+ Connection(393, 267),
2441
+ Connection(421, 200),
2442
+ Connection(200, 428),
2443
+ Connection(428, 421),
2444
+ Connection(371, 266),
2445
+ Connection(266, 329),
2446
+ Connection(329, 371),
2447
+ Connection(432, 287),
2448
+ Connection(287, 422),
2449
+ Connection(422, 432),
2450
+ Connection(290, 250),
2451
+ Connection(250, 328),
2452
+ Connection(328, 290),
2453
+ Connection(385, 258),
2454
+ Connection(258, 384),
2455
+ Connection(384, 385),
2456
+ Connection(446, 265),
2457
+ Connection(265, 342),
2458
+ Connection(342, 446),
2459
+ Connection(386, 387),
2460
+ Connection(387, 257),
2461
+ Connection(257, 386),
2462
+ Connection(422, 424),
2463
+ Connection(424, 430),
2464
+ Connection(430, 422),
2465
+ Connection(445, 342),
2466
+ Connection(342, 276),
2467
+ Connection(276, 445),
2468
+ Connection(422, 273),
2469
+ Connection(273, 424),
2470
+ Connection(424, 422),
2471
+ Connection(306, 292),
2472
+ Connection(292, 307),
2473
+ Connection(307, 306),
2474
+ Connection(352, 366),
2475
+ Connection(366, 345),
2476
+ Connection(345, 352),
2477
+ Connection(268, 271),
2478
+ Connection(271, 302),
2479
+ Connection(302, 268),
2480
+ Connection(358, 423),
2481
+ Connection(423, 371),
2482
+ Connection(371, 358),
2483
+ Connection(327, 294),
2484
+ Connection(294, 460),
2485
+ Connection(460, 327),
2486
+ Connection(331, 279),
2487
+ Connection(279, 294),
2488
+ Connection(294, 331),
2489
+ Connection(303, 271),
2490
+ Connection(271, 304),
2491
+ Connection(304, 303),
2492
+ Connection(436, 432),
2493
+ Connection(432, 427),
2494
+ Connection(427, 436),
2495
+ Connection(304, 272),
2496
+ Connection(272, 408),
2497
+ Connection(408, 304),
2498
+ Connection(395, 394),
2499
+ Connection(394, 431),
2500
+ Connection(431, 395),
2501
+ Connection(378, 395),
2502
+ Connection(395, 400),
2503
+ Connection(400, 378),
2504
+ Connection(296, 334),
2505
+ Connection(334, 299),
2506
+ Connection(299, 296),
2507
+ Connection(6, 351),
2508
+ Connection(351, 168),
2509
+ Connection(168, 6),
2510
+ Connection(376, 352),
2511
+ Connection(352, 411),
2512
+ Connection(411, 376),
2513
+ Connection(307, 325),
2514
+ Connection(325, 320),
2515
+ Connection(320, 307),
2516
+ Connection(285, 295),
2517
+ Connection(295, 336),
2518
+ Connection(336, 285),
2519
+ Connection(320, 319),
2520
+ Connection(319, 404),
2521
+ Connection(404, 320),
2522
+ Connection(329, 330),
2523
+ Connection(330, 349),
2524
+ Connection(349, 329),
2525
+ Connection(334, 293),
2526
+ Connection(293, 333),
2527
+ Connection(333, 334),
2528
+ Connection(366, 323),
2529
+ Connection(323, 447),
2530
+ Connection(447, 366),
2531
+ Connection(316, 15),
2532
+ Connection(15, 315),
2533
+ Connection(315, 316),
2534
+ Connection(331, 358),
2535
+ Connection(358, 279),
2536
+ Connection(279, 331),
2537
+ Connection(317, 14),
2538
+ Connection(14, 316),
2539
+ Connection(316, 317),
2540
+ Connection(8, 285),
2541
+ Connection(285, 9),
2542
+ Connection(9, 8),
2543
+ Connection(277, 329),
2544
+ Connection(329, 350),
2545
+ Connection(350, 277),
2546
+ Connection(253, 374),
2547
+ Connection(374, 252),
2548
+ Connection(252, 253),
2549
+ Connection(319, 318),
2550
+ Connection(318, 403),
2551
+ Connection(403, 319),
2552
+ Connection(351, 6),
2553
+ Connection(6, 419),
2554
+ Connection(419, 351),
2555
+ Connection(324, 318),
2556
+ Connection(318, 325),
2557
+ Connection(325, 324),
2558
+ Connection(397, 367),
2559
+ Connection(367, 365),
2560
+ Connection(365, 397),
2561
+ Connection(288, 435),
2562
+ Connection(435, 397),
2563
+ Connection(397, 288),
2564
+ Connection(278, 344),
2565
+ Connection(344, 439),
2566
+ Connection(439, 278),
2567
+ Connection(310, 272),
2568
+ Connection(272, 311),
2569
+ Connection(311, 310),
2570
+ Connection(248, 195),
2571
+ Connection(195, 281),
2572
+ Connection(281, 248),
2573
+ Connection(375, 273),
2574
+ Connection(273, 291),
2575
+ Connection(291, 375),
2576
+ Connection(175, 396),
2577
+ Connection(396, 199),
2578
+ Connection(199, 175),
2579
+ Connection(312, 311),
2580
+ Connection(311, 268),
2581
+ Connection(268, 312),
2582
+ Connection(276, 283),
2583
+ Connection(283, 445),
2584
+ Connection(445, 276),
2585
+ Connection(390, 373),
2586
+ Connection(373, 339),
2587
+ Connection(339, 390),
2588
+ Connection(295, 282),
2589
+ Connection(282, 296),
2590
+ Connection(296, 295),
2591
+ Connection(448, 449),
2592
+ Connection(449, 346),
2593
+ Connection(346, 448),
2594
+ Connection(356, 264),
2595
+ Connection(264, 454),
2596
+ Connection(454, 356),
2597
+ Connection(337, 336),
2598
+ Connection(336, 299),
2599
+ Connection(299, 337),
2600
+ Connection(337, 338),
2601
+ Connection(338, 151),
2602
+ Connection(151, 337),
2603
+ Connection(294, 278),
2604
+ Connection(278, 455),
2605
+ Connection(455, 294),
2606
+ Connection(308, 292),
2607
+ Connection(292, 415),
2608
+ Connection(415, 308),
2609
+ Connection(429, 358),
2610
+ Connection(358, 355),
2611
+ Connection(355, 429),
2612
+ Connection(265, 340),
2613
+ Connection(340, 372),
2614
+ Connection(372, 265),
2615
+ Connection(352, 346),
2616
+ Connection(346, 280),
2617
+ Connection(280, 352),
2618
+ Connection(295, 442),
2619
+ Connection(442, 282),
2620
+ Connection(282, 295),
2621
+ Connection(354, 19),
2622
+ Connection(19, 370),
2623
+ Connection(370, 354),
2624
+ Connection(285, 441),
2625
+ Connection(441, 295),
2626
+ Connection(295, 285),
2627
+ Connection(195, 248),
2628
+ Connection(248, 197),
2629
+ Connection(197, 195),
2630
+ Connection(457, 440),
2631
+ Connection(440, 274),
2632
+ Connection(274, 457),
2633
+ Connection(301, 300),
2634
+ Connection(300, 368),
2635
+ Connection(368, 301),
2636
+ Connection(417, 351),
2637
+ Connection(351, 465),
2638
+ Connection(465, 417),
2639
+ Connection(251, 301),
2640
+ Connection(301, 389),
2641
+ Connection(389, 251),
2642
+ Connection(394, 395),
2643
+ Connection(395, 379),
2644
+ Connection(379, 394),
2645
+ Connection(399, 412),
2646
+ Connection(412, 419),
2647
+ Connection(419, 399),
2648
+ Connection(410, 436),
2649
+ Connection(436, 322),
2650
+ Connection(322, 410),
2651
+ Connection(326, 2),
2652
+ Connection(2, 393),
2653
+ Connection(393, 326),
2654
+ Connection(354, 370),
2655
+ Connection(370, 461),
2656
+ Connection(461, 354),
2657
+ Connection(393, 164),
2658
+ Connection(164, 267),
2659
+ Connection(267, 393),
2660
+ Connection(268, 302),
2661
+ Connection(302, 12),
2662
+ Connection(12, 268),
2663
+ Connection(312, 268),
2664
+ Connection(268, 13),
2665
+ Connection(13, 312),
2666
+ Connection(298, 293),
2667
+ Connection(293, 301),
2668
+ Connection(301, 298),
2669
+ Connection(265, 446),
2670
+ Connection(446, 340),
2671
+ Connection(340, 265),
2672
+ Connection(280, 330),
2673
+ Connection(330, 425),
2674
+ Connection(425, 280),
2675
+ Connection(322, 426),
2676
+ Connection(426, 391),
2677
+ Connection(391, 322),
2678
+ Connection(420, 429),
2679
+ Connection(429, 437),
2680
+ Connection(437, 420),
2681
+ Connection(393, 391),
2682
+ Connection(391, 326),
2683
+ Connection(326, 393),
2684
+ Connection(344, 440),
2685
+ Connection(440, 438),
2686
+ Connection(438, 344),
2687
+ Connection(458, 459),
2688
+ Connection(459, 461),
2689
+ Connection(461, 458),
2690
+ Connection(364, 434),
2691
+ Connection(434, 394),
2692
+ Connection(394, 364),
2693
+ Connection(428, 396),
2694
+ Connection(396, 262),
2695
+ Connection(262, 428),
2696
+ Connection(274, 354),
2697
+ Connection(354, 457),
2698
+ Connection(457, 274),
2699
+ Connection(317, 316),
2700
+ Connection(316, 402),
2701
+ Connection(402, 317),
2702
+ Connection(316, 315),
2703
+ Connection(315, 403),
2704
+ Connection(403, 316),
2705
+ Connection(315, 314),
2706
+ Connection(314, 404),
2707
+ Connection(404, 315),
2708
+ Connection(314, 313),
2709
+ Connection(313, 405),
2710
+ Connection(405, 314),
2711
+ Connection(313, 421),
2712
+ Connection(421, 406),
2713
+ Connection(406, 313),
2714
+ Connection(323, 366),
2715
+ Connection(366, 361),
2716
+ Connection(361, 323),
2717
+ Connection(292, 306),
2718
+ Connection(306, 407),
2719
+ Connection(407, 292),
2720
+ Connection(306, 291),
2721
+ Connection(291, 408),
2722
+ Connection(408, 306),
2723
+ Connection(291, 287),
2724
+ Connection(287, 409),
2725
+ Connection(409, 291),
2726
+ Connection(287, 432),
2727
+ Connection(432, 410),
2728
+ Connection(410, 287),
2729
+ Connection(427, 434),
2730
+ Connection(434, 411),
2731
+ Connection(411, 427),
2732
+ Connection(372, 264),
2733
+ Connection(264, 383),
2734
+ Connection(383, 372),
2735
+ Connection(459, 309),
2736
+ Connection(309, 457),
2737
+ Connection(457, 459),
2738
+ Connection(366, 352),
2739
+ Connection(352, 401),
2740
+ Connection(401, 366),
2741
+ Connection(1, 274),
2742
+ Connection(274, 4),
2743
+ Connection(4, 1),
2744
+ Connection(418, 421),
2745
+ Connection(421, 262),
2746
+ Connection(262, 418),
2747
+ Connection(331, 294),
2748
+ Connection(294, 358),
2749
+ Connection(358, 331),
2750
+ Connection(435, 433),
2751
+ Connection(433, 367),
2752
+ Connection(367, 435),
2753
+ Connection(392, 289),
2754
+ Connection(289, 439),
2755
+ Connection(439, 392),
2756
+ Connection(328, 462),
2757
+ Connection(462, 326),
2758
+ Connection(326, 328),
2759
+ Connection(94, 2),
2760
+ Connection(2, 370),
2761
+ Connection(370, 94),
2762
+ Connection(289, 305),
2763
+ Connection(305, 455),
2764
+ Connection(455, 289),
2765
+ Connection(339, 254),
2766
+ Connection(254, 448),
2767
+ Connection(448, 339),
2768
+ Connection(359, 255),
2769
+ Connection(255, 446),
2770
+ Connection(446, 359),
2771
+ Connection(254, 253),
2772
+ Connection(253, 449),
2773
+ Connection(449, 254),
2774
+ Connection(253, 252),
2775
+ Connection(252, 450),
2776
+ Connection(450, 253),
2777
+ Connection(252, 256),
2778
+ Connection(256, 451),
2779
+ Connection(451, 252),
2780
+ Connection(256, 341),
2781
+ Connection(341, 452),
2782
+ Connection(452, 256),
2783
+ Connection(414, 413),
2784
+ Connection(413, 463),
2785
+ Connection(463, 414),
2786
+ Connection(286, 441),
2787
+ Connection(441, 414),
2788
+ Connection(414, 286),
2789
+ Connection(286, 258),
2790
+ Connection(258, 441),
2791
+ Connection(441, 286),
2792
+ Connection(258, 257),
2793
+ Connection(257, 442),
2794
+ Connection(442, 258),
2795
+ Connection(257, 259),
2796
+ Connection(259, 443),
2797
+ Connection(443, 257),
2798
+ Connection(259, 260),
2799
+ Connection(260, 444),
2800
+ Connection(444, 259),
2801
+ Connection(260, 467),
2802
+ Connection(467, 445),
2803
+ Connection(445, 260),
2804
+ Connection(309, 459),
2805
+ Connection(459, 250),
2806
+ Connection(250, 309),
2807
+ Connection(305, 289),
2808
+ Connection(289, 290),
2809
+ Connection(290, 305),
2810
+ Connection(305, 290),
2811
+ Connection(290, 460),
2812
+ Connection(460, 305),
2813
+ Connection(401, 376),
2814
+ Connection(376, 435),
2815
+ Connection(435, 401),
2816
+ Connection(309, 250),
2817
+ Connection(250, 392),
2818
+ Connection(392, 309),
2819
+ Connection(376, 411),
2820
+ Connection(411, 433),
2821
+ Connection(433, 376),
2822
+ Connection(453, 341),
2823
+ Connection(341, 464),
2824
+ Connection(464, 453),
2825
+ Connection(357, 453),
2826
+ Connection(453, 465),
2827
+ Connection(465, 357),
2828
+ Connection(343, 357),
2829
+ Connection(357, 412),
2830
+ Connection(412, 343),
2831
+ Connection(437, 343),
2832
+ Connection(343, 399),
2833
+ Connection(399, 437),
2834
+ Connection(344, 360),
2835
+ Connection(360, 440),
2836
+ Connection(440, 344),
2837
+ Connection(420, 437),
2838
+ Connection(437, 456),
2839
+ Connection(456, 420),
2840
+ Connection(360, 420),
2841
+ Connection(420, 363),
2842
+ Connection(363, 360),
2843
+ Connection(361, 401),
2844
+ Connection(401, 288),
2845
+ Connection(288, 361),
2846
+ Connection(265, 372),
2847
+ Connection(372, 353),
2848
+ Connection(353, 265),
2849
+ Connection(390, 339),
2850
+ Connection(339, 249),
2851
+ Connection(249, 390),
2852
+ Connection(339, 448),
2853
+ Connection(448, 255),
2854
+ Connection(255, 339),
2855
+ ]
2856
+
2857
+
2858
+ @dataclasses.dataclass
2859
+ class FaceLandmarkerResult:
2860
+ """The face landmarks detection result from FaceLandmarker, where each vector element represents a single face detected in the image.
2861
+
2862
+ Attributes:
2863
+ face_landmarks: Detected face landmarks in normalized image coordinates.
2864
+ face_blendshapes: Optional face blendshapes results.
2865
+ facial_transformation_matrixes: Optional facial transformation matrix.
2866
+ """
2867
+
2868
+ face_landmarks: List[List[landmark_module.NormalizedLandmark]]
2869
+ face_blendshapes: List[List[category_module.Category]]
2870
+ facial_transformation_matrixes: List[np.ndarray]
2871
+
2872
+
2873
+ def _build_landmarker_result(
2874
+ output_packets: Mapping[str, packet_module.Packet]
2875
+ ) -> FaceLandmarkerResult:
2876
+ """Constructs a `FaceLandmarkerResult` from output packets."""
2877
+ face_landmarks_proto_list = packet_getter.get_proto_list(
2878
+ output_packets[_NORM_LANDMARKS_STREAM_NAME]
2879
+ )
2880
+
2881
+ face_landmarks_results = []
2882
+ for proto in face_landmarks_proto_list:
2883
+ face_landmarks = landmark_pb2.NormalizedLandmarkList()
2884
+ face_landmarks.MergeFrom(proto)
2885
+ face_landmarks_list = []
2886
+ for face_landmark in face_landmarks.landmark:
2887
+ face_landmarks_list.append(
2888
+ landmark_module.NormalizedLandmark.create_from_pb2(face_landmark)
2889
+ )
2890
+ face_landmarks_results.append(face_landmarks_list)
2891
+
2892
+ face_blendshapes_results = []
2893
+ if _BLENDSHAPES_STREAM_NAME in output_packets:
2894
+ face_blendshapes_proto_list = packet_getter.get_proto_list(
2895
+ output_packets[_BLENDSHAPES_STREAM_NAME]
2896
+ )
2897
+ for proto in face_blendshapes_proto_list:
2898
+ face_blendshapes_categories = []
2899
+ face_blendshapes_classifications = classification_pb2.ClassificationList()
2900
+ face_blendshapes_classifications.MergeFrom(proto)
2901
+ for face_blendshapes in face_blendshapes_classifications.classification:
2902
+ face_blendshapes_categories.append(
2903
+ category_module.Category(
2904
+ index=face_blendshapes.index,
2905
+ score=face_blendshapes.score,
2906
+ display_name=face_blendshapes.display_name,
2907
+ category_name=face_blendshapes.label,
2908
+ )
2909
+ )
2910
+ face_blendshapes_results.append(face_blendshapes_categories)
2911
+
2912
+ facial_transformation_matrixes_results = []
2913
+ if _FACE_GEOMETRY_STREAM_NAME in output_packets:
2914
+ facial_transformation_matrixes_proto_list = packet_getter.get_proto_list(
2915
+ output_packets[_FACE_GEOMETRY_STREAM_NAME]
2916
+ )
2917
+ for proto in facial_transformation_matrixes_proto_list:
2918
+ if hasattr(proto, 'pose_transform_matrix'):
2919
+ matrix_data = matrix_data_pb2.MatrixData()
2920
+ matrix_data.MergeFrom(proto.pose_transform_matrix)
2921
+ matrix = np.array(matrix_data.packed_data)
2922
+ matrix = matrix.reshape((matrix_data.rows, matrix_data.cols))
2923
+ matrix = (
2924
+ matrix if matrix_data.layout == _LayoutEnum.ROW_MAJOR else matrix.T
2925
+ )
2926
+ facial_transformation_matrixes_results.append(matrix)
2927
+
2928
+ return FaceLandmarkerResult(
2929
+ face_landmarks_results,
2930
+ face_blendshapes_results,
2931
+ facial_transformation_matrixes_results,
2932
+ )
2933
+
2934
+ def _build_landmarker_result2(
2935
+ output_packets: Mapping[str, packet_module.Packet]
2936
+ ) -> FaceLandmarkerResult:
2937
+ """Constructs a `FaceLandmarkerResult` from output packets."""
2938
+ face_landmarks_proto_list = packet_getter.get_proto_list(
2939
+ output_packets[_NORM_LANDMARKS_STREAM_NAME]
2940
+ )
2941
+
2942
+ face_landmarks_results = []
2943
+ for proto in face_landmarks_proto_list:
2944
+ face_landmarks = landmark_pb2.NormalizedLandmarkList()
2945
+ face_landmarks.MergeFrom(proto)
2946
+ face_landmarks_list = []
2947
+ for face_landmark in face_landmarks.landmark:
2948
+ face_landmarks_list.append(
2949
+ landmark_module.NormalizedLandmark.create_from_pb2(face_landmark)
2950
+ )
2951
+ face_landmarks_results.append(face_landmarks_list)
2952
+
2953
+ face_blendshapes_results = []
2954
+ if _BLENDSHAPES_STREAM_NAME in output_packets:
2955
+ face_blendshapes_proto_list = packet_getter.get_proto_list(
2956
+ output_packets[_BLENDSHAPES_STREAM_NAME]
2957
+ )
2958
+ for proto in face_blendshapes_proto_list:
2959
+ face_blendshapes_categories = []
2960
+ face_blendshapes_classifications = classification_pb2.ClassificationList()
2961
+ face_blendshapes_classifications.MergeFrom(proto)
2962
+ for face_blendshapes in face_blendshapes_classifications.classification:
2963
+ face_blendshapes_categories.append(
2964
+ category_module.Category(
2965
+ index=face_blendshapes.index,
2966
+ score=face_blendshapes.score,
2967
+ display_name=face_blendshapes.display_name,
2968
+ category_name=face_blendshapes.label,
2969
+ )
2970
+ )
2971
+ face_blendshapes_results.append(face_blendshapes_categories)
2972
+
2973
+ facial_transformation_matrixes_results = []
2974
+ if _FACE_GEOMETRY_STREAM_NAME in output_packets:
2975
+ facial_transformation_matrixes_proto_list = packet_getter.get_proto_list(
2976
+ output_packets[_FACE_GEOMETRY_STREAM_NAME]
2977
+ )
2978
+ for proto in facial_transformation_matrixes_proto_list:
2979
+ if hasattr(proto, 'pose_transform_matrix'):
2980
+ matrix_data = matrix_data_pb2.MatrixData()
2981
+ matrix_data.MergeFrom(proto.pose_transform_matrix)
2982
+ matrix = np.array(matrix_data.packed_data)
2983
+ matrix = matrix.reshape((matrix_data.rows, matrix_data.cols))
2984
+ matrix = (
2985
+ matrix if matrix_data.layout == _LayoutEnum.ROW_MAJOR else matrix.T
2986
+ )
2987
+ facial_transformation_matrixes_results.append(matrix)
2988
+
2989
+ return FaceLandmarkerResult(
2990
+ face_landmarks_results,
2991
+ face_blendshapes_results,
2992
+ facial_transformation_matrixes_results,
2993
+ ), facial_transformation_matrixes_proto_list[0].mesh
2994
+
2995
+ @dataclasses.dataclass
2996
+ class FaceLandmarkerOptions:
2997
+ """Options for the face landmarker task.
2998
+
2999
+ Attributes:
3000
+ base_options: Base options for the face landmarker task.
3001
+ running_mode: The running mode of the task. Default to the image mode.
3002
+ FaceLandmarker has three running modes: 1) The image mode for detecting
3003
+ face landmarks on single image inputs. 2) The video mode for detecting
3004
+ face landmarks on the decoded frames of a video. 3) The live stream mode
3005
+ for detecting face landmarks on the live stream of input data, such as
3006
+ from camera. In this mode, the "result_callback" below must be specified
3007
+ to receive the detection results asynchronously.
3008
+ num_faces: The maximum number of faces that can be detected by the
3009
+ FaceLandmarker.
3010
+ min_face_detection_confidence: The minimum confidence score for the face
3011
+ detection to be considered successful.
3012
+ min_face_presence_confidence: The minimum confidence score of face presence
3013
+ score in the face landmark detection.
3014
+ min_tracking_confidence: The minimum confidence score for the face tracking
3015
+ to be considered successful.
3016
+ output_face_blendshapes: Whether FaceLandmarker outputs face blendshapes
3017
+ classification. Face blendshapes are used for rendering the 3D face model.
3018
+ output_facial_transformation_matrixes: Whether FaceLandmarker outputs facial
3019
+ transformation_matrix. Facial transformation matrix is used to transform
3020
+ the face landmarks in canonical face to the detected face, so that users
3021
+ can apply face effects on the detected landmarks.
3022
+ result_callback: The user-defined result callback for processing live stream
3023
+ data. The result callback should only be specified when the running mode
3024
+ is set to the live stream mode.
3025
+ """
3026
+
3027
+ base_options: _BaseOptions
3028
+ running_mode: _RunningMode = _RunningMode.IMAGE
3029
+ num_faces: int = 1
3030
+ min_face_detection_confidence: float = 0.5
3031
+ min_face_presence_confidence: float = 0.5
3032
+ min_tracking_confidence: float = 0.5
3033
+ output_face_blendshapes: bool = False
3034
+ output_facial_transformation_matrixes: bool = False
3035
+ result_callback: Optional[
3036
+ Callable[[FaceLandmarkerResult, image_module.Image, int], None]
3037
+ ] = None
3038
+
3039
+ @doc_controls.do_not_generate_docs
3040
+ def to_pb2(self) -> _FaceLandmarkerGraphOptionsProto:
3041
+ """Generates an FaceLandmarkerGraphOptions protobuf object."""
3042
+ base_options_proto = self.base_options.to_pb2()
3043
+ base_options_proto.use_stream_mode = (
3044
+ False if self.running_mode == _RunningMode.IMAGE else True
3045
+ )
3046
+
3047
+ # Initialize the face landmarker options from base options.
3048
+ face_landmarker_options_proto = _FaceLandmarkerGraphOptionsProto(
3049
+ base_options=base_options_proto
3050
+ )
3051
+
3052
+ # Configure face detector options.
3053
+ face_landmarker_options_proto.face_detector_graph_options.num_faces = (
3054
+ self.num_faces
3055
+ )
3056
+ face_landmarker_options_proto.face_detector_graph_options.min_detection_confidence = (
3057
+ self.min_face_detection_confidence
3058
+ )
3059
+
3060
+ # Configure face landmark detector options.
3061
+ face_landmarker_options_proto.min_tracking_confidence = (
3062
+ self.min_tracking_confidence
3063
+ )
3064
+ face_landmarker_options_proto.face_landmarks_detector_graph_options.min_detection_confidence = (
3065
+ self.min_face_detection_confidence
3066
+ )
3067
+ return face_landmarker_options_proto
3068
+
3069
+
3070
+ class FaceLandmarker(base_vision_task_api.BaseVisionTaskApi):
3071
+ """Class that performs face landmarks detection on images."""
3072
+
3073
+ @classmethod
3074
+ def create_from_model_path(cls, model_path: str) -> 'FaceLandmarker':
3075
+ """Creates an `FaceLandmarker` object from a TensorFlow Lite model and the default `FaceLandmarkerOptions`.
3076
+
3077
+ Note that the created `FaceLandmarker` instance is in image mode, for
3078
+ detecting face landmarks on single image inputs.
3079
+
3080
+ Args:
3081
+ model_path: Path to the model.
3082
+
3083
+ Returns:
3084
+ `FaceLandmarker` object that's created from the model file and the
3085
+ default `FaceLandmarkerOptions`.
3086
+
3087
+ Raises:
3088
+ ValueError: If failed to create `FaceLandmarker` object from the
3089
+ provided file such as invalid file path.
3090
+ RuntimeError: If other types of error occurred.
3091
+ """
3092
+ base_options = _BaseOptions(model_asset_path=model_path)
3093
+ options = FaceLandmarkerOptions(
3094
+ base_options=base_options, running_mode=_RunningMode.IMAGE
3095
+ )
3096
+ return cls.create_from_options(options)
3097
+
3098
+ @classmethod
3099
+ def create_from_options(
3100
+ cls, options: FaceLandmarkerOptions
3101
+ ) -> 'FaceLandmarker':
3102
+ """Creates the `FaceLandmarker` object from face landmarker options.
3103
+
3104
+ Args:
3105
+ options: Options for the face landmarker task.
3106
+
3107
+ Returns:
3108
+ `FaceLandmarker` object that's created from `options`.
3109
+
3110
+ Raises:
3111
+ ValueError: If failed to create `FaceLandmarker` object from
3112
+ `FaceLandmarkerOptions` such as missing the model.
3113
+ RuntimeError: If other types of error occurred.
3114
+ """
3115
+
3116
+ def packets_callback(output_packets: Mapping[str, packet_module.Packet]):
3117
+ if output_packets[_IMAGE_OUT_STREAM_NAME].is_empty():
3118
+ return
3119
+
3120
+ image = packet_getter.get_image(output_packets[_IMAGE_OUT_STREAM_NAME])
3121
+ if output_packets[_IMAGE_OUT_STREAM_NAME].is_empty():
3122
+ return
3123
+
3124
+ if output_packets[_NORM_LANDMARKS_STREAM_NAME].is_empty():
3125
+ empty_packet = output_packets[_NORM_LANDMARKS_STREAM_NAME]
3126
+ options.result_callback(
3127
+ FaceLandmarkerResult([], [], []),
3128
+ image,
3129
+ empty_packet.timestamp.value // _MICRO_SECONDS_PER_MILLISECOND,
3130
+ )
3131
+ return
3132
+
3133
+ face_landmarks_result = _build_landmarker_result(output_packets)
3134
+ timestamp = output_packets[_NORM_LANDMARKS_STREAM_NAME].timestamp
3135
+ options.result_callback(
3136
+ face_landmarks_result,
3137
+ image,
3138
+ timestamp.value // _MICRO_SECONDS_PER_MILLISECOND,
3139
+ )
3140
+
3141
+ output_streams = [
3142
+ ':'.join([_NORM_LANDMARKS_TAG, _NORM_LANDMARKS_STREAM_NAME]),
3143
+ ':'.join([_IMAGE_TAG, _IMAGE_OUT_STREAM_NAME]),
3144
+ ]
3145
+
3146
+ if options.output_face_blendshapes:
3147
+ output_streams.append(
3148
+ ':'.join([_BLENDSHAPES_TAG, _BLENDSHAPES_STREAM_NAME])
3149
+ )
3150
+ if options.output_facial_transformation_matrixes:
3151
+ output_streams.append(
3152
+ ':'.join([_FACE_GEOMETRY_TAG, _FACE_GEOMETRY_STREAM_NAME])
3153
+ )
3154
+
3155
+ task_info = _TaskInfo(
3156
+ task_graph=_TASK_GRAPH_NAME,
3157
+ input_streams=[
3158
+ ':'.join([_IMAGE_TAG, _IMAGE_IN_STREAM_NAME]),
3159
+ ':'.join([_NORM_RECT_TAG, _NORM_RECT_STREAM_NAME]),
3160
+ ],
3161
+ output_streams=output_streams,
3162
+ task_options=options,
3163
+ )
3164
+ return cls(
3165
+ task_info.generate_graph_config(
3166
+ enable_flow_limiting=options.running_mode
3167
+ == _RunningMode.LIVE_STREAM
3168
+ ),
3169
+ options.running_mode,
3170
+ packets_callback if options.result_callback else None,
3171
+ )
3172
+
3173
+ def detect(
3174
+ self,
3175
+ image: image_module.Image,
3176
+ image_processing_options: Optional[_ImageProcessingOptions] = None,
3177
+ ) -> FaceLandmarkerResult:
3178
+ """Performs face landmarks detection on the given image.
3179
+
3180
+ Only use this method when the FaceLandmarker is created with the image
3181
+ running mode.
3182
+
3183
+ The image can be of any size with format RGB or RGBA.
3184
+ TODO: Describes how the input image will be preprocessed after the yuv
3185
+ support is implemented.
3186
+
3187
+ Args:
3188
+ image: MediaPipe Image.
3189
+ image_processing_options: Options for image processing.
3190
+
3191
+ Returns:
3192
+ The face landmarks detection results.
3193
+
3194
+ Raises:
3195
+ ValueError: If any of the input arguments is invalid.
3196
+ RuntimeError: If face landmarker detection failed to run.
3197
+ """
3198
+
3199
+ normalized_rect = self.convert_to_normalized_rect(
3200
+ image_processing_options, image, roi_allowed=False
3201
+ )
3202
+ output_packets = self._process_image_data({
3203
+ _IMAGE_IN_STREAM_NAME: packet_creator.create_image(image),
3204
+ _NORM_RECT_STREAM_NAME: packet_creator.create_proto(
3205
+ normalized_rect.to_pb2()
3206
+ ),
3207
+ })
3208
+
3209
+ if output_packets[_NORM_LANDMARKS_STREAM_NAME].is_empty():
3210
+ return FaceLandmarkerResult([], [], [])
3211
+
3212
+ return _build_landmarker_result2(output_packets)
3213
+
3214
+ def detect_for_video(
3215
+ self,
3216
+ image: image_module.Image,
3217
+ timestamp_ms: int,
3218
+ image_processing_options: Optional[_ImageProcessingOptions] = None,
3219
+ ):
3220
+ """Performs face landmarks detection on the provided video frame.
3221
+
3222
+ Only use this method when the FaceLandmarker is created with the video
3223
+ running mode.
3224
+
3225
+ Only use this method when the FaceLandmarker is created with the video
3226
+ running mode. It's required to provide the video frame's timestamp (in
3227
+ milliseconds) along with the video frame. The input timestamps should be
3228
+ monotonically increasing for adjacent calls of this method.
3229
+
3230
+ Args:
3231
+ image: MediaPipe Image.
3232
+ timestamp_ms: The timestamp of the input video frame in milliseconds.
3233
+ image_processing_options: Options for image processing.
3234
+
3235
+ Returns:
3236
+ The face landmarks detection results.
3237
+
3238
+ Raises:
3239
+ ValueError: If any of the input arguments is invalid.
3240
+ RuntimeError: If face landmarker detection failed to run.
3241
+ """
3242
+ normalized_rect = self.convert_to_normalized_rect(
3243
+ image_processing_options, image, roi_allowed=False
3244
+ )
3245
+ output_packets = self._process_video_data({
3246
+ _IMAGE_IN_STREAM_NAME: packet_creator.create_image(image).at(
3247
+ timestamp_ms * _MICRO_SECONDS_PER_MILLISECOND
3248
+ ),
3249
+ _NORM_RECT_STREAM_NAME: packet_creator.create_proto(
3250
+ normalized_rect.to_pb2()
3251
+ ).at(timestamp_ms * _MICRO_SECONDS_PER_MILLISECOND),
3252
+ })
3253
+
3254
+ if output_packets[_NORM_LANDMARKS_STREAM_NAME].is_empty():
3255
+ return FaceLandmarkerResult([], [], [])
3256
+
3257
+ return _build_landmarker_result2(output_packets)
3258
+
3259
+ def detect_async(
3260
+ self,
3261
+ image: image_module.Image,
3262
+ timestamp_ms: int,
3263
+ image_processing_options: Optional[_ImageProcessingOptions] = None,
3264
+ ) -> None:
3265
+ """Sends live image data to perform face landmarks detection.
3266
+
3267
+ The results will be available via the "result_callback" provided in the
3268
+ FaceLandmarkerOptions. Only use this method when the FaceLandmarker is
3269
+ created with the live stream running mode.
3270
+
3271
+ Only use this method when the FaceLandmarker is created with the live
3272
+ stream running mode. The input timestamps should be monotonically increasing
3273
+ for adjacent calls of this method. This method will return immediately after
3274
+ the input image is accepted. The results will be available via the
3275
+ `result_callback` provided in the `FaceLandmarkerOptions`. The
3276
+ `detect_async` method is designed to process live stream data such as
3277
+ camera input. To lower the overall latency, face landmarker may drop the
3278
+ input images if needed. In other words, it's not guaranteed to have output
3279
+ per input image.
3280
+
3281
+ The `result_callback` provides:
3282
+ - The face landmarks detection results.
3283
+ - The input image that the face landmarker runs on.
3284
+ - The input timestamp in milliseconds.
3285
+
3286
+ Args:
3287
+ image: MediaPipe Image.
3288
+ timestamp_ms: The timestamp of the input image in milliseconds.
3289
+ image_processing_options: Options for image processing.
3290
+
3291
+ Raises:
3292
+ ValueError: If the current input timestamp is smaller than what the
3293
+ face landmarker has already processed.
3294
+ """
3295
+ normalized_rect = self.convert_to_normalized_rect(
3296
+ image_processing_options, image, roi_allowed=False
3297
+ )
3298
+ self._send_live_stream_data({
3299
+ _IMAGE_IN_STREAM_NAME: packet_creator.create_image(image).at(
3300
+ timestamp_ms * _MICRO_SECONDS_PER_MILLISECOND
3301
+ ),
3302
+ _NORM_RECT_STREAM_NAME: packet_creator.create_proto(
3303
+ normalized_rect.to_pb2()
3304
+ ).at(timestamp_ms * _MICRO_SECONDS_PER_MILLISECOND),
3305
+ })
aniportrait/src/utils/frame_interpolation.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Adapted from https://github.com/dajes/frame-interpolation-pytorch
2
+ import os
3
+ import cv2
4
+ import numpy as np
5
+ import torch
6
+ import bisect
7
+ import shutil
8
+ import pdb
9
+ from tqdm import tqdm
10
+
11
+ def init_frame_interpolation_model():
12
+ print("Initializing frame interpolation model")
13
+ checkpoint_name = os.path.join("./pretrained_model/film_net_fp16.pt")
14
+
15
+ model = torch.jit.load(checkpoint_name, map_location='cpu')
16
+ model.eval()
17
+ model = model.half()
18
+ model = model.to(device="cuda")
19
+ return model
20
+
21
+
22
+ def batch_images_interpolation_tool(input_tensor, model, inter_frames=1):
23
+
24
+ video_tensor = []
25
+ frame_num = input_tensor.shape[2] # bs, channel, frame, height, width
26
+
27
+ for idx in tqdm(range(frame_num-1)):
28
+ image1 = input_tensor[:,:,idx]
29
+ image2 = input_tensor[:,:,idx+1]
30
+
31
+ results = [image1, image2]
32
+
33
+ inter_frames = int(inter_frames)
34
+ idxes = [0, inter_frames + 1]
35
+ remains = list(range(1, inter_frames + 1))
36
+
37
+ splits = torch.linspace(0, 1, inter_frames + 2)
38
+
39
+ for _ in range(len(remains)):
40
+ starts = splits[idxes[:-1]]
41
+ ends = splits[idxes[1:]]
42
+ distances = ((splits[None, remains] - starts[:, None]) / (ends[:, None] - starts[:, None]) - .5).abs()
43
+ matrix = torch.argmin(distances).item()
44
+ start_i, step = np.unravel_index(matrix, distances.shape)
45
+ end_i = start_i + 1
46
+
47
+ x0 = results[start_i]
48
+ x1 = results[end_i]
49
+
50
+ x0 = x0.half()
51
+ x1 = x1.half()
52
+ x0 = x0.cuda()
53
+ x1 = x1.cuda()
54
+
55
+ dt = x0.new_full((1, 1), (splits[remains[step]] - splits[idxes[start_i]])) / (splits[idxes[end_i]] - splits[idxes[start_i]])
56
+
57
+ with torch.no_grad():
58
+ prediction = model(x0, x1, dt)
59
+ insert_position = bisect.bisect_left(idxes, remains[step])
60
+ idxes.insert(insert_position, remains[step])
61
+ results.insert(insert_position, prediction.clamp(0, 1).cpu().float())
62
+ del remains[step]
63
+
64
+ for sub_idx in range(len(results)-1):
65
+ video_tensor.append(results[sub_idx].unsqueeze(2))
66
+
67
+ video_tensor.append(input_tensor[:,:,-1].unsqueeze(2))
68
+ video_tensor = torch.cat(video_tensor, dim=2)
69
+ return video_tensor
aniportrait/src/utils/mp_models/blaze_face_short_range.tflite ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b4578f35940bf5a1a655214a1cce5cab13eba73c1297cd78e1a04c2380b0152f
3
+ size 229746
aniportrait/src/utils/mp_models/face_landmarker_v2_with_blendshapes.task ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:64184e229b263107bc2b804c6625db1341ff2bb731874b0bcc2fe6544e0bc9ff
3
+ size 3758596
aniportrait/src/utils/mp_models/pose_landmarker_heavy.task ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:64437af838a65d18e5ba7a0d39b465540069bc8aae8308de3e318aad31fcbc7b
3
+ size 30664242
aniportrait/src/utils/mp_utils.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import numpy as np
3
+ import cv2
4
+ import time
5
+ from tqdm import tqdm
6
+ import multiprocessing
7
+ import glob
8
+
9
+ import mediapipe as mp
10
+ from mediapipe import solutions
11
+ from mediapipe.framework.formats import landmark_pb2
12
+ from mediapipe.tasks import python
13
+ from mediapipe.tasks.python import vision
14
+ from . import face_landmark
15
+
16
+ CUR_DIR = os.path.dirname(__file__)
17
+
18
+
19
+ class LMKExtractor():
20
+ def __init__(self, FPS=25):
21
+ # Create an FaceLandmarker object.
22
+ self.mode = mp.tasks.vision.FaceDetectorOptions.running_mode.IMAGE
23
+ base_options = python.BaseOptions(model_asset_path=os.path.join(CUR_DIR, 'mp_models/face_landmarker_v2_with_blendshapes.task'))
24
+ base_options.delegate = mp.tasks.BaseOptions.Delegate.CPU
25
+ options = vision.FaceLandmarkerOptions(base_options=base_options,
26
+ running_mode=self.mode,
27
+ output_face_blendshapes=True,
28
+ output_facial_transformation_matrixes=True,
29
+ num_faces=1)
30
+ self.detector = face_landmark.FaceLandmarker.create_from_options(options)
31
+ self.last_ts = 0
32
+ self.frame_ms = int(1000 / FPS)
33
+
34
+ det_base_options = python.BaseOptions(model_asset_path=os.path.join(CUR_DIR, 'mp_models/blaze_face_short_range.tflite'))
35
+ det_options = vision.FaceDetectorOptions(base_options=det_base_options)
36
+ self.det_detector = vision.FaceDetector.create_from_options(det_options)
37
+
38
+
39
+ def __call__(self, img):
40
+ frame = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
41
+ image = mp.Image(image_format=mp.ImageFormat.SRGB, data=frame)
42
+ t0 = time.time()
43
+ if self.mode == mp.tasks.vision.FaceDetectorOptions.running_mode.VIDEO:
44
+ det_result = self.det_detector.detect(image)
45
+ if len(det_result.detections) != 1:
46
+ return None
47
+ self.last_ts += self.frame_ms
48
+ try:
49
+ detection_result, mesh3d = self.detector.detect_for_video(image, timestamp_ms=self.last_ts)
50
+ except:
51
+ return None
52
+ elif self.mode == mp.tasks.vision.FaceDetectorOptions.running_mode.IMAGE:
53
+ # det_result = self.det_detector.detect(image)
54
+
55
+ # if len(det_result.detections) != 1:
56
+ # return None
57
+ try:
58
+ detection_result, mesh3d = self.detector.detect(image)
59
+ except:
60
+ return None
61
+
62
+
63
+ bs_list = detection_result.face_blendshapes
64
+ if len(bs_list) == 1:
65
+ bs = bs_list[0]
66
+ bs_values = []
67
+ for index in range(len(bs)):
68
+ bs_values.append(bs[index].score)
69
+ bs_values = bs_values[1:] # remove neutral
70
+ trans_mat = detection_result.facial_transformation_matrixes[0]
71
+ face_landmarks_list = detection_result.face_landmarks
72
+ face_landmarks = face_landmarks_list[0]
73
+ lmks = []
74
+ for index in range(len(face_landmarks)):
75
+ x = face_landmarks[index].x
76
+ y = face_landmarks[index].y
77
+ z = face_landmarks[index].z
78
+ lmks.append([x, y, z])
79
+ lmks = np.array(lmks)
80
+
81
+ lmks3d = np.array(mesh3d.vertex_buffer)
82
+ lmks3d = lmks3d.reshape(-1, 5)[:, :3]
83
+ mp_tris = np.array(mesh3d.index_buffer).reshape(-1, 3) + 1
84
+
85
+ return {
86
+ "lmks": lmks,
87
+ 'lmks3d': lmks3d,
88
+ "trans_mat": trans_mat,
89
+ 'faces': mp_tris,
90
+ "bs": bs_values
91
+ }
92
+ else:
93
+ # print('multiple faces in the image: {}'.format(img_path))
94
+ return None
95
+
aniportrait/src/utils/pose_util.py ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+
3
+ import numpy as np
4
+ from scipy.spatial.transform import Rotation as R
5
+
6
+
7
+ def create_perspective_matrix(aspect_ratio):
8
+ kDegreesToRadians = np.pi / 180.
9
+ near = 1
10
+ far = 10000
11
+ perspective_matrix = np.zeros(16, dtype=np.float32)
12
+
13
+ # Standard perspective projection matrix calculations.
14
+ f = 1.0 / np.tan(kDegreesToRadians * 63 / 2.)
15
+
16
+ denom = 1.0 / (near - far)
17
+ perspective_matrix[0] = f / aspect_ratio
18
+ perspective_matrix[5] = f
19
+ perspective_matrix[10] = (near + far) * denom
20
+ perspective_matrix[11] = -1.
21
+ perspective_matrix[14] = 1. * far * near * denom
22
+
23
+ # If the environment's origin point location is in the top left corner,
24
+ # then skip additional flip along Y-axis is required to render correctly.
25
+
26
+ perspective_matrix[5] *= -1.
27
+ return perspective_matrix
28
+
29
+
30
+ def project_points(points_3d, transformation_matrix, pose_vectors, image_shape):
31
+ P = create_perspective_matrix(image_shape[1] / image_shape[0]).reshape(4, 4).T
32
+ L, N, _ = points_3d.shape
33
+ projected_points = np.zeros((L, N, 2))
34
+ for i in range(L):
35
+ points_3d_frame = points_3d[i]
36
+ ones = np.ones((points_3d_frame.shape[0], 1))
37
+ points_3d_homogeneous = np.hstack([points_3d_frame, ones])
38
+ transformed_points = points_3d_homogeneous @ (transformation_matrix @ euler_and_translation_to_matrix(pose_vectors[i][:3], pose_vectors[i][3:])).T @ P
39
+ projected_points_frame = transformed_points[:, :2] / transformed_points[:, 3, np.newaxis] # -1 ~ 1
40
+ projected_points_frame[:, 0] = (projected_points_frame[:, 0] + 1) * 0.5 * image_shape[1]
41
+ projected_points_frame[:, 1] = (projected_points_frame[:, 1] + 1) * 0.5 * image_shape[0]
42
+ projected_points[i] = projected_points_frame
43
+ return projected_points
44
+
45
+
46
+ def project_points_with_trans(points_3d, transformation_matrix, image_shape):
47
+ P = create_perspective_matrix(image_shape[1] / image_shape[0]).reshape(4, 4).T
48
+ L, N, _ = points_3d.shape
49
+ projected_points = np.zeros((L, N, 2))
50
+ for i in range(L):
51
+ points_3d_frame = points_3d[i]
52
+ ones = np.ones((points_3d_frame.shape[0], 1))
53
+ points_3d_homogeneous = np.hstack([points_3d_frame, ones])
54
+ transformed_points = points_3d_homogeneous @ transformation_matrix[i].T @ P
55
+ projected_points_frame = transformed_points[:, :2] / transformed_points[:, 3, np.newaxis] # -1 ~ 1
56
+ projected_points_frame[:, 0] = (projected_points_frame[:, 0] + 1) * 0.5 * image_shape[1]
57
+ projected_points_frame[:, 1] = (projected_points_frame[:, 1] + 1) * 0.5 * image_shape[0]
58
+ projected_points[i] = projected_points_frame
59
+ return projected_points
60
+
61
+
62
+ def euler_and_translation_to_matrix(euler_angles, translation_vector):
63
+ rotation = R.from_euler('xyz', euler_angles, degrees=True)
64
+ rotation_matrix = rotation.as_matrix()
65
+
66
+ matrix = np.eye(4)
67
+ matrix[:3, :3] = rotation_matrix
68
+ matrix[:3, 3] = translation_vector
69
+
70
+ return matrix
71
+
72
+
73
+ def matrix_to_euler_and_translation(matrix):
74
+ rotation_matrix = matrix[:3, :3]
75
+ translation_vector = matrix[:3, 3]
76
+ rotation = R.from_matrix(rotation_matrix)
77
+ euler_angles = rotation.as_euler('xyz', degrees=True)
78
+ return euler_angles, translation_vector
79
+
80
+
81
+ def smooth_pose_seq(pose_seq, window_size=5):
82
+ smoothed_pose_seq = np.zeros_like(pose_seq)
83
+
84
+ for i in range(len(pose_seq)):
85
+ start = max(0, i - window_size // 2)
86
+ end = min(len(pose_seq), i + window_size // 2 + 1)
87
+ smoothed_pose_seq[i] = np.mean(pose_seq[start:end], axis=0)
88
+
89
+ return smoothed_pose_seq
aniportrait/src/utils/util.py ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import importlib
2
+ import os
3
+ import os.path as osp
4
+ import shutil
5
+ import sys
6
+ import cv2
7
+ from pathlib import Path
8
+
9
+ import av
10
+ import numpy as np
11
+ import torch
12
+ import torchvision
13
+ from einops import rearrange
14
+ from PIL import Image
15
+
16
+
17
+ def seed_everything(seed):
18
+ import random
19
+
20
+ import numpy as np
21
+
22
+ torch.manual_seed(seed)
23
+ torch.cuda.manual_seed_all(seed)
24
+ np.random.seed(seed % (2**32))
25
+ random.seed(seed)
26
+
27
+
28
+ def import_filename(filename):
29
+ spec = importlib.util.spec_from_file_location("mymodule", filename)
30
+ module = importlib.util.module_from_spec(spec)
31
+ sys.modules[spec.name] = module
32
+ spec.loader.exec_module(module)
33
+ return module
34
+
35
+
36
+ def delete_additional_ckpt(base_path, num_keep):
37
+ dirs = []
38
+ for d in os.listdir(base_path):
39
+ if d.startswith("checkpoint-"):
40
+ dirs.append(d)
41
+ num_tot = len(dirs)
42
+ if num_tot <= num_keep:
43
+ return
44
+ # ensure ckpt is sorted and delete the ealier!
45
+ del_dirs = sorted(dirs, key=lambda x: int(x.split("-")[-1]))[: num_tot - num_keep]
46
+ for d in del_dirs:
47
+ path_to_dir = osp.join(base_path, d)
48
+ if osp.exists(path_to_dir):
49
+ shutil.rmtree(path_to_dir)
50
+
51
+
52
+ def save_videos_from_pil(pil_images, path, fps=8):
53
+ import av
54
+
55
+ save_fmt = Path(path).suffix
56
+ os.makedirs(os.path.dirname(path), exist_ok=True)
57
+ width, height = pil_images[0].size
58
+
59
+ if save_fmt == ".mp4":
60
+ codec = "libx264"
61
+ container = av.open(path, "w")
62
+ stream = container.add_stream(codec, rate=fps)
63
+
64
+ stream.width = width
65
+ stream.height = height
66
+
67
+ for pil_image in pil_images:
68
+ # pil_image = Image.fromarray(image_arr).convert("RGB")
69
+ av_frame = av.VideoFrame.from_image(pil_image)
70
+ container.mux(stream.encode(av_frame))
71
+ container.mux(stream.encode())
72
+ container.close()
73
+
74
+ elif save_fmt == ".gif":
75
+ pil_images[0].save(
76
+ fp=path,
77
+ format="GIF",
78
+ append_images=pil_images[1:],
79
+ save_all=True,
80
+ duration=(1 / fps * 1000),
81
+ loop=0,
82
+ )
83
+ else:
84
+ raise ValueError("Unsupported file type. Use .mp4 or .gif.")
85
+
86
+
87
+ def save_videos_grid(videos: torch.Tensor, path: str, rescale=False, n_rows=6, fps=8):
88
+ videos = rearrange(videos, "b c t h w -> t b c h w")
89
+ height, width = videos.shape[-2:]
90
+ outputs = []
91
+
92
+ for x in videos:
93
+ x = torchvision.utils.make_grid(x, nrow=n_rows) # (c h w)
94
+ x = x.transpose(0, 1).transpose(1, 2).squeeze(-1) # (h w c)
95
+ if rescale:
96
+ x = (x + 1.0) / 2.0 # -1,1 -> 0,1
97
+ x = (x * 255).numpy().astype(np.uint8)
98
+ x = Image.fromarray(x)
99
+
100
+ outputs.append(x)
101
+
102
+ os.makedirs(os.path.dirname(path), exist_ok=True)
103
+
104
+ save_videos_from_pil(outputs, path, fps)
105
+
106
+
107
+ def read_frames(video_path):
108
+ container = av.open(video_path)
109
+
110
+ video_stream = next(s for s in container.streams if s.type == "video")
111
+ frames = []
112
+ for packet in container.demux(video_stream):
113
+ for frame in packet.decode():
114
+ image = Image.frombytes(
115
+ "RGB",
116
+ (frame.width, frame.height),
117
+ frame.to_rgb().to_ndarray(),
118
+ )
119
+ frames.append(image)
120
+
121
+ return frames
122
+
123
+
124
+ def get_fps(video_path):
125
+ container = av.open(video_path)
126
+ video_stream = next(s for s in container.streams if s.type == "video")
127
+ fps = video_stream.average_rate
128
+ container.close()
129
+ return fps
130
+
131
+ def crop_face(img, lmk_extractor, expand=1.5):
132
+ result = lmk_extractor(img) # cv2 BGR
133
+
134
+ if result is None:
135
+ return None
136
+
137
+ H, W, _ = img.shape
138
+ lmks = result['lmks']
139
+ lmks[:, 0] *= W
140
+ lmks[:, 1] *= H
141
+
142
+ x_min = np.min(lmks[:, 0])
143
+ x_max = np.max(lmks[:, 0])
144
+ y_min = np.min(lmks[:, 1])
145
+ y_max = np.max(lmks[:, 1])
146
+
147
+ width = x_max - x_min
148
+ height = y_max - y_min
149
+
150
+ if width*height >= W*H*0.15:
151
+ if W == H:
152
+ return img
153
+ size = min(H, W)
154
+ offset = int((max(H, W) - size)/2)
155
+ if size == H:
156
+ return img[:, offset:-offset]
157
+ else:
158
+ return img[offset:-offset, :]
159
+ else:
160
+ center_x = x_min + width / 2
161
+ center_y = y_min + height / 2
162
+
163
+ width *= expand
164
+ height *= expand
165
+
166
+ size = max(width, height)
167
+
168
+ x_min = int(center_x - size / 2)
169
+ x_max = int(center_x + size / 2)
170
+ y_min = int(center_y - size / 2)
171
+ y_max = int(center_y + size / 2)
172
+
173
+ top = max(0, -y_min)
174
+ bottom = max(0, y_max - img.shape[0])
175
+ left = max(0, -x_min)
176
+ right = max(0, x_max - img.shape[1])
177
+ img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=0)
178
+
179
+ cropped_img = img[y_min + top:y_max + top, x_min + left:x_max + left]
180
+
181
+ return cropped_img
ckpt_tree.md ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ ```
3
+ |-- ckpts
4
+ | |-- aniportrait
5
+ | | `-- motion_module.pth
6
+ | | `-- audio2mesh.pt
7
+ | | `-- film_net_fp16.pt
8
+ | | |-- sd-vae-ft-mse
9
+ | | | `-- diffusion_pytorch_model.safetensors
10
+ | | | `-- config.json
11
+ | | | `-- diffusion_pytorch_model.bin
12
+ | | `-- denoising_unet.pth
13
+ | | `-- audio2pose.pt
14
+ | | `-- pose_guider.pth
15
+ | | |-- sd-image-variations-diffusers
16
+ | | | `-- v1-montage.jpg
17
+ | | | |-- scheduler
18
+ | | | | `-- scheduler_config.json
19
+ | | | `-- README.md
20
+ | | | `-- model_index.json
21
+ | | | |-- unet
22
+ | | | | `-- config.json
23
+ | | | | `-- diffusion_pytorch_model.bin
24
+ | | | |-- feature_extractor
25
+ | | | | `-- preprocessor_config.json
26
+ | | | `-- v2-montage.jpg
27
+ | | | |-- vae
28
+ | | | | `-- config.json
29
+ | | | | `-- diffusion_pytorch_model.bin
30
+ | | | `-- alias-montage.jpg
31
+ | | | `-- inputs.jpg
32
+ | | | |-- safety_checker
33
+ | | | | `-- pytorch_model.bin
34
+ | | | | `-- config.json
35
+ | | | `-- earring.jpg
36
+ | | | `-- default-montage.jpg
37
+ | | |-- image_encoder
38
+ | | | `-- pytorch_model.bin
39
+ | | | `-- config.json
40
+ | | |-- stable-diffusion-v1-5
41
+ | | | `-- model_index.json
42
+ | | | `-- v1-inference.yaml
43
+ | | | |-- unet
44
+ | | | | `-- config.json
45
+ | | | | `-- diffusion_pytorch_model.bin
46
+ | | | |-- feature_extractor
47
+ | | | | `-- preprocessor_config.json
48
+ | | `-- reference_unet.pth
49
+ | | |-- wav2vec2-base-960h
50
+ | | | `-- pytorch_model.bin
51
+ | | | `-- README.md
52
+ | | | `-- vocab.json
53
+ | | | `-- config.json
54
+ | | | `-- tf_model.h5
55
+ | | | `-- tokenizer_config.json
56
+ | | | `-- model.safetensors
57
+ | | | `-- special_tokens_map.json
58
+ | | | `-- preprocessor_config.json
59
+ | | | `-- feature_extractor_config.json
60
+ | |-- mofa
61
+ | | |-- traj_controlnet
62
+ | | | `-- diffusion_pytorch_model.safetensors
63
+ | | | `-- config.json
64
+ | | |-- stable-video-diffusion-img2vid-xt-1-1
65
+ | | | |-- scheduler
66
+ | | | | `-- scheduler_config.json
67
+ | | | `-- README.md
68
+ | | | `-- model_index.json
69
+ | | | |-- unet
70
+ | | | | `-- diffusion_pytorch_model.fp16.safetensors
71
+ | | | | `-- config.json
72
+ | | | |-- feature_extractor
73
+ | | | | `-- preprocessor_config.json
74
+ | | | |-- vae
75
+ | | | | `-- diffusion_pytorch_model.fp16.safetensors
76
+ | | | | `-- config.json
77
+ | | | `-- LICENSE
78
+ | | | `-- svd11.webp
79
+ | | | |-- image_encoder
80
+ | | | | `-- config.json
81
+ | | | | `-- model.fp16.safetensors
82
+ | | |-- ldmk_controlnet
83
+ | | | `-- diffusion_pytorch_model.safetensors
84
+ | | | `-- config.json
85
+ | |-- sad_talker
86
+ | | `-- SadTalker_V0.0.2_256.safetensors
87
+ | | |-- hub
88
+ | | `-- mapping_00229-model.pth.tar
89
+ | | |-- BFM_Fitting
90
+ | | | `-- select_vertex_id.mat
91
+ | | | `-- facemodel_info.mat
92
+ | | | `-- BFM_exp_idx.mat
93
+ | | | `-- BFM_model_front.mat
94
+ | | | `-- 01_MorphableModel.mat
95
+ | | | `-- similarity_Lm3D_all.mat
96
+ | | | `-- BFM_front_idx.mat
97
+ | | | `-- Exp_Pca.bin
98
+ | | | `-- std_exp.txt
99
+ | | `-- SadTalker_V0.0.2_512.safetensors
100
+ | | `-- similarity_Lm3D_all.mat
101
+ | | `-- epoch_00190_iteration_000400000_checkpoint.pt
102
+ | | `-- mapping_00109-model.pth.tar
103
+ | |-- gfpgan
104
+ | | `-- alignment_WFLW_4HG.pth
105
+ | | `-- parsing_parsenet.pth
106
+ | | `-- detection_Resnet50_Final.pth
107
+
108
+ ```
ckpts/.DS_Store ADDED
Binary file (6.15 kB). View file
 
ckpts/aniportrait/.DS_Store ADDED
Binary file (8.2 kB). View file
 
ckpts/aniportrait/audio2mesh.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:04996bebdad780a33642b0046036dae5d3c6db76e8f4ef5860e551fb9a1f0a1a
3
+ size 382031763
ckpts/aniportrait/audio2pose.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e61ffd104f8d1fe40476de1a8df9050559315976c830e5fdead1c31d1c5661f3
3
+ size 481586148
ckpts/aniportrait/denoising_unet.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ddc4990e0d33dd5393190e8609fd7b32bfc0b5c386763624a3bff8038e0c054c
3
+ size 3438374981
ckpts/aniportrait/film_net_fp16.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f0c8314674a6ba97787584fb04d59df9c6051ad5b735c89704f60801eece34d1
3
+ size 69032330
ckpts/aniportrait/image_encoder/config.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "/home/jpinkney/.cache/huggingface/diffusers/models--lambdalabs--sd-image-variations-diffusers/snapshots/ca6f97f838ae1b5bf764f31363a21f388f4d8f3e/image_encoder",
3
+ "architectures": [
4
+ "CLIPVisionModelWithProjection"
5
+ ],
6
+ "attention_dropout": 0.0,
7
+ "dropout": 0.0,
8
+ "hidden_act": "quick_gelu",
9
+ "hidden_size": 1024,
10
+ "image_size": 224,
11
+ "initializer_factor": 1.0,
12
+ "initializer_range": 0.02,
13
+ "intermediate_size": 4096,
14
+ "layer_norm_eps": 1e-05,
15
+ "model_type": "clip_vision_model",
16
+ "num_attention_heads": 16,
17
+ "num_channels": 3,
18
+ "num_hidden_layers": 24,
19
+ "patch_size": 14,
20
+ "projection_dim": 768,
21
+ "torch_dtype": "float32",
22
+ "transformers_version": "4.25.1"
23
+ }
ckpts/aniportrait/image_encoder/pytorch_model.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:89d2aa29b5fdf64f3ad4f45fb4227ea98bc45156bbae673b85be1af7783dbabb
3
+ size 1215993967
ckpts/aniportrait/motion_module.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:954aee616a81f143e0316d210445d1933cca05a397c760661b7046738c4c1f06
3
+ size 1817900817
ckpts/aniportrait/pose_guider.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b6e8a6c72efcbb4ed49421baeb2c218b6047e94f5f0c90b554748019f757e64f
3
+ size 670182863
ckpts/aniportrait/reference_unet.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2e3603f7d44917ca3330a4a4be81b9578b308e9b9e3398fd6b8a1c4c86c474bd
3
+ size 3438324501
ckpts/aniportrait/sd-image-variations-diffusers/README.md ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ thumbnail: "https://repository-images.githubusercontent.com/523487884/fdb03a69-8353-4387-b5fc-0d85f888a63f"
3
+ datasets:
4
+ - ChristophSchuhmann/improved_aesthetics_6plus
5
+ license: creativeml-openrail-m
6
+ tags:
7
+ - stable-diffusion
8
+ - stable-diffusion-diffusers
9
+ - image-to-image
10
+ ---
11
+
12
+ # Stable Diffusion Image Variations Model Card
13
+
14
+ 📣 V2 model released, and blurriness issues fixed! 📣
15
+
16
+ 🧨🎉 Image Variations is now natively supported in 🤗 Diffusers! 🎉🧨
17
+
18
+ ![](https://raw.githubusercontent.com/justinpinkney/stable-diffusion/main/assets/im-vars-thin.jpg)
19
+
20
+ ## Version 2
21
+
22
+ This version of Stable Diffusion has been fine tuned from [CompVis/stable-diffusion-v1-4-original](https://huggingface.co/CompVis/stable-diffusion-v-1-4-original) to accept CLIP image embedding rather than text embeddings. This allows the creation of "image variations" similar to DALLE-2 using Stable Diffusion. This version of the weights has been ported to huggingface Diffusers, to use this with the Diffusers library requires the [Lambda Diffusers repo](https://github.com/LambdaLabsML/lambda-diffusers).
23
+
24
+ This model was trained in two stages and longer than the original variations model and gives better image quality and better CLIP rated similarity compared to the original version
25
+
26
+ See training details and v1 vs v2 comparison below.
27
+
28
+
29
+ ## Example
30
+
31
+ Make sure you are using a version of Diffusers >=0.8.0 (for older version see the old instructions at the bottom of this model card)
32
+
33
+ ```python
34
+ from diffusers import StableDiffusionImageVariationPipeline
35
+ from PIL import Image
36
+
37
+ device = "cuda:0"
38
+ sd_pipe = StableDiffusionImageVariationPipeline.from_pretrained(
39
+ "lambdalabs/sd-image-variations-diffusers",
40
+ revision="v2.0",
41
+ )
42
+ sd_pipe = sd_pipe.to(device)
43
+
44
+ im = Image.open("path/to/image.jpg")
45
+ tform = transforms.Compose([
46
+ transforms.ToTensor(),
47
+ transforms.Resize(
48
+ (224, 224),
49
+ interpolation=transforms.InterpolationMode.BICUBIC,
50
+ antialias=False,
51
+ ),
52
+ transforms.Normalize(
53
+ [0.48145466, 0.4578275, 0.40821073],
54
+ [0.26862954, 0.26130258, 0.27577711]),
55
+ ])
56
+ inp = tform(im).to(device).unsqueeze(0)
57
+
58
+ out = sd_pipe(inp, guidance_scale=3)
59
+ out["images"][0].save("result.jpg")
60
+ ```
61
+
62
+ ### The importance of resizing correctly... (or not)
63
+
64
+ Note that due a bit of an oversight during training, the model expects resized images without anti-aliasing. This turns out to make a big difference and is important to do the resizing the same way during inference. When passing a PIL image to the Diffusers pipeline antialiasing will be applied during resize, so it's better to input a tensor which you have prepared manually according to the transfrom in the example above!
65
+
66
+ Here are examples of images generated without (top) and with (bottom) anti-aliasing during resize. (Input is [this image](https://github.com/SHI-Labs/Versatile-Diffusion/blob/master/assets/ghibli.jpg))
67
+
68
+ ![](alias-montage.jpg)
69
+
70
+ ![](default-montage.jpg)
71
+
72
+ ### V1 vs V2
73
+
74
+ Here's an example of V1 vs V2, version two was trained more carefully and for longer, see the details below. V2-top vs V1-bottom
75
+
76
+ ![](v2-montage.jpg)
77
+
78
+ ![](v1-montage.jpg)
79
+
80
+ Input images:
81
+
82
+ ![](inputs.jpg)
83
+
84
+ One important thing to note is that due to the longer training V2 appears to have memorised some common images from the training data, e.g. now the previous example of the Girl with a Pearl Earring almosts perfectly reproduce the original rather than creating variations. You can always use v1 by specifiying `revision="v1.0"`.
85
+
86
+ v2 output for girl with a pearl earing as input (guidance scale=3)
87
+
88
+ ![](earring.jpg)
89
+
90
+ # Training
91
+
92
+
93
+ **Training Procedure**
94
+ This model is fine tuned from Stable Diffusion v1-3 where the text encoder has been replaced with an image encoder. The training procedure is the same as for Stable Diffusion except for the fact that images are encoded through a ViT-L/14 image-encoder including the final projection layer to the CLIP shared embedding space. The model was trained on LAION improved aesthetics 6plus.
95
+
96
+ - **Hardware:** 8 x A100-40GB GPUs (provided by [Lambda GPU Cloud](https://lambdalabs.com/service/gpu-cloud))
97
+ - **Optimizer:** AdamW
98
+
99
+ - **Stage 1** - Fine tune only CrossAttention layer weights from Stable Diffusion v1.4 model
100
+ - **Steps**: 46,000
101
+ - **Batch:** batch size=4, GPUs=8, Gradient Accumulations=4. Total batch size=128
102
+ - **Learning rate:** warmup to 1e-5 for 10,000 steps and then kept constant
103
+
104
+ - **Stage 2** - Resume from Stage 1 training the whole unet
105
+ - **Steps**: 50,000
106
+ - **Batch:** batch size=4, GPUs=8, Gradient Accumulations=5. Total batch size=160
107
+ - **Learning rate:** warmup to 1e-5 for 5,000 steps and then kept constant
108
+
109
+
110
+ Training was done using a [modified version of the original Stable Diffusion training code](https://github.com/justinpinkney/stable-diffusion).
111
+
112
+
113
+ # Uses
114
+ _The following section is adapted from the [Stable Diffusion model card](https://huggingface.co/CompVis/stable-diffusion-v1-4)_
115
+
116
+ ## Direct Use
117
+ The model is intended for research purposes only. Possible research areas and
118
+ tasks include
119
+
120
+ - Safe deployment of models which have the potential to generate harmful content.
121
+ - Probing and understanding the limitations and biases of generative models.
122
+ - Generation of artworks and use in design and other artistic processes.
123
+ - Applications in educational or creative tools.
124
+ - Research on generative models.
125
+
126
+ Excluded uses are described below.
127
+
128
+ ### Misuse, Malicious Use, and Out-of-Scope Use
129
+
130
+ The model should not be used to intentionally create or disseminate images that create hostile or alienating environments for people. This includes generating images that people would foreseeably find disturbing, distressing, or offensive; or content that propagates historical or current stereotypes.
131
+
132
+ #### Out-of-Scope Use
133
+ The model was not trained to be factual or true representations of people or events, and therefore using the model to generate such content is out-of-scope for the abilities of this model.
134
+
135
+ #### Misuse and Malicious Use
136
+ Using the model to generate content that is cruel to individuals is a misuse of this model. This includes, but is not limited to:
137
+
138
+ - Generating demeaning, dehumanizing, or otherwise harmful representations of people or their environments, cultures, religions, etc.
139
+ - Intentionally promoting or propagating discriminatory content or harmful stereotypes.
140
+ - Impersonating individuals without their consent.
141
+ - Sexual content without consent of the people who might see it.
142
+ - Mis- and disinformation
143
+ - Representations of egregious violence and gore
144
+ - Sharing of copyrighted or licensed material in violation of its terms of use.
145
+ - Sharing content that is an alteration of copyrighted or licensed material in violation of its terms of use.
146
+
147
+ ## Limitations and Bias
148
+
149
+ ### Limitations
150
+
151
+ - The model does not achieve perfect photorealism
152
+ - The model cannot render legible text
153
+ - The model does not perform well on more difficult tasks which involve compositionality, such as rendering an image corresponding to “A red cube on top of a blue sphere”
154
+ - Faces and people in general may not be generated properly.
155
+ - The model was trained mainly with English captions and will not work as well in other languages.
156
+ - The autoencoding part of the model is lossy
157
+ - The model was trained on a large-scale dataset
158
+ [LAION-5B](https://laion.ai/blog/laion-5b/) which contains adult material
159
+ and is not fit for product use without additional safety mechanisms and
160
+ considerations.
161
+ - No additional measures were used to deduplicate the dataset. As a result, we observe some degree of memorization for images that are duplicated in the training data.
162
+ The training data can be searched at [https://rom1504.github.io/clip-retrieval/](https://rom1504.github.io/clip-retrieval/) to possibly assist in the detection of memorized images.
163
+
164
+ ### Bias
165
+
166
+ While the capabilities of image generation models are impressive, they can also reinforce or exacerbate social biases.
167
+ Stable Diffusion v1 was trained on subsets of [LAION-2B(en)](https://laion.ai/blog/laion-5b/),
168
+ which consists of images that are primarily limited to English descriptions.
169
+ Texts and images from communities and cultures that use other languages are likely to be insufficiently accounted for.
170
+ This affects the overall output of the model, as white and western cultures are often set as the default. Further, the
171
+ ability of the model to generate content with non-English prompts is significantly worse than with English-language prompts.
172
+
173
+ ### Safety Module
174
+
175
+ The intended use of this model is with the [Safety Checker](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/stable_diffusion/safety_checker.py) in Diffusers.
176
+ This checker works by checking model outputs against known hard-coded NSFW concepts.
177
+ The concepts are intentionally hidden to reduce the likelihood of reverse-engineering this filter.
178
+ Specifically, the checker compares the class probability of harmful concepts in the embedding space of the `CLIPModel` *after generation* of the images.
179
+ The concepts are passed into the model with the generated image and compared to a hand-engineered weight for each NSFW concept.
180
+
181
+
182
+ ## Old instructions
183
+
184
+ If you are using a diffusers version <0.8.0 there is no `StableDiffusionImageVariationPipeline`,
185
+ in this case you need to use an older revision (`2ddbd90b14bc5892c19925b15185e561bc8e5d0a`) in conjunction with the lambda-diffusers repo:
186
+
187
+
188
+ First clone [Lambda Diffusers](https://github.com/LambdaLabsML/lambda-diffusers) and install any requirements (in a virtual environment in the example below):
189
+
190
+ ```bash
191
+ git clone https://github.com/LambdaLabsML/lambda-diffusers.git
192
+ cd lambda-diffusers
193
+ python -m venv .venv
194
+ source .venv/bin/activate
195
+ pip install -r requirements.txt
196
+ ```
197
+
198
+ Then run the following python code:
199
+
200
+ ```python
201
+ from pathlib import Path
202
+ from lambda_diffusers import StableDiffusionImageEmbedPipeline
203
+ from PIL import Image
204
+ import torch
205
+
206
+ device = "cuda" if torch.cuda.is_available() else "cpu"
207
+ pipe = StableDiffusionImageEmbedPipeline.from_pretrained(
208
+ "lambdalabs/sd-image-variations-diffusers",
209
+ revision="2ddbd90b14bc5892c19925b15185e561bc8e5d0a",
210
+ )
211
+ pipe = pipe.to(device)
212
+
213
+ im = Image.open("your/input/image/here.jpg")
214
+ num_samples = 4
215
+ image = pipe(num_samples*[im], guidance_scale=3.0)
216
+ image = image["sample"]
217
+
218
+ base_path = Path("outputs/im2im")
219
+ base_path.mkdir(exist_ok=True, parents=True)
220
+ for idx, im in enumerate(image):
221
+ im.save(base_path/f"{idx:06}.jpg")
222
+ ```
223
+
224
+
225
+
226
+ *This model card was written by: Justin Pinkney and is based on the [Stable Diffusion model card](https://huggingface.co/CompVis/stable-diffusion-v1-4).*
ckpts/aniportrait/sd-image-variations-diffusers/alias-montage.jpg ADDED
ckpts/aniportrait/sd-image-variations-diffusers/default-montage.jpg ADDED
ckpts/aniportrait/sd-image-variations-diffusers/earring.jpg ADDED
ckpts/aniportrait/sd-image-variations-diffusers/feature_extractor/preprocessor_config.json ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "crop_size": {
3
+ "height": 224,
4
+ "width": 224
5
+ },
6
+ "do_center_crop": true,
7
+ "do_convert_rgb": true,
8
+ "do_normalize": true,
9
+ "do_rescale": true,
10
+ "do_resize": true,
11
+ "feature_extractor_type": "CLIPFeatureExtractor",
12
+ "image_mean": [
13
+ 0.48145466,
14
+ 0.4578275,
15
+ 0.40821073
16
+ ],
17
+ "image_processor_type": "CLIPImageProcessor",
18
+ "image_std": [
19
+ 0.26862954,
20
+ 0.26130258,
21
+ 0.27577711
22
+ ],
23
+ "resample": 3,
24
+ "rescale_factor": 0.00392156862745098,
25
+ "size": {
26
+ "shortest_edge": 224
27
+ }
28
+ }
ckpts/aniportrait/sd-image-variations-diffusers/inputs.jpg ADDED
ckpts/aniportrait/sd-image-variations-diffusers/model_index.json ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": "StableDiffusionImageVariationPipeline",
3
+ "_diffusers_version": "0.9.0",
4
+ "feature_extractor": [
5
+ "transformers",
6
+ "CLIPImageProcessor"
7
+ ],
8
+ "image_encoder": [
9
+ "transformers",
10
+ "CLIPVisionModelWithProjection"
11
+ ],
12
+ "requires_safety_checker": true,
13
+ "safety_checker": [
14
+ "stable_diffusion",
15
+ "StableDiffusionSafetyChecker"
16
+ ],
17
+ "scheduler": [
18
+ "diffusers",
19
+ "PNDMScheduler"
20
+ ],
21
+ "unet": [
22
+ "diffusers",
23
+ "UNet2DConditionModel"
24
+ ],
25
+ "vae": [
26
+ "diffusers",
27
+ "AutoencoderKL"
28
+ ]
29
+ }
ckpts/aniportrait/sd-image-variations-diffusers/safety_checker/config.json ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_commit_hash": "ca6f97f838ae1b5bf764f31363a21f388f4d8f3e",
3
+ "_name_or_path": "/home/jpinkney/.cache/huggingface/diffusers/models--lambdalabs--sd-image-variations-diffusers/snapshots/ca6f97f838ae1b5bf764f31363a21f388f4d8f3e/safety_checker",
4
+ "architectures": [
5
+ "StableDiffusionSafetyChecker"
6
+ ],
7
+ "initializer_factor": 1.0,
8
+ "logit_scale_init_value": 2.6592,
9
+ "model_type": "clip",
10
+ "projection_dim": 768,
11
+ "text_config": {
12
+ "_name_or_path": "",
13
+ "add_cross_attention": false,
14
+ "architectures": null,
15
+ "attention_dropout": 0.0,
16
+ "bad_words_ids": null,
17
+ "begin_suppress_tokens": null,
18
+ "bos_token_id": 0,
19
+ "chunk_size_feed_forward": 0,
20
+ "cross_attention_hidden_size": null,
21
+ "decoder_start_token_id": null,
22
+ "diversity_penalty": 0.0,
23
+ "do_sample": false,
24
+ "dropout": 0.0,
25
+ "early_stopping": false,
26
+ "encoder_no_repeat_ngram_size": 0,
27
+ "eos_token_id": 2,
28
+ "exponential_decay_length_penalty": null,
29
+ "finetuning_task": null,
30
+ "forced_bos_token_id": null,
31
+ "forced_eos_token_id": null,
32
+ "hidden_act": "quick_gelu",
33
+ "hidden_size": 768,
34
+ "id2label": {
35
+ "0": "LABEL_0",
36
+ "1": "LABEL_1"
37
+ },
38
+ "initializer_factor": 1.0,
39
+ "initializer_range": 0.02,
40
+ "intermediate_size": 3072,
41
+ "is_decoder": false,
42
+ "is_encoder_decoder": false,
43
+ "label2id": {
44
+ "LABEL_0": 0,
45
+ "LABEL_1": 1
46
+ },
47
+ "layer_norm_eps": 1e-05,
48
+ "length_penalty": 1.0,
49
+ "max_length": 20,
50
+ "max_position_embeddings": 77,
51
+ "min_length": 0,
52
+ "model_type": "clip_text_model",
53
+ "no_repeat_ngram_size": 0,
54
+ "num_attention_heads": 12,
55
+ "num_beam_groups": 1,
56
+ "num_beams": 1,
57
+ "num_hidden_layers": 12,
58
+ "num_return_sequences": 1,
59
+ "output_attentions": false,
60
+ "output_hidden_states": false,
61
+ "output_scores": false,
62
+ "pad_token_id": 1,
63
+ "prefix": null,
64
+ "problem_type": null,
65
+ "projection_dim": 512,
66
+ "pruned_heads": {},
67
+ "remove_invalid_values": false,
68
+ "repetition_penalty": 1.0,
69
+ "return_dict": true,
70
+ "return_dict_in_generate": false,
71
+ "sep_token_id": null,
72
+ "suppress_tokens": null,
73
+ "task_specific_params": null,
74
+ "temperature": 1.0,
75
+ "tf_legacy_loss": false,
76
+ "tie_encoder_decoder": false,
77
+ "tie_word_embeddings": true,
78
+ "tokenizer_class": null,
79
+ "top_k": 50,
80
+ "top_p": 1.0,
81
+ "torch_dtype": null,
82
+ "torchscript": false,
83
+ "transformers_version": "4.25.1",
84
+ "typical_p": 1.0,
85
+ "use_bfloat16": false,
86
+ "vocab_size": 49408
87
+ },
88
+ "text_config_dict": {
89
+ "hidden_size": 768,
90
+ "intermediate_size": 3072,
91
+ "num_attention_heads": 12,
92
+ "num_hidden_layers": 12
93
+ },
94
+ "torch_dtype": "float32",
95
+ "transformers_version": null,
96
+ "vision_config": {
97
+ "_name_or_path": "",
98
+ "add_cross_attention": false,
99
+ "architectures": null,
100
+ "attention_dropout": 0.0,
101
+ "bad_words_ids": null,
102
+ "begin_suppress_tokens": null,
103
+ "bos_token_id": null,
104
+ "chunk_size_feed_forward": 0,
105
+ "cross_attention_hidden_size": null,
106
+ "decoder_start_token_id": null,
107
+ "diversity_penalty": 0.0,
108
+ "do_sample": false,
109
+ "dropout": 0.0,
110
+ "early_stopping": false,
111
+ "encoder_no_repeat_ngram_size": 0,
112
+ "eos_token_id": null,
113
+ "exponential_decay_length_penalty": null,
114
+ "finetuning_task": null,
115
+ "forced_bos_token_id": null,
116
+ "forced_eos_token_id": null,
117
+ "hidden_act": "quick_gelu",
118
+ "hidden_size": 1024,
119
+ "id2label": {
120
+ "0": "LABEL_0",
121
+ "1": "LABEL_1"
122
+ },
123
+ "image_size": 224,
124
+ "initializer_factor": 1.0,
125
+ "initializer_range": 0.02,
126
+ "intermediate_size": 4096,
127
+ "is_decoder": false,
128
+ "is_encoder_decoder": false,
129
+ "label2id": {
130
+ "LABEL_0": 0,
131
+ "LABEL_1": 1
132
+ },
133
+ "layer_norm_eps": 1e-05,
134
+ "length_penalty": 1.0,
135
+ "max_length": 20,
136
+ "min_length": 0,
137
+ "model_type": "clip_vision_model",
138
+ "no_repeat_ngram_size": 0,
139
+ "num_attention_heads": 16,
140
+ "num_beam_groups": 1,
141
+ "num_beams": 1,
142
+ "num_channels": 3,
143
+ "num_hidden_layers": 24,
144
+ "num_return_sequences": 1,
145
+ "output_attentions": false,
146
+ "output_hidden_states": false,
147
+ "output_scores": false,
148
+ "pad_token_id": null,
149
+ "patch_size": 14,
150
+ "prefix": null,
151
+ "problem_type": null,
152
+ "projection_dim": 512,
153
+ "pruned_heads": {},
154
+ "remove_invalid_values": false,
155
+ "repetition_penalty": 1.0,
156
+ "return_dict": true,
157
+ "return_dict_in_generate": false,
158
+ "sep_token_id": null,
159
+ "suppress_tokens": null,
160
+ "task_specific_params": null,
161
+ "temperature": 1.0,
162
+ "tf_legacy_loss": false,
163
+ "tie_encoder_decoder": false,
164
+ "tie_word_embeddings": true,
165
+ "tokenizer_class": null,
166
+ "top_k": 50,
167
+ "top_p": 1.0,
168
+ "torch_dtype": null,
169
+ "torchscript": false,
170
+ "transformers_version": "4.25.1",
171
+ "typical_p": 1.0,
172
+ "use_bfloat16": false
173
+ },
174
+ "vision_config_dict": {
175
+ "hidden_size": 1024,
176
+ "intermediate_size": 4096,
177
+ "num_attention_heads": 16,
178
+ "num_hidden_layers": 24,
179
+ "patch_size": 14
180
+ }
181
+ }
ckpts/aniportrait/sd-image-variations-diffusers/safety_checker/pytorch_model.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:193490b58ef62739077262e833bf091c66c29488058681ac25cf7df3d8190974
3
+ size 1216061799
ckpts/aniportrait/sd-image-variations-diffusers/scheduler/scheduler_config.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": "PNDMScheduler",
3
+ "_diffusers_version": "0.9.0",
4
+ "beta_end": 0.012,
5
+ "beta_schedule": "scaled_linear",
6
+ "beta_start": 0.00085,
7
+ "clip_sample": false,
8
+ "num_train_timesteps": 1000,
9
+ "set_alpha_to_one": false,
10
+ "skip_prk_steps": true,
11
+ "steps_offset": 1,
12
+ "trained_betas": null
13
+ }
ckpts/aniportrait/sd-image-variations-diffusers/unet/config.json ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": "UNet2DConditionModel",
3
+ "_diffusers_version": "0.9.0",
4
+ "act_fn": "silu",
5
+ "attention_head_dim": 8,
6
+ "block_out_channels": [
7
+ 320,
8
+ 640,
9
+ 1280,
10
+ 1280
11
+ ],
12
+ "center_input_sample": false,
13
+ "cross_attention_dim": 768,
14
+ "down_block_types": [
15
+ "CrossAttnDownBlock2D",
16
+ "CrossAttnDownBlock2D",
17
+ "CrossAttnDownBlock2D",
18
+ "DownBlock2D"
19
+ ],
20
+ "downsample_padding": 1,
21
+ "dual_cross_attention": false,
22
+ "flip_sin_to_cos": true,
23
+ "freq_shift": 0,
24
+ "in_channels": 4,
25
+ "layers_per_block": 2,
26
+ "mid_block_scale_factor": 1,
27
+ "norm_eps": 1e-05,
28
+ "norm_num_groups": 32,
29
+ "num_class_embeds": null,
30
+ "only_cross_attention": false,
31
+ "out_channels": 4,
32
+ "sample_size": 64,
33
+ "up_block_types": [
34
+ "UpBlock2D",
35
+ "CrossAttnUpBlock2D",
36
+ "CrossAttnUpBlock2D",
37
+ "CrossAttnUpBlock2D"
38
+ ],
39
+ "use_linear_projection": false
40
+ }
ckpts/aniportrait/sd-image-variations-diffusers/unet/diffusion_pytorch_model.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ee23e3368e4e7c0e4ef636ed61923609c97fcaa583f8bb416e3e0986d4a0cfc6
3
+ size 3438354725
ckpts/aniportrait/sd-image-variations-diffusers/v1-montage.jpg ADDED
ckpts/aniportrait/sd-image-variations-diffusers/v2-montage.jpg ADDED