Spaces:
Sleeping
Sleeping
adding download functionality into the code.
Browse filesThis view is limited to 50 files because it contains too many changes. Β
See raw diff
- MakeItTalk/__pycache__/download.cpython-37.pyc +0 -0
- download.py β MakeItTalk/download.py +2 -2
- MakeItTalk/examples/dump/random_val_au.pickle +2 -2
- MakeItTalk/examples/dump/random_val_fl.pickle +2 -2
- MakeItTalk/examples/dump/random_val_gaze.pickle +2 -2
- MakeItTalk/examples/in_audio.wav +0 -0
- MakeItTalk/examples/in_audio_av.mp4 +0 -0
- MakeItTalk/examples/in_image.jpg +0 -0
- MakeItTalk/examples/in_image_pred_fls_in_audio_audio_embed.mp4 +0 -0
- MakeItTalk/main_end2end.py +6 -2
- MakeItTalk/thirdparty/AdaptiveWingLoss/core/__pycache__/models.cpython-37.pyc +0 -0
- upload.py β MakeItTalk/upload.py +0 -0
- app.py +4 -0
- example_image.jpg +0 -0
- marlene_example.wav +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/.gitignore +0 -8
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/LICENSE +0 -201
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/README.md +0 -82
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/__init__.py +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/__pycache__/__init__.cpython-37.pyc +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/__pycache__/__init__.cpython-39.pyc +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/ckpt/.gitkeep +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/__init__.py +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/__pycache__/__init__.cpython-37.pyc +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/__pycache__/__init__.cpython-39.pyc +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/__pycache__/coord_conv.cpython-37.pyc +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/__pycache__/coord_conv.cpython-39.pyc +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/__pycache__/models.cpython-37.pyc +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/__pycache__/models.cpython-39.pyc +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/coord_conv.py +0 -157
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/dataloader.py +0 -368
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/evaler.py +0 -151
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/models.py +0 -228
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/eval.py +0 -77
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/images/wflw.png +0 -3
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/images/wflw_table.png +0 -3
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/requirements.txt +0 -12
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/scripts/eval_wflw.sh +0 -10
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/utils/__init__.py +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/utils/__pycache__/__init__.cpython-37.pyc +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/utils/__pycache__/__init__.cpython-39.pyc +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/utils/__pycache__/utils.cpython-37.pyc +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/utils/__pycache__/utils.cpython-39.pyc +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/utils/utils.py +0 -354
- marlenezw/audio-driven-animations/MakeItTalk/__init__.py +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/__pycache__/__init__.cpython-37.pyc +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/__pycache__/__init__.cpython-39.pyc +0 -0
- marlenezw/audio-driven-animations/MakeItTalk/face_of_art/CODEOWNERS +0 -1
- marlenezw/audio-driven-animations/MakeItTalk/face_of_art/LICENCE.txt +0 -21
- marlenezw/audio-driven-animations/MakeItTalk/face_of_art/README.md +0 -98
MakeItTalk/__pycache__/download.cpython-37.pyc
ADDED
Binary file (645 Bytes). View file
|
|
download.py β MakeItTalk/download.py
RENAMED
@@ -2,9 +2,9 @@ from huggingface_hub import hf_hub_download
|
|
2 |
from huggingface_hub import snapshot_download
|
3 |
|
4 |
#download files
|
5 |
-
def download_file(repo_name, filename, repo_type):
|
6 |
|
7 |
-
file_location = hf_hub_download(repo_id=repo_name, filename=filename,repo_type=repo_type)
|
8 |
return file_location
|
9 |
|
10 |
#download a folder
|
|
|
2 |
from huggingface_hub import snapshot_download
|
3 |
|
4 |
#download files
|
5 |
+
def download_file(repo_name, filename, revision='main',repo_type='model'):
|
6 |
|
7 |
+
file_location = hf_hub_download(repo_id=repo_name, filename=filename,revision=revision, repo_type=repo_type)
|
8 |
return file_location
|
9 |
|
10 |
#download a folder
|
MakeItTalk/examples/dump/random_val_au.pickle
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:1d74d65f2bf553d2709cc580cea6253f3eac846e1bb02f004909793d7a5db015
|
3 |
+
size 133114
|
MakeItTalk/examples/dump/random_val_fl.pickle
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:5dbbcd724cf21a3e4b03dfae86d72fb594b17e603f0f3f6cbdf985807435fdfe
|
3 |
+
size 673699
|
MakeItTalk/examples/dump/random_val_gaze.pickle
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:7fe3aee71b27209901f71e191319864424c1355cab907fcc250dc998054e0ffb
|
3 |
+
size 725434
|
MakeItTalk/examples/in_audio.wav
CHANGED
Binary files a/MakeItTalk/examples/in_audio.wav and b/MakeItTalk/examples/in_audio.wav differ
|
|
MakeItTalk/examples/in_audio_av.mp4
CHANGED
Binary files a/MakeItTalk/examples/in_audio_av.mp4 and b/MakeItTalk/examples/in_audio_av.mp4 differ
|
|
MakeItTalk/examples/in_image.jpg
CHANGED
![]() |
![]() |
MakeItTalk/examples/in_image_pred_fls_in_audio_audio_embed.mp4
CHANGED
Binary files a/MakeItTalk/examples/in_image_pred_fls_in_audio_audio_embed.mp4 and b/MakeItTalk/examples/in_image_pred_fls_in_audio_audio_embed.mp4 differ
|
|
MakeItTalk/main_end2end.py
CHANGED
@@ -22,6 +22,7 @@ from src.autovc.AutoVC_mel_Convertor_retrain_version import AutoVC_mel_Convertor
|
|
22 |
import shutil
|
23 |
import util.utils as util
|
24 |
from scipy.signal import savgol_filter
|
|
|
25 |
|
26 |
from src.approaches.train_audio2landmark import Audio2landmark_model
|
27 |
|
@@ -29,13 +30,16 @@ default_head_name = 'dali'
|
|
29 |
ADD_NAIVE_EYE = True
|
30 |
CLOSE_INPUT_FACE_MOUTH = False
|
31 |
|
|
|
|
|
|
|
32 |
|
33 |
parser = argparse.ArgumentParser()
|
34 |
parser.add_argument('--jpg', type=str, default='{}.jpg'.format(default_head_name))
|
35 |
parser.add_argument('--close_input_face_mouth', default=CLOSE_INPUT_FACE_MOUTH, action='store_true')
|
36 |
|
37 |
-
parser.add_argument('--load_AUTOVC_name', type=str, default=
|
38 |
-
parser.add_argument('--load_a2l_G_name', type=str, default=
|
39 |
parser.add_argument('--load_a2l_C_name', type=str, default='MakeItTalk/examples/ckpt/ckpt_content_branch.pth') #ckpt_audio2landmark_c.pth')
|
40 |
parser.add_argument('--load_G_name', type=str, default='MakeItTalk/examples/ckpt/ckpt_116_i2i_comb.pth') #ckpt_image2image.pth') #ckpt_i2i_finetune_150.pth') #c
|
41 |
|
|
|
22 |
import shutil
|
23 |
import util.utils as util
|
24 |
from scipy.signal import savgol_filter
|
25 |
+
from download import download_file
|
26 |
|
27 |
from src.approaches.train_audio2landmark import Audio2landmark_model
|
28 |
|
|
|
30 |
ADD_NAIVE_EYE = True
|
31 |
CLOSE_INPUT_FACE_MOUTH = False
|
32 |
|
33 |
+
auto_vc_model_path = download_file(repo_name='marlenezw/AutoVC_Voice_Conversion', filename='ckpt_autovc.pth')
|
34 |
+
speaker_model_path = download_file(repo_name='marlenezw/Self_Attention_Network', filename='ckpt_speaker_branch.pth')
|
35 |
+
|
36 |
|
37 |
parser = argparse.ArgumentParser()
|
38 |
parser.add_argument('--jpg', type=str, default='{}.jpg'.format(default_head_name))
|
39 |
parser.add_argument('--close_input_face_mouth', default=CLOSE_INPUT_FACE_MOUTH, action='store_true')
|
40 |
|
41 |
+
parser.add_argument('--load_AUTOVC_name', type=str, default=auto_vc_model_path)
|
42 |
+
parser.add_argument('--load_a2l_G_name', type=str, default=speaker_model_path)
|
43 |
parser.add_argument('--load_a2l_C_name', type=str, default='MakeItTalk/examples/ckpt/ckpt_content_branch.pth') #ckpt_audio2landmark_c.pth')
|
44 |
parser.add_argument('--load_G_name', type=str, default='MakeItTalk/examples/ckpt/ckpt_116_i2i_comb.pth') #ckpt_image2image.pth') #ckpt_i2i_finetune_150.pth') #c
|
45 |
|
MakeItTalk/thirdparty/AdaptiveWingLoss/core/__pycache__/models.cpython-37.pyc
CHANGED
Binary files a/MakeItTalk/thirdparty/AdaptiveWingLoss/core/__pycache__/models.cpython-37.pyc and b/MakeItTalk/thirdparty/AdaptiveWingLoss/core/__pycache__/models.cpython-37.pyc differ
|
|
upload.py β MakeItTalk/upload.py
RENAMED
File without changes
|
app.py
CHANGED
@@ -30,6 +30,10 @@ demo = gr.Interface(
|
|
30 |
fn=generateVideo,
|
31 |
inputs=[gr.Image(shape=(256, 256)), gr.Audio(), ],
|
32 |
outputs= gr.Video().style(height=256, width=256),
|
|
|
|
|
|
|
|
|
33 |
|
34 |
)
|
35 |
|
|
|
30 |
fn=generateVideo,
|
31 |
inputs=[gr.Image(shape=(256, 256)), gr.Audio(), ],
|
32 |
outputs= gr.Video().style(height=256, width=256),
|
33 |
+
title='Audio Driven Animation',
|
34 |
+
description='This is my app',
|
35 |
+
examples =[['example_image.jpg', 'marlene_example.wav']]
|
36 |
+
|
37 |
|
38 |
)
|
39 |
|
example_image.jpg
ADDED
![]() |
marlene_example.wav
ADDED
Binary file (421 kB). View file
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/.gitignore
DELETED
@@ -1,8 +0,0 @@
|
|
1 |
-
# Python generated files
|
2 |
-
*.pyc
|
3 |
-
|
4 |
-
# Project related files
|
5 |
-
ckpt/*.pth
|
6 |
-
dataset/*
|
7 |
-
!dataset/!.py
|
8 |
-
experiments/*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/LICENSE
DELETED
@@ -1,201 +0,0 @@
|
|
1 |
-
Apache License
|
2 |
-
Version 2.0, January 2004
|
3 |
-
http://www.apache.org/licenses/
|
4 |
-
|
5 |
-
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
6 |
-
|
7 |
-
1. Definitions.
|
8 |
-
|
9 |
-
"License" shall mean the terms and conditions for use, reproduction,
|
10 |
-
and distribution as defined by Sections 1 through 9 of this document.
|
11 |
-
|
12 |
-
"Licensor" shall mean the copyright owner or entity authorized by
|
13 |
-
the copyright owner that is granting the License.
|
14 |
-
|
15 |
-
"Legal Entity" shall mean the union of the acting entity and all
|
16 |
-
other entities that control, are controlled by, or are under common
|
17 |
-
control with that entity. For the purposes of this definition,
|
18 |
-
"control" means (i) the power, direct or indirect, to cause the
|
19 |
-
direction or management of such entity, whether by contract or
|
20 |
-
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
21 |
-
outstanding shares, or (iii) beneficial ownership of such entity.
|
22 |
-
|
23 |
-
"You" (or "Your") shall mean an individual or Legal Entity
|
24 |
-
exercising permissions granted by this License.
|
25 |
-
|
26 |
-
"Source" form shall mean the preferred form for making modifications,
|
27 |
-
including but not limited to software source code, documentation
|
28 |
-
source, and configuration files.
|
29 |
-
|
30 |
-
"Object" form shall mean any form resulting from mechanical
|
31 |
-
transformation or translation of a Source form, including but
|
32 |
-
not limited to compiled object code, generated documentation,
|
33 |
-
and conversions to other media types.
|
34 |
-
|
35 |
-
"Work" shall mean the work of authorship, whether in Source or
|
36 |
-
Object form, made available under the License, as indicated by a
|
37 |
-
copyright notice that is included in or attached to the work
|
38 |
-
(an example is provided in the Appendix below).
|
39 |
-
|
40 |
-
"Derivative Works" shall mean any work, whether in Source or Object
|
41 |
-
form, that is based on (or derived from) the Work and for which the
|
42 |
-
editorial revisions, annotations, elaborations, or other modifications
|
43 |
-
represent, as a whole, an original work of authorship. For the purposes
|
44 |
-
of this License, Derivative Works shall not include works that remain
|
45 |
-
separable from, or merely link (or bind by name) to the interfaces of,
|
46 |
-
the Work and Derivative Works thereof.
|
47 |
-
|
48 |
-
"Contribution" shall mean any work of authorship, including
|
49 |
-
the original version of the Work and any modifications or additions
|
50 |
-
to that Work or Derivative Works thereof, that is intentionally
|
51 |
-
submitted to Licensor for inclusion in the Work by the copyright owner
|
52 |
-
or by an individual or Legal Entity authorized to submit on behalf of
|
53 |
-
the copyright owner. For the purposes of this definition, "submitted"
|
54 |
-
means any form of electronic, verbal, or written communication sent
|
55 |
-
to the Licensor or its representatives, including but not limited to
|
56 |
-
communication on electronic mailing lists, source code control systems,
|
57 |
-
and issue tracking systems that are managed by, or on behalf of, the
|
58 |
-
Licensor for the purpose of discussing and improving the Work, but
|
59 |
-
excluding communication that is conspicuously marked or otherwise
|
60 |
-
designated in writing by the copyright owner as "Not a Contribution."
|
61 |
-
|
62 |
-
"Contributor" shall mean Licensor and any individual or Legal Entity
|
63 |
-
on behalf of whom a Contribution has been received by Licensor and
|
64 |
-
subsequently incorporated within the Work.
|
65 |
-
|
66 |
-
2. Grant of Copyright License. Subject to the terms and conditions of
|
67 |
-
this License, each Contributor hereby grants to You a perpetual,
|
68 |
-
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
69 |
-
copyright license to reproduce, prepare Derivative Works of,
|
70 |
-
publicly display, publicly perform, sublicense, and distribute the
|
71 |
-
Work and such Derivative Works in Source or Object form.
|
72 |
-
|
73 |
-
3. Grant of Patent License. Subject to the terms and conditions of
|
74 |
-
this License, each Contributor hereby grants to You a perpetual,
|
75 |
-
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
76 |
-
(except as stated in this section) patent license to make, have made,
|
77 |
-
use, offer to sell, sell, import, and otherwise transfer the Work,
|
78 |
-
where such license applies only to those patent claims licensable
|
79 |
-
by such Contributor that are necessarily infringed by their
|
80 |
-
Contribution(s) alone or by combination of their Contribution(s)
|
81 |
-
with the Work to which such Contribution(s) was submitted. If You
|
82 |
-
institute patent litigation against any entity (including a
|
83 |
-
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
84 |
-
or a Contribution incorporated within the Work constitutes direct
|
85 |
-
or contributory patent infringement, then any patent licenses
|
86 |
-
granted to You under this License for that Work shall terminate
|
87 |
-
as of the date such litigation is filed.
|
88 |
-
|
89 |
-
4. Redistribution. You may reproduce and distribute copies of the
|
90 |
-
Work or Derivative Works thereof in any medium, with or without
|
91 |
-
modifications, and in Source or Object form, provided that You
|
92 |
-
meet the following conditions:
|
93 |
-
|
94 |
-
(a) You must give any other recipients of the Work or
|
95 |
-
Derivative Works a copy of this License; and
|
96 |
-
|
97 |
-
(b) You must cause any modified files to carry prominent notices
|
98 |
-
stating that You changed the files; and
|
99 |
-
|
100 |
-
(c) You must retain, in the Source form of any Derivative Works
|
101 |
-
that You distribute, all copyright, patent, trademark, and
|
102 |
-
attribution notices from the Source form of the Work,
|
103 |
-
excluding those notices that do not pertain to any part of
|
104 |
-
the Derivative Works; and
|
105 |
-
|
106 |
-
(d) If the Work includes a "NOTICE" text file as part of its
|
107 |
-
distribution, then any Derivative Works that You distribute must
|
108 |
-
include a readable copy of the attribution notices contained
|
109 |
-
within such NOTICE file, excluding those notices that do not
|
110 |
-
pertain to any part of the Derivative Works, in at least one
|
111 |
-
of the following places: within a NOTICE text file distributed
|
112 |
-
as part of the Derivative Works; within the Source form or
|
113 |
-
documentation, if provided along with the Derivative Works; or,
|
114 |
-
within a display generated by the Derivative Works, if and
|
115 |
-
wherever such third-party notices normally appear. The contents
|
116 |
-
of the NOTICE file are for informational purposes only and
|
117 |
-
do not modify the License. You may add Your own attribution
|
118 |
-
notices within Derivative Works that You distribute, alongside
|
119 |
-
or as an addendum to the NOTICE text from the Work, provided
|
120 |
-
that such additional attribution notices cannot be construed
|
121 |
-
as modifying the License.
|
122 |
-
|
123 |
-
You may add Your own copyright statement to Your modifications and
|
124 |
-
may provide additional or different license terms and conditions
|
125 |
-
for use, reproduction, or distribution of Your modifications, or
|
126 |
-
for any such Derivative Works as a whole, provided Your use,
|
127 |
-
reproduction, and distribution of the Work otherwise complies with
|
128 |
-
the conditions stated in this License.
|
129 |
-
|
130 |
-
5. Submission of Contributions. Unless You explicitly state otherwise,
|
131 |
-
any Contribution intentionally submitted for inclusion in the Work
|
132 |
-
by You to the Licensor shall be under the terms and conditions of
|
133 |
-
this License, without any additional terms or conditions.
|
134 |
-
Notwithstanding the above, nothing herein shall supersede or modify
|
135 |
-
the terms of any separate license agreement you may have executed
|
136 |
-
with Licensor regarding such Contributions.
|
137 |
-
|
138 |
-
6. Trademarks. This License does not grant permission to use the trade
|
139 |
-
names, trademarks, service marks, or product names of the Licensor,
|
140 |
-
except as required for reasonable and customary use in describing the
|
141 |
-
origin of the Work and reproducing the content of the NOTICE file.
|
142 |
-
|
143 |
-
7. Disclaimer of Warranty. Unless required by applicable law or
|
144 |
-
agreed to in writing, Licensor provides the Work (and each
|
145 |
-
Contributor provides its Contributions) on an "AS IS" BASIS,
|
146 |
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
147 |
-
implied, including, without limitation, any warranties or conditions
|
148 |
-
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
149 |
-
PARTICULAR PURPOSE. You are solely responsible for determining the
|
150 |
-
appropriateness of using or redistributing the Work and assume any
|
151 |
-
risks associated with Your exercise of permissions under this License.
|
152 |
-
|
153 |
-
8. Limitation of Liability. In no event and under no legal theory,
|
154 |
-
whether in tort (including negligence), contract, or otherwise,
|
155 |
-
unless required by applicable law (such as deliberate and grossly
|
156 |
-
negligent acts) or agreed to in writing, shall any Contributor be
|
157 |
-
liable to You for damages, including any direct, indirect, special,
|
158 |
-
incidental, or consequential damages of any character arising as a
|
159 |
-
result of this License or out of the use or inability to use the
|
160 |
-
Work (including but not limited to damages for loss of goodwill,
|
161 |
-
work stoppage, computer failure or malfunction, or any and all
|
162 |
-
other commercial damages or losses), even if such Contributor
|
163 |
-
has been advised of the possibility of such damages.
|
164 |
-
|
165 |
-
9. Accepting Warranty or Additional Liability. While redistributing
|
166 |
-
the Work or Derivative Works thereof, You may choose to offer,
|
167 |
-
and charge a fee for, acceptance of support, warranty, indemnity,
|
168 |
-
or other liability obligations and/or rights consistent with this
|
169 |
-
License. However, in accepting such obligations, You may act only
|
170 |
-
on Your own behalf and on Your sole responsibility, not on behalf
|
171 |
-
of any other Contributor, and only if You agree to indemnify,
|
172 |
-
defend, and hold each Contributor harmless for any liability
|
173 |
-
incurred by, or claims asserted against, such Contributor by reason
|
174 |
-
of your accepting any such warranty or additional liability.
|
175 |
-
|
176 |
-
END OF TERMS AND CONDITIONS
|
177 |
-
|
178 |
-
APPENDIX: How to apply the Apache License to your work.
|
179 |
-
|
180 |
-
To apply the Apache License to your work, attach the following
|
181 |
-
boilerplate notice, with the fields enclosed by brackets "[]"
|
182 |
-
replaced with your own identifying information. (Don't include
|
183 |
-
the brackets!) The text should be enclosed in the appropriate
|
184 |
-
comment syntax for the file format. We also recommend that a
|
185 |
-
file or class name and description of purpose be included on the
|
186 |
-
same "printed page" as the copyright notice for easier
|
187 |
-
identification within third-party archives.
|
188 |
-
|
189 |
-
Copyright [yyyy] [name of copyright owner]
|
190 |
-
|
191 |
-
Licensed under the Apache License, Version 2.0 (the "License");
|
192 |
-
you may not use this file except in compliance with the License.
|
193 |
-
You may obtain a copy of the License at
|
194 |
-
|
195 |
-
http://www.apache.org/licenses/LICENSE-2.0
|
196 |
-
|
197 |
-
Unless required by applicable law or agreed to in writing, software
|
198 |
-
distributed under the License is distributed on an "AS IS" BASIS,
|
199 |
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
200 |
-
See the License for the specific language governing permissions and
|
201 |
-
limitations under the License.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/README.md
DELETED
@@ -1,82 +0,0 @@
|
|
1 |
-
# AdaptiveWingLoss
|
2 |
-
## [arXiv](https://arxiv.org/abs/1904.07399)
|
3 |
-
Pytorch Implementation of Adaptive Wing Loss for Robust Face Alignment via Heatmap Regression.
|
4 |
-
|
5 |
-
<img src='images/wflw.png' width="1000px">
|
6 |
-
|
7 |
-
## Update Logs:
|
8 |
-
### October 28, 2019
|
9 |
-
* Pretrained Model and evaluation code on WFLW dataset is released.
|
10 |
-
|
11 |
-
## Installation
|
12 |
-
#### Note: Code was originally developed under Python2.X and Pytorch 0.4. This released version was revisioned from original code and was tested on Python3.5.7 and Pytorch 1.3.0.
|
13 |
-
|
14 |
-
Install system requirements:
|
15 |
-
```
|
16 |
-
sudo apt-get install python3-dev python3-pip python3-tk libglib2.0-0
|
17 |
-
```
|
18 |
-
|
19 |
-
Install python dependencies:
|
20 |
-
```
|
21 |
-
pip3 install -r requirements.txt
|
22 |
-
```
|
23 |
-
|
24 |
-
## Run Evaluation on WFLW dataset
|
25 |
-
1. Download and process WFLW dataset
|
26 |
-
* Download WFLW dataset and annotation from [Here](https://wywu.github.io/projects/LAB/WFLW.html).
|
27 |
-
* Unzip WFLW dataset and annotations and move files into ```./dataset``` directory. Your directory should look like this:
|
28 |
-
```
|
29 |
-
AdaptiveWingLoss
|
30 |
-
ββββdataset
|
31 |
-
β
|
32 |
-
ββββWFLW_annotations
|
33 |
-
β ββββlist_98pt_rect_attr_train_test
|
34 |
-
β β
|
35 |
-
β ββββlist_98pt_test
|
36 |
-
β
|
37 |
-
ββββWFLW_images
|
38 |
-
ββββ0--Parade
|
39 |
-
β
|
40 |
-
ββββ...
|
41 |
-
```
|
42 |
-
* Inside ```./dataset``` directory, run:
|
43 |
-
```
|
44 |
-
python convert_WFLW.py
|
45 |
-
```
|
46 |
-
A new directory ```./dataset/WFLW_test``` should be generated with 2500 processed testing images and corresponding landmarks.
|
47 |
-
|
48 |
-
2. Download pretrained model from [Google Drive](https://drive.google.com/file/d/1HZaSjLoorQ4QCEx7PRTxOmg0bBPYSqhH/view?usp=sharing) and put it in ```./ckpt``` directory.
|
49 |
-
|
50 |
-
3. Within ```./Scripts``` directory, run following command:
|
51 |
-
```
|
52 |
-
sh eval_wflw.sh
|
53 |
-
```
|
54 |
-
|
55 |
-
<img src='images/wflw_table.png' width="800px">
|
56 |
-
*GTBbox indicates the ground truth landmarks are used as bounding box to crop faces.
|
57 |
-
|
58 |
-
## Future Plans
|
59 |
-
- [x] Release evaluation code and pretrained model on WFLW dataset.
|
60 |
-
|
61 |
-
- [ ] Release training code on WFLW dataset.
|
62 |
-
|
63 |
-
- [ ] Release pretrained model and code on 300W, AFLW and COFW dataset.
|
64 |
-
|
65 |
-
- [ ] Replease facial landmark detection API
|
66 |
-
|
67 |
-
|
68 |
-
## Citation
|
69 |
-
If you find this useful for your research, please cite the following paper.
|
70 |
-
|
71 |
-
```
|
72 |
-
@InProceedings{Wang_2019_ICCV,
|
73 |
-
author = {Wang, Xinyao and Bo, Liefeng and Fuxin, Li},
|
74 |
-
title = {Adaptive Wing Loss for Robust Face Alignment via Heatmap Regression},
|
75 |
-
booktitle = {The IEEE International Conference on Computer Vision (ICCV)},
|
76 |
-
month = {October},
|
77 |
-
year = {2019}
|
78 |
-
}
|
79 |
-
```
|
80 |
-
|
81 |
-
## Acknowledgments
|
82 |
-
This repository borrows or partially modifies hourglass model and data processing code from [face alignment](https://github.com/1adrianb/face-alignment) and [pose-hg-train](https://github.com/princeton-vl/pose-hg-train).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/__init__.py
DELETED
File without changes
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/__pycache__/__init__.cpython-37.pyc
DELETED
Binary file (164 Bytes)
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/__pycache__/__init__.cpython-39.pyc
DELETED
Binary file (179 Bytes)
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/ckpt/.gitkeep
DELETED
File without changes
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/__init__.py
DELETED
File without changes
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/__pycache__/__init__.cpython-37.pyc
DELETED
Binary file (169 Bytes)
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/__pycache__/__init__.cpython-39.pyc
DELETED
Binary file (184 Bytes)
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/__pycache__/coord_conv.cpython-37.pyc
DELETED
Binary file (4.33 kB)
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/__pycache__/coord_conv.cpython-39.pyc
DELETED
Binary file (4.38 kB)
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/__pycache__/models.cpython-37.pyc
DELETED
Binary file (5.77 kB)
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/__pycache__/models.cpython-39.pyc
DELETED
Binary file (5.83 kB)
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/coord_conv.py
DELETED
@@ -1,157 +0,0 @@
|
|
1 |
-
import torch
|
2 |
-
import torch.nn as nn
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
7 |
-
|
8 |
-
class AddCoordsTh(nn.Module):
|
9 |
-
def __init__(self, x_dim=64, y_dim=64, with_r=False, with_boundary=False):
|
10 |
-
super(AddCoordsTh, self).__init__()
|
11 |
-
self.x_dim = x_dim
|
12 |
-
self.y_dim = y_dim
|
13 |
-
self.with_r = with_r
|
14 |
-
self.with_boundary = with_boundary
|
15 |
-
|
16 |
-
def forward(self, input_tensor, heatmap=None):
|
17 |
-
"""
|
18 |
-
input_tensor: (batch, c, x_dim, y_dim)
|
19 |
-
"""
|
20 |
-
batch_size_tensor = input_tensor.shape[0]
|
21 |
-
|
22 |
-
xx_ones = torch.ones([1, self.y_dim], dtype=torch.int32).to(device)
|
23 |
-
xx_ones = xx_ones.unsqueeze(-1)
|
24 |
-
|
25 |
-
xx_range = torch.arange(self.x_dim, dtype=torch.int32).unsqueeze(0).to(device)
|
26 |
-
xx_range = xx_range.unsqueeze(1)
|
27 |
-
|
28 |
-
xx_channel = torch.matmul(xx_ones.float(), xx_range.float())
|
29 |
-
xx_channel = xx_channel.unsqueeze(-1)
|
30 |
-
|
31 |
-
|
32 |
-
yy_ones = torch.ones([1, self.x_dim], dtype=torch.int32).to(device)
|
33 |
-
yy_ones = yy_ones.unsqueeze(1)
|
34 |
-
|
35 |
-
yy_range = torch.arange(self.y_dim, dtype=torch.int32).unsqueeze(0).to(device)
|
36 |
-
yy_range = yy_range.unsqueeze(-1)
|
37 |
-
|
38 |
-
yy_channel = torch.matmul(yy_range.float(), yy_ones.float())
|
39 |
-
yy_channel = yy_channel.unsqueeze(-1)
|
40 |
-
|
41 |
-
xx_channel = xx_channel.permute(0, 3, 2, 1)
|
42 |
-
yy_channel = yy_channel.permute(0, 3, 2, 1)
|
43 |
-
|
44 |
-
xx_channel = xx_channel / (self.x_dim - 1)
|
45 |
-
yy_channel = yy_channel / (self.y_dim - 1)
|
46 |
-
|
47 |
-
xx_channel = xx_channel * 2 - 1
|
48 |
-
yy_channel = yy_channel * 2 - 1
|
49 |
-
|
50 |
-
xx_channel = xx_channel.repeat(batch_size_tensor, 1, 1, 1)
|
51 |
-
yy_channel = yy_channel.repeat(batch_size_tensor, 1, 1, 1)
|
52 |
-
|
53 |
-
if self.with_boundary and type(heatmap) != type(None):
|
54 |
-
boundary_channel = torch.clamp(heatmap[:, -1:, :, :],
|
55 |
-
0.0, 1.0)
|
56 |
-
|
57 |
-
zero_tensor = torch.zeros_like(xx_channel)
|
58 |
-
xx_boundary_channel = torch.where(boundary_channel>0.05,
|
59 |
-
xx_channel, zero_tensor)
|
60 |
-
yy_boundary_channel = torch.where(boundary_channel>0.05,
|
61 |
-
yy_channel, zero_tensor)
|
62 |
-
if self.with_boundary and type(heatmap) != type(None):
|
63 |
-
xx_boundary_channel = xx_boundary_channel.to(device)
|
64 |
-
yy_boundary_channel = yy_boundary_channel.to(device)
|
65 |
-
|
66 |
-
ret = torch.cat([input_tensor, xx_channel, yy_channel], dim=1)
|
67 |
-
|
68 |
-
|
69 |
-
if self.with_r:
|
70 |
-
rr = torch.sqrt(torch.pow(xx_channel, 2) + torch.pow(yy_channel, 2))
|
71 |
-
rr = rr / torch.max(rr)
|
72 |
-
ret = torch.cat([ret, rr], dim=1)
|
73 |
-
|
74 |
-
if self.with_boundary and type(heatmap) != type(None):
|
75 |
-
ret = torch.cat([ret, xx_boundary_channel,
|
76 |
-
yy_boundary_channel], dim=1)
|
77 |
-
return ret
|
78 |
-
|
79 |
-
|
80 |
-
class CoordConvTh(nn.Module):
|
81 |
-
"""CoordConv layer as in the paper."""
|
82 |
-
def __init__(self, x_dim, y_dim, with_r, with_boundary,
|
83 |
-
in_channels, first_one=False, *args, **kwargs):
|
84 |
-
super(CoordConvTh, self).__init__()
|
85 |
-
self.addcoords = AddCoordsTh(x_dim=x_dim, y_dim=y_dim, with_r=with_r,
|
86 |
-
with_boundary=with_boundary)
|
87 |
-
in_channels += 2
|
88 |
-
if with_r:
|
89 |
-
in_channels += 1
|
90 |
-
if with_boundary and not first_one:
|
91 |
-
in_channels += 2
|
92 |
-
self.conv = nn.Conv2d(in_channels=in_channels, *args, **kwargs)
|
93 |
-
|
94 |
-
def forward(self, input_tensor, heatmap=None):
|
95 |
-
ret = self.addcoords(input_tensor, heatmap)
|
96 |
-
last_channel = ret[:, -2:, :, :]
|
97 |
-
ret = self.conv(ret)
|
98 |
-
return ret, last_channel
|
99 |
-
|
100 |
-
|
101 |
-
'''
|
102 |
-
An alternative implementation for PyTorch with auto-infering the x-y dimensions.
|
103 |
-
'''
|
104 |
-
class AddCoords(nn.Module):
|
105 |
-
|
106 |
-
def __init__(self, with_r=False):
|
107 |
-
super().__init__()
|
108 |
-
self.with_r = with_r
|
109 |
-
|
110 |
-
def forward(self, input_tensor):
|
111 |
-
"""
|
112 |
-
Args:
|
113 |
-
input_tensor: shape(batch, channel, x_dim, y_dim)
|
114 |
-
"""
|
115 |
-
batch_size, _, x_dim, y_dim = input_tensor.size()
|
116 |
-
|
117 |
-
xx_channel = torch.arange(x_dim).repeat(1, y_dim, 1)
|
118 |
-
yy_channel = torch.arange(y_dim).repeat(1, x_dim, 1).transpose(1, 2)
|
119 |
-
|
120 |
-
xx_channel = xx_channel / (x_dim - 1)
|
121 |
-
yy_channel = yy_channel / (y_dim - 1)
|
122 |
-
|
123 |
-
xx_channel = xx_channel * 2 - 1
|
124 |
-
yy_channel = yy_channel * 2 - 1
|
125 |
-
|
126 |
-
xx_channel = xx_channel.repeat(batch_size, 1, 1, 1).transpose(2, 3)
|
127 |
-
yy_channel = yy_channel.repeat(batch_size, 1, 1, 1).transpose(2, 3)
|
128 |
-
|
129 |
-
if input_tensor.is_cuda:
|
130 |
-
xx_channel = xx_channel.to(device)
|
131 |
-
yy_channel = yy_channel.to(device)
|
132 |
-
|
133 |
-
ret = torch.cat([
|
134 |
-
input_tensor,
|
135 |
-
xx_channel.type_as(input_tensor),
|
136 |
-
yy_channel.type_as(input_tensor)], dim=1)
|
137 |
-
|
138 |
-
if self.with_r:
|
139 |
-
rr = torch.sqrt(torch.pow(xx_channel - 0.5, 2) + torch.pow(yy_channel - 0.5, 2))
|
140 |
-
if input_tensor.is_cuda:
|
141 |
-
rr = rr.to(device)
|
142 |
-
ret = torch.cat([ret, rr], dim=1)
|
143 |
-
|
144 |
-
return ret
|
145 |
-
|
146 |
-
|
147 |
-
class CoordConv(nn.Module):
|
148 |
-
|
149 |
-
def __init__(self, in_channels, out_channels, with_r=False, **kwargs):
|
150 |
-
super().__init__()
|
151 |
-
self.addcoords = AddCoords(with_r=with_r)
|
152 |
-
self.conv = nn.Conv2d(in_channels + 2, out_channels, **kwargs)
|
153 |
-
|
154 |
-
def forward(self, x):
|
155 |
-
ret = self.addcoords(x)
|
156 |
-
ret = self.conv(ret)
|
157 |
-
return ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/dataloader.py
DELETED
@@ -1,368 +0,0 @@
|
|
1 |
-
import sys
|
2 |
-
import os
|
3 |
-
import random
|
4 |
-
import glob
|
5 |
-
import torch
|
6 |
-
from skimage import io
|
7 |
-
from skimage import transform as ski_transform
|
8 |
-
from skimage.color import rgb2gray
|
9 |
-
import scipy.io as sio
|
10 |
-
from scipy import interpolate
|
11 |
-
import numpy as np
|
12 |
-
import matplotlib.pyplot as plt
|
13 |
-
from torch.utils.data import Dataset, DataLoader
|
14 |
-
from torchvision import transforms, utils
|
15 |
-
from torchvision.transforms import Lambda, Compose
|
16 |
-
from torchvision.transforms.functional import adjust_brightness, adjust_contrast, adjust_saturation, adjust_hue
|
17 |
-
from utils.utils import cv_crop, cv_rotate, draw_gaussian, transform, power_transform, shuffle_lr, fig2data, generate_weight_map
|
18 |
-
from PIL import Image
|
19 |
-
import cv2
|
20 |
-
import copy
|
21 |
-
import math
|
22 |
-
from imgaug import augmenters as iaa
|
23 |
-
|
24 |
-
|
25 |
-
class AddBoundary(object):
|
26 |
-
def __init__(self, num_landmarks=68):
|
27 |
-
self.num_landmarks = num_landmarks
|
28 |
-
|
29 |
-
def __call__(self, sample):
|
30 |
-
landmarks_64 = np.floor(sample['landmarks'] / 4.0)
|
31 |
-
if self.num_landmarks == 68:
|
32 |
-
boundaries = {}
|
33 |
-
boundaries['cheek'] = landmarks_64[0:17]
|
34 |
-
boundaries['left_eyebrow'] = landmarks_64[17:22]
|
35 |
-
boundaries['right_eyebrow'] = landmarks_64[22:27]
|
36 |
-
boundaries['uper_left_eyelid'] = landmarks_64[36:40]
|
37 |
-
boundaries['lower_left_eyelid'] = np.array([landmarks_64[i] for i in [36, 41, 40, 39]])
|
38 |
-
boundaries['upper_right_eyelid'] = landmarks_64[42:46]
|
39 |
-
boundaries['lower_right_eyelid'] = np.array([landmarks_64[i] for i in [42, 47, 46, 45]])
|
40 |
-
boundaries['noise'] = landmarks_64[27:31]
|
41 |
-
boundaries['noise_bot'] = landmarks_64[31:36]
|
42 |
-
boundaries['upper_outer_lip'] = landmarks_64[48:55]
|
43 |
-
boundaries['upper_inner_lip'] = np.array([landmarks_64[i] for i in [60, 61, 62, 63, 64]])
|
44 |
-
boundaries['lower_outer_lip'] = np.array([landmarks_64[i] for i in [48, 59, 58, 57, 56, 55, 54]])
|
45 |
-
boundaries['lower_inner_lip'] = np.array([landmarks_64[i] for i in [60, 67, 66, 65, 64]])
|
46 |
-
elif self.num_landmarks == 98:
|
47 |
-
boundaries = {}
|
48 |
-
boundaries['cheek'] = landmarks_64[0:33]
|
49 |
-
boundaries['left_eyebrow'] = landmarks_64[33:38]
|
50 |
-
boundaries['right_eyebrow'] = landmarks_64[42:47]
|
51 |
-
boundaries['uper_left_eyelid'] = landmarks_64[60:65]
|
52 |
-
boundaries['lower_left_eyelid'] = np.array([landmarks_64[i] for i in [60, 67, 66, 65, 64]])
|
53 |
-
boundaries['upper_right_eyelid'] = landmarks_64[68:73]
|
54 |
-
boundaries['lower_right_eyelid'] = np.array([landmarks_64[i] for i in [68, 75, 74, 73, 72]])
|
55 |
-
boundaries['noise'] = landmarks_64[51:55]
|
56 |
-
boundaries['noise_bot'] = landmarks_64[55:60]
|
57 |
-
boundaries['upper_outer_lip'] = landmarks_64[76:83]
|
58 |
-
boundaries['upper_inner_lip'] = np.array([landmarks_64[i] for i in [88, 89, 90, 91, 92]])
|
59 |
-
boundaries['lower_outer_lip'] = np.array([landmarks_64[i] for i in [76, 87, 86, 85, 84, 83, 82]])
|
60 |
-
boundaries['lower_inner_lip'] = np.array([landmarks_64[i] for i in [88, 95, 94, 93, 92]])
|
61 |
-
elif self.num_landmarks == 19:
|
62 |
-
boundaries = {}
|
63 |
-
boundaries['left_eyebrow'] = landmarks_64[0:3]
|
64 |
-
boundaries['right_eyebrow'] = landmarks_64[3:5]
|
65 |
-
boundaries['left_eye'] = landmarks_64[6:9]
|
66 |
-
boundaries['right_eye'] = landmarks_64[9:12]
|
67 |
-
boundaries['noise'] = landmarks_64[12:15]
|
68 |
-
|
69 |
-
elif self.num_landmarks == 29:
|
70 |
-
boundaries = {}
|
71 |
-
boundaries['upper_left_eyebrow'] = np.stack([
|
72 |
-
landmarks_64[0],
|
73 |
-
landmarks_64[4],
|
74 |
-
landmarks_64[2]
|
75 |
-
], axis=0)
|
76 |
-
boundaries['lower_left_eyebrow'] = np.stack([
|
77 |
-
landmarks_64[0],
|
78 |
-
landmarks_64[5],
|
79 |
-
landmarks_64[2]
|
80 |
-
], axis=0)
|
81 |
-
boundaries['upper_right_eyebrow'] = np.stack([
|
82 |
-
landmarks_64[1],
|
83 |
-
landmarks_64[6],
|
84 |
-
landmarks_64[3]
|
85 |
-
], axis=0)
|
86 |
-
boundaries['lower_right_eyebrow'] = np.stack([
|
87 |
-
landmarks_64[1],
|
88 |
-
landmarks_64[7],
|
89 |
-
landmarks_64[3]
|
90 |
-
], axis=0)
|
91 |
-
boundaries['upper_left_eye'] = np.stack([
|
92 |
-
landmarks_64[8],
|
93 |
-
landmarks_64[12],
|
94 |
-
landmarks_64[10]
|
95 |
-
], axis=0)
|
96 |
-
boundaries['lower_left_eye'] = np.stack([
|
97 |
-
landmarks_64[8],
|
98 |
-
landmarks_64[13],
|
99 |
-
landmarks_64[10]
|
100 |
-
], axis=0)
|
101 |
-
boundaries['upper_right_eye'] = np.stack([
|
102 |
-
landmarks_64[9],
|
103 |
-
landmarks_64[14],
|
104 |
-
landmarks_64[11]
|
105 |
-
], axis=0)
|
106 |
-
boundaries['lower_right_eye'] = np.stack([
|
107 |
-
landmarks_64[9],
|
108 |
-
landmarks_64[15],
|
109 |
-
landmarks_64[11]
|
110 |
-
], axis=0)
|
111 |
-
boundaries['noise'] = np.stack([
|
112 |
-
landmarks_64[18],
|
113 |
-
landmarks_64[21],
|
114 |
-
landmarks_64[19]
|
115 |
-
], axis=0)
|
116 |
-
boundaries['outer_upper_lip'] = np.stack([
|
117 |
-
landmarks_64[22],
|
118 |
-
landmarks_64[24],
|
119 |
-
landmarks_64[23]
|
120 |
-
], axis=0)
|
121 |
-
boundaries['inner_upper_lip'] = np.stack([
|
122 |
-
landmarks_64[22],
|
123 |
-
landmarks_64[25],
|
124 |
-
landmarks_64[23]
|
125 |
-
], axis=0)
|
126 |
-
boundaries['outer_lower_lip'] = np.stack([
|
127 |
-
landmarks_64[22],
|
128 |
-
landmarks_64[26],
|
129 |
-
landmarks_64[23]
|
130 |
-
], axis=0)
|
131 |
-
boundaries['inner_lower_lip'] = np.stack([
|
132 |
-
landmarks_64[22],
|
133 |
-
landmarks_64[27],
|
134 |
-
landmarks_64[23]
|
135 |
-
], axis=0)
|
136 |
-
functions = {}
|
137 |
-
|
138 |
-
for key, points in boundaries.items():
|
139 |
-
temp = points[0]
|
140 |
-
new_points = points[0:1, :]
|
141 |
-
for point in points[1:]:
|
142 |
-
if point[0] == temp[0] and point[1] == temp[1]:
|
143 |
-
continue
|
144 |
-
else:
|
145 |
-
new_points = np.concatenate((new_points, np.expand_dims(point, 0)), axis=0)
|
146 |
-
temp = point
|
147 |
-
points = new_points
|
148 |
-
if points.shape[0] == 1:
|
149 |
-
points = np.concatenate((points, points+0.001), axis=0)
|
150 |
-
k = min(4, points.shape[0])
|
151 |
-
functions[key] = interpolate.splprep([points[:, 0], points[:, 1]], k=k-1,s=0)
|
152 |
-
|
153 |
-
boundary_map = np.zeros((64, 64))
|
154 |
-
|
155 |
-
fig = plt.figure(figsize=[64/96.0, 64/96.0], dpi=96)
|
156 |
-
|
157 |
-
ax = fig.add_axes([0, 0, 1, 1])
|
158 |
-
|
159 |
-
ax.axis('off')
|
160 |
-
|
161 |
-
ax.imshow(boundary_map, interpolation='nearest', cmap='gray')
|
162 |
-
#ax.scatter(landmarks[:, 0], landmarks[:, 1], s=1, marker=',', c='w')
|
163 |
-
|
164 |
-
for key in functions.keys():
|
165 |
-
xnew = np.arange(0, 1, 0.01)
|
166 |
-
out = interpolate.splev(xnew, functions[key][0], der=0)
|
167 |
-
plt.plot(out[0], out[1], ',', linewidth=1, color='w')
|
168 |
-
|
169 |
-
img = fig2data(fig)
|
170 |
-
|
171 |
-
plt.close()
|
172 |
-
|
173 |
-
sigma = 1
|
174 |
-
temp = 255-img[:,:,1]
|
175 |
-
temp = cv2.distanceTransform(temp, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
|
176 |
-
temp = temp.astype(np.float32)
|
177 |
-
temp = np.where(temp < 3*sigma, np.exp(-(temp*temp)/(2*sigma*sigma)), 0 )
|
178 |
-
|
179 |
-
fig = plt.figure(figsize=[64/96.0, 64/96.0], dpi=96)
|
180 |
-
|
181 |
-
ax = fig.add_axes([0, 0, 1, 1])
|
182 |
-
|
183 |
-
ax.axis('off')
|
184 |
-
ax.imshow(temp, cmap='gray')
|
185 |
-
plt.close()
|
186 |
-
|
187 |
-
boundary_map = fig2data(fig)
|
188 |
-
|
189 |
-
sample['boundary'] = boundary_map[:, :, 0]
|
190 |
-
|
191 |
-
return sample
|
192 |
-
|
193 |
-
class AddWeightMap(object):
|
194 |
-
def __call__(self, sample):
|
195 |
-
heatmap= sample['heatmap']
|
196 |
-
boundary = sample['boundary']
|
197 |
-
heatmap = np.concatenate((heatmap, np.expand_dims(boundary, axis=0)), 0)
|
198 |
-
weight_map = np.zeros_like(heatmap)
|
199 |
-
for i in range(heatmap.shape[0]):
|
200 |
-
weight_map[i] = generate_weight_map(weight_map[i],
|
201 |
-
heatmap[i])
|
202 |
-
sample['weight_map'] = weight_map
|
203 |
-
return sample
|
204 |
-
|
205 |
-
class ToTensor(object):
|
206 |
-
"""Convert ndarrays in sample to Tensors."""
|
207 |
-
|
208 |
-
def __call__(self, sample):
|
209 |
-
image, heatmap, landmarks, boundary, weight_map= sample['image'], sample['heatmap'], sample['landmarks'], sample['boundary'], sample['weight_map']
|
210 |
-
|
211 |
-
# swap color axis because
|
212 |
-
# numpy image: H x W x C
|
213 |
-
# torch image: C X H X W
|
214 |
-
if len(image.shape) == 2:
|
215 |
-
image = np.expand_dims(image, axis=2)
|
216 |
-
image_small = np.expand_dims(image_small, axis=2)
|
217 |
-
image = image.transpose((2, 0, 1))
|
218 |
-
boundary = np.expand_dims(boundary, axis=2)
|
219 |
-
boundary = boundary.transpose((2, 0, 1))
|
220 |
-
return {'image': torch.from_numpy(image).float().div(255.0),
|
221 |
-
'heatmap': torch.from_numpy(heatmap).float(),
|
222 |
-
'landmarks': torch.from_numpy(landmarks).float(),
|
223 |
-
'boundary': torch.from_numpy(boundary).float().div(255.0),
|
224 |
-
'weight_map': torch.from_numpy(weight_map).float()}
|
225 |
-
|
226 |
-
class FaceLandmarksDataset(Dataset):
|
227 |
-
"""Face Landmarks dataset."""
|
228 |
-
|
229 |
-
def __init__(self, img_dir, landmarks_dir, num_landmarks=68, gray_scale=False,
|
230 |
-
detect_face=False, enhance=False, center_shift=0,
|
231 |
-
transform=None,):
|
232 |
-
"""
|
233 |
-
Args:
|
234 |
-
landmark_dir (string): Path to the mat file with landmarks saved.
|
235 |
-
img_dir (string): Directory with all the images.
|
236 |
-
transform (callable, optional): Optional transform to be applied
|
237 |
-
on a sample.
|
238 |
-
"""
|
239 |
-
self.img_dir = img_dir
|
240 |
-
self.landmarks_dir = landmarks_dir
|
241 |
-
self.num_lanmdkars = num_landmarks
|
242 |
-
self.transform = transform
|
243 |
-
self.img_names = glob.glob(self.img_dir+'*.jpg') + \
|
244 |
-
glob.glob(self.img_dir+'*.png')
|
245 |
-
self.gray_scale = gray_scale
|
246 |
-
self.detect_face = detect_face
|
247 |
-
self.enhance = enhance
|
248 |
-
self.center_shift = center_shift
|
249 |
-
if self.detect_face:
|
250 |
-
self.face_detector = MTCNN(thresh=[0.5, 0.6, 0.7])
|
251 |
-
def __len__(self):
|
252 |
-
return len(self.img_names)
|
253 |
-
|
254 |
-
def __getitem__(self, idx):
|
255 |
-
img_name = self.img_names[idx]
|
256 |
-
pil_image = Image.open(img_name)
|
257 |
-
if pil_image.mode != "RGB":
|
258 |
-
# if input is grayscale image, convert it to 3 channel image
|
259 |
-
if self.enhance:
|
260 |
-
pil_image = power_transform(pil_image, 0.5)
|
261 |
-
temp_image = Image.new('RGB', pil_image.size)
|
262 |
-
temp_image.paste(pil_image)
|
263 |
-
pil_image = temp_image
|
264 |
-
image = np.array(pil_image)
|
265 |
-
if self.gray_scale:
|
266 |
-
image = rgb2gray(image)
|
267 |
-
image = np.expand_dims(image, axis=2)
|
268 |
-
image = np.concatenate((image, image, image), axis=2)
|
269 |
-
image = image * 255.0
|
270 |
-
image = image.astype(np.uint8)
|
271 |
-
if not self.detect_face:
|
272 |
-
center = [450//2, 450//2+0]
|
273 |
-
if self.center_shift != 0:
|
274 |
-
center[0] += int(np.random.uniform(-self.center_shift,
|
275 |
-
self.center_shift))
|
276 |
-
center[1] += int(np.random.uniform(-self.center_shift,
|
277 |
-
self.center_shift))
|
278 |
-
scale = 1.8
|
279 |
-
else:
|
280 |
-
detected_faces = self.face_detector.detect_image(image)
|
281 |
-
if len(detected_faces) > 0:
|
282 |
-
box = detected_faces[0]
|
283 |
-
left, top, right, bottom, _ = box
|
284 |
-
center = [right - (right - left) / 2.0,
|
285 |
-
bottom - (bottom - top) / 2.0]
|
286 |
-
center[1] = center[1] - (bottom - top) * 0.12
|
287 |
-
scale = (right - left + bottom - top) / 195.0
|
288 |
-
else:
|
289 |
-
center = [450//2, 450//2+0]
|
290 |
-
scale = 1.8
|
291 |
-
if self.center_shift != 0:
|
292 |
-
shift = self.center * self.center_shift / 450
|
293 |
-
center[0] += int(np.random.uniform(-shift, shift))
|
294 |
-
center[1] += int(np.random.uniform(-shift, shift))
|
295 |
-
base_name = os.path.basename(img_name)
|
296 |
-
landmarks_base_name = base_name[:-4] + '_pts.mat'
|
297 |
-
landmarks_name = os.path.join(self.landmarks_dir, landmarks_base_name)
|
298 |
-
if os.path.isfile(landmarks_name):
|
299 |
-
mat_data = sio.loadmat(landmarks_name)
|
300 |
-
landmarks = mat_data['pts_2d']
|
301 |
-
elif os.path.isfile(landmarks_name[:-8] + '.pts.npy'):
|
302 |
-
landmarks = np.load(landmarks_name[:-8] + '.pts.npy')
|
303 |
-
else:
|
304 |
-
landmarks = []
|
305 |
-
heatmap = []
|
306 |
-
|
307 |
-
if landmarks != []:
|
308 |
-
new_image, new_landmarks = cv_crop(image, landmarks, center,
|
309 |
-
scale, 256, self.center_shift)
|
310 |
-
tries = 0
|
311 |
-
while self.center_shift != 0 and tries < 5 and (np.max(new_landmarks) > 240 or np.min(new_landmarks) < 15):
|
312 |
-
center = [450//2, 450//2+0]
|
313 |
-
scale += 0.05
|
314 |
-
center[0] += int(np.random.uniform(-self.center_shift,
|
315 |
-
self.center_shift))
|
316 |
-
center[1] += int(np.random.uniform(-self.center_shift,
|
317 |
-
self.center_shift))
|
318 |
-
|
319 |
-
new_image, new_landmarks = cv_crop(image, landmarks,
|
320 |
-
center, scale, 256,
|
321 |
-
self.center_shift)
|
322 |
-
tries += 1
|
323 |
-
if np.max(new_landmarks) > 250 or np.min(new_landmarks) < 5:
|
324 |
-
center = [450//2, 450//2+0]
|
325 |
-
scale = 2.25
|
326 |
-
new_image, new_landmarks = cv_crop(image, landmarks,
|
327 |
-
center, scale, 256,
|
328 |
-
100)
|
329 |
-
assert (np.min(new_landmarks) > 0 and np.max(new_landmarks) < 256), \
|
330 |
-
"Landmarks out of boundary!"
|
331 |
-
image = new_image
|
332 |
-
landmarks = new_landmarks
|
333 |
-
heatmap = np.zeros((self.num_lanmdkars, 64, 64))
|
334 |
-
for i in range(self.num_lanmdkars):
|
335 |
-
if landmarks[i][0] > 0:
|
336 |
-
heatmap[i] = draw_gaussian(heatmap[i], landmarks[i]/4.0+1, 1)
|
337 |
-
sample = {'image': image, 'heatmap': heatmap, 'landmarks': landmarks}
|
338 |
-
if self.transform:
|
339 |
-
sample = self.transform(sample)
|
340 |
-
|
341 |
-
return sample
|
342 |
-
|
343 |
-
def get_dataset(val_img_dir, val_landmarks_dir, batch_size,
|
344 |
-
num_landmarks=68, rotation=0, scale=0,
|
345 |
-
center_shift=0, random_flip=False,
|
346 |
-
brightness=0, contrast=0, saturation=0,
|
347 |
-
blur=False, noise=False, jpeg_effect=False,
|
348 |
-
random_occlusion=False, gray_scale=False,
|
349 |
-
detect_face=False, enhance=False):
|
350 |
-
val_transforms = transforms.Compose([AddBoundary(num_landmarks),
|
351 |
-
AddWeightMap(),
|
352 |
-
ToTensor()])
|
353 |
-
|
354 |
-
val_dataset = FaceLandmarksDataset(val_img_dir, val_landmarks_dir,
|
355 |
-
num_landmarks=num_landmarks,
|
356 |
-
gray_scale=gray_scale,
|
357 |
-
detect_face=detect_face,
|
358 |
-
enhance=enhance,
|
359 |
-
transform=val_transforms)
|
360 |
-
|
361 |
-
val_dataloader = torch.utils.data.DataLoader(val_dataset,
|
362 |
-
batch_size=batch_size,
|
363 |
-
shuffle=False,
|
364 |
-
num_workers=6)
|
365 |
-
data_loaders = {'val': val_dataloader}
|
366 |
-
dataset_sizes = {}
|
367 |
-
dataset_sizes['val'] = len(val_dataset)
|
368 |
-
return data_loaders, dataset_sizes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/evaler.py
DELETED
@@ -1,151 +0,0 @@
|
|
1 |
-
import matplotlib
|
2 |
-
matplotlib.use('Agg')
|
3 |
-
import math
|
4 |
-
import torch
|
5 |
-
import copy
|
6 |
-
import time
|
7 |
-
from torch.autograd import Variable
|
8 |
-
import shutil
|
9 |
-
from skimage import io
|
10 |
-
import numpy as np
|
11 |
-
from utils.utils import fan_NME, show_landmarks, get_preds_fromhm
|
12 |
-
from PIL import Image, ImageDraw
|
13 |
-
import os
|
14 |
-
import sys
|
15 |
-
import cv2
|
16 |
-
import matplotlib.pyplot as plt
|
17 |
-
|
18 |
-
|
19 |
-
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
20 |
-
|
21 |
-
def eval_model(model, dataloaders, dataset_sizes,
|
22 |
-
writer, use_gpu=True, epoches=5, dataset='val',
|
23 |
-
save_path='./', num_landmarks=68):
|
24 |
-
global_nme = 0
|
25 |
-
model.eval()
|
26 |
-
for epoch in range(epoches):
|
27 |
-
running_loss = 0
|
28 |
-
step = 0
|
29 |
-
total_nme = 0
|
30 |
-
total_count = 0
|
31 |
-
fail_count = 0
|
32 |
-
nmes = []
|
33 |
-
# running_corrects = 0
|
34 |
-
|
35 |
-
# Iterate over data.
|
36 |
-
with torch.no_grad():
|
37 |
-
for data in dataloaders[dataset]:
|
38 |
-
total_runtime = 0
|
39 |
-
run_count = 0
|
40 |
-
step_start = time.time()
|
41 |
-
step += 1
|
42 |
-
# get the inputs
|
43 |
-
inputs = data['image'].type(torch.FloatTensor)
|
44 |
-
labels_heatmap = data['heatmap'].type(torch.FloatTensor)
|
45 |
-
labels_boundary = data['boundary'].type(torch.FloatTensor)
|
46 |
-
landmarks = data['landmarks'].type(torch.FloatTensor)
|
47 |
-
loss_weight_map = data['weight_map'].type(torch.FloatTensor)
|
48 |
-
# wrap them in Variable
|
49 |
-
if use_gpu:
|
50 |
-
inputs = inputs.to(device)
|
51 |
-
labels_heatmap = labels_heatmap.to(device)
|
52 |
-
labels_boundary = labels_boundary.to(device)
|
53 |
-
loss_weight_map = loss_weight_map.to(device)
|
54 |
-
else:
|
55 |
-
inputs, labels_heatmap = Variable(inputs), Variable(labels_heatmap)
|
56 |
-
labels_boundary = Variable(labels_boundary)
|
57 |
-
labels = torch.cat((labels_heatmap, labels_boundary), 1)
|
58 |
-
single_start = time.time()
|
59 |
-
outputs, boundary_channels = model(inputs)
|
60 |
-
single_end = time.time()
|
61 |
-
total_runtime += time.time() - single_start
|
62 |
-
run_count += 1
|
63 |
-
step_end = time.time()
|
64 |
-
for i in range(inputs.shape[0]):
|
65 |
-
print(inputs.shape)
|
66 |
-
img = inputs[i]
|
67 |
-
img = img.cpu().numpy()
|
68 |
-
img = img.transpose((1, 2, 0)) #*255.0
|
69 |
-
# img = img.astype(np.uint8)
|
70 |
-
# img = Image.fromarray(img)
|
71 |
-
# pred_heatmap = outputs[-1][i].detach().cpu()[:-1, :, :]
|
72 |
-
pred_heatmap = outputs[-1][:, :-1, :, :][i].detach().cpu()
|
73 |
-
pred_landmarks, _ = get_preds_fromhm(pred_heatmap.unsqueeze(0))
|
74 |
-
pred_landmarks = pred_landmarks.squeeze().numpy()
|
75 |
-
|
76 |
-
gt_landmarks = data['landmarks'][i].numpy()
|
77 |
-
print(pred_landmarks, gt_landmarks)
|
78 |
-
import cv2
|
79 |
-
while(True):
|
80 |
-
imgshow = vis_landmark_on_img(cv2.UMat(img), pred_landmarks*4)
|
81 |
-
cv2.imshow('img', imgshow)
|
82 |
-
|
83 |
-
if(cv2.waitKey(10) == ord('q')):
|
84 |
-
break
|
85 |
-
|
86 |
-
|
87 |
-
if num_landmarks == 68:
|
88 |
-
left_eye = np.average(gt_landmarks[36:42], axis=0)
|
89 |
-
right_eye = np.average(gt_landmarks[42:48], axis=0)
|
90 |
-
norm_factor = np.linalg.norm(left_eye - right_eye)
|
91 |
-
# norm_factor = np.linalg.norm(gt_landmarks[36]- gt_landmarks[45])
|
92 |
-
|
93 |
-
elif num_landmarks == 98:
|
94 |
-
norm_factor = np.linalg.norm(gt_landmarks[60]- gt_landmarks[72])
|
95 |
-
elif num_landmarks == 19:
|
96 |
-
left, top = gt_landmarks[-2, :]
|
97 |
-
right, bottom = gt_landmarks[-1, :]
|
98 |
-
norm_factor = math.sqrt(abs(right - left)*abs(top-bottom))
|
99 |
-
gt_landmarks = gt_landmarks[:-2, :]
|
100 |
-
elif num_landmarks == 29:
|
101 |
-
# norm_factor = np.linalg.norm(gt_landmarks[8]- gt_landmarks[9])
|
102 |
-
norm_factor = np.linalg.norm(gt_landmarks[16]- gt_landmarks[17])
|
103 |
-
single_nme = (np.sum(np.linalg.norm(pred_landmarks*4 - gt_landmarks, axis=1)) / pred_landmarks.shape[0]) / norm_factor
|
104 |
-
|
105 |
-
nmes.append(single_nme)
|
106 |
-
total_count += 1
|
107 |
-
if single_nme > 0.1:
|
108 |
-
fail_count += 1
|
109 |
-
if step % 10 == 0:
|
110 |
-
print('Step {} Time: {:.6f} Input Mean: {:.6f} Output Mean: {:.6f}'.format(
|
111 |
-
step, step_end - step_start,
|
112 |
-
torch.mean(labels),
|
113 |
-
torch.mean(outputs[0])))
|
114 |
-
# gt_landmarks = landmarks.numpy()
|
115 |
-
# pred_heatmap = outputs[-1].to('cpu').numpy()
|
116 |
-
gt_landmarks = landmarks
|
117 |
-
batch_nme = fan_NME(outputs[-1][:, :-1, :, :].detach().cpu(), gt_landmarks, num_landmarks)
|
118 |
-
# batch_nme = 0
|
119 |
-
total_nme += batch_nme
|
120 |
-
epoch_nme = total_nme / dataset_sizes['val']
|
121 |
-
global_nme += epoch_nme
|
122 |
-
nme_save_path = os.path.join(save_path, 'nme_log.npy')
|
123 |
-
np.save(nme_save_path, np.array(nmes))
|
124 |
-
print('NME: {:.6f} Failure Rate: {:.6f} Total Count: {:.6f} Fail Count: {:.6f}'.format(epoch_nme, fail_count/total_count, total_count, fail_count))
|
125 |
-
print('Evaluation done! Average NME: {:.6f}'.format(global_nme/epoches))
|
126 |
-
print('Everage runtime for a single batch: {:.6f}'.format(total_runtime/run_count))
|
127 |
-
return model
|
128 |
-
|
129 |
-
|
130 |
-
def vis_landmark_on_img(img, shape, linewidth=2):
|
131 |
-
'''
|
132 |
-
Visualize landmark on images.
|
133 |
-
'''
|
134 |
-
|
135 |
-
def draw_curve(idx_list, color=(0, 255, 0), loop=False, lineWidth=linewidth):
|
136 |
-
for i in idx_list:
|
137 |
-
cv2.line(img, (shape[i, 0], shape[i, 1]), (shape[i + 1, 0], shape[i + 1, 1]), color, lineWidth)
|
138 |
-
if (loop):
|
139 |
-
cv2.line(img, (shape[idx_list[0], 0], shape[idx_list[0], 1]),
|
140 |
-
(shape[idx_list[-1] + 1, 0], shape[idx_list[-1] + 1, 1]), color, lineWidth)
|
141 |
-
|
142 |
-
draw_curve(list(range(0, 32))) # jaw
|
143 |
-
draw_curve(list(range(33, 41)), color=(0, 0, 255), loop=True) # eye brow
|
144 |
-
draw_curve(list(range(42, 50)), color=(0, 0, 255), loop=True)
|
145 |
-
draw_curve(list(range(51, 59))) # nose
|
146 |
-
draw_curve(list(range(60, 67)), loop=True) # eyes
|
147 |
-
draw_curve(list(range(68, 75)), loop=True)
|
148 |
-
draw_curve(list(range(76, 87)), loop=True, color=(0, 255, 255)) # mouth
|
149 |
-
draw_curve(list(range(88, 95)), loop=True, color=(255, 255, 0))
|
150 |
-
|
151 |
-
return img
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/core/models.py
DELETED
@@ -1,228 +0,0 @@
|
|
1 |
-
import torch
|
2 |
-
import torch.nn as nn
|
3 |
-
import torch.nn.functional as F
|
4 |
-
import math
|
5 |
-
from core.coord_conv import CoordConvTh
|
6 |
-
|
7 |
-
|
8 |
-
def conv3x3(in_planes, out_planes, strd=1, padding=1,
|
9 |
-
bias=False,dilation=1):
|
10 |
-
"3x3 convolution with padding"
|
11 |
-
return nn.Conv2d(in_planes, out_planes, kernel_size=3,
|
12 |
-
stride=strd, padding=padding, bias=bias,
|
13 |
-
dilation=dilation)
|
14 |
-
|
15 |
-
class BasicBlock(nn.Module):
|
16 |
-
expansion = 1
|
17 |
-
|
18 |
-
def __init__(self, inplanes, planes, stride=1, downsample=None):
|
19 |
-
super(BasicBlock, self).__init__()
|
20 |
-
self.conv1 = conv3x3(inplanes, planes, stride)
|
21 |
-
# self.bn1 = nn.BatchNorm2d(planes)
|
22 |
-
self.relu = nn.ReLU(inplace=True)
|
23 |
-
self.conv2 = conv3x3(planes, planes)
|
24 |
-
# self.bn2 = nn.BatchNorm2d(planes)
|
25 |
-
self.downsample = downsample
|
26 |
-
self.stride = stride
|
27 |
-
|
28 |
-
def forward(self, x):
|
29 |
-
residual = x
|
30 |
-
|
31 |
-
out = self.conv1(x)
|
32 |
-
# out = self.bn1(out)
|
33 |
-
out = self.relu(out)
|
34 |
-
|
35 |
-
out = self.conv2(out)
|
36 |
-
# out = self.bn2(out)
|
37 |
-
|
38 |
-
if self.downsample is not None:
|
39 |
-
residual = self.downsample(x)
|
40 |
-
|
41 |
-
out += residual
|
42 |
-
out = self.relu(out)
|
43 |
-
|
44 |
-
return out
|
45 |
-
|
46 |
-
class ConvBlock(nn.Module):
|
47 |
-
def __init__(self, in_planes, out_planes):
|
48 |
-
super(ConvBlock, self).__init__()
|
49 |
-
self.bn1 = nn.BatchNorm2d(in_planes)
|
50 |
-
self.conv1 = conv3x3(in_planes, int(out_planes / 2))
|
51 |
-
self.bn2 = nn.BatchNorm2d(int(out_planes / 2))
|
52 |
-
self.conv2 = conv3x3(int(out_planes / 2), int(out_planes / 4),
|
53 |
-
padding=1, dilation=1)
|
54 |
-
self.bn3 = nn.BatchNorm2d(int(out_planes / 4))
|
55 |
-
self.conv3 = conv3x3(int(out_planes / 4), int(out_planes / 4),
|
56 |
-
padding=1, dilation=1)
|
57 |
-
|
58 |
-
if in_planes != out_planes:
|
59 |
-
self.downsample = nn.Sequential(
|
60 |
-
nn.BatchNorm2d(in_planes),
|
61 |
-
nn.ReLU(True),
|
62 |
-
nn.Conv2d(in_planes, out_planes,
|
63 |
-
kernel_size=1, stride=1, bias=False),
|
64 |
-
)
|
65 |
-
else:
|
66 |
-
self.downsample = None
|
67 |
-
|
68 |
-
def forward(self, x):
|
69 |
-
residual = x
|
70 |
-
|
71 |
-
out1 = self.bn1(x)
|
72 |
-
out1 = F.relu(out1, True)
|
73 |
-
out1 = self.conv1(out1)
|
74 |
-
|
75 |
-
out2 = self.bn2(out1)
|
76 |
-
out2 = F.relu(out2, True)
|
77 |
-
out2 = self.conv2(out2)
|
78 |
-
|
79 |
-
out3 = self.bn3(out2)
|
80 |
-
out3 = F.relu(out3, True)
|
81 |
-
out3 = self.conv3(out3)
|
82 |
-
|
83 |
-
out3 = torch.cat((out1, out2, out3), 1)
|
84 |
-
|
85 |
-
if self.downsample is not None:
|
86 |
-
residual = self.downsample(residual)
|
87 |
-
|
88 |
-
out3 += residual
|
89 |
-
|
90 |
-
return out3
|
91 |
-
|
92 |
-
class HourGlass(nn.Module):
|
93 |
-
def __init__(self, num_modules, depth, num_features, first_one=False):
|
94 |
-
super(HourGlass, self).__init__()
|
95 |
-
self.num_modules = num_modules
|
96 |
-
self.depth = depth
|
97 |
-
self.features = num_features
|
98 |
-
self.coordconv = CoordConvTh(x_dim=64, y_dim=64,
|
99 |
-
with_r=True, with_boundary=True,
|
100 |
-
in_channels=256, first_one=first_one,
|
101 |
-
out_channels=256,
|
102 |
-
kernel_size=1,
|
103 |
-
stride=1, padding=0)
|
104 |
-
self._generate_network(self.depth)
|
105 |
-
|
106 |
-
def _generate_network(self, level):
|
107 |
-
self.add_module('b1_' + str(level), ConvBlock(256, 256))
|
108 |
-
|
109 |
-
self.add_module('b2_' + str(level), ConvBlock(256, 256))
|
110 |
-
|
111 |
-
if level > 1:
|
112 |
-
self._generate_network(level - 1)
|
113 |
-
else:
|
114 |
-
self.add_module('b2_plus_' + str(level), ConvBlock(256, 256))
|
115 |
-
|
116 |
-
self.add_module('b3_' + str(level), ConvBlock(256, 256))
|
117 |
-
|
118 |
-
def _forward(self, level, inp):
|
119 |
-
# Upper branch
|
120 |
-
up1 = inp
|
121 |
-
up1 = self._modules['b1_' + str(level)](up1)
|
122 |
-
|
123 |
-
# Lower branch
|
124 |
-
low1 = F.avg_pool2d(inp, 2, stride=2)
|
125 |
-
low1 = self._modules['b2_' + str(level)](low1)
|
126 |
-
|
127 |
-
if level > 1:
|
128 |
-
low2 = self._forward(level - 1, low1)
|
129 |
-
else:
|
130 |
-
low2 = low1
|
131 |
-
low2 = self._modules['b2_plus_' + str(level)](low2)
|
132 |
-
|
133 |
-
low3 = low2
|
134 |
-
low3 = self._modules['b3_' + str(level)](low3)
|
135 |
-
|
136 |
-
up2 = F.upsample(low3, scale_factor=2, mode='nearest')
|
137 |
-
|
138 |
-
return up1 + up2
|
139 |
-
|
140 |
-
def forward(self, x, heatmap):
|
141 |
-
x, last_channel = self.coordconv(x, heatmap)
|
142 |
-
return self._forward(self.depth, x), last_channel
|
143 |
-
|
144 |
-
class FAN(nn.Module):
|
145 |
-
|
146 |
-
def __init__(self, num_modules=1, end_relu=False, gray_scale=False,
|
147 |
-
num_landmarks=68):
|
148 |
-
super(FAN, self).__init__()
|
149 |
-
self.num_modules = num_modules
|
150 |
-
self.gray_scale = gray_scale
|
151 |
-
self.end_relu = end_relu
|
152 |
-
self.num_landmarks = num_landmarks
|
153 |
-
|
154 |
-
# Base part
|
155 |
-
if self.gray_scale:
|
156 |
-
self.conv1 = CoordConvTh(x_dim=256, y_dim=256,
|
157 |
-
with_r=True, with_boundary=False,
|
158 |
-
in_channels=3, out_channels=64,
|
159 |
-
kernel_size=7,
|
160 |
-
stride=2, padding=3)
|
161 |
-
else:
|
162 |
-
self.conv1 = CoordConvTh(x_dim=256, y_dim=256,
|
163 |
-
with_r=True, with_boundary=False,
|
164 |
-
in_channels=3, out_channels=64,
|
165 |
-
kernel_size=7,
|
166 |
-
stride=2, padding=3)
|
167 |
-
self.bn1 = nn.BatchNorm2d(64)
|
168 |
-
self.conv2 = ConvBlock(64, 128)
|
169 |
-
self.conv3 = ConvBlock(128, 128)
|
170 |
-
self.conv4 = ConvBlock(128, 256)
|
171 |
-
|
172 |
-
# Stacking part
|
173 |
-
for hg_module in range(self.num_modules):
|
174 |
-
if hg_module == 0:
|
175 |
-
first_one = True
|
176 |
-
else:
|
177 |
-
first_one = False
|
178 |
-
self.add_module('m' + str(hg_module), HourGlass(1, 4, 256,
|
179 |
-
first_one))
|
180 |
-
self.add_module('top_m_' + str(hg_module), ConvBlock(256, 256))
|
181 |
-
self.add_module('conv_last' + str(hg_module),
|
182 |
-
nn.Conv2d(256, 256, kernel_size=1, stride=1, padding=0))
|
183 |
-
self.add_module('bn_end' + str(hg_module), nn.BatchNorm2d(256))
|
184 |
-
self.add_module('l' + str(hg_module), nn.Conv2d(256,
|
185 |
-
num_landmarks+1, kernel_size=1, stride=1, padding=0))
|
186 |
-
|
187 |
-
if hg_module < self.num_modules - 1:
|
188 |
-
self.add_module(
|
189 |
-
'bl' + str(hg_module), nn.Conv2d(256, 256, kernel_size=1, stride=1, padding=0))
|
190 |
-
self.add_module('al' + str(hg_module), nn.Conv2d(num_landmarks+1,
|
191 |
-
256, kernel_size=1, stride=1, padding=0))
|
192 |
-
|
193 |
-
def forward(self, x):
|
194 |
-
x, _ = self.conv1(x)
|
195 |
-
x = F.relu(self.bn1(x), True)
|
196 |
-
# x = F.relu(self.bn1(self.conv1(x)), True)
|
197 |
-
x = F.avg_pool2d(self.conv2(x), 2, stride=2)
|
198 |
-
x = self.conv3(x)
|
199 |
-
x = self.conv4(x)
|
200 |
-
|
201 |
-
previous = x
|
202 |
-
|
203 |
-
outputs = []
|
204 |
-
boundary_channels = []
|
205 |
-
tmp_out = None
|
206 |
-
for i in range(self.num_modules):
|
207 |
-
hg, boundary_channel = self._modules['m' + str(i)](previous,
|
208 |
-
tmp_out)
|
209 |
-
|
210 |
-
ll = hg
|
211 |
-
ll = self._modules['top_m_' + str(i)](ll)
|
212 |
-
|
213 |
-
ll = F.relu(self._modules['bn_end' + str(i)]
|
214 |
-
(self._modules['conv_last' + str(i)](ll)), True)
|
215 |
-
|
216 |
-
# Predict heatmaps
|
217 |
-
tmp_out = self._modules['l' + str(i)](ll)
|
218 |
-
if self.end_relu:
|
219 |
-
tmp_out = F.relu(tmp_out) # HACK: Added relu
|
220 |
-
outputs.append(tmp_out)
|
221 |
-
boundary_channels.append(boundary_channel)
|
222 |
-
|
223 |
-
if i < self.num_modules - 1:
|
224 |
-
ll = self._modules['bl' + str(i)](ll)
|
225 |
-
tmp_out_ = self._modules['al' + str(i)](tmp_out)
|
226 |
-
previous = previous + ll + tmp_out_
|
227 |
-
|
228 |
-
return outputs, boundary_channels
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/eval.py
DELETED
@@ -1,77 +0,0 @@
|
|
1 |
-
from __future__ import print_function, division
|
2 |
-
import torch
|
3 |
-
import argparse
|
4 |
-
import numpy as np
|
5 |
-
import torch.nn as nn
|
6 |
-
import time
|
7 |
-
import os
|
8 |
-
from core.evaler import eval_model
|
9 |
-
from core.dataloader import get_dataset
|
10 |
-
from core import models
|
11 |
-
from tensorboardX import SummaryWriter
|
12 |
-
|
13 |
-
# Parse arguments
|
14 |
-
parser = argparse.ArgumentParser()
|
15 |
-
# Dataset paths
|
16 |
-
parser.add_argument('--val_img_dir', type=str,
|
17 |
-
help='Validation image directory')
|
18 |
-
parser.add_argument('--val_landmarks_dir', type=str,
|
19 |
-
help='Validation landmarks directory')
|
20 |
-
parser.add_argument('--num_landmarks', type=int, default=68,
|
21 |
-
help='Number of landmarks')
|
22 |
-
|
23 |
-
# Checkpoint and pretrained weights
|
24 |
-
parser.add_argument('--ckpt_save_path', type=str,
|
25 |
-
help='a directory to save checkpoint file')
|
26 |
-
parser.add_argument('--pretrained_weights', type=str,
|
27 |
-
help='a directory to save pretrained_weights')
|
28 |
-
|
29 |
-
# Eval options
|
30 |
-
parser.add_argument('--batch_size', type=int, default=25,
|
31 |
-
help='learning rate decay after each epoch')
|
32 |
-
|
33 |
-
# Network parameters
|
34 |
-
parser.add_argument('--hg_blocks', type=int, default=4,
|
35 |
-
help='Number of HG blocks to stack')
|
36 |
-
parser.add_argument('--gray_scale', type=str, default="False",
|
37 |
-
help='Whether to convert RGB image into gray scale during training')
|
38 |
-
parser.add_argument('--end_relu', type=str, default="False",
|
39 |
-
help='Whether to add relu at the end of each HG module')
|
40 |
-
|
41 |
-
args = parser.parse_args()
|
42 |
-
|
43 |
-
VAL_IMG_DIR = args.val_img_dir
|
44 |
-
VAL_LANDMARKS_DIR = args.val_landmarks_dir
|
45 |
-
CKPT_SAVE_PATH = args.ckpt_save_path
|
46 |
-
BATCH_SIZE = args.batch_size
|
47 |
-
PRETRAINED_WEIGHTS = args.pretrained_weights
|
48 |
-
GRAY_SCALE = False if args.gray_scale == 'False' else True
|
49 |
-
HG_BLOCKS = args.hg_blocks
|
50 |
-
END_RELU = False if args.end_relu == 'False' else True
|
51 |
-
NUM_LANDMARKS = args.num_landmarks
|
52 |
-
|
53 |
-
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
54 |
-
|
55 |
-
writer = SummaryWriter(CKPT_SAVE_PATH)
|
56 |
-
|
57 |
-
dataloaders, dataset_sizes = get_dataset(VAL_IMG_DIR, VAL_LANDMARKS_DIR,
|
58 |
-
BATCH_SIZE, NUM_LANDMARKS)
|
59 |
-
use_gpu = torch.cuda.is_available()
|
60 |
-
model_ft = models.FAN(HG_BLOCKS, END_RELU, GRAY_SCALE, NUM_LANDMARKS)
|
61 |
-
|
62 |
-
if PRETRAINED_WEIGHTS != "None":
|
63 |
-
checkpoint = torch.load(PRETRAINED_WEIGHTS)
|
64 |
-
if 'state_dict' not in checkpoint:
|
65 |
-
model_ft.load_state_dict(checkpoint)
|
66 |
-
else:
|
67 |
-
pretrained_weights = checkpoint['state_dict']
|
68 |
-
model_weights = model_ft.state_dict()
|
69 |
-
pretrained_weights = {k: v for k, v in pretrained_weights.items() \
|
70 |
-
if k in model_weights}
|
71 |
-
model_weights.update(pretrained_weights)
|
72 |
-
model_ft.load_state_dict(model_weights)
|
73 |
-
|
74 |
-
model_ft = model_ft.to(device)
|
75 |
-
|
76 |
-
model_ft = eval_model(model_ft, dataloaders, dataset_sizes, writer, use_gpu, 1, 'val', CKPT_SAVE_PATH, NUM_LANDMARKS)
|
77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/images/wflw.png
DELETED
Git LFS Details
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/images/wflw_table.png
DELETED
Git LFS Details
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/requirements.txt
DELETED
@@ -1,12 +0,0 @@
|
|
1 |
-
opencv-python
|
2 |
-
scipy>=0.17.0
|
3 |
-
scikit-image
|
4 |
-
numpy
|
5 |
-
matplotlib
|
6 |
-
Pillow>=4.3.0
|
7 |
-
imgaug
|
8 |
-
tensorflow
|
9 |
-
git+https://github.com/lanpa/tensorboardX
|
10 |
-
joblib
|
11 |
-
torch==1.3.0
|
12 |
-
torchvision==0.4.1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/scripts/eval_wflw.sh
DELETED
@@ -1,10 +0,0 @@
|
|
1 |
-
CUDA_VISIBLE_DEVICES=1 python ../eval.py \
|
2 |
-
--val_img_dir='../dataset/WFLW_test/images/' \
|
3 |
-
--val_landmarks_dir='../dataset/WFLW_test/landmarks/' \
|
4 |
-
--ckpt_save_path='../experiments/eval_iccv_0620' \
|
5 |
-
--hg_blocks=4 \
|
6 |
-
--pretrained_weights='../ckpt/WFLW_4HG.pth' \
|
7 |
-
--num_landmarks=98 \
|
8 |
-
--end_relu='False' \
|
9 |
-
--batch_size=20 \
|
10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/utils/__init__.py
DELETED
File without changes
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/utils/__pycache__/__init__.cpython-37.pyc
DELETED
Binary file (170 Bytes)
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/utils/__pycache__/__init__.cpython-39.pyc
DELETED
Binary file (185 Bytes)
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/utils/__pycache__/utils.cpython-37.pyc
DELETED
Binary file (11.8 kB)
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/utils/__pycache__/utils.cpython-39.pyc
DELETED
Binary file (11.6 kB)
|
|
marlenezw/audio-driven-animations/MakeItTalk/AdaptiveWingLoss/utils/utils.py
DELETED
@@ -1,354 +0,0 @@
|
|
1 |
-
from __future__ import print_function, division
|
2 |
-
import os
|
3 |
-
import sys
|
4 |
-
import math
|
5 |
-
import torch
|
6 |
-
import cv2
|
7 |
-
from PIL import Image
|
8 |
-
from skimage import io
|
9 |
-
from skimage import transform as ski_transform
|
10 |
-
from scipy import ndimage
|
11 |
-
import numpy as np
|
12 |
-
import matplotlib
|
13 |
-
import matplotlib.pyplot as plt
|
14 |
-
from torch.utils.data import Dataset, DataLoader
|
15 |
-
from torchvision import transforms, utils
|
16 |
-
|
17 |
-
def _gaussian(
|
18 |
-
size=3, sigma=0.25, amplitude=1, normalize=False, width=None,
|
19 |
-
height=None, sigma_horz=None, sigma_vert=None, mean_horz=0.5,
|
20 |
-
mean_vert=0.5):
|
21 |
-
# handle some defaults
|
22 |
-
if width is None:
|
23 |
-
width = size
|
24 |
-
if height is None:
|
25 |
-
height = size
|
26 |
-
if sigma_horz is None:
|
27 |
-
sigma_horz = sigma
|
28 |
-
if sigma_vert is None:
|
29 |
-
sigma_vert = sigma
|
30 |
-
center_x = mean_horz * width + 0.5
|
31 |
-
center_y = mean_vert * height + 0.5
|
32 |
-
gauss = np.empty((height, width), dtype=np.float32)
|
33 |
-
# generate kernel
|
34 |
-
for i in range(height):
|
35 |
-
for j in range(width):
|
36 |
-
gauss[i][j] = amplitude * math.exp(-(math.pow((j + 1 - center_x) / (
|
37 |
-
sigma_horz * width), 2) / 2.0 + math.pow((i + 1 - center_y) / (sigma_vert * height), 2) / 2.0))
|
38 |
-
if normalize:
|
39 |
-
gauss = gauss / np.sum(gauss)
|
40 |
-
return gauss
|
41 |
-
|
42 |
-
def draw_gaussian(image, point, sigma):
|
43 |
-
# Check if the gaussian is inside
|
44 |
-
ul = [np.floor(np.floor(point[0]) - 3 * sigma),
|
45 |
-
np.floor(np.floor(point[1]) - 3 * sigma)]
|
46 |
-
br = [np.floor(np.floor(point[0]) + 3 * sigma),
|
47 |
-
np.floor(np.floor(point[1]) + 3 * sigma)]
|
48 |
-
if (ul[0] > image.shape[1] or ul[1] >
|
49 |
-
image.shape[0] or br[0] < 1 or br[1] < 1):
|
50 |
-
return image
|
51 |
-
size = 6 * sigma + 1
|
52 |
-
g = _gaussian(size)
|
53 |
-
g_x = [int(max(1, -ul[0])), int(min(br[0], image.shape[1])) -
|
54 |
-
int(max(1, ul[0])) + int(max(1, -ul[0]))]
|
55 |
-
g_y = [int(max(1, -ul[1])), int(min(br[1], image.shape[0])) -
|
56 |
-
int(max(1, ul[1])) + int(max(1, -ul[1]))]
|
57 |
-
img_x = [int(max(1, ul[0])), int(min(br[0], image.shape[1]))]
|
58 |
-
img_y = [int(max(1, ul[1])), int(min(br[1], image.shape[0]))]
|
59 |
-
assert (g_x[0] > 0 and g_y[1] > 0)
|
60 |
-
correct = False
|
61 |
-
while not correct:
|
62 |
-
try:
|
63 |
-
image[img_y[0] - 1:img_y[1], img_x[0] - 1:img_x[1]
|
64 |
-
] = image[img_y[0] - 1:img_y[1], img_x[0] - 1:img_x[1]] + g[g_y[0] - 1:g_y[1], g_x[0] - 1:g_x[1]]
|
65 |
-
correct = True
|
66 |
-
except:
|
67 |
-
print('img_x: {}, img_y: {}, g_x:{}, g_y:{}, point:{}, g_shape:{}, ul:{}, br:{}'.format(img_x, img_y, g_x, g_y, point, g.shape, ul, br))
|
68 |
-
ul = [np.floor(np.floor(point[0]) - 3 * sigma),
|
69 |
-
np.floor(np.floor(point[1]) - 3 * sigma)]
|
70 |
-
br = [np.floor(np.floor(point[0]) + 3 * sigma),
|
71 |
-
np.floor(np.floor(point[1]) + 3 * sigma)]
|
72 |
-
g_x = [int(max(1, -ul[0])), int(min(br[0], image.shape[1])) -
|
73 |
-
int(max(1, ul[0])) + int(max(1, -ul[0]))]
|
74 |
-
g_y = [int(max(1, -ul[1])), int(min(br[1], image.shape[0])) -
|
75 |
-
int(max(1, ul[1])) + int(max(1, -ul[1]))]
|
76 |
-
img_x = [int(max(1, ul[0])), int(min(br[0], image.shape[1]))]
|
77 |
-
img_y = [int(max(1, ul[1])), int(min(br[1], image.shape[0]))]
|
78 |
-
pass
|
79 |
-
image[image > 1] = 1
|
80 |
-
return image
|
81 |
-
|
82 |
-
def transform(point, center, scale, resolution, rotation=0, invert=False):
|
83 |
-
_pt = np.ones(3)
|
84 |
-
_pt[0] = point[0]
|
85 |
-
_pt[1] = point[1]
|
86 |
-
|
87 |
-
h = 200.0 * scale
|
88 |
-
t = np.eye(3)
|
89 |
-
t[0, 0] = resolution / h
|
90 |
-
t[1, 1] = resolution / h
|
91 |
-
t[0, 2] = resolution * (-center[0] / h + 0.5)
|
92 |
-
t[1, 2] = resolution * (-center[1] / h + 0.5)
|
93 |
-
|
94 |
-
if rotation != 0:
|
95 |
-
rotation = -rotation
|
96 |
-
r = np.eye(3)
|
97 |
-
ang = rotation * math.pi / 180.0
|
98 |
-
s = math.sin(ang)
|
99 |
-
c = math.cos(ang)
|
100 |
-
r[0][0] = c
|
101 |
-
r[0][1] = -s
|
102 |
-
r[1][0] = s
|
103 |
-
r[1][1] = c
|
104 |
-
|
105 |
-
t_ = np.eye(3)
|
106 |
-
t_[0][2] = -resolution / 2.0
|
107 |
-
t_[1][2] = -resolution / 2.0
|
108 |
-
t_inv = torch.eye(3)
|
109 |
-
t_inv[0][2] = resolution / 2.0
|
110 |
-
t_inv[1][2] = resolution / 2.0
|
111 |
-
t = reduce(np.matmul, [t_inv, r, t_, t])
|
112 |
-
|
113 |
-
if invert:
|
114 |
-
t = np.linalg.inv(t)
|
115 |
-
new_point = (np.matmul(t, _pt))[0:2]
|
116 |
-
|
117 |
-
return new_point.astype(int)
|
118 |
-
|
119 |
-
def cv_crop(image, landmarks, center, scale, resolution=256, center_shift=0):
|
120 |
-
new_image = cv2.copyMakeBorder(image, center_shift,
|
121 |
-
center_shift,
|
122 |
-
center_shift,
|
123 |
-
center_shift,
|
124 |
-
cv2.BORDER_CONSTANT, value=[0,0,0])
|
125 |
-
new_landmarks = landmarks.copy()
|
126 |
-
if center_shift != 0:
|
127 |
-
center[0] += center_shift
|
128 |
-
center[1] += center_shift
|
129 |
-
new_landmarks = new_landmarks + center_shift
|
130 |
-
length = 200 * scale
|
131 |
-
top = int(center[1] - length // 2)
|
132 |
-
bottom = int(center[1] + length // 2)
|
133 |
-
left = int(center[0] - length // 2)
|
134 |
-
right = int(center[0] + length // 2)
|
135 |
-
y_pad = abs(min(top, new_image.shape[0] - bottom, 0))
|
136 |
-
x_pad = abs(min(left, new_image.shape[1] - right, 0))
|
137 |
-
top, bottom, left, right = top + y_pad, bottom + y_pad, left + x_pad, right + x_pad
|
138 |
-
new_image = cv2.copyMakeBorder(new_image, y_pad,
|
139 |
-
y_pad,
|
140 |
-
x_pad,
|
141 |
-
x_pad,
|
142 |
-
cv2.BORDER_CONSTANT, value=[0,0,0])
|
143 |
-
new_image = new_image[top:bottom, left:right]
|
144 |
-
new_image = cv2.resize(new_image, dsize=(int(resolution), int(resolution)),
|
145 |
-
interpolation=cv2.INTER_LINEAR)
|
146 |
-
new_landmarks[:, 0] = (new_landmarks[:, 0] + x_pad - left) * resolution / length
|
147 |
-
new_landmarks[:, 1] = (new_landmarks[:, 1] + y_pad - top) * resolution / length
|
148 |
-
return new_image, new_landmarks
|
149 |
-
|
150 |
-
def cv_rotate(image, landmarks, heatmap, rot, scale, resolution=256):
|
151 |
-
img_mat = cv2.getRotationMatrix2D((resolution//2, resolution//2), rot, scale)
|
152 |
-
ones = np.ones(shape=(landmarks.shape[0], 1))
|
153 |
-
stacked_landmarks = np.hstack([landmarks, ones])
|
154 |
-
new_landmarks = img_mat.dot(stacked_landmarks.T).T
|
155 |
-
if np.max(new_landmarks) > 255 or np.min(new_landmarks) < 0:
|
156 |
-
return image, landmarks, heatmap
|
157 |
-
else:
|
158 |
-
new_image = cv2.warpAffine(image, img_mat, (resolution, resolution))
|
159 |
-
if heatmap is not None:
|
160 |
-
new_heatmap = np.zeros((heatmap.shape[0], 64, 64))
|
161 |
-
for i in range(heatmap.shape[0]):
|
162 |
-
if new_landmarks[i][0] > 0:
|
163 |
-
new_heatmap[i] = draw_gaussian(new_heatmap[i],
|
164 |
-
new_landmarks[i]/4.0+1, 1)
|
165 |
-
return new_image, new_landmarks, new_heatmap
|
166 |
-
|
167 |
-
def show_landmarks(image, heatmap, gt_landmarks, gt_heatmap):
|
168 |
-
"""Show image with pred_landmarks"""
|
169 |
-
pred_landmarks = []
|
170 |
-
pred_landmarks, _ = get_preds_fromhm(torch.from_numpy(heatmap).unsqueeze(0))
|
171 |
-
pred_landmarks = pred_landmarks.squeeze()*4
|
172 |
-
|
173 |
-
# pred_landmarks2 = get_preds_fromhm2(heatmap)
|
174 |
-
heatmap = np.max(gt_heatmap, axis=0)
|
175 |
-
heatmap = heatmap / np.max(heatmap)
|
176 |
-
# image = ski_transform.resize(image, (64, 64))*255
|
177 |
-
image = image.astype(np.uint8)
|
178 |
-
heatmap = np.max(gt_heatmap, axis=0)
|
179 |
-
heatmap = ski_transform.resize(heatmap, (image.shape[0], image.shape[1]))
|
180 |
-
heatmap *= 255
|
181 |
-
heatmap = heatmap.astype(np.uint8)
|
182 |
-
heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
|
183 |
-
plt.imshow(image)
|
184 |
-
plt.scatter(gt_landmarks[:, 0], gt_landmarks[:, 1], s=0.5, marker='.', c='g')
|
185 |
-
plt.scatter(pred_landmarks[:, 0], pred_landmarks[:, 1], s=0.5, marker='.', c='r')
|
186 |
-
plt.pause(0.001) # pause a bit so that plots are updated
|
187 |
-
|
188 |
-
def fan_NME(pred_heatmaps, gt_landmarks, num_landmarks=68):
|
189 |
-
'''
|
190 |
-
Calculate total NME for a batch of data
|
191 |
-
|
192 |
-
Args:
|
193 |
-
pred_heatmaps: torch tensor of size [batch, points, height, width]
|
194 |
-
gt_landmarks: torch tesnsor of size [batch, points, x, y]
|
195 |
-
|
196 |
-
Returns:
|
197 |
-
nme: sum of nme for this batch
|
198 |
-
'''
|
199 |
-
nme = 0
|
200 |
-
pred_landmarks, _ = get_preds_fromhm(pred_heatmaps)
|
201 |
-
pred_landmarks = pred_landmarks.numpy()
|
202 |
-
gt_landmarks = gt_landmarks.numpy()
|
203 |
-
for i in range(pred_landmarks.shape[0]):
|
204 |
-
pred_landmark = pred_landmarks[i] * 4.0
|
205 |
-
gt_landmark = gt_landmarks[i]
|
206 |
-
|
207 |
-
if num_landmarks == 68:
|
208 |
-
left_eye = np.average(gt_landmark[36:42], axis=0)
|
209 |
-
right_eye = np.average(gt_landmark[42:48], axis=0)
|
210 |
-
norm_factor = np.linalg.norm(left_eye - right_eye)
|
211 |
-
# norm_factor = np.linalg.norm(gt_landmark[36]- gt_landmark[45])
|
212 |
-
elif num_landmarks == 98:
|
213 |
-
norm_factor = np.linalg.norm(gt_landmark[60]- gt_landmark[72])
|
214 |
-
elif num_landmarks == 19:
|
215 |
-
left, top = gt_landmark[-2, :]
|
216 |
-
right, bottom = gt_landmark[-1, :]
|
217 |
-
norm_factor = math.sqrt(abs(right - left)*abs(top-bottom))
|
218 |
-
gt_landmark = gt_landmark[:-2, :]
|
219 |
-
elif num_landmarks == 29:
|
220 |
-
# norm_factor = np.linalg.norm(gt_landmark[8]- gt_landmark[9])
|
221 |
-
norm_factor = np.linalg.norm(gt_landmark[16]- gt_landmark[17])
|
222 |
-
nme += (np.sum(np.linalg.norm(pred_landmark - gt_landmark, axis=1)) / pred_landmark.shape[0]) / norm_factor
|
223 |
-
return nme
|
224 |
-
|
225 |
-
def fan_NME_hm(pred_heatmaps, gt_heatmaps, num_landmarks=68):
|
226 |
-
'''
|
227 |
-
Calculate total NME for a batch of data
|
228 |
-
|
229 |
-
Args:
|
230 |
-
pred_heatmaps: torch tensor of size [batch, points, height, width]
|
231 |
-
gt_landmarks: torch tesnsor of size [batch, points, x, y]
|
232 |
-
|
233 |
-
Returns:
|
234 |
-
nme: sum of nme for this batch
|
235 |
-
'''
|
236 |
-
nme = 0
|
237 |
-
pred_landmarks, _ = get_index_fromhm(pred_heatmaps)
|
238 |
-
pred_landmarks = pred_landmarks.numpy()
|
239 |
-
gt_landmarks = gt_landmarks.numpy()
|
240 |
-
for i in range(pred_landmarks.shape[0]):
|
241 |
-
pred_landmark = pred_landmarks[i] * 4.0
|
242 |
-
gt_landmark = gt_landmarks[i]
|
243 |
-
if num_landmarks == 68:
|
244 |
-
left_eye = np.average(gt_landmark[36:42], axis=0)
|
245 |
-
right_eye = np.average(gt_landmark[42:48], axis=0)
|
246 |
-
norm_factor = np.linalg.norm(left_eye - right_eye)
|
247 |
-
else:
|
248 |
-
norm_factor = np.linalg.norm(gt_landmark[60]- gt_landmark[72])
|
249 |
-
nme += (np.sum(np.linalg.norm(pred_landmark - gt_landmark, axis=1)) / pred_landmark.shape[0]) / norm_factor
|
250 |
-
return nme
|
251 |
-
|
252 |
-
def power_transform(img, power):
|
253 |
-
img = np.array(img)
|
254 |
-
img_new = np.power((img/255.0), power) * 255.0
|
255 |
-
img_new = img_new.astype(np.uint8)
|
256 |
-
img_new = Image.fromarray(img_new)
|
257 |
-
return img_new
|
258 |
-
|
259 |
-
def get_preds_fromhm(hm, center=None, scale=None, rot=None):
|
260 |
-
max, idx = torch.max(
|
261 |
-
hm.view(hm.size(0), hm.size(1), hm.size(2) * hm.size(3)), 2)
|
262 |
-
idx += 1
|
263 |
-
preds = idx.view(idx.size(0), idx.size(1), 1).repeat(1, 1, 2).float()
|
264 |
-
preds[..., 0].apply_(lambda x: (x - 1) % hm.size(3) + 1)
|
265 |
-
preds[..., 1].add_(-1).div_(hm.size(2)).floor_().add_(1)
|
266 |
-
|
267 |
-
for i in range(preds.size(0)):
|
268 |
-
for j in range(preds.size(1)):
|
269 |
-
hm_ = hm[i, j, :]
|
270 |
-
pX, pY = int(preds[i, j, 0]) - 1, int(preds[i, j, 1]) - 1
|
271 |
-
if pX > 0 and pX < 63 and pY > 0 and pY < 63:
|
272 |
-
diff = torch.FloatTensor(
|
273 |
-
[hm_[pY, pX + 1] - hm_[pY, pX - 1],
|
274 |
-
hm_[pY + 1, pX] - hm_[pY - 1, pX]])
|
275 |
-
preds[i, j].add_(diff.sign_().mul_(.25))
|
276 |
-
|
277 |
-
preds.add_(-0.5)
|
278 |
-
|
279 |
-
preds_orig = torch.zeros(preds.size())
|
280 |
-
if center is not None and scale is not None:
|
281 |
-
for i in range(hm.size(0)):
|
282 |
-
for j in range(hm.size(1)):
|
283 |
-
preds_orig[i, j] = transform(
|
284 |
-
preds[i, j], center, scale, hm.size(2), rot, True)
|
285 |
-
|
286 |
-
return preds, preds_orig
|
287 |
-
|
288 |
-
def get_index_fromhm(hm):
|
289 |
-
max, idx = torch.max(
|
290 |
-
hm.view(hm.size(0), hm.size(1), hm.size(2) * hm.size(3)), 2)
|
291 |
-
preds = idx.view(idx.size(0), idx.size(1), 1).repeat(1, 1, 2).float()
|
292 |
-
preds[..., 0].remainder_(hm.size(3))
|
293 |
-
preds[..., 1].div_(hm.size(2)).floor_()
|
294 |
-
|
295 |
-
for i in range(preds.size(0)):
|
296 |
-
for j in range(preds.size(1)):
|
297 |
-
hm_ = hm[i, j, :]
|
298 |
-
pX, pY = int(preds[i, j, 0]), int(preds[i, j, 1])
|
299 |
-
if pX > 0 and pX < 63 and pY > 0 and pY < 63:
|
300 |
-
diff = torch.FloatTensor(
|
301 |
-
[hm_[pY, pX + 1] - hm_[pY, pX - 1],
|
302 |
-
hm_[pY + 1, pX] - hm_[pY - 1, pX]])
|
303 |
-
preds[i, j].add_(diff.sign_().mul_(.25))
|
304 |
-
|
305 |
-
return preds
|
306 |
-
|
307 |
-
def shuffle_lr(parts, num_landmarks=68, pairs=None):
|
308 |
-
if num_landmarks == 68:
|
309 |
-
if pairs is None:
|
310 |
-
pairs = [[0, 16], [1, 15], [2, 14], [3, 13], [4, 12], [5, 11], [6, 10],
|
311 |
-
[7, 9], [17, 26], [18, 25], [19, 24], [20, 23], [21, 22], [36, 45],
|
312 |
-
[37, 44], [38, 43], [39, 42], [41, 46], [40, 47], [31, 35], [32, 34],
|
313 |
-
[50, 52], [49, 53], [48, 54], [61, 63], [60, 64], [67, 65], [59, 55], [58, 56]]
|
314 |
-
elif num_landmarks == 98:
|
315 |
-
if pairs is None:
|
316 |
-
pairs = [[0, 32], [1,31], [2, 30], [3, 29], [4, 28], [5, 27], [6, 26], [7, 25], [8, 24], [9, 23], [10, 22], [11, 21], [12, 20], [13, 19], [14, 18], [15, 17], [33, 46], [34, 45], [35, 44], [36, 43], [37, 42], [38, 50], [39, 49], [40, 48], [41, 47], [60, 72], [61, 71], [62, 70], [63, 69], [64, 68], [65, 75], [66, 74], [67, 73], [96, 97], [55, 59], [56, 58], [76, 82], [77, 81], [78, 80], [88, 92], [89, 91], [95, 93], [87, 83], [86, 84]]
|
317 |
-
elif num_landmarks == 19:
|
318 |
-
if pairs is None:
|
319 |
-
pairs = [[0, 5], [1, 4], [2, 3], [6, 11], [7, 10], [8, 9], [12, 14], [15, 17]]
|
320 |
-
elif num_landmarks == 29:
|
321 |
-
if pairs is None:
|
322 |
-
pairs = [[0, 1], [4, 6], [5, 7], [2, 3], [8, 9], [12, 14], [16, 17], [13, 15], [10, 11], [18, 19], [22, 23]]
|
323 |
-
for matched_p in pairs:
|
324 |
-
idx1, idx2 = matched_p[0], matched_p[1]
|
325 |
-
tmp = np.copy(parts[idx1])
|
326 |
-
np.copyto(parts[idx1], parts[idx2])
|
327 |
-
np.copyto(parts[idx2], tmp)
|
328 |
-
return parts
|
329 |
-
|
330 |
-
|
331 |
-
def generate_weight_map(weight_map,heatmap):
|
332 |
-
|
333 |
-
k_size = 3
|
334 |
-
dilate = ndimage.grey_dilation(heatmap ,size=(k_size,k_size))
|
335 |
-
weight_map[np.where(dilate>0.2)] = 1
|
336 |
-
return weight_map
|
337 |
-
|
338 |
-
def fig2data(fig):
|
339 |
-
"""
|
340 |
-
@brief Convert a Matplotlib figure to a 4D numpy array with RGBA channels and return it
|
341 |
-
@param fig a matplotlib figure
|
342 |
-
@return a numpy 3D array of RGBA values
|
343 |
-
"""
|
344 |
-
# draw the renderer
|
345 |
-
fig.canvas.draw ( )
|
346 |
-
|
347 |
-
# Get the RGB buffer from the figure
|
348 |
-
w,h = fig.canvas.get_width_height()
|
349 |
-
buf = np.fromstring (fig.canvas.tostring_rgb(), dtype=np.uint8)
|
350 |
-
buf.shape = (w, h, 3)
|
351 |
-
|
352 |
-
# canvas.tostring_argb give pixmap in ARGB mode. Roll the ALPHA channel to have it in RGBA mode
|
353 |
-
buf = np.roll (buf, 3, axis=2)
|
354 |
-
return buf
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
marlenezw/audio-driven-animations/MakeItTalk/__init__.py
DELETED
File without changes
|
marlenezw/audio-driven-animations/MakeItTalk/__pycache__/__init__.cpython-37.pyc
DELETED
Binary file (147 Bytes)
|
|
marlenezw/audio-driven-animations/MakeItTalk/__pycache__/__init__.cpython-39.pyc
DELETED
Binary file (162 Bytes)
|
|
marlenezw/audio-driven-animations/MakeItTalk/face_of_art/CODEOWNERS
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
* @papulke
|
|
|
|
marlenezw/audio-driven-animations/MakeItTalk/face_of_art/LICENCE.txt
DELETED
@@ -1,21 +0,0 @@
|
|
1 |
-
MIT License
|
2 |
-
|
3 |
-
Copyright (c) 2019 Jordan Yaniv
|
4 |
-
|
5 |
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
-
of this software and associated documentation files (the "Software"), to deal
|
7 |
-
in the Software without restriction, including without limitation the rights
|
8 |
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
-
copies of the Software, and to permit persons to whom the Software is
|
10 |
-
furnished to do so, subject to the following conditions:
|
11 |
-
|
12 |
-
The above copyright notice and this permission notice shall be included in all
|
13 |
-
copies or substantial portions of the Software.
|
14 |
-
|
15 |
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16 |
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17 |
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
18 |
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
19 |
-
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
20 |
-
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
21 |
-
OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
marlenezw/audio-driven-animations/MakeItTalk/face_of_art/README.md
DELETED
@@ -1,98 +0,0 @@
|
|
1 |
-
# The Face of Art: Landmark Detection and Geometric Style in Portraits
|
2 |
-
|
3 |
-
Code for the landmark detection framework described in [The Face of Art: Landmark Detection and Geometric Style in Portraits](http://www.faculty.idc.ac.il/arik/site/foa/face-of-art.asp) (SIGGRAPH 2019)
|
4 |
-
|
5 |
-

|
6 |
-
<sub><sup>Top: landmark detection results on artistic portraits with different styles allows to define the geometric style of an artist. Bottom: results of the style transfer of portraits using various artists' geometric style, including Amedeo Modigliani, Pablo Picasso, Margaret Keane, Fernand LΓ©ger, and Tsuguharu Foujita. Top right portrait is from 'Woman with Peanuts,' Β©1962, Estate of Roy Lichtenstein.</sup></sub>
|
7 |
-
|
8 |
-
## Getting Started
|
9 |
-
|
10 |
-
### Requirements
|
11 |
-
|
12 |
-
* python
|
13 |
-
* anaconda
|
14 |
-
|
15 |
-
### Download
|
16 |
-
|
17 |
-
#### Model
|
18 |
-
download model weights from [here](https://www.dropbox.com/sh/hrxcyug1bmbj6cs/AAAxq_zI5eawcLjM8zvUwaXha?dl=0).
|
19 |
-
|
20 |
-
#### Datasets
|
21 |
-
* The datasets used for training and evaluating our model can be found [here](https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/).
|
22 |
-
|
23 |
-
* The Artistic-Faces dataset can be found [here](http://www.faculty.idc.ac.il/arik/site/foa/artistic-faces-dataset.asp).
|
24 |
-
|
25 |
-
* Training images with texture augmentation can be found [here](https://www.dropbox.com/sh/av2k1i1082z0nie/AAC5qV1E2UkqpDLVsv7TazMta?dl=0).
|
26 |
-
before applying texture style transfer, the training images were cropped to the ground-truth face bounding-box with 25% margin. To crop training images, run the script `crop_training_set.py`.
|
27 |
-
|
28 |
-
* our model expects the following directory structure of landmark detection datasets:
|
29 |
-
```
|
30 |
-
landmark_detection_datasets
|
31 |
-
βββ training
|
32 |
-
βββ test
|
33 |
-
βββ challenging
|
34 |
-
βββ common
|
35 |
-
βββ full
|
36 |
-
βββ crop_gt_margin_0.25 (cropped images of training set)
|
37 |
-
βββ crop_gt_margin_0.25_ns (cropped images of training set + texture style transfer)
|
38 |
-
```
|
39 |
-
### Install
|
40 |
-
|
41 |
-
Create a virtual environment and install the following:
|
42 |
-
* opencv
|
43 |
-
* menpo
|
44 |
-
* menpofit
|
45 |
-
* tensorflow-gpu
|
46 |
-
|
47 |
-
for python 2:
|
48 |
-
```
|
49 |
-
conda create -n foa_env python=2.7 anaconda
|
50 |
-
source activate foa_env
|
51 |
-
conda install -c menpo opencv
|
52 |
-
conda install -c menpo menpo
|
53 |
-
conda install -c menpo menpofit
|
54 |
-
pip install tensorflow-gpu
|
55 |
-
|
56 |
-
```
|
57 |
-
|
58 |
-
for python 3:
|
59 |
-
```
|
60 |
-
conda create -n foa_env python=3.5 anaconda
|
61 |
-
source activate foa_env
|
62 |
-
conda install -c menpo opencv
|
63 |
-
conda install -c menpo menpo
|
64 |
-
conda install -c menpo menpofit
|
65 |
-
pip3 install tensorflow-gpu
|
66 |
-
|
67 |
-
```
|
68 |
-
|
69 |
-
Clone repository:
|
70 |
-
|
71 |
-
```
|
72 |
-
git clone https://github.com/papulke/deep_face_heatmaps
|
73 |
-
```
|
74 |
-
|
75 |
-
## Instructions
|
76 |
-
|
77 |
-
### Training
|
78 |
-
|
79 |
-
To train the network you need to run `train_heatmaps_network.py`
|
80 |
-
|
81 |
-
example for training a model with texture augmentation (100% of images) and geometric augmentation (~70% of images):
|
82 |
-
```
|
83 |
-
python train_heatmaps_network.py --output_dir='test_artistic_aug' --augment_geom=True \
|
84 |
-
--augment_texture=True --p_texture=1. --p_geom=0.7
|
85 |
-
```
|
86 |
-
|
87 |
-
### Testing
|
88 |
-
|
89 |
-
For using the detection framework to predict landmarks, run the script `predict_landmarks.py`
|
90 |
-
|
91 |
-
## Acknowledgments
|
92 |
-
|
93 |
-
* [ect](https://github.com/HongwenZhang/ECT-FaceAlignment)
|
94 |
-
* [menpo](https://github.com/menpo/menpo)
|
95 |
-
* [menpofit](https://github.com/menpo/menpofit)
|
96 |
-
* [mdm](https://github.com/trigeorgis/mdm)
|
97 |
-
* [style transfer implementation](https://github.com/woodrush/neural-art-tf)
|
98 |
-
* [painter-by-numbers dataset](https://www.kaggle.com/c/painter-by-numbers/data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|