Generalize facetool strength argument

This commit is contained in:
db3000 2022-10-13 09:14:21 -04:00 committed by Lincoln Stein
parent e98fe9c22d
commit ce5e57d828
19 changed files with 542 additions and 525 deletions

View File

@ -319,7 +319,7 @@ class InvokeAIWebServer:
elif postprocessing_parameters['type'] == 'gfpgan': elif postprocessing_parameters['type'] == 'gfpgan':
image = self.gfpgan.process( image = self.gfpgan.process(
image=image, image=image,
strength=postprocessing_parameters['gfpgan_strength'], strength=postprocessing_parameters['facetool_strength'],
seed=seed, seed=seed,
) )
else: else:
@ -625,7 +625,7 @@ class InvokeAIWebServer:
seed=seed, seed=seed,
) )
postprocessing = True postprocessing = True
all_parameters['gfpgan_strength'] = gfpgan_parameters[ all_parameters['facetool_strength'] = gfpgan_parameters[
'strength' 'strength'
] ]
@ -736,12 +736,12 @@ class InvokeAIWebServer:
postprocessing = [] postprocessing = []
# 'postprocessing' is either null or an # 'postprocessing' is either null or an
if 'gfpgan_strength' in parameters: if 'facetool_strength' in parameters:
postprocessing.append( postprocessing.append(
{ {
'type': 'gfpgan', 'type': 'gfpgan',
'strength': float(parameters['gfpgan_strength']), 'strength': float(parameters['facetool_strength']),
} }
) )
@ -838,7 +838,7 @@ class InvokeAIWebServer:
elif parameters['type'] == 'gfpgan': elif parameters['type'] == 'gfpgan':
postprocessing_metadata['type'] = 'gfpgan' postprocessing_metadata['type'] = 'gfpgan'
postprocessing_metadata['strength'] = parameters[ postprocessing_metadata['strength'] = parameters[
'gfpgan_strength' 'facetool_strength'
] ]
else: else:
raise TypeError(f"Invalid type: {parameters['type']}") raise TypeError(f"Invalid type: {parameters['type']}")

View File

@ -48,8 +48,14 @@ def parameters_to_command(params):
switches.append(f'-f {params["strength"]}') switches.append(f'-f {params["strength"]}')
if "fit" in params and params["fit"] == True: if "fit" in params and params["fit"] == True:
switches.append(f"--fit") switches.append(f"--fit")
if "gfpgan_strength" in params and params["gfpgan_strength"]: if "facetool" in params:
switches.append(f'-ft {params["facetool"]}')
if "facetool_strength" in params and params["facetool_strength"]:
switches.append(f'-G {params["facetool_strength"]}')
elif "gfpgan_strength" in params and params["gfpgan_strength"]:
switches.append(f'-G {params["gfpgan_strength"]}') switches.append(f'-G {params["gfpgan_strength"]}')
if "codeformer_fidelity" in params:
switches.append(f'-cf {params["codeformer_fidelity"]}')
if "upscale" in params and params["upscale"]: if "upscale" in params and params["upscale"]:
switches.append(f'-U {params["upscale"][0]} {params["upscale"][1]}') switches.append(f'-U {params["upscale"][0]} {params["upscale"][1]}')
if "variation_amount" in params and params["variation_amount"] > 0: if "variation_amount" in params and params["variation_amount"] > 0:

View File

