Sistema de Correspondência de Thumbnails e Títulos para Vídeos Curtos com CLIP-GmP-ViT-L-14

Implementação Prática de Correspondência Multimodal para Conteúdo de Vídeos

Este sistema automatiza a verificação de consistência entre thumbnailss e títulos de vídeos curtos, utilizando o modelo CLIP-GmP-ViT-L-14. A solução opera localmente, preservando privacidade dos dados e oferecendo processamento eficiente sem depandência de serviços externos.

Para configurar o ambiente, execute os seguintes comandos no terminal:

pip install torch torchvision transformers pillow streamlit

Em seguida, crie um script Python com a seguinte estrutura:

import streamlit as st
import torch
from PIL import Image
from transformers import CLIPProcessor, CLIPModel
import warnings

warnings.filterwarnings("ignore")

st.set_page_config(page_title="Ferramenta de Correspondência Multimodal", layout="wide")
st.title("CLIP-GmP-ViT-L-14 - Correspondência Imagem-Texto")
st.markdown("Envie uma imagem e insira múltiplas descrições textuais (separadas por vírgulas). A ferramenta calculará e classificará a correspondência entre cada descrição e a imagem.")

@st.cache_resource
def carregar_modelo_multimodal():
    identificador_modelo = "openai/clip-vit-large-patch14"
    try:
        modelo = CLIPModel.from_pretrained(identificador_modelo)
        processador = CLIPProcessor.from_pretrained(identificador_modelo)
        return modelo, processador
    except Exception as erro:
        st.error(f"Falha ao carregar modelo: {erro}")
        return None, None

modelo, processador = carregar_modelo_multimodal()

if modelo is None or processador is None:
    st.stop()

coluna_esquerda, coluna_direita = st.columns([1, 2])

with coluna_esquerda:
    st.subheader("📷 Envio de Imagem")
    arquivo_imagem = st.file_uploader("Selecione uma imagem para análise", type=["jpg", "jpeg", "png"])
    if arquivo_imagem:
        img = Image.open(arquivo_imagem).convert("RGB")
        st.image(img, caption="Imagem carregada", width=300)
        st.success("Imagem processada com sucesso!")
    else:
        st.info("Aguardando upload da imagem...")
        img = None

with coluna_direita:
    st.subheader("📝 Descrições Textuais")
    exemplos_descricoes = "cachorro brincando no parque, gato dormindo no sofá, carro vermelho na rua, prato de comida deliciosa"
    descricoes_input = st.text_area(
        "Insira descrições separadas por vírgulas",
        value=exemplos_descricoes,
        height=100,
        help="Exemplo: praia ensolarada, rua movimentada, floresta tranquila"
    )

    if descricoes_input:
        lista_descricoes = [t.strip() for t in descricoes_input.split(",") if t.strip()]
    else:
        lista_descricoes = []

    st.subheader("🚀 Resultados da Análise")
    if st.button("Iniciar Análise", type="primary") and img and lista_descricoes:
        with st.spinner("Processando similaridade..."):
            try:
                entradas = processador(text=lista_descricoes, images=img, return_tensors="pt", padding=True)
                with torch.no_grad():
                    saidas = modelo(**entradas)
                    pontuacoes_imagem = saidas.logits_per_image
                    probabilidades = pontuacoes_imagem.softmax(dim=1).squeeze().tolist()
                resultados = list(zip(lista_descricoes, probabilidades))
                resultados.sort(key=lambda x: x[1], reverse=True)
                st.markdown("### 📊 Classificação por Correspondência (ordem decrescente)")
                for descricao, confianca in resultados:
                    st.write(f"**{descricao}**")
                    st.progress(confianca, text=f"{confianca * 100:.2f}%")
                    st.write("")
            except Exception as erro:
                st.error(f"Erro durante processamento: {erro}")
    elif st.button("Iniciar Análise"):
        if not img:
            st.warning("Por favor, envie uma imagem primeiro.")
        elif not lista_descricoes:
            st.warning("Insira pelo menos uma descrição textual.")

# Script para análise em lote
import os
from PIL import Image
from transformers import CLIPProcessor, CLIPModel
import torch

print("Carregando modelo CLIP...")
modelo = CLIPModel.from_pretrained("openai/clip-vit-large-patch14")
processador = CLIPProcessor.from_pretrained("openai/clip-vit-large-patch14")
print("Modelo carregado com sucesso!")

palavras_positivas = ["tutorial", "comida", "esportes", "musica", "pet"]
palavras_alerta = ["chocante", "você não vai acreditar", "ganhe dinheiro rápido", "emergência", "clickbait"]

diretorio_thumbnails = "./thumbnails_videos"
arquivos_imagem = [f for f in os.listdir(diretorio_thumbnails) if f.endswith(('.jpg', '.png', '.jpeg'))]

if not arquivos_imagem:
    print("Nenhuma imagem encontrada no diretório.")
    exit()

for img_file in arquivos_imagem:
    print(f"\n=== Analisando thumbnail: {img_file} ===")
    caminho_imagem = os.path.join(diretorio_thumbnails, img_file)
    try:
        imagem = Image.open(caminho_imagem).convert("RGB")
    except Exception as erro:
        print(f"  Erro: não foi possível abrir {img_file}: {erro}")
        continue

    todas_palavras = palavras_positivas + palavras_alerta
    entradas = processador(text=todas_palavras, images=imagem, return_tensors="pt", padding=True)
    with torch.no_grad():
        saidas = modelo(**entradas)
        pontuacoes = saidas.logits_per_image.softmax(dim=1).squeeze().tolist()

    resultados = list(zip(todas_palavras, pontuacoes))
    top_3 = sorted(resultados, key=lambda x: x[1], reverse=True)[:3]
    print("  Top 3 palavras-chave:")
    for kw, score in top_3:
        print(f"    - '{kw}': {score * 100:.1f}%")

    palavra_top, pontuacao_top = top_3[0]
    limiar_alerta = 0.3

    if palavra_top in palavras_alerta and pontuacao_top > limiar_alerta:
        print(f"  ⚠️  [Alerta] Thumbnail pode ser clickbait! Palavra '{palavra_top}' (confiança {pontuacao_top * 100:.1f}%) está na lista de alerta.")
    elif palavra_top in palavras_positivas:
        print(f"  ✅ Correspondência alta com '{palavra_top}', conteúdo consistente.")
    else:
        print(f"  ℹ️  Análise concluída, sem regras ativadas.")

print("\nProcessamento em lote finalizado!")

Tags: CLIP computer-vision machine-learning Streamlit Pytorch

Publicado em 8-25 17:56