mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Adds Codeformer support
This commit is contained in:
parent
62dd3b7d7d
commit
32a5ffe436
@ -257,14 +257,14 @@ class InvokeAIWebServer:
|
|||||||
|
|
||||||
@socketio.on('generateImage')
|
@socketio.on('generateImage')
|
||||||
def handle_generate_image_event(
|
def handle_generate_image_event(
|
||||||
generation_parameters, esrgan_parameters, gfpgan_parameters
|
generation_parameters, esrgan_parameters, facetool_parameters
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
print(
|
print(
|
||||||
f'>> Image generation requested: {generation_parameters}\nESRGAN parameters: {esrgan_parameters}\nGFPGAN parameters: {gfpgan_parameters}'
|
f'>> Image generation requested: {generation_parameters}\nESRGAN parameters: {esrgan_parameters}\nFacetool parameters: {facetool_parameters}'
|
||||||
)
|
)
|
||||||
self.generate_images(
|
self.generate_images(
|
||||||
generation_parameters, esrgan_parameters, gfpgan_parameters
|
generation_parameters, esrgan_parameters, facetool_parameters
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.socketio.emit('error', {'message': (str(e))})
|
self.socketio.emit('error', {'message': (str(e))})
|
||||||
@ -300,9 +300,11 @@ class InvokeAIWebServer:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if postprocessing_parameters['type'] == 'esrgan':
|
if postprocessing_parameters['type'] == 'esrgan':
|
||||||
progress.set_current_status('Upscaling')
|
progress.set_current_status('Upscaling (ESRGAN)')
|
||||||
elif postprocessing_parameters['type'] == 'gfpgan':
|
elif postprocessing_parameters['type'] == 'gfpgan':
|
||||||
progress.set_current_status('Restoring Faces')
|
progress.set_current_status('Restoring Faces (GFPGAN)')
|
||||||
|
elif postprocessing_parameters['type'] == 'codeformer':
|
||||||
|
progress.set_current_status('Restoring Faces (Codeformer)')
|
||||||
|
|
||||||
socketio.emit('progressUpdate', progress.to_formatted_dict())
|
socketio.emit('progressUpdate', progress.to_formatted_dict())
|
||||||
eventlet.sleep(0)
|
eventlet.sleep(0)
|
||||||
@ -322,6 +324,14 @@ class InvokeAIWebServer:
|
|||||||
strength=postprocessing_parameters['facetool_strength'],
|
strength=postprocessing_parameters['facetool_strength'],
|
||||||
seed=seed,
|
seed=seed,
|
||||||
)
|
)
|
||||||
|
elif postprocessing_parameters['type'] == 'codeformer':
|
||||||
|
image = self.codeformer.process(
|
||||||
|
image=image,
|
||||||
|
strength=postprocessing_parameters['facetool_strength'],
|
||||||
|
fidelity=postprocessing_parameters['codeformer_fidelity'],
|
||||||
|
seed=seed,
|
||||||
|
device='cpu' if str(self.generate.device) == 'mps' else self.generate.device
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
f'{postprocessing_parameters["type"]} is not a valid postprocessing type'
|
f'{postprocessing_parameters["type"]} is not a valid postprocessing type'
|
||||||
@ -448,7 +458,7 @@ class InvokeAIWebServer:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def generate_images(
|
def generate_images(
|
||||||
self, generation_parameters, esrgan_parameters, gfpgan_parameters
|
self, generation_parameters, esrgan_parameters, facetool_parameters
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
self.canceled.clear()
|
self.canceled.clear()
|
||||||
@ -551,7 +561,7 @@ class InvokeAIWebServer:
|
|||||||
|
|
||||||
nonlocal generation_parameters
|
nonlocal generation_parameters
|
||||||
nonlocal esrgan_parameters
|
nonlocal esrgan_parameters
|
||||||
nonlocal gfpgan_parameters
|
nonlocal facetool_parameters
|
||||||
nonlocal progress
|
nonlocal progress
|
||||||
|
|
||||||
step_index = 1
|
step_index = 1
|
||||||
@ -611,23 +621,41 @@ class InvokeAIWebServer:
|
|||||||
if self.canceled.is_set():
|
if self.canceled.is_set():
|
||||||
raise CanceledException
|
raise CanceledException
|
||||||
|
|
||||||
if gfpgan_parameters:
|
if facetool_parameters:
|
||||||
progress.set_current_status('Restoring Faces')
|
if facetool_parameters['type'] == 'gfpgan':
|
||||||
|
progress.set_current_status('Restoring Faces (GFPGAN)')
|
||||||
|
elif facetool_parameters['type'] == 'codeformer':
|
||||||
|
progress.set_current_status('Restoring Faces (Codeformer)')
|
||||||
|
|
||||||
progress.set_current_status_has_steps(False)
|
progress.set_current_status_has_steps(False)
|
||||||
self.socketio.emit(
|
self.socketio.emit(
|
||||||
'progressUpdate', progress.to_formatted_dict()
|
'progressUpdate', progress.to_formatted_dict()
|
||||||
)
|
)
|
||||||
eventlet.sleep(0)
|
eventlet.sleep(0)
|
||||||
|
|
||||||
image = self.gfpgan.process(
|
if facetool_parameters['type'] == 'gfpgan':
|
||||||
image=image,
|
image = self.gfpgan.process(
|
||||||
strength=gfpgan_parameters['strength'],
|
image=image,
|
||||||
seed=seed,
|
strength=facetool_parameters['strength'],
|
||||||
)
|
seed=seed,
|
||||||
|
)
|
||||||
|
elif facetool_parameters['type'] == 'codeformer':
|
||||||
|
image = self.codeformer.process(
|
||||||
|
image=image,
|
||||||
|
strength=facetool_parameters['strength'],
|
||||||
|
fidelity=facetool_parameters['codeformer_fidelity'],
|
||||||
|
seed=seed,
|
||||||
|
device='cpu' if str(self.generate.device) == 'mps' else self.generate.device,
|
||||||
|
)
|
||||||
|
all_parameters['codeformer_fidelity'] = facetool_parameters['codeformer_fidelity']
|
||||||
|
|
||||||
postprocessing = True
|
postprocessing = True
|
||||||
all_parameters['facetool_strength'] = gfpgan_parameters[
|
all_parameters['facetool_strength'] = facetool_parameters[
|
||||||
'strength'
|
'strength'
|
||||||
]
|
]
|
||||||
|
all_parameters['facetool_type'] = facetool_parameters[
|
||||||
|
'type'
|
||||||
|
]
|
||||||
|
|
||||||
progress.set_current_status('Saving Image')
|
progress.set_current_status('Saving Image')
|
||||||
self.socketio.emit(
|
self.socketio.emit(
|
||||||
@ -737,13 +765,15 @@ class InvokeAIWebServer:
|
|||||||
|
|
||||||
# 'postprocessing' is either null or an
|
# 'postprocessing' is either null or an
|
||||||
if 'facetool_strength' in parameters:
|
if 'facetool_strength' in parameters:
|
||||||
|
facetool_parameters = {
|
||||||
postprocessing.append(
|
'type': str(parameters['facetool_type']),
|
||||||
{
|
|
||||||
'type': 'gfpgan',
|
|
||||||
'strength': float(parameters['facetool_strength']),
|
'strength': float(parameters['facetool_strength']),
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
if parameters['facetool_type'] == 'codeformer':
|
||||||
|
facetool_parameters['fidelity'] = float(parameters['codeformer_fidelity'])
|
||||||
|
|
||||||
|
postprocessing.append(facetool_parameters)
|
||||||
|
|
||||||
if 'upscale' in parameters:
|
if 'upscale' in parameters:
|
||||||
postprocessing.append(
|
postprocessing.append(
|
||||||
@ -840,6 +870,13 @@ class InvokeAIWebServer:
|
|||||||
postprocessing_metadata['strength'] = parameters[
|
postprocessing_metadata['strength'] = parameters[
|
||||||
'facetool_strength'
|
'facetool_strength'
|
||||||
]
|
]
|
||||||
|
elif parameters['type'] == 'codeformer':
|
||||||
|
postprocessing_metadata['type'] = 'codeformer'
|
||||||
|
postprocessing_metadata['strength'] = parameters[
|
||||||
|
'facetool_strength'
|
||||||
|
]
|
||||||
|
postprocessing_metadata['fidelity'] = parameters['codeformer_fidelity']
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise TypeError(f"Invalid type: {parameters['type']}")
|
raise TypeError(f"Invalid type: {parameters['type']}")
|
||||||
|
|
||||||
|
482
frontend/dist/assets/index.89883620.js
vendored
482
frontend/dist/assets/index.89883620.js
vendored
File diff suppressed because one or more lines are too long
690
frontend/dist/assets/index.ef6347d3.js
vendored
Normal file
690
frontend/dist/assets/index.ef6347d3.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
frontend/dist/index.html
vendored
4
frontend/dist/index.html
vendored
@ -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.89883620.js"></script>
|
<script type="module" crossorigin src="/assets/index.ef6347d3.js"></script>
|
||||||
<link rel="stylesheet" href="/assets/index.58175ea1.css">
|
<link rel="stylesheet" href="/assets/index.58175ea1.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@ -15,4 +15,4 @@
|
|||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -43,7 +43,7 @@ export const PARAMETERS: { [key: string]: string } = {
|
|||||||
sampler: 'Sampler',
|
sampler: 'Sampler',
|
||||||
seed: 'Seed',
|
seed: 'Seed',
|
||||||
img2imgStrength: 'img2img Strength',
|
img2imgStrength: 'img2img Strength',
|
||||||
gfpganStrength: 'GFPGAN Strength',
|
facetoolStrength: 'GFPGAN Strength',
|
||||||
upscalingLevel: 'Upscaling Level',
|
upscalingLevel: 'Upscaling Level',
|
||||||
upscalingStrength: 'Upscaling Strength',
|
upscalingStrength: 'Upscaling Strength',
|
||||||
initialImagePath: 'Initial Image',
|
initialImagePath: 'Initial Image',
|
||||||
@ -56,3 +56,5 @@ export const PARAMETERS: { [key: string]: string } = {
|
|||||||
export const NUMPY_RAND_MIN = 0;
|
export const NUMPY_RAND_MIN = 0;
|
||||||
|
|
||||||
export const NUMPY_RAND_MAX = 4294967295;
|
export const NUMPY_RAND_MAX = 4294967295;
|
||||||
|
|
||||||
|
export const FACETOOL_TYPES = ['gfpgan', 'codeformer'] as const;
|
||||||
|
7
frontend/src/app/invokeai.d.ts
vendored
7
frontend/src/app/invokeai.d.ts
vendored
@ -89,15 +89,16 @@ export declare type ESRGANMetadata = CommonPostProcessedImageMetadata & {
|
|||||||
strength: number;
|
strength: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export declare type GFPGANMetadata = CommonPostProcessedImageMetadata & {
|
export declare type FacetoolMetadata = CommonPostProcessedImageMetadata & {
|
||||||
type: 'gfpgan';
|
type: 'gfpgan' | 'codeformer';
|
||||||
strength: number;
|
strength: number;
|
||||||
|
fidelity?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Superset of all postprocessed image metadata types..
|
// Superset of all postprocessed image metadata types..
|
||||||
export declare type PostProcessedImageMetadata =
|
export declare type PostProcessedImageMetadata =
|
||||||
| ESRGANMetadata
|
| ESRGANMetadata
|
||||||
| GFPGANMetadata;
|
| FacetoolMetadata;
|
||||||
|
|
||||||
// Metadata includes the system config and image metadata.
|
// Metadata includes the system config and image metadata.
|
||||||
export declare type Metadata = SystemConfig & {
|
export declare type Metadata = SystemConfig & {
|
||||||
|
@ -30,14 +30,14 @@ const makeSocketIOEmitters = (
|
|||||||
options.shouldUseInitImage = false;
|
options.shouldUseInitImage = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { generationParameters, esrganParameters, gfpganParameters } =
|
const { generationParameters, esrganParameters, facetoolParameters } =
|
||||||
frontendToBackendParameters(options, getState().system);
|
frontendToBackendParameters(options, getState().system);
|
||||||
|
|
||||||
socketio.emit(
|
socketio.emit(
|
||||||
'generateImage',
|
'generateImage',
|
||||||
generationParameters,
|
generationParameters,
|
||||||
esrganParameters,
|
esrganParameters,
|
||||||
gfpganParameters
|
facetoolParameters
|
||||||
);
|
);
|
||||||
|
|
||||||
dispatch(
|
dispatch(
|
||||||
@ -46,7 +46,7 @@ const makeSocketIOEmitters = (
|
|||||||
message: `Image generation requested: ${JSON.stringify({
|
message: `Image generation requested: ${JSON.stringify({
|
||||||
...generationParameters,
|
...generationParameters,
|
||||||
...esrganParameters,
|
...esrganParameters,
|
||||||
...gfpganParameters,
|
...facetoolParameters,
|
||||||
})}`,
|
})}`,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -71,24 +71,32 @@ const makeSocketIOEmitters = (
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
emitRunGFPGAN: (imageToProcess: InvokeAI.Image) => {
|
emitRunFacetool: (imageToProcess: InvokeAI.Image) => {
|
||||||
dispatch(setIsProcessing(true));
|
dispatch(setIsProcessing(true));
|
||||||
const { gfpganStrength } = getState().options;
|
const { facetoolType, facetoolStrength, codeformerFidelity } =
|
||||||
|
getState().options;
|
||||||
|
|
||||||
const gfpganParameters = {
|
const facetoolParameters: Record<string, any> = {
|
||||||
facetool_strength: gfpganStrength,
|
facetool_strength: facetoolStrength,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (facetoolType === 'codeformer') {
|
||||||
|
facetoolParameters.codeformer_fidelity = codeformerFidelity;
|
||||||
|
}
|
||||||
|
|
||||||
socketio.emit('runPostprocessing', imageToProcess, {
|
socketio.emit('runPostprocessing', imageToProcess, {
|
||||||
type: 'gfpgan',
|
type: facetoolType,
|
||||||
...gfpganParameters,
|
...facetoolParameters,
|
||||||
});
|
});
|
||||||
dispatch(
|
dispatch(
|
||||||
addLogEntry({
|
addLogEntry({
|
||||||
timestamp: dateFormat(new Date(), 'isoDateTime'),
|
timestamp: dateFormat(new Date(), 'isoDateTime'),
|
||||||
message: `GFPGAN fix faces requested: ${JSON.stringify({
|
message: `Face restoration (${facetoolType}) requested: ${JSON.stringify(
|
||||||
file: imageToProcess.url,
|
{
|
||||||
...gfpganParameters,
|
file: imageToProcess.url,
|
||||||
})}`,
|
...facetoolParameters,
|
||||||
|
}
|
||||||
|
)}`,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -151,32 +151,6 @@ const makeSocketIOListeners = (
|
|||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
|
||||||
* Callback to run when we receive a 'gfpganResult' event.
|
|
||||||
*/
|
|
||||||
onGFPGANResult: (data: InvokeAI.ImageResultResponse) => {
|
|
||||||
try {
|
|
||||||
const { url, metadata, mtime } = data;
|
|
||||||
|
|
||||||
dispatch(
|
|
||||||
addImage({
|
|
||||||
uuid: uuidv4(),
|
|
||||||
url,
|
|
||||||
mtime,
|
|
||||||
metadata,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
dispatch(
|
|
||||||
addLogEntry({
|
|
||||||
timestamp: dateFormat(new Date(), 'isoDateTime'),
|
|
||||||
message: `Fixed faces: ${url}`,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* Callback to run when we receive a 'progressUpdate' event.
|
* Callback to run when we receive a 'progressUpdate' event.
|
||||||
* TODO: Add additional progress phases
|
* TODO: Add additional progress phases
|
||||||
|
@ -50,7 +50,7 @@ export const socketioMiddleware = () => {
|
|||||||
const {
|
const {
|
||||||
emitGenerateImage,
|
emitGenerateImage,
|
||||||
emitRunESRGAN,
|
emitRunESRGAN,
|
||||||
emitRunGFPGAN,
|
emitRunFacetool: emitRunGFPGAN,
|
||||||
emitDeleteImage,
|
emitDeleteImage,
|
||||||
emitRequestImages,
|
emitRequestImages,
|
||||||
emitRequestNewImages,
|
emitRequestNewImages,
|
||||||
|
@ -41,8 +41,10 @@ export const frontendToBackendParameters = (
|
|||||||
shouldRunESRGAN,
|
shouldRunESRGAN,
|
||||||
upscalingLevel,
|
upscalingLevel,
|
||||||
upscalingStrength,
|
upscalingStrength,
|
||||||
shouldRunGFPGAN,
|
shouldRunFacetool,
|
||||||
gfpganStrength,
|
facetoolStrength,
|
||||||
|
codeformerFidelity,
|
||||||
|
facetoolType,
|
||||||
shouldRandomizeSeed,
|
shouldRandomizeSeed,
|
||||||
} = optionsState;
|
} = optionsState;
|
||||||
|
|
||||||
@ -88,7 +90,7 @@ export const frontendToBackendParameters = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
let esrganParameters: false | { [k: string]: any } = false;
|
let esrganParameters: false | { [k: string]: any } = false;
|
||||||
let gfpganParameters: false | { [k: string]: any } = false;
|
let facetoolParameters: false | { [k: string]: any } = false;
|
||||||
|
|
||||||
if (shouldRunESRGAN) {
|
if (shouldRunESRGAN) {
|
||||||
esrganParameters = {
|
esrganParameters = {
|
||||||
@ -97,99 +99,19 @@ export const frontendToBackendParameters = (
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldRunGFPGAN) {
|
if (shouldRunFacetool) {
|
||||||
gfpganParameters = {
|
facetoolParameters = {
|
||||||
strength: gfpganStrength,
|
type: facetoolType,
|
||||||
|
strength: facetoolStrength,
|
||||||
};
|
};
|
||||||
|
if (facetoolType === 'codeformer') {
|
||||||
|
facetoolParameters.codeformer_fidelity = codeformerFidelity
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
generationParameters,
|
generationParameters,
|
||||||
esrganParameters,
|
esrganParameters,
|
||||||
gfpganParameters,
|
facetoolParameters,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const backendToFrontendParameters = (parameters: {
|
|
||||||
[key: string]: any;
|
|
||||||
}) => {
|
|
||||||
const {
|
|
||||||
prompt,
|
|
||||||
iterations,
|
|
||||||
steps,
|
|
||||||
cfg_scale,
|
|
||||||
threshold,
|
|
||||||
perlin,
|
|
||||||
height,
|
|
||||||
width,
|
|
||||||
sampler_name,
|
|
||||||
seed,
|
|
||||||
seamless,
|
|
||||||
hires_fix,
|
|
||||||
progress_images,
|
|
||||||
variation_amount,
|
|
||||||
with_variations,
|
|
||||||
facetool_strength,
|
|
||||||
upscale,
|
|
||||||
init_img,
|
|
||||||
init_mask,
|
|
||||||
strength,
|
|
||||||
} = parameters;
|
|
||||||
|
|
||||||
const options: { [key: string]: any } = {
|
|
||||||
shouldDisplayInProgress: progress_images,
|
|
||||||
// init
|
|
||||||
shouldGenerateVariations: false,
|
|
||||||
shouldRunESRGAN: false,
|
|
||||||
shouldRunGFPGAN: false,
|
|
||||||
initialImagePath: '',
|
|
||||||
maskPath: '',
|
|
||||||
};
|
|
||||||
|
|
||||||
if (variation_amount > 0) {
|
|
||||||
options.shouldGenerateVariations = true;
|
|
||||||
options.variationAmount = variation_amount;
|
|
||||||
if (with_variations) {
|
|
||||||
options.seedWeights = seedWeightsToString(with_variations);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (facetool_strength > 0) {
|
|
||||||
options.shouldRunGFPGAN = true;
|
|
||||||
options.gfpganStrength = facetool_strength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (upscale) {
|
|
||||||
options.shouldRunESRGAN = true;
|
|
||||||
options.upscalingLevel = upscale[0];
|
|
||||||
options.upscalingStrength = upscale[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (init_img) {
|
|
||||||
options.shouldUseInitImage = true;
|
|
||||||
options.initialImagePath = init_img;
|
|
||||||
options.strength = strength;
|
|
||||||
if (init_mask) {
|
|
||||||
options.maskPath = init_mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we had a prompt, add all the metadata, but if we don't have a prompt,
|
|
||||||
// we must have only done ESRGAN or GFPGAN so do not add that metadata
|
|
||||||
if (prompt) {
|
|
||||||
options.prompt = prompt;
|
|
||||||
options.iterations = iterations;
|
|
||||||
options.steps = steps;
|
|
||||||
options.cfgScale = cfg_scale;
|
|
||||||
options.threshold = threshold;
|
|
||||||
options.perlin = perlin;
|
|
||||||
options.height = height;
|
|
||||||
options.width = width;
|
|
||||||
options.sampler = sampler_name;
|
|
||||||
options.seed = seed;
|
|
||||||
options.seamless = seamless;
|
|
||||||
options.hiresFix = hires_fix;
|
|
||||||
}
|
|
||||||
|
|
||||||
return options;
|
|
||||||
};
|
|
||||||
|
@ -66,8 +66,8 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
|
|||||||
(state: RootState) => state.options.upscalingLevel
|
(state: RootState) => state.options.upscalingLevel
|
||||||
);
|
);
|
||||||
|
|
||||||
const gfpganStrength = useAppSelector(
|
const facetoolStrength = useAppSelector(
|
||||||
(state: RootState) => state.options.gfpganStrength
|
(state: RootState) => state.options.facetoolStrength
|
||||||
);
|
);
|
||||||
|
|
||||||
const { isProcessing, isConnected, isGFPGANAvailable, isESRGANAvailable } =
|
const { isProcessing, isConnected, isGFPGANAvailable, isESRGANAvailable } =
|
||||||
@ -195,7 +195,7 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
|
|||||||
Boolean(!intermediateImage) &&
|
Boolean(!intermediateImage) &&
|
||||||
isConnected &&
|
isConnected &&
|
||||||
!isProcessing &&
|
!isProcessing &&
|
||||||
gfpganStrength
|
facetoolStrength
|
||||||
) {
|
) {
|
||||||
handleClickFixFaces();
|
handleClickFixFaces();
|
||||||
} else {
|
} else {
|
||||||
@ -213,7 +213,7 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
|
|||||||
intermediateImage,
|
intermediateImage,
|
||||||
isConnected,
|
isConnected,
|
||||||
isProcessing,
|
isProcessing,
|
||||||
gfpganStrength,
|
facetoolStrength,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -270,7 +270,7 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
|
|||||||
!isGFPGANAvailable ||
|
!isGFPGANAvailable ||
|
||||||
Boolean(intermediateImage) ||
|
Boolean(intermediateImage) ||
|
||||||
!(isConnected && !isProcessing) ||
|
!(isConnected && !isProcessing) ||
|
||||||
!gfpganStrength
|
!facetoolStrength
|
||||||
}
|
}
|
||||||
onClick={handleClickFixFaces}
|
onClick={handleClickFixFaces}
|
||||||
/>
|
/>
|
||||||
|
@ -14,7 +14,9 @@ import { useAppDispatch } from '../../../app/store';
|
|||||||
import * as InvokeAI from '../../../app/invokeai';
|
import * as InvokeAI from '../../../app/invokeai';
|
||||||
import {
|
import {
|
||||||
setCfgScale,
|
setCfgScale,
|
||||||
setGfpganStrength,
|
setFacetoolStrength,
|
||||||
|
setCodeformerFidelity,
|
||||||
|
setFacetoolType,
|
||||||
setHeight,
|
setHeight,
|
||||||
setHiresFix,
|
setHiresFix,
|
||||||
setImg2imgStrength,
|
setImg2imgStrength,
|
||||||
@ -151,7 +153,7 @@ const ImageMetadataViewer = memo(
|
|||||||
<MetadataItem
|
<MetadataItem
|
||||||
label="Fix faces strength"
|
label="Fix faces strength"
|
||||||
value={strength}
|
value={strength}
|
||||||
onClick={() => dispatch(setGfpganStrength(strength))}
|
onClick={() => dispatch(setFacetoolStrength(strength))}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{type === 'esrgan' && scale !== undefined && (
|
{type === 'esrgan' && scale !== undefined && (
|
||||||
@ -321,12 +323,46 @@ const ImageMetadataViewer = memo(
|
|||||||
<MetadataItem
|
<MetadataItem
|
||||||
label="Strength"
|
label="Strength"
|
||||||
value={strength}
|
value={strength}
|
||||||
onClick={() =>
|
onClick={() => {
|
||||||
dispatch(setGfpganStrength(strength))
|
dispatch(setFacetoolStrength(strength));
|
||||||
}
|
dispatch(setFacetoolType('gfpgan'));
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
|
} else if (postprocess.type === 'codeformer') {
|
||||||
|
const { strength, fidelity } = postprocess;
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
key={i}
|
||||||
|
pl={'2rem'}
|
||||||
|
gap={1}
|
||||||
|
direction={'column'}
|
||||||
|
>
|
||||||
|
<Text size={'md'}>{`${
|
||||||
|
i + 1
|
||||||
|
}: Face restoration (Codeformer)`}</Text>
|
||||||
|
|
||||||
|
<MetadataItem
|
||||||
|
label="Strength"
|
||||||
|
value={strength}
|
||||||
|
onClick={() => {
|
||||||
|
dispatch(setFacetoolStrength(strength));
|
||||||
|
dispatch(setFacetoolType('codeformer'));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{fidelity && (
|
||||||
|
<MetadataItem
|
||||||
|
label="Fidelity"
|
||||||
|
value={fidelity}
|
||||||
|
onClick={() => {
|
||||||
|
dispatch(setCodeformerFidelity(fidelity));
|
||||||
|
dispatch(setFacetoolType('codeformer'));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
|
@ -6,21 +6,21 @@ import {
|
|||||||
useAppSelector,
|
useAppSelector,
|
||||||
} from '../../../../app/store';
|
} from '../../../../app/store';
|
||||||
import IAISwitch from '../../../../common/components/IAISwitch';
|
import IAISwitch from '../../../../common/components/IAISwitch';
|
||||||
import { setShouldRunGFPGAN } from '../../optionsSlice';
|
import { setShouldRunFacetool } from '../../optionsSlice';
|
||||||
|
|
||||||
export default function FaceRestore() {
|
export default function FaceRestore() {
|
||||||
const isGFPGANAvailable = useAppSelector(
|
const isGFPGANAvailable = useAppSelector(
|
||||||
(state: RootState) => state.system.isGFPGANAvailable
|
(state: RootState) => state.system.isGFPGANAvailable
|
||||||
);
|
);
|
||||||
|
|
||||||
const shouldRunGFPGAN = useAppSelector(
|
const shouldRunFacetool = useAppSelector(
|
||||||
(state: RootState) => state.options.shouldRunGFPGAN
|
(state: RootState) => state.options.shouldRunFacetool
|
||||||
);
|
);
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const handleChangeShouldRunGFPGAN = (e: ChangeEvent<HTMLInputElement>) =>
|
const handleChangeShouldRunFacetool = (e: ChangeEvent<HTMLInputElement>) =>
|
||||||
dispatch(setShouldRunGFPGAN(e.target.checked));
|
dispatch(setShouldRunFacetool(e.target.checked));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
@ -32,8 +32,8 @@ export default function FaceRestore() {
|
|||||||
<p>Restore Face</p>
|
<p>Restore Face</p>
|
||||||
<IAISwitch
|
<IAISwitch
|
||||||
isDisabled={!isGFPGANAvailable}
|
isDisabled={!isGFPGANAvailable}
|
||||||
isChecked={shouldRunGFPGAN}
|
isChecked={shouldRunFacetool}
|
||||||
onChange={handleChangeShouldRunGFPGAN}
|
onChange={handleChangeShouldRunFacetool}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
|
@ -3,18 +3,29 @@ import { Flex } from '@chakra-ui/react';
|
|||||||
import { RootState } from '../../../../app/store';
|
import { RootState } from '../../../../app/store';
|
||||||
import { useAppDispatch, useAppSelector } from '../../../../app/store';
|
import { useAppDispatch, useAppSelector } from '../../../../app/store';
|
||||||
|
|
||||||
import { OptionsState, setGfpganStrength } from '../../optionsSlice';
|
import {
|
||||||
|
FacetoolType,
|
||||||
|
OptionsState,
|
||||||
|
setCodeformerFidelity,
|
||||||
|
setFacetoolStrength,
|
||||||
|
setFacetoolType,
|
||||||
|
} from '../../optionsSlice';
|
||||||
|
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash';
|
||||||
import { SystemState } from '../../../system/systemSlice';
|
import { SystemState } from '../../../system/systemSlice';
|
||||||
import IAINumberInput from '../../../../common/components/IAINumberInput';
|
import IAINumberInput from '../../../../common/components/IAINumberInput';
|
||||||
|
import IAISelect from '../../../../common/components/IAISelect';
|
||||||
|
import { FACETOOL_TYPES } from '../../../../app/constants';
|
||||||
|
import { ChangeEvent } from 'react';
|
||||||
|
|
||||||
const optionsSelector = createSelector(
|
const optionsSelector = createSelector(
|
||||||
(state: RootState) => state.options,
|
(state: RootState) => state.options,
|
||||||
(options: OptionsState) => {
|
(options: OptionsState) => {
|
||||||
return {
|
return {
|
||||||
gfpganStrength: options.gfpganStrength,
|
facetoolStrength: options.facetoolStrength,
|
||||||
|
facetoolType: options.facetoolType,
|
||||||
|
codeformerFidelity: options.codeformerFidelity,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -43,13 +54,26 @@ const systemSelector = createSelector(
|
|||||||
*/
|
*/
|
||||||
const FaceRestoreOptions = () => {
|
const FaceRestoreOptions = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { gfpganStrength } = useAppSelector(optionsSelector);
|
const { facetoolStrength, facetoolType, codeformerFidelity } =
|
||||||
|
useAppSelector(optionsSelector);
|
||||||
const { isGFPGANAvailable } = useAppSelector(systemSelector);
|
const { isGFPGANAvailable } = useAppSelector(systemSelector);
|
||||||
|
|
||||||
const handleChangeStrength = (v: number) => dispatch(setGfpganStrength(v));
|
const handleChangeStrength = (v: number) => dispatch(setFacetoolStrength(v));
|
||||||
|
|
||||||
|
const handleChangeCodeformerFidelity = (v: number) =>
|
||||||
|
dispatch(setCodeformerFidelity(v));
|
||||||
|
|
||||||
|
const handleChangeFacetoolType = (e: ChangeEvent<HTMLSelectElement>) =>
|
||||||
|
dispatch(setFacetoolType(e.target.value as FacetoolType));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex direction={'column'} gap={2}>
|
<Flex direction={'column'} gap={2}>
|
||||||
|
<IAISelect
|
||||||
|
label="Type"
|
||||||
|
validValues={FACETOOL_TYPES.concat()}
|
||||||
|
value={facetoolType}
|
||||||
|
onChange={handleChangeFacetoolType}
|
||||||
|
/>
|
||||||
<IAINumberInput
|
<IAINumberInput
|
||||||
isDisabled={!isGFPGANAvailable}
|
isDisabled={!isGFPGANAvailable}
|
||||||
label="Strength"
|
label="Strength"
|
||||||
@ -57,10 +81,23 @@ const FaceRestoreOptions = () => {
|
|||||||
min={0}
|
min={0}
|
||||||
max={1}
|
max={1}
|
||||||
onChange={handleChangeStrength}
|
onChange={handleChangeStrength}
|
||||||
value={gfpganStrength}
|
value={facetoolStrength}
|
||||||
width="90px"
|
width="90px"
|
||||||
isInteger={false}
|
isInteger={false}
|
||||||
/>
|
/>
|
||||||
|
{facetoolType === 'codeformer' && (
|
||||||
|
<IAINumberInput
|
||||||
|
isDisabled={!isGFPGANAvailable}
|
||||||
|
label="Fidelity"
|
||||||
|
step={0.05}
|
||||||
|
min={0}
|
||||||
|
max={1}
|
||||||
|
onChange={handleChangeCodeformerFidelity}
|
||||||
|
value={codeformerFidelity}
|
||||||
|
width="90px"
|
||||||
|
isInteger={false}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -3,9 +3,12 @@ import type { PayloadAction } from '@reduxjs/toolkit';
|
|||||||
import * as InvokeAI from '../../app/invokeai';
|
import * as InvokeAI from '../../app/invokeai';
|
||||||
import promptToString from '../../common/util/promptToString';
|
import promptToString from '../../common/util/promptToString';
|
||||||
import { seedWeightsToString } from '../../common/util/seedWeightPairs';
|
import { seedWeightsToString } from '../../common/util/seedWeightPairs';
|
||||||
|
import { FACETOOL_TYPES } from '../../app/constants';
|
||||||
|
|
||||||
export type UpscalingLevel = 2 | 4;
|
export type UpscalingLevel = 2 | 4;
|
||||||
|
|
||||||
|
export type FacetoolType = typeof FACETOOL_TYPES[number];
|
||||||
|
|
||||||
export interface OptionsState {
|
export interface OptionsState {
|
||||||
prompt: string;
|
prompt: string;
|
||||||
iterations: number;
|
iterations: number;
|
||||||
@ -18,7 +21,9 @@ export interface OptionsState {
|
|||||||
perlin: number;
|
perlin: number;
|
||||||
seed: number;
|
seed: number;
|
||||||
img2imgStrength: number;
|
img2imgStrength: number;
|
||||||
gfpganStrength: number;
|
facetoolType: FacetoolType;
|
||||||
|
facetoolStrength: number;
|
||||||
|
codeformerFidelity: number;
|
||||||
upscalingLevel: UpscalingLevel;
|
upscalingLevel: UpscalingLevel;
|
||||||
upscalingStrength: number;
|
upscalingStrength: number;
|
||||||
shouldUseInitImage: boolean;
|
shouldUseInitImage: boolean;
|
||||||
@ -31,7 +36,7 @@ export interface OptionsState {
|
|||||||
variationAmount: number;
|
variationAmount: number;
|
||||||
seedWeights: string;
|
seedWeights: string;
|
||||||
shouldRunESRGAN: boolean;
|
shouldRunESRGAN: boolean;
|
||||||
shouldRunGFPGAN: boolean;
|
shouldRunFacetool: boolean;
|
||||||
shouldRandomizeSeed: boolean;
|
shouldRandomizeSeed: boolean;
|
||||||
showAdvancedOptions: boolean;
|
showAdvancedOptions: boolean;
|
||||||
activeTab: number;
|
activeTab: number;
|
||||||
@ -63,8 +68,10 @@ const initialOptionsState: OptionsState = {
|
|||||||
shouldRunESRGAN: false,
|
shouldRunESRGAN: false,
|
||||||
upscalingLevel: 4,
|
upscalingLevel: 4,
|
||||||
upscalingStrength: 0.75,
|
upscalingStrength: 0.75,
|
||||||
shouldRunGFPGAN: false,
|
shouldRunFacetool: false,
|
||||||
gfpganStrength: 0.8,
|
facetoolStrength: 0.8,
|
||||||
|
facetoolType: 'gfpgan',
|
||||||
|
codeformerFidelity: 0.75,
|
||||||
shouldRandomizeSeed: true,
|
shouldRandomizeSeed: true,
|
||||||
showAdvancedOptions: true,
|
showAdvancedOptions: true,
|
||||||
activeTab: 0,
|
activeTab: 0,
|
||||||
@ -117,8 +124,11 @@ export const optionsSlice = createSlice({
|
|||||||
setImg2imgStrength: (state, action: PayloadAction<number>) => {
|
setImg2imgStrength: (state, action: PayloadAction<number>) => {
|
||||||
state.img2imgStrength = action.payload;
|
state.img2imgStrength = action.payload;
|
||||||
},
|
},
|
||||||
setGfpganStrength: (state, action: PayloadAction<number>) => {
|
setFacetoolStrength: (state, action: PayloadAction<number>) => {
|
||||||
state.gfpganStrength = action.payload;
|
state.facetoolStrength = action.payload;
|
||||||
|
},
|
||||||
|
setCodeformerFidelity: (state, action: PayloadAction<number>) => {
|
||||||
|
state.codeformerFidelity = action.payload;
|
||||||
},
|
},
|
||||||
setUpscalingLevel: (state, action: PayloadAction<UpscalingLevel>) => {
|
setUpscalingLevel: (state, action: PayloadAction<UpscalingLevel>) => {
|
||||||
state.upscalingLevel = action.payload;
|
state.upscalingLevel = action.payload;
|
||||||
@ -229,8 +239,8 @@ export const optionsSlice = createSlice({
|
|||||||
// (postprocess: InvokeAI.PostProcessedImageMetadata) => {
|
// (postprocess: InvokeAI.PostProcessedImageMetadata) => {
|
||||||
// if (postprocess.type === 'gfpgan') {
|
// if (postprocess.type === 'gfpgan') {
|
||||||
// const { strength } = postprocess;
|
// const { strength } = postprocess;
|
||||||
// if (strength) state.gfpganStrength = strength;
|
// if (strength) state.facetoolStrength = strength;
|
||||||
// state.shouldRunGFPGAN = true;
|
// state.shouldRunFacetool = true;
|
||||||
// postprocessingNotDone = postprocessingNotDone.filter(
|
// postprocessingNotDone = postprocessingNotDone.filter(
|
||||||
// (p) => p !== 'gfpgan'
|
// (p) => p !== 'gfpgan'
|
||||||
// );
|
// );
|
||||||
@ -250,7 +260,7 @@ export const optionsSlice = createSlice({
|
|||||||
|
|
||||||
// postprocessingNotDone.forEach((p) => {
|
// postprocessingNotDone.forEach((p) => {
|
||||||
// if (p === 'esrgan') state.shouldRunESRGAN = false;
|
// if (p === 'esrgan') state.shouldRunESRGAN = false;
|
||||||
// if (p === 'gfpgan') state.shouldRunGFPGAN = false;
|
// if (p === 'gfpgan') state.shouldRunFacetool = false;
|
||||||
// });
|
// });
|
||||||
|
|
||||||
if (prompt) state.prompt = promptToString(prompt);
|
if (prompt) state.prompt = promptToString(prompt);
|
||||||
@ -260,7 +270,7 @@ export const optionsSlice = createSlice({
|
|||||||
if (threshold) state.threshold = threshold;
|
if (threshold) state.threshold = threshold;
|
||||||
if (typeof threshold === 'undefined') state.threshold = 0;
|
if (typeof threshold === 'undefined') state.threshold = 0;
|
||||||
if (perlin) state.perlin = perlin;
|
if (perlin) state.perlin = perlin;
|
||||||
if (typeof perlin === 'undefined') state.perlin = 0;
|
if (typeof perlin === 'undefined') state.perlin = 0;
|
||||||
if (typeof seamless === 'boolean') state.seamless = seamless;
|
if (typeof seamless === 'boolean') state.seamless = seamless;
|
||||||
if (typeof hires_fix === 'boolean') state.hiresFix = hires_fix;
|
if (typeof hires_fix === 'boolean') state.hiresFix = hires_fix;
|
||||||
if (width) state.width = width;
|
if (width) state.width = width;
|
||||||
@ -272,8 +282,11 @@ export const optionsSlice = createSlice({
|
|||||||
...initialOptionsState,
|
...initialOptionsState,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
setShouldRunGFPGAN: (state, action: PayloadAction<boolean>) => {
|
setShouldRunFacetool: (state, action: PayloadAction<boolean>) => {
|
||||||
state.shouldRunGFPGAN = action.payload;
|
state.shouldRunFacetool = action.payload;
|
||||||
|
},
|
||||||
|
setFacetoolType: (state, action: PayloadAction<FacetoolType>) => {
|
||||||
|
state.facetoolType = action.payload;
|
||||||
},
|
},
|
||||||
setShouldRunESRGAN: (state, action: PayloadAction<boolean>) => {
|
setShouldRunESRGAN: (state, action: PayloadAction<boolean>) => {
|
||||||
state.shouldRunESRGAN = action.payload;
|
state.shouldRunESRGAN = action.payload;
|
||||||
@ -310,7 +323,9 @@ export const {
|
|||||||
setSeamless,
|
setSeamless,
|
||||||
setHiresFix,
|
setHiresFix,
|
||||||
setImg2imgStrength,
|
setImg2imgStrength,
|
||||||
setGfpganStrength,
|
setFacetoolStrength,
|
||||||
|
setFacetoolType,
|
||||||
|
setCodeformerFidelity,
|
||||||
setUpscalingLevel,
|
setUpscalingLevel,
|
||||||
setUpscalingStrength,
|
setUpscalingStrength,
|
||||||
setShouldUseInitImage,
|
setShouldUseInitImage,
|
||||||
@ -324,7 +339,7 @@ export const {
|
|||||||
setSeedWeights,
|
setSeedWeights,
|
||||||
setVariationAmount,
|
setVariationAmount,
|
||||||
setAllParameters,
|
setAllParameters,
|
||||||
setShouldRunGFPGAN,
|
setShouldRunFacetool,
|
||||||
setShouldRunESRGAN,
|
setShouldRunESRGAN,
|
||||||
setShouldRandomizeSeed,
|
setShouldRandomizeSeed,
|
||||||
setShowAdvancedOptions,
|
setShowAdvancedOptions,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user