@ -349,7 +349,7 @@ def handle_run_gfpgan_event(original_image, gfpgan_parameters):
eventlet.sleep(0) eventlet.sleep(0)
image = gfpgan.process( image = gfpgan.process(
image=image, strength=gfpgan_parameters["gfpgan_strength"], seed=seed image=image, strength=gfpgan_parameters["facetool_strength"], seed=seed
) )
progress["currentStatus"] = "Saving image" progress["currentStatus"] = "Saving image"
@ -464,7 +464,7 @@ def parameters_to_post_processed_image_metadata(parameters, original_image_path,
image["strength"] = parameters["upscale"][1] image["strength"] = parameters["upscale"][1]
elif type == "gfpgan": elif type == "gfpgan":
image["type"] = "gfpgan" image["type"] = "gfpgan"
image["strength"] = parameters["gfpgan_strength"] image["strength"] = parameters["facetool_strength"]
else: else:
raise TypeError(f"Invalid type: {type}") raise TypeError(f"Invalid type: {type}")
@ -506,10 +506,10 @@ def parameters_to_generated_image_metadata(parameters):
postprocessing = [] postprocessing = []
# 'postprocessing' is either null or an # 'postprocessing' is either null or an
if "gfpgan_strength" in parameters: if "facetool_strength" in parameters:
postprocessing.append( postprocessing.append(
{"type": "gfpgan", "strength": float(parameters["gfpgan_strength"])} {"type": "gfpgan", "strength": float(parameters["facetool_strength"])}
) )
if "upscale" in parameters: if "upscale" in parameters:
@ -752,7 +752,7 @@ def generate_images(generation_parameters, esrgan_parameters, gfpgan_parameters)
image=image, strength=gfpgan_parameters["strength"], seed=seed image=image, strength=gfpgan_parameters["strength"], seed=seed
) )
postprocessing = True postprocessing = True
all_parameters["gfpgan_strength"] = gfpgan_parameters["strength"] all_parameters["facetool_strength"] = gfpgan_parameters["strength"]
progress["currentStatus"] = "Saving image" progress["currentStatus"] = "Saving image"
socketio.emit("progressUpdate", progress) socketio.emit("progressUpdate", progress)

View File

