Communitygithub.com

qiwen-bot/gif-background-removal

Remove fundo de GIFs animados, sequências de imagens e vídeos curtos, exportando GIF + WebP + APNG com fundo transparente.

O que é gif-background-removal?

Esta skill automatiza a remoção de fundo de GIFs animados, sequências de imagens PNG e vídeos curtos, gerando arquivos com transparência em três formatos: GIF (com borda dura indexada), WebP (com alpha contínuo) e APNG (compatível com navegadores). Ela utiliza o modelo BiRefNet para segmentação de matting e executa um pipeline completo: verificação de solvabilidade (para evitar processamento inútil quando partes claras do objeto são muito próximas do fundo), processamento com escala 2× para preservar fendas estreitas entre membros, limpeza topológica somente com operações de abertura (nunca fechamento), e filtragem guiada com raio ≤ 2. A skill é acionada por comandos como "把背景透明", "抠图", "remove background from GIF" ou reclamações sobre resíduos, ruído, bordas brancas ou reflexos. Suporta Windows (win32) e requer Python 3 com dependências (rembg, onnxruntime, pillow, scipy). Inclui verificação rigorosa via ferramenta verify.py que gera comparativos em quatro cores de fundo e detecta cintilação, pontos soltos e erros de quantização de cor. Adequada para desenvolvedores e usuários avançados que precisam de resultados profissionais em animações com transparência.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add qiwen-bot/gif-background-removal

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Remoção de Fundo Transparente para GIF / Animação

Informações a Coletar

  • Arquivo fonte: GIF, sequência PNG ou vídeo. Vídeos passam por extração de quadros via ffmpeg (já incluso no script).
  • Cor de fundo onde o usuário visualiza: O usuário vê a imagem sobre fundo escuro ou claro? Cores de fundo diferentes revelam resíduos diferentes. Se não souber, execute a verificação completa com todas as cores de fundo (já inclusa). Não pule esta etapa.
  • O objeto possui partes claras próximas à cor de fundo (luvas, botas, bordas brancas)? Esta é a limitação técnica – veja "Teste de Solvabilidade" abaixo.

Teste de Solvabilidade (Pular esta etapa pode custar dezenas de minutos)

Remoção de fundo é um problema de recuperação de informação, não de ajuste de parâmetros. Quando partes claras do objeto são cromaticamente próximas ao fundo, o pós-processamento não consegue separá-las – critérios de croma, suavidade, mediana temporal e ajuste de superfície de fundo sempre prejudicam o objeto.

Não confie na estimativa visual da cor. Execute:

.venv-bg\Scripts\python scripts\cutout.py --input <arquivo_fonte> --work work --stage solvability

Ele separa o fundo (câmera parada + objeto em movimento) do objeto e gera três números:

  • Cor mediana do fundo / Matiz mais claro do objeto / Diferença entre eles
  • Percentual de pixels do objeto que caem dentro de ±25/255 da cor de fundo – este é o mais explicativo.

Testado com material de robô: fundo (212,207,210), objeto mais claro (250,251,250), diferença 40,7, mas 32,6% dos pixels do objeto estão dentro de 25 da cor de fundo → exibe AMBIGUOUS.

Ao ver AMBIGUOUS, informe o usuário imediatamente:

As partes claras deste material estão muito próximas da cor de fundo. A remoção pura não consegue atingir limpeza em nível de pixel – no máximo, resíduos muito finos visíveis apenas com ampliação. Se tiver o projeto fonte, renderize novamente com fundo verde/rosa puro de alta saturação para obter resultado sem resíduos. Com apenas o arquivo final, consigo chegar próximo da limpeza.

Pergunte se deseja continuar. Não rode 20 minutos sem aviso.

Nota: Este teste é um sinal de alerta, não uma sentença. O resultado final depende da quantificação de resíduos após o processamento – "separável" pode gerar resíduos devido a bordas imprecisas do modelo; "não separável" pode, na prática, ficar muito limpo.

Procedimento

  1. Criar ambiente de trabalho e instalar dependências python -m venv .venv-bg && .venv-bg\Scripts\python -m pip install rembg onnxruntime pillow scipy (scipy vem da cadeia de dependências do rembg; é usado para filtragem guiada – veja abaixo)

  2. Executar pipeline

    .venv-bg\Scripts\python scripts\cutout.py --input <arquivo_fonte> --outdir out --scale 2
    

    --input aceita arquivos de vídeo, GIF/PNG ou um diretório de quadros PNG já extraídos. --scale 2 não é opcional: as fendas entre membros têm apenas 5–15 px e o modelo de segmentação em 720p não as enxerga. Se alguns quadros persistirem, use --stage matte apenas para aqueles quadros com --scale 3.

    Em CPU puro, para 70 quadros em 720p com escala 2×, leva cerca de 20 minutos (~17,6 s/quadro, onnxruntime sem GPU). Informe o usuário com antecedência para não parecer travado.

  3. Verificação (veja seção abaixo): se falhar, localize o estágio e execute novamente apenas ele – não reprocesse tudo.

  4. Entrega: forneça os três formatos GIF + WebP + APNG, explicando o cenário de uso de cada um.

