Mascare qualquer coisa digitando o nome: máscaras e inpainting com o Florence 2 no ComfyUI

Digite «crown», «tiger» ou «glasses» e o Florence 2 devolve uma máscara. Monte o fluxo no ComfyUI, faça inpainting da área mascarada com o SD 1.5, combine duas máscaras em uma e transforme uma máscara numa borda.

Anton Tenitsky13 de outubro de 20267 min de leituraVersão em vídeo abaixo

Este guia foi traduzido do inglês com IA e pode conter erros. Leia o original.

Uma caveira branca usando uma coroa, com a coroa destacada em verde por uma máscara do Florence 2 guiada por texto

Digite «t-shirt» e você recebe uma máscara da camiseta. Digite «face», «bookshelf» ou «wall» e recebe essas. O Florence 2 é um modelo de visão da Microsoft que encontra objetos a partir de uma descrição em texto e, no ComfyUI, transforma isso numa máscara que você pode usar no inpainting. É quase inacreditável o que ele faz, mas tem ressalvas, e também vou tratar delas.

O Florence 2 é descrito no artigo Florence-2: Advancing a Unified Representation for a Variety of Vision Tasks (Xiao et al., 2023). É um modelo de pesquisa para muitas tarefas (legendas, detecção de objetos, segmentação e mais); aqui o uso só para máscaras.

Em resumo

  • Nós: ComfyUI-Florence2 (do Kijai), ComfyUI Essentials, Universal Styler para saída de texto, rgthree para comparar.
  • Modelo: Florence-2-large para as melhores máscaras; base como alternativa.
  • Tarefa: referring_expression_segmentation, depois digite o que mascarar.
  • Inpaint: InpaintModelConditioning com a imagem original e a máscara; denoise em torno de 0,5–0,62.
  • Máscaras se combinam: o Mask Composite (add) une duas máscaras; Grow Mask mais multiply faz uma borda.

Novo no ComfyUI? Comece por noções básicas do ComfyUI e texto para imagem e instalando o ComfyUI Manager. O fluxo pronto é gratuito no meu Patreon: arraste o JSON e instale os nós que faltam pelo Manager.

Instale os nós

Em Manager → Custom Nodes Manager, instale:

  1. ComfyUI Essentials, uma coleção básica de nós de que você realmente precisa (Mask Preview, Image Resize e mais).
  2. ComfyUI Universal Styler, que ajuda a extrair texto (o nó Get Text dele mostra as legendas do Florence).
  3. Florence 2. Há dois pacotes, o do Kijai e o do spacepxl. O do Kijai tem mais estrelas e foi atualizado mais recentemente. Os dois são muito parecidos, mas tive que reescrever parte do código do spacepxl para rodá-lo no ComfyUI mais recente. Fique com o do Kijai.

Reinicie o ComfyUI depois de instalar.

Monte a parte do Florence 2

  1. Adicione o DownloadAndLoadFlorence2Model. Ele baixa o modelo automaticamente na primeira execução, então nada de git clone nem de procurar pastas de modelos.
  2. Adicione o Florence2Run e conecte o modelo.
  3. Adicione o Load Image com sua imagem, na entrada de imagem do Florence2Run.
  4. Conecte todas as saídas: um Preview Image para a imagem, um Mask Preview (do Essentials) para a máscara e um nó Get Text para a legenda. Se uma saída não estiver conectada, a rede não roda, e o modelo não é baixado.
Load Image com uma foto de tigre alimentando o nó Florence2Run com a tarefa referring_expression_segmentation e o prompt tiger, com a pré-visualização da máscara mostrando a silhueta do tigre
A configuração básica: carregador do modelo, Florence2Run com um prompt de texto e pré-visualizações em cada saída.

Clique em Queue. A primeira execução baixa o modelo, o que pode levar alguns minutos ou mais dependendo da sua conexão; dá para acompanhar na janela de comando. A tarefa padrão encontra os objetos da imagem e desenha uma caixa delimitadora em volta de cada um (aqui: uma coroa e uma caveira). Caixas delimitadoras não são tão úteis para isto; máscaras de verdade são.