@ -154,7 +154,9 @@ Here are the invoke> command that apply to txt2img:
| --log_tokenization | -t | False | Display a color-coded list of the parsed tokens derived from the prompt | | --log_tokenization | -t | False | Display a color-coded list of the parsed tokens derived from the prompt |
| --skip_normalization| -x | False | Weighted subprompts will not be normalized. See [Weighted Prompts](./OTHER.md#weighted-prompts) | | --skip_normalization| -x | False | Weighted subprompts will not be normalized. See [Weighted Prompts](./OTHER.md#weighted-prompts) |
| --upscale <int> <float> | -U <int> <float> | -U 1 0.75| Upscale image by magnification factor (2, 4), and set strength of upscaling (0.0-1.0). If strength not set, will default to 0.75. | | --upscale <int> <float> | -U <int> <float> | -U 1 0.75| Upscale image by magnification factor (2, 4), and set strength of upscaling (0.0-1.0). If strength not set, will default to 0.75. |
| --gfpgan_strength <float> | -G <float> | -G0 | Fix faces using the GFPGAN algorithm; argument indicates how hard the algorithm should try (0.0-1.0) | | --facetool_strength <float> | -G <float> | -G0 | Fix faces (defaults to using the GFPGAN algorithm); argument indicates how hard the algorithm should try (0.0-1.0) |
| --facetool <name> | -ft <name> | -ft gfpgan | Select face restoration algorithm to use: gfpgan, codeformer |
| --codeformer_fidelity | -cf <float> | 0.75 | Used along with CodeFormer. Takes values between 0 and 1. 0 produces high quality but low accuracy. 1 produces high accuracy but low quality |
| --save_original | -save_orig| False | When upscaling or fixing faces, this will cause the original image to be saved rather than replaced. | | --save_original | -save_orig| False | When upscaling or fixing faces, this will cause the original image to be saved rather than replaced. |
| --variation <float> |-v<float>| 0.0 | Add a bit of noise (0.0=none, 1.0=high) to the image in order to generate a series of variations. Usually used in combination with -S<seed> and -n<int> to generate a series a riffs on a starting image. See [Variations](./VARIATIONS.md). | | --variation <float> |-v<float>| 0.0 | Add a bit of noise (0.0=none, 1.0=high) to the image in order to generate a series of variations. Usually used in combination with -S<seed> and -n<int> to generate a series a riffs on a starting image. See [Variations](./VARIATIONS.md). |
| --with_variations <pattern> | -V<pattern>| None | Combine two or more variations. See [Variations](./VARIATIONS.md) for now to use this. | | --with_variations <pattern> | -V<pattern>| None | Combine two or more variations. See [Variations](./VARIATIONS.md) for now to use this. |

View File

@ -69,7 +69,7 @@ If you do not explicitly specify an upscaling_strength, it will default to 0.75.
### Face Restoration ### Face Restoration
`-G : <gfpgan_strength>` `-G : <facetool_strength>`
This prompt argument controls the strength of the face restoration that is being This prompt argument controls the strength of the face restoration that is being
applied. Similar to upscaling, values between `0.5 to 0.8` are recommended. applied. Similar to upscaling, values between `0.5 to 0.8` are recommended.

File diff suppressed because one or more lines are too long

483
frontend/dist/assets/index.ea68b5f5.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>InvokeAI - A Stable Diffusion Toolkit</title> <title>InvokeAI - A Stable Diffusion Toolkit</title>
<link rel="shortcut icon" type="icon" href="/assets/favicon.0d253ced.ico" /> <link rel="shortcut icon" type="icon" href="/assets/favicon.0d253ced.ico" />
<script type="module" crossorigin src="/assets/index.560edd47.js"></script> <script type="module" crossorigin src="/assets/index.ea68b5f5.js"></script>
<link rel="stylesheet" href="/assets/index.58175ea1.css"> <link rel="stylesheet" href="/assets/index.58175ea1.css">
</head> </head>

View File

@ -76,7 +76,7 @@ const makeSocketIOEmitters = (
const { gfpganStrength } = getState().options; const { gfpganStrength } = getState().options;
const gfpganParameters = { const gfpganParameters = {
gfpgan_strength: gfpganStrength, facetool_strength: gfpganStrength,
}; };
socketio.emit('runPostprocessing', imageToProcess, { socketio.emit('runPostprocessing', imageToProcess, {
type: 'gfpgan', type: 'gfpgan',

View File

@ -129,7 +129,7 @@ export const backendToFrontendParameters = (parameters: {
progress_images, progress_images,
variation_amount, variation_amount,
with_variations, with_variations,
gfpgan_strength, facetool_strength,
upscale, upscale,
init_img, init_img,
init_mask, init_mask,
@ -154,9 +154,9 @@ export const backendToFrontendParameters = (parameters: {
} }
} }
if (gfpgan_strength > 0) { if (facetool_strength > 0) {
options.shouldRunGFPGAN = true; options.shouldRunGFPGAN = true;
options.gfpganStrength = gfpgan_strength; options.gfpganStrength = facetool_strength;
} }
if (upscale) { if (upscale) {

View File

@ -251,7 +251,7 @@ class Generate:
embiggen_tiles = None, embiggen_tiles = None,
# these are specific to GFPGAN/ESRGAN # these are specific to GFPGAN/ESRGAN
facetool = None, facetool = None,
gfpgan_strength = 0, facetool_strength = 0,
codeformer_fidelity = None, codeformer_fidelity = None,
save_original = False, save_original = False,
upscale = None, upscale = None,
@ -274,7 +274,7 @@ class Generate:
hires_fix // whether the Hires Fix should be applied during generation hires_fix // whether the Hires Fix should be applied during generation
init_img // path to an initial image init_img // path to an initial image
strength // strength for noising/unnoising init_img. 0.0 preserves image exactly, 1.0 replaces it completely strength // strength for noising/unnoising init_img. 0.0 preserves image exactly, 1.0 replaces it completely
gfpgan_strength // strength for GFPGAN. 0.0 preserves image exactly, 1.0 replaces it completely facetool_strength // strength for GFPGAN/CodeFormer. 0.0 preserves image exactly, 1.0 replaces it completely
ddim_eta // image randomness (eta=0.0 means the same seed always produces the same image) ddim_eta // image randomness (eta=0.0 means the same seed always produces the same image)
step_callback // a function or method that will be called each step step_callback // a function or method that will be called each step
image_callback // a function or method that will be called each time an image is generated image_callback // a function or method that will be called each time an image is generated
@ -417,11 +417,11 @@ class Generate:
reference_image_path = init_color, reference_image_path = init_color,
image_callback = image_callback) image_callback = image_callback)
if upscale is not None or gfpgan_strength > 0: if upscale is not None or facetool_strength > 0:
self.upscale_and_reconstruct(results, self.upscale_and_reconstruct(results,
upscale = upscale, upscale = upscale,
facetool = facetool, facetool = facetool,
strength = gfpgan_strength, strength = facetool_strength,
codeformer_fidelity = codeformer_fidelity, codeformer_fidelity = codeformer_fidelity,
save_original = save_original, save_original = save_original,
image_callback = image_callback) image_callback = image_callback)
@ -464,7 +464,7 @@ class Generate:
self, self,
image_path, image_path,
tool = 'gfpgan', # one of 'upscale', 'gfpgan', 'codeformer', 'outpaint', or 'embiggen' tool = 'gfpgan', # one of 'upscale', 'gfpgan', 'codeformer', 'outpaint', or 'embiggen'
gfpgan_strength = 0.0, facetool_strength = 0.0,
codeformer_fidelity = 0.75, codeformer_fidelity = 0.75,
upscale = None, upscale = None,
out_direction = None, out_direction = None,
@ -511,11 +511,11 @@ class Generate:
facetool = 'codeformer' facetool = 'codeformer'
elif tool == 'upscale': elif tool == 'upscale':
facetool = 'gfpgan' # but won't be run facetool = 'gfpgan' # but won't be run
gfpgan_strength = 0 facetool_strength = 0
return self.upscale_and_reconstruct( return self.upscale_and_reconstruct(
[[image,seed]], [[image,seed]],
facetool = facetool, facetool = facetool,
strength = gfpgan_strength, strength = facetool_strength,
codeformer_fidelity = codeformer_fidelity, codeformer_fidelity = codeformer_fidelity,
save_original = save_original, save_original = save_original,
upscale = upscale, upscale = upscale,

View File

@ -242,9 +242,15 @@ class Args(object):
else: else:
switches.append(f'-A {a["sampler_name"]}') switches.append(f'-A {a["sampler_name"]}')
# gfpgan-specific parameters # facetool-specific parameters
if a['gfpgan_strength']: if a['facetool']:
switches.append(f'-ft {a["facetool"]}')
if a['facetool_strength']:
switches.append(f'-G {a["facetool_strength"]}')
elif a['gfpgan_strength']:
switches.append(f'-G {a["gfpgan_strength"]}') switches.append(f'-G {a["gfpgan_strength"]}')
if a['codeformer_fidelity']:
switches.append(f'-cf {a["codeformer_fidelity"]}')
if a['outcrop']: if a['outcrop']:
switches.append(f'-c {" ".join([str(u) for u in a["outcrop"]])}') switches.append(f'-c {" ".join([str(u) for u in a["outcrop"]])}')
@ -699,6 +705,7 @@ class Args(object):
) )
postprocessing_group.add_argument( postprocessing_group.add_argument(
'-G', '-G',
'--facetool_strength',
'--gfpgan_strength', '--gfpgan_strength',
type=float, type=float,
help='The strength at which to apply the face restoration to the result.', help='The strength at which to apply the face restoration to the result.',

View File

@ -42,7 +42,9 @@ COMMANDS = (
'--embedding_path', '--embedding_path',
'--device', '--device',
'--grid','-g', '--grid','-g',
'--gfpgan_strength','-G', '--facetool','-ft',
'--facetool_strength','-G',
'--codeformer_fidelity','-cf',
'--upscale','-U', '--upscale','-U',
'-save_orig','--save_original', '-save_orig','--save_original',
'--skip_normalize','-x', '--skip_normalize','-x',

View File

@ -31,7 +31,7 @@ def build_opt(post_data, seed, gfpgan_model_exists):
setattr(opt, 'embiggen', None) setattr(opt, 'embiggen', None)
setattr(opt, 'embiggen_tiles', None) setattr(opt, 'embiggen_tiles', None)
setattr(opt, 'gfpgan_strength', float(post_data['gfpgan_strength']) if gfpgan_model_exists else 0) setattr(opt, 'facetool_strength', float(post_data['facetool_strength']) if gfpgan_model_exists else 0)
setattr(opt, 'upscale', [int(post_data['upscale_level']), float(post_data['upscale_strength'])] if post_data['upscale_level'] != '' else None) setattr(opt, 'upscale', [int(post_data['upscale_level']), float(post_data['upscale_strength'])] if post_data['upscale_level'] != '' else None)
setattr(opt, 'progress_images', 'progress_images' in post_data) setattr(opt, 'progress_images', 'progress_images' in post_data)
setattr(opt, 'seed', None if int(post_data['seed']) == -1 else int(post_data['seed'])) setattr(opt, 'seed', None if int(post_data['seed']) == -1 else int(post_data['seed']))
@ -197,7 +197,7 @@ class DreamServer(BaseHTTPRequestHandler):
) + '\n',"utf-8")) ) + '\n',"utf-8"))
# control state of the "postprocessing..." message # control state of the "postprocessing..." message
upscaling_requested = opt.upscale or opt.gfpgan_strength > 0 upscaling_requested = opt.upscale or opt.facetool_strength > 0
nonlocal images_generated # NB: Is this bad python style? It is typical usage in a perl closure. nonlocal images_generated # NB: Is this bad python style? It is typical usage in a perl closure.
nonlocal images_upscaled # NB: Is this bad python style? It is typical usage in a perl closure. nonlocal images_upscaled # NB: Is this bad python style? It is typical usage in a perl closure.
if upscaled: if upscaled:

View File

@ -400,7 +400,7 @@ def do_postprocess (gen, opt, callback):
file_path = os.path.join(opt.outdir,file_path) file_path = os.path.join(opt.outdir,file_path)
tool=None tool=None
if opt.gfpgan_strength > 0: if opt.facetool_strength > 0:
tool = opt.facetool tool = opt.facetool
elif opt.embiggen: elif opt.embiggen:
tool = 'embiggen' tool = 'embiggen'
@ -416,7 +416,7 @@ def do_postprocess (gen, opt, callback):
gen.apply_postprocessor( gen.apply_postprocessor(
image_path = file_path, image_path = file_path,
tool = tool, tool = tool,
gfpgan_strength = opt.gfpgan_strength, facetool_strength = opt.facetool_strength,
codeformer_fidelity = opt.codeformer_fidelity, codeformer_fidelity = opt.codeformer_fidelity,
save_original = opt.save_original, save_original = opt.save_original,
upscale = opt.upscale, upscale = opt.upscale,

View File

@ -42,7 +42,7 @@ class DreamBase():
# GFPGAN # GFPGAN
enable_gfpgan: bool enable_gfpgan: bool
gfpgan_strength: float = 0 facetool_strength: float = 0
# Upscale # Upscale
enable_upscale: bool enable_upscale: bool
@ -98,7 +98,7 @@ class DreamBase():
# GFPGAN # GFPGAN
self.enable_gfpgan = 'enable_gfpgan' in j and bool(j.get('enable_gfpgan')) self.enable_gfpgan = 'enable_gfpgan' in j and bool(j.get('enable_gfpgan'))
if self.enable_gfpgan: if self.enable_gfpgan:
self.gfpgan_strength = float(j.get('gfpgan_strength')) self.facetool_strength = float(j.get('facetool_strength'))
# Upscale # Upscale
self.enable_upscale = 'enable_upscale' in j and bool(j.get('enable_upscale')) self.enable_upscale = 'enable_upscale' in j and bool(j.get('enable_upscale'))

View File

@ -334,11 +334,11 @@ class GeneratorService:
# TODO: Support no generation (just upscaling/gfpgan) # TODO: Support no generation (just upscaling/gfpgan)
upscale = None if not jobRequest.enable_upscale else jobRequest.upscale upscale = None if not jobRequest.enable_upscale else jobRequest.upscale
gfpgan_strength = 0 if not jobRequest.enable_gfpgan else jobRequest.gfpgan_strength facetool_strength = 0 if not jobRequest.enable_gfpgan else jobRequest.facetool_strength
if not jobRequest.enable_generate: if not jobRequest.enable_generate:
# If not generating, check if we're upscaling or running gfpgan # If not generating, check if we're upscaling or running gfpgan
if not upscale and not gfpgan_strength: if not upscale and not facetool_strength:
# Invalid settings (TODO: Add message to help user) # Invalid settings (TODO: Add message to help user)
raise CanceledException() raise CanceledException()
@ -347,7 +347,7 @@ class GeneratorService:
self.__model.upscale_and_reconstruct( self.__model.upscale_and_reconstruct(
image_list = [[image,0]], image_list = [[image,0]],
upscale = upscale, upscale = upscale,
strength = gfpgan_strength, strength = facetool_strength,
save_original = False, save_original = False,
image_callback = lambda image, seed, upscaled=False: self.__on_image_result(jobRequest, image, seed, upscaled)) image_callback = lambda image, seed, upscaled=False: self.__on_image_result(jobRequest, image, seed, upscaled))
@ -371,7 +371,7 @@ class GeneratorService:
steps = jobRequest.steps, steps = jobRequest.steps,
variation_amount = jobRequest.variation_amount, variation_amount = jobRequest.variation_amount,
with_variations = jobRequest.with_variations, with_variations = jobRequest.with_variations,
gfpgan_strength = gfpgan_strength, facetool_strength = facetool_strength,
upscale = upscale, upscale = upscale,
sampler_name = jobRequest.sampler_name, sampler_name = jobRequest.sampler_name,
seamless = jobRequest.seamless, seamless = jobRequest.seamless,

View File

@ -144,8 +144,8 @@
<input type="checkbox" name="enable_gfpgan" id="enable_gfpgan"> <input type="checkbox" name="enable_gfpgan" id="enable_gfpgan">
<label for="enable_gfpgan">Enable gfpgan</label> <label for="enable_gfpgan">Enable gfpgan</label>
</legend> </legend>
<label title="Strength of the gfpgan (face fixing) algorithm." for="gfpgan_strength">GPFGAN Strength:</label> <label title="Strength of the gfpgan (face fixing) algorithm." for="facetool_strength">GPFGAN Strength:</label>
<input value="0.8" min="0" max="1" type="number" id="gfpgan_strength" name="gfpgan_strength" step="0.05"> <input value="0.8" min="0" max="1" type="number" id="facetool_strength" name="facetool_strength" step="0.05">
</fieldset> </fieldset>
<fieldset id="upscale"> <fieldset id="upscale">
<legend> <legend>

View File

@ -100,8 +100,8 @@
</fieldset> </fieldset>
<fieldset id="gfpgan"> <fieldset id="gfpgan">
<div class="section-header">Post-processing options</div> <div class="section-header">Post-processing options</div>
<label title="Strength of the gfpgan (face fixing) algorithm." for="gfpgan_strength">GPFGAN Strength (0 to disable):</label> <label title="Strength of the gfpgan (face fixing) algorithm." for="facetool_strength">GPFGAN Strength (0 to disable):</label>
<input value="0.0" min="0" max="1" type="number" id="gfpgan_strength" name="gfpgan_strength" step="0.1"> <input value="0.0" min="0" max="1" type="number" id="facetool_strength" name="facetool_strength" step="0.1">
<label title="Upscaling to perform using ESRGAN." for="upscale_level">Upscaling Level</label> <label title="Upscaling to perform using ESRGAN." for="upscale_level">Upscaling Level</label>
<select id="upscale_level" name="upscale_level" value=""> <select id="upscale_level" name="upscale_level" value="">
<option value="" selected>None</option> <option value="" selected>None</option>