andro1241 commited on
Commit
164430d
·
verified ·
1 Parent(s): 36a3eb4

Upload 4 files

Browse files
processors/modules/frame_colorizer/choices.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Sequence, get_args
2
+
3
+ from facefusion.common_helper import create_int_range
4
+ from facefusion.processors.modules.frame_colorizer.types import FrameColorizerModel
5
+
6
+ frame_colorizer_models : List[FrameColorizerModel] = list(get_args(FrameColorizerModel))
7
+
8
+ frame_colorizer_sizes : List[str] = [ '192x192', '256x256', '384x384', '512x512' ]
9
+
10
+ frame_colorizer_blend_range : Sequence[int] = create_int_range(0, 100, 1)
processors/modules/frame_colorizer/core.py ADDED
@@ -0,0 +1,313 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from argparse import ArgumentParser
2
+ from functools import lru_cache
3
+ from types import ModuleType
4
+ from typing import List
5
+
6
+ import cv2
7
+ import numpy
8
+
9
+ import facefusion.choices
10
+ import facefusion.jobs.job_manager
11
+ import facefusion.jobs.job_store
12
+ from facefusion import config, content_analyser, inference_manager, logger, state_manager, translator, video_manager
13
+ from facefusion.common_helper import create_int_metavar, is_macos
14
+ from facefusion.download import conditional_download_hashes, conditional_download_sources, resolve_download_url
15
+ from facefusion.execution import has_execution_provider
16
+ from facefusion.filesystem import in_directory, is_image, is_video, resolve_relative_path, same_file_extension
17
+ from facefusion.processors.modules.frame_colorizer import choices as frame_colorizer_choices
18
+ from facefusion.processors.modules.frame_colorizer.types import FrameColorizerInputs
19
+ from facefusion.processors.types import ProcessorOutputs
20
+ from facefusion.program_helper import find_argument_group
21
+ from facefusion.thread_helper import thread_semaphore
22
+ from facefusion.types import ApplyStateItem, Args, DownloadScope, InferencePool, InferenceProvider, ModelOptions, ModelSet, ProcessMode, VisionFrame
23
+ from facefusion.vision import blend_frame, read_static_image, read_static_video_frame, unpack_resolution
24
+
25
+
26
+ @lru_cache()
27
+ def create_static_model_set(download_scope : DownloadScope) -> ModelSet:
28
+ return\
29
+ {
30
+ 'ddcolor':
31
+ {
32
+ '__metadata__':
33
+ {
34
+ 'vendor': 'piddnad',
35
+ 'license': 'Apache-2.0',
36
+ 'year': 2023
37
+ },
38
+ 'hashes':
39
+ {
40
+ 'frame_colorizer':
41
+ {
42
+ 'url': resolve_download_url('models-3.0.0', 'ddcolor.hash'),
43
+ 'path': resolve_relative_path('../.assets/models/ddcolor.hash')
44
+ }
45
+ },
46
+ 'sources':
47
+ {
48
+ 'frame_colorizer':
49
+ {
50
+ 'url': resolve_download_url('models-3.0.0', 'ddcolor.onnx'),
51
+ 'path': resolve_relative_path('../.assets/models/ddcolor.onnx')
52
+ }
53
+ },
54
+ 'type': 'ddcolor'
55
+ },
56
+ 'ddcolor_artistic':
57
+ {
58
+ '__metadata__':
59
+ {
60
+ 'vendor': 'piddnad',
61
+ 'license': 'Apache-2.0',
62
+ 'year': 2023
63
+ },
64
+ 'hashes':
65
+ {
66
+ 'frame_colorizer':
67
+ {
68
+ 'url': resolve_download_url('models-3.0.0', 'ddcolor_artistic.hash'),
69
+ 'path': resolve_relative_path('../.assets/models/ddcolor_artistic.hash')
70
+ }
71
+ },
72
+ 'sources':
73
+ {
74
+ 'frame_colorizer':
75
+ {
76
+ 'url': resolve_download_url('models-3.0.0', 'ddcolor_artistic.onnx'),
77
+ 'path': resolve_relative_path('../.assets/models/ddcolor_artistic.onnx')
78
+ }
79
+ },
80
+ 'type': 'ddcolor'
81
+ },
82
+ 'deoldify':
83
+ {
84
+ '__metadata__':
85
+ {
86
+ 'vendor': 'jantic',
87
+ 'license': 'MIT',
88
+ 'year': 2022
89
+ },
90
+ 'hashes':
91
+ {
92
+ 'frame_colorizer':
93
+ {
94
+ 'url': resolve_download_url('models-3.0.0', 'deoldify.hash'),
95
+ 'path': resolve_relative_path('../.assets/models/deoldify.hash')
96
+ }
97
+ },
98
+ 'sources':
99
+ {
100
+ 'frame_colorizer':
101
+ {
102
+ 'url': resolve_download_url('models-3.0.0', 'deoldify.onnx'),
103
+ 'path': resolve_relative_path('../.assets/models/deoldify.onnx')
104
+ }
105
+ },
106
+ 'type': 'deoldify'
107
+ },
108
+ 'deoldify_artistic':
109
+ {
110
+ '__metadata__':
111
+ {
112
+ 'vendor': 'jantic',
113
+ 'license': 'MIT',
114
+ 'year': 2022
115
+ },
116
+ 'hashes':
117
+ {
118
+ 'frame_colorizer':
119
+ {
120
+ 'url': resolve_download_url('models-3.0.0', 'deoldify_artistic.hash'),
121
+ 'path': resolve_relative_path('../.assets/models/deoldify_artistic.hash')
122
+ }
123
+ },
124
+ 'sources':
125
+ {
126
+ 'frame_colorizer':
127
+ {
128
+ 'url': resolve_download_url('models-3.0.0', 'deoldify_artistic.onnx'),
129
+ 'path': resolve_relative_path('../.assets/models/deoldify_artistic.onnx')
130
+ }
131
+ },
132
+ 'type': 'deoldify'
133
+ },
134
+ 'deoldify_stable':
135
+ {
136
+ '__metadata__':
137
+ {
138
+ 'vendor': 'jantic',
139
+ 'license': 'MIT',
140
+ 'year': 2022
141
+ },
142
+ 'hashes':
143
+ {
144
+ 'frame_colorizer':
145
+ {
146
+ 'url': resolve_download_url('models-3.0.0', 'deoldify_stable.hash'),
147
+ 'path': resolve_relative_path('../.assets/models/deoldify_stable.hash')
148
+ }
149
+ },
150
+ 'sources':
151
+ {
152
+ 'frame_colorizer':
153
+ {
154
+ 'url': resolve_download_url('models-3.0.0', 'deoldify_stable.onnx'),
155
+ 'path': resolve_relative_path('../.assets/models/deoldify_stable.onnx')
156
+ }
157
+ },
158
+ 'type': 'deoldify'
159
+ }
160
+ }
161
+
162
+
163
+ def get_inference_pool() -> InferencePool:
164
+ model_names = [ state_manager.get_item('frame_colorizer_model') ]
165
+ model_source_set = get_model_options().get('sources')
166
+
167
+ return inference_manager.get_inference_pool(__name__, model_names, model_source_set)
168
+
169
+
170
+ def clear_inference_pool() -> None:
171
+ model_names = [ state_manager.get_item('frame_colorizer_model') ]
172
+ inference_manager.clear_inference_pool(__name__, model_names)
173
+
174
+
175
+ def override_inference_providers() -> List[InferenceProvider]:
176
+ if is_macos() and has_execution_provider('coreml'):
177
+ return [ facefusion.choices.execution_provider_set.get('cpu') ]
178
+
179
+ return []
180
+
181
+
182
+ def get_model_options() -> ModelOptions:
183
+ model_name = state_manager.get_item('frame_colorizer_model')
184
+ return create_static_model_set('full').get(model_name)
185
+
186
+
187
+ def register_args(program : ArgumentParser) -> None:
188
+ group_processors = find_argument_group(program, 'processors')
189
+ if group_processors:
190
+ group_processors.add_argument('--frame-colorizer-model', help = translator.get('help.model', __package__), default = config.get_str_value('processors', 'frame_colorizer_model', 'ddcolor'), choices = frame_colorizer_choices.frame_colorizer_models)
191
+ group_processors.add_argument('--frame-colorizer-size', help = translator.get('help.size', __package__), type = str, default = config.get_str_value('processors', 'frame_colorizer_size', '256x256'), choices = frame_colorizer_choices.frame_colorizer_sizes)
192
+ group_processors.add_argument('--frame-colorizer-blend', help = translator.get('help.blend', __package__), type = int, default = config.get_int_value('processors', 'frame_colorizer_blend', '100'), choices = frame_colorizer_choices.frame_colorizer_blend_range, metavar = create_int_metavar(frame_colorizer_choices.frame_colorizer_blend_range))
193
+ facefusion.jobs.job_store.register_step_keys([ 'frame_colorizer_model', 'frame_colorizer_blend', 'frame_colorizer_size' ])
194
+
195
+
196
+ def apply_args(args : Args, apply_state_item : ApplyStateItem) -> None:
197
+ apply_state_item('frame_colorizer_model', args.get('frame_colorizer_model'))
198
+ apply_state_item('frame_colorizer_blend', args.get('frame_colorizer_blend'))
199
+ apply_state_item('frame_colorizer_size', args.get('frame_colorizer_size'))
200
+
201
+
202
+ def get_common_modules() -> List[ModuleType]:
203
+ return [ content_analyser ]
204
+
205
+
206
+ def pre_check() -> bool:
207
+ model_hash_set = get_model_options().get('hashes')
208
+ model_source_set = get_model_options().get('sources')
209
+
210
+ for common_module in get_common_modules():
211
+ if not common_module.pre_check():
212
+ return False
213
+
214
+ return conditional_download_hashes(model_hash_set) and conditional_download_sources(model_source_set)
215
+
216
+
217
+ def pre_process(mode : ProcessMode) -> bool:
218
+ if mode in [ 'output', 'preview' ] and not is_image(state_manager.get_item('target_path')) and not is_video(state_manager.get_item('target_path')):
219
+ logger.error(translator.get('choose_image_or_video_target') + translator.get('exclamation_mark'), __name__)
220
+ return False
221
+ if mode == 'output' and not in_directory(state_manager.get_item('output_path')):
222
+ logger.error(translator.get('specify_image_or_video_output') + translator.get('exclamation_mark'), __name__)
223
+ return False
224
+ if mode == 'output' and not same_file_extension(state_manager.get_item('target_path'), state_manager.get_item('output_path')):
225
+ logger.error(translator.get('match_target_and_output_extension') + translator.get('exclamation_mark'), __name__)
226
+ return False
227
+ return True
228
+
229
+
230
+ def post_process() -> None:
231
+ read_static_image.cache_clear()
232
+ read_static_video_frame.cache_clear()
233
+ video_manager.clear_video_pool()
234
+
235
+ if state_manager.get_item('video_memory_strategy') in [ 'strict', 'moderate' ]:
236
+ clear_inference_pool()
237
+
238
+ if state_manager.get_item('video_memory_strategy') == 'strict':
239
+ for common_module in get_common_modules():
240
+ common_module.clear_inference_pool()
241
+
242
+
243
+ def colorize_frame(temp_vision_frame : VisionFrame) -> VisionFrame:
244
+ color_vision_frame = prepare_temp_frame(temp_vision_frame)
245
+ color_vision_frame = forward(color_vision_frame)
246
+ color_vision_frame = merge_color_frame(temp_vision_frame, color_vision_frame)
247
+ color_vision_frame = blend_color_frame(temp_vision_frame, color_vision_frame)
248
+ return color_vision_frame
249
+
250
+
251
+ def forward(color_vision_frame : VisionFrame) -> VisionFrame:
252
+ frame_colorizer = get_inference_pool().get('frame_colorizer')
253
+
254
+ with thread_semaphore():
255
+ color_vision_frame = frame_colorizer.run(None,
256
+ {
257
+ 'input': color_vision_frame
258
+ })[0][0]
259
+
260
+ return color_vision_frame
261
+
262
+
263
+ def prepare_temp_frame(temp_vision_frame : VisionFrame) -> VisionFrame:
264
+ model_size = unpack_resolution(state_manager.get_item('frame_colorizer_size'))
265
+ model_type = get_model_options().get('type')
266
+ temp_vision_frame = cv2.cvtColor(temp_vision_frame, cv2.COLOR_BGR2GRAY)
267
+ temp_vision_frame = cv2.cvtColor(temp_vision_frame, cv2.COLOR_GRAY2RGB)
268
+
269
+ if model_type == 'ddcolor':
270
+ temp_vision_frame = (temp_vision_frame / 255.0).astype(numpy.float32) #type:ignore[operator]
271
+ temp_vision_frame = cv2.cvtColor(temp_vision_frame, cv2.COLOR_RGB2LAB)[:, :, :1]
272
+ temp_vision_frame = numpy.concatenate((temp_vision_frame, numpy.zeros_like(temp_vision_frame), numpy.zeros_like(temp_vision_frame)), axis = -1)
273
+ temp_vision_frame = cv2.cvtColor(temp_vision_frame, cv2.COLOR_LAB2RGB)
274
+
275
+ temp_vision_frame = cv2.resize(temp_vision_frame, model_size)
276
+ temp_vision_frame = temp_vision_frame.transpose((2, 0, 1))
277
+ temp_vision_frame = numpy.expand_dims(temp_vision_frame, axis = 0).astype(numpy.float32)
278
+ return temp_vision_frame
279
+
280
+
281
+ def merge_color_frame(temp_vision_frame : VisionFrame, color_vision_frame : VisionFrame) -> VisionFrame:
282
+ model_type = get_model_options().get('type')
283
+ color_vision_frame = color_vision_frame.transpose(1, 2, 0)
284
+ color_vision_frame = cv2.resize(color_vision_frame, (temp_vision_frame.shape[1], temp_vision_frame.shape[0]))
285
+
286
+ if model_type == 'ddcolor':
287
+ temp_vision_frame = (temp_vision_frame / 255.0).astype(numpy.float32)
288
+ temp_vision_frame = cv2.cvtColor(temp_vision_frame, cv2.COLOR_BGR2LAB)[:, :, :1]
289
+ color_vision_frame = numpy.concatenate((temp_vision_frame, color_vision_frame), axis = -1)
290
+ color_vision_frame = cv2.cvtColor(color_vision_frame, cv2.COLOR_LAB2BGR)
291
+ color_vision_frame = (color_vision_frame * 255.0).round().astype(numpy.uint8) #type:ignore[operator]
292
+
293
+ if model_type == 'deoldify':
294
+ temp_blue_channel, _, _ = cv2.split(temp_vision_frame)
295
+ color_vision_frame = cv2.cvtColor(color_vision_frame, cv2.COLOR_BGR2RGB).astype(numpy.uint8)
296
+ color_vision_frame = cv2.cvtColor(color_vision_frame, cv2.COLOR_BGR2LAB)
297
+ _, color_green_channel, color_red_channel = cv2.split(color_vision_frame)
298
+ color_vision_frame = cv2.merge((temp_blue_channel, color_green_channel, color_red_channel))
299
+ color_vision_frame = cv2.cvtColor(color_vision_frame, cv2.COLOR_LAB2BGR)
300
+ return color_vision_frame
301
+
302
+
303
+ def blend_color_frame(temp_vision_frame : VisionFrame, color_vision_frame : VisionFrame) -> VisionFrame:
304
+ frame_colorizer_blend = 1 - (state_manager.get_item('frame_colorizer_blend') / 100)
305
+ temp_vision_frame = blend_frame(temp_vision_frame, color_vision_frame, 1 - frame_colorizer_blend)
306
+ return temp_vision_frame
307
+
308
+
309
+ def process_frame(inputs : FrameColorizerInputs) -> ProcessorOutputs:
310
+ temp_vision_frame = inputs.get('temp_vision_frame')
311
+ temp_vision_mask = inputs.get('temp_vision_mask')
312
+ temp_vision_frame = colorize_frame(temp_vision_frame)
313
+ return temp_vision_frame, temp_vision_mask
processors/modules/frame_colorizer/locales.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from facefusion.types import Locales
2
+
3
+ LOCALES : Locales =\
4
+ {
5
+ 'en':
6
+ {
7
+ 'help':
8
+ {
9
+ 'model': 'choose the model responsible for colorizing the frame',
10
+ 'size': 'specify the frame size provided to the frame colorizer',
11
+ 'blend': 'blend the colorized into the previous frame'
12
+ },
13
+ 'uis':
14
+ {
15
+ 'blend_slider': 'FRAME COLORIZER BLEND',
16
+ 'model_dropdown': 'FRAME COLORIZER MODEL',
17
+ 'size_dropdown': 'FRAME COLORIZER SIZE'
18
+ }
19
+ }
20
+ }
processors/modules/frame_colorizer/types.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Literal, TypedDict
2
+
3
+ from facefusion.types import Mask, VisionFrame
4
+
5
+ FrameColorizerInputs = TypedDict('FrameColorizerInputs',
6
+ {
7
+ 'target_vision_frames' : List[VisionFrame],
8
+ 'temp_vision_frame' : VisionFrame,
9
+ 'temp_vision_mask' : Mask
10
+ })
11
+
12
+ FrameColorizerModel = Literal['ddcolor', 'ddcolor_artistic', 'deoldify', 'deoldify_artistic', 'deoldify_stable']