Uma caveira usando uma coroa com caixas delimitadoras desenhadas pelo Florence 2
A tarefa padrão: caixas delimitadoras em volta dos objetos que ele reconhece.

Escolha o modelo

  • Florence-2-base: o padrão.
  • Florence-2-base-ft / large-ft: «ft» quer dizer fine-tuned para fins específicos. Não os recomendo; deram resultados piores que o base.
  • Florence-2-large: muito recomendado. Leva bem mais tempo por imagem, mas faz máscaras muito melhores.

Escolha a tarefa

A lista task é o ajuste mais importante. Defina como caption e ele descreve a imagem; para mim o texto não apareceu no nó Get Text nesta máquina, embora tenha aparecido na janela de comando e funcionado em outra máquina. Legendas não são o objetivo aqui de qualquer forma.

A tarefa que você usará quase sempre é a referring_expression_segmentation. Digite o que quer no campo de texto, execute, e você recebe uma máscara.

A imagem da caveira com a coroa mascarada em verde
«Crown»: a máscara cobre a coroa inteira e mais nada.

«Skull» deu uma boa máscara de cara. «Crown» não, no começo: os modelos de IA não são perfeitos e isso acontece de vez em quando. Quando voltei do large para o base e rodei o mesmo prompt, obtive uma boa máscara da coroa. Trocar de modelo de vez em quando faz parte do processo.

Faça inpainting da área mascarada

  1. Adicione o InpaintModelConditioning. Conecte a mask do Florence2Run e a imagem do seu Load Image original, não do Florence2Run: a saída de imagem do Florence tem a máscara colorida pintada nela.
  2. Monte uma cadeia padrão de texto para imagem: Load Checkpoint (uso o epiCPhotoGasm), um CLIP Text Encode positivo e um negativo (pinto de verde e vermelho), um KSampler, VAE Decode e Save Image.
  3. Passe os prompts primeiro pelo InpaintModelConditioning, depois para o KSampler. Conecte o VAE ao InpaintModelConditioning e a saída latent dele à entrada latente do KSampler.
  4. Digite a mudança que quer («silver» para a coroa) e defina o denoise em cerca de 0,62. O denoise controla a mistura entre o prompt e a imagem original, e é o valor mais importante aqui.

Se ele reclamar de uma conexão de VAE ausente, arraste uma. O resultado:

A caveira, agora usando uma coroa de prata ornamentada, ao lado de um nó Image Comparer do rgthree
Só a coroa muda: prata em vez de ouro, escolhido digitando duas palavras.

Para comparar, adicione um Image Comparer do rgthree, com a imagem nova como A e a original como B. Você precisará executar de novo para ativá-lo, o que dá outro resultado.

Combine duas máscaras: o tigre inteiro

Numa foto de tigre da Fotoref (o banco de fotos do qual sou cofundador), «tiger» mascarou a frente do corpo mas não a perna traseira. Ignore os nós de inpainting (selecione-os e aperte Ctrl+B) enquanto testa máscaras.

  1. Copie o ramo do Florence com Ctrl+C, Ctrl+Shift+V, que mantém as conexões. Dê a ele os mesmos nós de saída (preview, mask preview, Get Text); sem eles não roda, mesmo que você não os use.
  2. Teste prompts para a parte que faltou. «Tiger back leg» não funcionou. Com o modelo large e um prompt mais criativo, «tiger black stripes front and back», peguei a perna traseira. Testei uns dez prompts para chegar lá.
  3. Adicione o Mask Composite: uma máscara em destination, a outra em source (deveriam se chamar simplesmente A e B), operação add, já que você está somando branco com branco. Multiply removeria tudo.
  4. Pré-visualize a máscara combinada: o tigre inteiro.
O segundo ramo do Florence com o tigre destacado em verde e uma pré-visualização de máscara da silhueta completa do tigre
O segundo prompt pega a perna traseira; juntas, as máscaras cobrem o tigre inteiro.

