Este repositório contém a implementação oficial do artigo "InsertDiffusion: Identity Preserving Visualization of Objects through a Training-Free Diffusion Architecture".
A implementação oferece suporte a dois modos de execução diferentes:
Além disso, a implementação oferece a opção de colorir as imagens pré-existentes ou geradas. Quando não são utilizadas imagens já coloridas, isso melhora drasticamente o realismo.
Além disso, um novo ambiente pode ser criado do zero (modo de substituição de fundo) ou uma imagem pré-existente pode ser usada e adaptada.
Todos os recursos estão disponíveis na CLI main.py
e também podem ser integrados em seus próprios projetos. Para usar a CLI ou o código é necessário um ambiente com tocha, travesseiro, pandas, transformadores e difusores.
Para inserir uma imagem em um plano de fundo recém-criado, execute:
python main.py --image " <path to your image> " --background_prompt " <your prompt> "
Então, por exemplo:
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 "
Em vez de fornecer um prompt diretamente, você pode usar os recursos de prompt automático, fornecendo as informações necessárias. Para bicicletas é necessário fornecer o local desejado, o índice da bicicleta e um caminho para a ficha técnica. Para carros você terá que fornecer a nova localização desejada, o fabricante do carro e o tipo de carro. Para produtos, apenas o novo local e um tipo de produto são necessários.
Para mais opções e inserção em um determinado plano de fundo, consulte a documentação completa da CLI abaixo.
Em vez de usar a CLI, você pode integrar o procedimento ao seu código com esta função python (novamente certifique-se de ter todas as dependências instaladas e copie o módulo utils para o seu projeto):
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
Implementamos um método adicional para gerar imagens Biked a partir de nuvens de pontos e depois inseri-las em um plano de fundo. Este método não funciona bem, no entanto, e, portanto, não é central para a nossa pesquisa . A geração a partir de nuvens de pontos foi implementada por Ioan-Daniel Craciun e é baseada em um DDPM/DDIM implementado e treinado por Jiajae Fan .
Para criar imagens a partir de nuvens de pontos, remova o argumento --image
da sua chamada CLI. No modo de ponto, você deve fornecer um caminho de folha de dados via --datasheet_path
. Assim, o comando CLI mínimo torna-se:
python main.py --point --datasheet_path " <path to datasheet> " --background_prompt " <your prompt> "
Você também pode usar a solicitação automática no modo de ponto.
Para integrar a geração de bicicletas a partir de nuvens de pontos em seu projeto copie a pasta utils e utilize a seguinte função:
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' )
A imagem retornada por esta função está pronta para ser usada para colorização ou inserção.
Se você estiver usando uma imagem sem cor, adicione --colorize
a uma das chamadas CLI anteriores. Além disso, você precisa fornecer um prompt de colorização via --colorization_prompt
ou usar o prompt automático fornecendo uma cor via --color
.
Um exemplo de chamada CLI poderia ser:
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 "
Alternativamente, para integrar a colorização ao seu projeto, copie o módulo utils e use:
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
Nota : CLI ainda está em construção e pode estar sujeito a alterações.
Nota : Quando aplicável, os valores padrão representam os parâmetros determinados em nossos experimentos. Mas valores diferentes podem ser ideais dependendo do caso de uso específico.
argumento | tipo | descrição |
---|---|---|
--imagem | corda | caminho para uma imagem para começar, mutuamente exclusivo com --points |
--pontos | quando pontos são usados, o algoritmo é executado no modo de nuvem de pontos e gera primeiro um contorno de bicicleta a partir de uma nuvem de pontos, mutuamente exclusivo com --image | |
--mask_threshold | interno | para pintura interna, limite para distinguir o fundo branco do primeiro plano colorido |
--background_prompt | corda | o prompt para a geração de plano de fundo |
--negative_prompt | corda | prompt negativo para geração de plano de fundo |
--background_image | corda | string para uma imagem de fundo a ser usada como ponto de partida, relevante apenas se --composition Strength for definido como um valor menor que 1 |
--composição_força | flutuador | determina o quanto alterar a imagem de fundo do ponto inicial, apenas usado é --background_image é definido, intervalo 0-1 |
--auto_bike_prompt | se os prompts definidos forem criados automaticamente usando o modelo para bicicletas, requer que --place, --datasheet_path e --bike_idx sejam definidos | |
--auto_car_prompt | se os prompts definidos forem criados automaticamente usando o modelo para carros, requer que --place, --car_manufacturer e --car_type sejam definidos | |
--auto_produto | se os prompts definidos forem criados automaticamente usando o modelo para produtos, requer que --place e --product_type sejam definidos | |
--lugar | corda | descrição do local onde o objeto será inserido, usado apenas se um dos modelos de prompt automático for usado |
--cor | corda | se estiver usando o prompt automático, qual cor a bicicleta tem |
--datasheet_path | corda | se estiver usando o prompt automático para bicicletas, caminho para a folha de dados para pesquisa do tipo de bicicleta |
--bike_idx | interno | se estiver usando o prompt automático para bicicletas, indexe na folha de dados para pesquisa do tipo de bicicleta |
--car_fabricante | corda | se estiver usando o prompt automático para carros, fabricante do carro, por exemplo, BMW |
--car_type | corda | se estiver usando o prompt automático para carros, tipo de carro, por exemplo, SUV ou X5 |
--produto_tipo | corda | se estiver usando prompt automático para produtos, tipo de produto, por exemplo, lâmpada |
--inpainting_model | corda | qual modelo usar para geração de plano de fundo (huggingface id) |
--img2img_modelo | corda | qual modelo usar para a etapa de redifusão (huggingface id) |
--img2img_strength | flutuador | quanto da imagem original produz ruído na rediffusão |
--inpainting_steps | interno | quantas etapas de difusão executar para pintura interna |
--inpainting_guidance | flutuador | quanta orientação sem classificador aplicar na pintura interna |
--img2img_guidance | flutuador | quanta orientação sem classificador aplicar na rediffusão |
--output_folder | corda | caminho para a pasta na qual as imagens de saída devem ser salvas |
--colorizar | se deve colorir a imagem antes de pintar | |
--colorization_model | corda | qual modelo usar para colorização (huggingface id) |
--upscaling_model | corda | qual modelo usar para upscaling, necessário para colorização (huggingface id) |
--colorization_prompt | corda | prompt para colorização, não é necessário que datasheet_path e color sejam fornecidos |
--colorization_negative_prompt | corda | prompt negativo para colorização |
--do_not_fill_holes | alternar preenchimento de furo para máscara de colorização, relevante apenas ao colorir | |
--dilatação | interno | quanto estender a máscara para colorização, relevante apenas na hora de colorir |
--colorization_strength | flutuador | quanta difusão aplicar para colorização, relevante apenas ao colorir |
--colorization_prompt_guidance | flutuador | quanta orientação sem classificador aplicar durante a colorização, relevante apenas ao colorir |
--escala | flutuador | quanto diminuir ou aumentar a bicicleta, valores mais altos resultam na bicicleta ocupando mais espaço no quadro, o padrão é 1. |
--fração_down | flutuador | posição relativa y da bicicleta (centro da), valores mais altos colocam a bicicleta mais próxima da borda inferior da imagem, o padrão é 0,5 (centralizado) |
--fração_direita | flutuador | posição relativa x da bicicleta (centro da), valores mais altos colocam a bicicleta mais próxima da borda direita da imagem, o padrão é 0,5 (centralizado) |
--ckpt_id | corda | id do ponto de verificação a ser usado para a criação de contornos de bicicletas a partir de nuvens de pontos, relevante apenas no modo de pontos |
--bike_mask_dilation | interno | quanto estender as máscaras geradas a partir das nuvens de pontos, relevante apenas no modo de pontos |
--do_not_fill_bike_holes | se deve ser aplicado preenchimento de furos em máscaras de bicicleta, relevante apenas no modo pontual | |
--wheel_design | interno | qual design de roda usar para a geração de contornos de bicicleta, atualmente apenas 0 e 1 são implementados, relevantes apenas no modo de ponto |
Um script adicional interactive.py
fornece uma implementação para gerar imagens interativamente no estilo Human-in-the-Loop. Isso significa que a cada etapa são geradas cinco opções em paralelo e o usuário é solicitado a escolher a melhor opção. Então, apenas a imagem escolhida é utilizada para a próxima etapa.
Nenhum argumento CLI adicional é aceito pelo script e o usuário será solicitado a tomar todas as decisões.
Para executar em modo interativo execute:
python interactive.py
O código de avaliação usado ou nosso artigo pode ser encontrado em ./evaluation
. Observe que as métricas quantitativas foram calculadas usando o seguinte comando CLI:
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> "
Métricas de avaliação humana e estatísticas inferenciais foram calculadas usando o caderno fornecido.
Se achar nosso trabalho útil e quiser usá-lo em sua pesquisa ou projeto, cite o artigo da seguinte forma:
@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 } ,
}