Regras Rígidas (Violações custaram caro)

  • Use apenas abertura (opening) para topologia, nunca fechamento (closing). binary_closing preencheria fendas de ≤2 px, soldando braços ao tronco de forma irreversível. Esta regra gerou mais retrabalho que todos os outros problemas juntos.
  • Limiar de preenchimento de buracos pequeno (ordem de 60 px, não centenas). Fendas reais têm milhares de pixels; buracos de agulha, dezenas.
  • Raio da filtragem guiada ≤ 2 e sem mediana por padrão. Mediana 3×3 e filtragem guiada com raio 4 apagam fendas de alguns pixels.
  • Não comprimir alpha de forma não linear. Já houve mapeamentos como clip((clip((a-0.04)/0.92)-0.06)/0.88) que, na prática, elevam alpha em torno de 0,7, tornando os resíduos mais sólidos.
  • GIF sem dither ordenado (Bayer). Em quadro estático, a borda parece mais suave, mas o ponto de tela fixo na coordenada da tela causa "fervura" ao se mover – pior no animado. Use threshold duro limpo para GIF; alpha suave fica para WebP / APNG.
  • Modelo: BiRefNet. isnet / u2net podem interpretar reflexos especulares do chão como parte do objeto; birefnet-general-lite zera alpha em solas de botas.
  • Não "limpar" resíduos apagando cor de fundo. Limpar grandes áreas com superfície de fundo / critério cromático apagará também partes claras do objeto. A solução correta é aumentar a resolução do matte, não alterar limiares.

Contrato de Saída

  • out/<nome>.gif – transparência indexada 255, transparency=255, disposal=2, borda dura 1-bit. Limpeza topológica (remoção de pontos) aplicada apenas ao GIF.
  • out/<nome>.webp – alpha contínuo preservado, sem limpeza topológica, portanto pode reter uma fina borda suave de cor quente. Use prioritariamente sobre fundos complexos – esta diferença é intencional, não é bug.
  • out/<nome>.png – APNG, melhor compatibilidade com navegadores.
  • Dimensões, número de quadros, duração por quadro e configuração de loop do arquivo original são mantidos; liste esses valores medidos na resposta (para WebP animado, PIL não lê duração por quadro – neste caso, informe "com base no GIF medido", não invente).
  • Entregue os arquivos com tag <media> e explique os cenários de uso de GIF vs. WebP.

Tratamento de Falhas

  • GIF exibido com fundo cinza no navegador: não altere o arquivo imediatamente. Verifique o bit ALPHA do VP8X e a cor de fundo do ANIM (verify.py exibe). Se ambos estiverem normais, é o visualizador que está colocando fundo na área transparente. Se verify.py indicar ANMF ... blend=0, é um problema real – cutout.py exporta com blend=1; se blend=0, o arquivo não foi gerado por este script ou passou por ferramenta externa.
  • Objeto cortado: quase sempre devido a critério de fundo muito amplo. Volte ao nível final/ e reexporte; não ajuste parâmetros da lógica de remoção.
  • Fendas não abertas em alguns quadros: --stage matte --scale 3 apenas nesses quadros – cada quadro leva cerca de 20 segundos.
  • Download lento do modelo rembg: rembg 2.x armazena modelos em ~/.rembg/models/<model>/<model>.onnx (não no antigo ~/.u2net). birefnet-general-lite tem ~214 MB. A primeira execução requer download.

Verificação (Não Pular)

Assista quadro a quadro sobre a cor de fundo real do usuário, caso contrário a verificação é inútil:

.venv-bg\Scripts\python scripts\verify.py out\<nome>.gif --backdrop grey --ref work\final

O script gera: contagem de pontos soltos, proporção de opacidade por quadro (para detectar cintilação), linha menos opaca, erro de quantização de cor do GIF em relação ao matte de referência, flags do contêiner WebP, além de uma imagem comparativa em quatro cores de fundo + tabela de contato de todos os quadros + ampliação de região especificada.

Critérios de aprovação:

IndicadorAprovado se
Pontos soltos0
Variação de opacidade entre quadros< 0,05
Linha menos opacaConsistente entre quadros (resíduo de reflexo a faz variar ou tocar o fundo)
Erro médio de quantização de cor< 3/255 (só este número detecta perda de matiz em miniatura)
Comparação em 4 cores de fundoCada cor de fundo aparece, sem um cinza claro uniforme
Tabela de contatoSem resíduos, sem ruído, fendas entre membros transparentes

Inspecionar apenas um quadro ou apenas sobre fundo preto deixará passar problemas – resíduos de cores quentes só aparecem sobre fundo cinza escuro.

Notas para Windows (win32)

  • Use py ou python no terminal – python3 não existe no Windows. Não use o python do PATH (pode apontar para um hermes venv sem pip); prefira o .venv-bg\Scripts\python.exe do ambiente virtual.
  • Para caminhos com caracteres chineses, use as ferramentas Write/Read para escrever arquivos de script; não use Set-Content para montar conteúdo.
  • O ImageFilter.GaussianBlur do PIL não suporta o modo "F" e float RGB; para desfocar imagens float, use scipy.ndimage.gaussian_filter (o scipy já está instalado pelo rembg).
  • Image.fromarray(float32_array, "RGB") falha diretamente – converta primeiro para .astype(np.float32) e processe por canal.
  • Não use Remove-Item para limpeza; cutout.py --clean já encapsula a limpeza de diretórios.

Exemplos

Entrada: "Remova o fundo deste GIF deixando transparente" → cutout.py --input acao.gif --outdir out --scale 2, então verify.py, → Entrega GIF/WebP/APNG, listando 720×720 / 70 quadros / 100ms por quadro / total 7000ms.

Entrada: "Limpe melhor, ainda tem ruído nas bordas e fendas entre braço e corpo não abertas" → Não ajuste limiares. Primeiro execute verify.py --zoom <coordenadas> para confirmar a localização do defeito, → Se muitos pontos soltos, adicione --median 3; se fendas não abertas, --stage matte --scale 3 apenas para os quadros afetados, → Verifique novamente. Na resposta, especifique qual tipo de defeito e qual correção foi aplicada – não diga apenas "otimizado".

Habilidades Relacionadas