Reative os nós de inpainting e conecte a máscara composta ao InpaintModelConditioning. Esqueci de mudar o prompt e obtive um tigre prateado. Com «cat» ele fez um gato, e se misturou bem: substituiu a parte de baixo do corpo por vegetação próxima e pôs uma pedra sob uma pata. Não está longe de uma ótima geração; precisa de mais execuções.

O tigre substituído por um gato rajado andando pela mesma cena de selva
«Cat» no lugar do tigre, misturado às plantas ao redor.

Rostos

Numa das minhas esculturas 3D, «face» deu uma máscara do rosto. Com o prompt «male» ele fez inpainting do rosto de outra pessoa. Com denoise 0,25 o resultado ficou mais parecido com o original, embora tenha tido dificuldade com a anatomia estranha que esculpi (chifres, um piercing embaixo) e a substituiu por uma barba, o que é de se esperar.

Dica: o Florence2Run tem uma seed. Mude o control_after_generate de randomize para fixed, para a máscara não ser gerada de novo toda vez que você testa um prompt novo.

Transforme uma máscara numa borda

Numa selfie, «glasses» deu uma máscara bem decente. Mas eu queria mudar só a armação, e ela é fina demais para o Florence mascarar a partir de um prompt. Os nós clássicos de máscara podem fazer isso:

  1. Invert Mask (um nó nativo) na máscara dos óculos.
  2. Grow Mask em 10 pixels. Na máscara invertida, o branco cresce e o preto encolhe.
  3. Mask Composite com a máscara expandida como destination e a máscara original como source, operação multiply. Isso subtrai uma da outra e deixa a borda da armação.
  4. Adicione nós Mask Preview pelo caminho para ver cada etapa.
Grow Mask com expand 10, alimentando um Mask Composite em multiply, com máscaras de óculos invertida e encolhida nas pré-visualizações
Inverter, expandir 10 px, multiplicar: a diferença é uma borda fina.

Conectei essa borda ao InpaintModelConditioning com «silver» como prompt e denoise 0,5. Sinceramente, não obtive um resultado muito bom aqui, apesar de testar diferentes valores de denoise e prompts. O ponto é a técnica: obter uma máscara a partir de um prompt e depois aplicar os mesmos truques de expandir e subtrair que você usaria em qualquer app de VFX ou composição.

Próximos passos

Para um inpainting mais pesado com um modelo mais forte, veja inpainting com o Flux. Para corrigir rostos e mãos sem desenhar máscaras, veja corrigindo automaticamente rostos e mãos de IA. As máscaras também ajudam a transferência de estilo com IPAdapter a se concentrar num só assunto.

Assista à versão em vídeo (15:54)

Tudo o que está acima também está no vídeo, se você preferir acompanhar na tela. O vídeo está em inglês.

Perguntas frequentes

Que modelo do Florence 2 devo usar para máscaras?

O Florence-2-large dá máscaras muito melhores que o base, mas demora mais. As versões fine-tuned (ft) deram resultados piores que o base nos meus testes. Quando o large erra algo, tente o base com o mesmo prompt; às vezes ele acerta.

Que tarefa do Florence 2 faz máscaras a partir de um prompt de texto?

referring_expression_segmentation. Digite o que quer mascarar no campo de texto do nó Florence2Run.

O Florence 2 mascarou só parte do objeto. O que posso fazer?

Mascare a parte que faltou com um segundo prompt (ou outro modelo) e depois una as duas máscaras com um nó Mask Composite em add.

Por que a máscara muda a cada execução?

O Florence2Run tem a própria seed. Mude o control_after_generate de randomize para fixed, para a máscara continuar igual enquanto você testa diferentes prompts de inpainting.

Anton Tenitsky é artista 3D com mais de 15 anos em computação gráfica, que trabalhou com Nickelodeon, Gameloft, Marvel Rivals e muitos outros clientes. Mais sobre mim

Guias relacionados