Ce référentiel contient l'implémentation officielle de l'article "InsertDiffusion: Identity Preserving Visualization of Objects through a Training-Free Diffusion Architecture".
L'implémentation prend en charge deux modes d'exécution différents :
De plus, l'implémentation offre la possibilité de coloriser les images préexistantes ou générées. Lorsque vous n'utilisez pas d'images déjà colorées, cela améliore considérablement le réalisme.
De plus, un nouvel environnement peut être créé à partir de zéro (mode de remplacement d’arrière-plan) ou une image préexistante peut être utilisée et adaptée.
Toutes les fonctionnalités sont disponibles depuis la CLI main.py
et peuvent également être intégrées dans vos propres projets. Pour utiliser la CLI ou le code, un environnement avec une torche, un oreiller, des pandas, des transformateurs et des diffuseurs est requis.
Pour insérer une image dans un arrière-plan nouvellement créé, exécutez :
python main.py --image " <path to your image> " --background_prompt " <your prompt> "
Ainsi par exemple :
python main.py --image " ./test_images/bikes/166.png " --background_prompt " a bicycle centered in frame in munich, 8k, red gemini, 50mm, f2.8, cinematic "
Au lieu de fournir une invite directement, vous pouvez utiliser les fonctionnalités d'invite automatique en fournissant les informations nécessaires. Pour les vélos vous devez fournir l'emplacement souhaité, l'index du vélo et un chemin vers la fiche technique. Pour les voitures, vous devrez indiquer le nouvel emplacement souhaité, le constructeur automobile et le type de voiture. Pour les produits, seuls le nouvel emplacement et un type de produit sont requis.
Pour plus d'options et d'insertion dans un arrière-plan donné, consultez la documentation CLI complète ci-dessous.
Au lieu d'utiliser la CLI, vous pouvez intégrer la procédure dans votre code avec cette fonction python (assurez-vous encore une fois d'avoir toutes les dépendances installées et copiez le module utils dans votre projet) :
from utils import get_mask_from_image , sd_inpainting , sd_img2img , paste_image
def insert_diffusion ( image : Image , mask_threshold : int , prompt : str , negative_prompt : str , img2img_model : str , inpainting_model : str , img2img_strength : float , inpainting_steps : int , inpainting_guidance : float , img2img_guidance : float , background_image : Image = None , composition_strength : float = 1 ) -> Image :
mask = get_mask_from_image ( image , mask_threshold )
if background_image is not None :
image = paste_image ( image , background_image )
inpainted = sd_inpainting ( inpainting_model , image , mask , prompt , negative_prompt , inpainting_guidance , inpainting_steps , inpainting_strength = composition_strength )
result = sd_img2img ( img2img_model , inpainted , prompt , negative_prompt , img2img_strength , img2img_guidance )
return result
Nous avons implémenté une méthode supplémentaire pour générer des images Biked à partir de nuages de points, puis les insérer dans un arrière-plan. Cette méthode ne fonctionne cependant pas bien et n’est donc pas au cœur de notre recherche . La génération à partir de nuages de points a été implémentée par Ioan-Daniel Craciun et est basée sur un DDPM/DDIM implémenté et formé par Jiajae Fan .
Pour créer des images à partir de nuages de points, supprimez l'argument --image
de votre appel CLI. En mode point, vous devez fournir un chemin de feuille de données via --datasheet_path
. Ainsi, la commande CLI minimale devient :
python main.py --point --datasheet_path " <path to datasheet> " --background_prompt " <your prompt> "
Vous pouvez également utiliser l'invite automatique en mode point.
Pour intégrer la génération de vélos à partir de nuages de points dans votre projet copiez le dossier utils et utilisez la fonction suivante :
from utils import get_mask_and_background
from utils import inpaint as bike_inpainting
def bike_diffusion ( parameter_csv_path : str , device : torch . device , ckpt_id : str = '29000' , mask_dilation : int = 5 , mask_fill_holes : bool = True , bike_idx : int = 0 , wheel_design_type : int = 0 , width : int = 256 , height : int = 256 ):
assert wheel_design_type == 0 or wheel_design_type == 1
mask , background = get_mask_and_background ( parameter_csv_path , bike_idx , wheel_design_type , width , height )
bike_img = bike_inpainting ( background , mask , device , 50 , ckpt_id , mask_dilation , mask_fill_holes )
return bike_img . convert ( 'RGB' )
L'image renvoyée par cette fonction est prête à être utilisée pour la colorisation ou l'insertion.
Si vous utilisez une image non colorée, ajoutez --colorize
à l'un des appels CLI précédents. De plus, vous devez fournir une invite de colorisation via --colorization_prompt
ou utiliser l'invite automatique en fournissant une couleur via --color
.
Un exemple d'appel CLI pourrait être :
python main.py --image " ./test_images/bike_outline/168.png " --colorize --datasheet_path " ./csv/df_parameters_final.csv " --place " beach at sunset " --color " purple " --bike_idx 5 "
Alternativement, pour intégrer la colorisation dans votre projet, copiez le module utils et utilisez :
from utils import sd_colorization
def colorization ( image : Image , colorization_model : str , upscaling_model : str , colorization_prompt : str , colorization_negative_prompt : str , fill_holes : bool , dilation : int , strength : float , prompt_guidance : float ):
colorized = sd_colorization ( colorization_model , upscaling_model , image , colorization_prompt , negative_prompt = colorization_negative_prompt , fill_holes = fill_holes , dilation_iterations = dilation , colorization_strength = strength , prompt_guidance = prompt_guidance )
return colorized
Remarque : La CLI est encore en construction et peut être sujette à modification.
Remarque : Le cas échéant, les valeurs par défaut représentent les paramètres déterminés dans nos expériences. Mais différentes valeurs peuvent être optimales en fonction du cas d'utilisation spécifique.
argument | taper | description |
---|---|---|
--image | chaîne | chemin vers une image à partir de laquelle commencer, mutuellement exclusif avec --points |
--points | lorsque des points sont utilisés, l'algorithme s'exécute en mode nuage de points et génère d'abord un contour de vélo à partir d'un nuage de points, mutuellement exclusif avec --image | |
--mask_threshold | int | pour l'inpainting, seuil permettant de distinguer le fond blanc du premier plan coloré |
--background_prompt | chaîne | l'invite pour la génération en arrière-plan |
--negative_prompt | chaîne | invite négative pour la génération d'arrière-plan |
--background_image | chaîne | chaîne vers une image d'arrière-plan à utiliser comme point de départ, pertinent uniquement si --composition Strength est défini sur une valeur inférieure à 1 |
--composition_force | flotter | détermine dans quelle mesure il faut modifier l'image d'arrière-plan du point de départ, seul utilisé est --background_image est défini, plage 0-1 |
--auto_bike_prompt | si les invites définies seront automatiquement créées à l'aide du modèle pour les vélos, nécessite que --place, --datasheet_path et --bike_idx soient définis | |
--auto_car_prompt | si les invites définies seront automatiquement créées à l'aide du modèle pour les voitures, nécessite que --place, --car_manufacturer et --car_type soient définis | |
--auto_product | si les invites définies seront automatiquement créées à l'aide du modèle pour les produits, nécessite que --place et --product_type soient définis | |
--lieu | chaîne | description de l'emplacement où l'objet doit être inséré, utilisée uniquement si l'un des modèles d'invite automatique est utilisé |
--couleur | chaîne | si vous utilisez l'invite automatique, quelle couleur a le vélo |
--datasheet_path | chaîne | si vous utilisez l'invite automatique pour les vélos, chemin vers la fiche technique pour la recherche du type de vélo |
--bike_idx | int | si vous utilisez l'invite automatique pour les vélos, indexez dans la fiche technique pour rechercher le type de vélo |
--car_manufacturer | chaîne | si vous utilisez l'invite automatique pour les voitures, le fabricant de la voiture, par exemple BMW |
--car_type | chaîne | si vous utilisez l'invite automatique pour les voitures, type de voiture, par exemple SUV ou X5 |
--type_produit | chaîne | si vous utilisez l'invite automatique pour les produits, type de produit, par exemple lampe |
--inpainting_model | chaîne | quel modèle utiliser pour la génération d'arrière-plan (huggingface id) |
--img2img_model | chaîne | quel modèle utiliser pour l'étape de rediffusion (huggingface id) |
--img2img_force | flotter | quelle part de l'image originale doit faire du bruit lors de la rediffusion |
--inpainting_steps | int | combien d'étapes de diffusion effectuer pour l'inpainting |
--inpainting_guidance | flotter | combien de conseils sans classificateur appliquer en inpainting |
--img2img_guidance | flotter | quelle quantité de conseils sans classificateur appliquer dans la rediffusion |
--output_folder | chaîne | chemin d'accès au dossier dans lequel les images de sortie doivent être enregistrées |
--coloriser | s'il faut coloriser l'image avant de la peindre | |
--colorization_model | chaîne | quel modèle utiliser pour la colorisation (huggingface id) |
--upscaling_model | chaîne | quel modèle utiliser pour la mise à l'échelle, nécessaire à la colorisation (huggingface id) |
--colorization_prompt | chaîne | invite pour la colorisation, ce n'est pas nécessaire si datasheet_path et la couleur sont fournis |
--colorization_negative_prompt | chaîne | invite négative pour la colorisation |
--do_not_fill_holes | basculer le remplissage des trous pour le masque de colorisation, pertinent uniquement lors de la colorisation | |
--dilatation | int | combien étendre le masque pour la colorisation, pertinent uniquement lors de la colorisation |
--colorization_strength | flotter | quelle quantité de diffusion appliquer pour la colorisation, pertinent uniquement lors de la colorisation |
--colorization_prompt_guidance | flotter | quelle quantité de conseils sans classificateur appliquer pendant la colorisation, pertinent uniquement lors de la colorisation |
--échelle | flotter | de combien il faut réduire ou augmenter le vélo, des valeurs plus élevées entraînent que le vélo occupe plus de place dans le cadre, la valeur par défaut est 1. |
--fraction_down | flotter | position relative y du (centre du) vélo, les valeurs plus élevées placent le vélo plus près du bord inférieur de l'image, la valeur par défaut est 0,5 (centré) |
--fraction_right | flotter | position relative x du (centre du) vélo, des valeurs plus élevées placent le vélo plus près du bord droit de l'image, la valeur par défaut est 0,5 (centré) |
--ckpt_id | chaîne | identifiant du point de contrôle à utiliser pour la création de contours de vélo à partir de nuages de points, pertinent uniquement en mode points |
--bike_mask_dilation | int | dans quelle mesure étendre les masques générés à partir des nuages de points, pertinent uniquement en mode points |
--do_not_fill_bike_holes | s'il faut appliquer un remplissage de trous sur les masques de vélo, pertinent uniquement en mode point | |
--wheel_design | int | quelle conception de roue utiliser pour la génération des contours de vélo, actuellement seuls 0 et 1 sont implémentés, pertinent uniquement en mode point |
Un script supplémentaire interactive.py
fournit une implémentation pour générer des images de manière interactive à la manière d'un humain dans la boucle. Cela signifie qu'à chaque étape, cinq options sont générées en parallèle et l'utilisateur est invité à choisir la meilleure option. Ensuite, seule l’image choisie est utilisée pour l’étape suivante.
Aucun argument CLI supplémentaire n'est accepté par le script, l'utilisateur sera invité à prendre toutes les décisions.
Pour exécuter en mode interactif, exécutez :
python interactive.py
Le code d'évaluation utilisé ou notre article se trouve sous ./evaluation
. Notez que les métriques quantitatives ont été calculées à l'aide de la commande CLI suivante :
python evaluate.py --exp_name " <experiment name> " --gen_file_path " <path to generated images> " --ref_file_path " <path to reference files> " --masks_path " <only used for composition, path to masks> "
Les mesures d'évaluation humaine et les statistiques inférentielles ont été calculées à l'aide du cahier fourni.
Si vous trouvez notre travail utile et souhaitez l'utiliser pour votre recherche ou votre projet, veuillez citer l'article comme suit :
@misc { 2407.10592 ,
Author = { Phillip Mueller and Jannik Wiese and Ioan Craciun and Lars Mikelsons } ,
Title = { InsertDiffusion: Identity Preserving Visualization of Objects through a Training-Free Diffusion Architecture } ,
Year = { 2024 } ,
Eprint = { arXiv:2407.10592 } ,
}