Vai al contenuto principale

Tutorial SAM3 (Segment Everything Model 3): crea un filtro privacy

Scopri come usare SAM3 per creare un filtro privacy guidato da prompt testuale che maschera volti, targhe, schermi, telefoni e documenti in immagini e video.
· 9 min leggi

Scopri con l'IA

SAM 3 è il nuovo modello di Meta per “segmentare qualsiasi cosa”, capace di trovare ogni istanza di un concetto tramite brevi prompt testuali o esempi e restituire maschere pixel-accurate su immagini e video. Questo lo rende perfetto per compiti di privacy pratici come sfocare volti, targhe o schermi senza dover disegnare selezioni a mano o scrivere detector classici.

In questo tutorial costruiremo un Filtro Privacy SAM3 in Colab usando un'interfaccia Gradio. Ti basta caricare un'immagine o un video, digitare un prompt (ad esempio volti, targhe), e SAM3 restituirà maschere per istanza così da poter sfocare solo quei pixel. Vedremo setup, generazione delle maschere, applicazione di una sfocatura gaussiana e collegamento dell'app Gradio per esportare i file finali.

Cos'è SAM3?

Segment Anything Model 3 (SAM 3) è il modello unificato di Meta per rilevamento, segmentazione e tracking a vocabolario aperto su immagini e video. Invece di configurare detector separati per ogni classe, puoi usare brevi frasi o esempi come prompt, e SAM 3 restituisce maschere per istanza.

Sotto il cofano, SAM 3 fonde un text encoder e un image encoder con un detector in stile DETR e un tracker derivato da SAM-2 con memory bank. A ogni fotogramma rileva maschere per il tuo concetto dal prompt, propaga le maschere in avanti tramite il tracker e unisce le maschere appena rilevate e tracciate nell'output finale per quel frame. 

SAM3

Fonte: SAM3 GitHub

SAM 3 è distribuito con pesi del modello, codice per il fine-tuning e dati di valutazione, incluso il benchmark SA-Co per la segmentazione di concetti con prompt. 

Nei report di Meta mostra ~2x di miglioramento rispetto a baseline forti nella segmentazione a vocabolario aperto su immagini e video, mantenendo i punti di forza interattivi di SAM-2. 

In questo tutorial prenderemo le maschere di SAM 3 e le trasformeremo in un compositing con sfocatura gaussiana sia per immagini che per video, il tutto all'interno di una UI Gradio. 

Esempio SAM3: creare un filtro privacy per immagini e video

In questa sezione costruiremo un filtro privacy con SAM3 per immagini e video, incorporato in una semplice UI Gradio.

Ecco come funziona:

  • Inizia digitando un target, ad esempio volti, targhe, schermi di computer, ecc.
  • SAM3 segmenta le istanze che corrispondono al tuo prompt testuale e restituisce maschere per oggetto
  • Uniamo poi quelle maschere e sfociamo solo i pixel mascherati
  • Quindi usiamo il componente UI di Gradio per caricare un'immagine o un video, regolare intensità della sfocatura e confidenza, quindi visualizzare l'anteprima e scaricare i risultati.

SAM3 Demo

Vedremo l'implementazione completa a piccoli passi.

Passo 1:  Installa le dipendenze

Prima di eseguire questa demo, assicuriamoci di avere tutti i prerequisiti. Per eseguire il Filtro Privacy SAM3 in Colab, ti serve l'ultima libreria Transformers insieme a qualche libreria runtime per UI, operazioni sui tensori, immagini e I/O video. Lo snippet qui sotto installa tutto in un colpo solo.

import subprocess
import sys
import os
def install(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", package])
print(" Installing latest Transformers")
install("git+https://github.com/huggingface/transformers.git")
pkgs = [
    "accelerate",
    "gradio",
    "numpy",
    "pillow",
    "torch",
    "torchvision",
    "imageio[ffmpeg]" 
]
for p in pkgs:
    install(p)

Ecco a cosa serve ciascun prerequisito:

  • git+https://github.com/huggingface/transformers.git: scarica l'ultima libreria Transformers dal sorgente, così le classi Sam3Processor e Sam3Model sono disponibili.
  • torch e torchvision: sono le utility di calcolo su tensori e immagini che eseguono il forward pass di SAM3
  • accelerate: è l'helper di inferenza usato da Transformers.
  • gradio: una web UI leggera per caricare contenuti multimediali e visualizzare anteprime sfocate.
  • numpy, pillow: includono array di immagini e operazioni PIL per composizione maschera/sfocatura.
  • imageio[ffmpeg]: legge/scrive video e codifica MP4 (FFmpeg) per la scheda video.

Una volta configurato l'ambiente e caricato facebook/sam3, la demo ti permette di segmentare con brevi prompt testuali e sfocare le maschere risultanti su immagini o video tramite una semplice app Gradio. 

Nota: se pensi di usare una GPU in Colab, imposta il runtime su GPU (T4/A100) prima dell'installazione. Io ho usato una A100 su Colab per un'esperienza più veloce.

Passo 2:  Import

Con l'ambiente pronto, importa le librerie che gestiscono UI, inferenza del modello, gestione di immagini/video e timing. Questi sono gli unici moduli che ti servono per il filtro privacy SAM3.

import gradio as gr
import torch
import numpy as np
import imageio
from PIL import Image, ImageFilter
from transformers import Sam3Processor, Sam3Model
import time

Ora, Gradio fornisce l'interfaccia web, la libreria transformers esegue SAM3, e PyTorch effettua l'inferenza su GPU o CPU. Mentre PIL carica e modifica le immagini (inclusa la sfocatura gaussiana), NumPy gestisce gli array delle maschere e imageio legge e scrive file video.

Poi caricheremo il modello e costruiremo un piccolo motore che trasforma prompt testuali in maschere da sfocare.

Passo 3: Carica SAM3 e predici le maschere

Ora che l'ambiente è pronto, incapsuliamo SAM3 in un piccolo motore che carica il modello una volta, esegue la segmentazione di istanza guidata da prompt testuale su richiesta e restituisce maschere binarie da usare per la sfocatura.

class Sam3PrivacyEngine:
    def __init__(self):
        self.device = "cuda" if torch.cuda.is_available() else "cpu"
        self.model = None
        self.processor = None
        print(f"Initializing SAM3 on {self.device}")
        try:
            self.model = Sam3Model.from_pretrained("facebook/sam3").to(self.device)
            self.processor = Sam3Processor.from_pretrained("facebook/sam3")
            print("SAM3 Loaded Successfully!")
        except Exception as e:
            print(f"Error loading SAM3: {e}")
    def predict_masks(self, image_pil, text_prompt, threshold=0.4):
        if self.model is None: return []
        inputs = self.processor(
            images=image_pil,
            text=text_prompt,
            return_tensors="pt"
        ).to(self.device)
        with torch.no_grad():
            outputs = self.model(**inputs)
        results = self.processor.post_process_instance_segmentation(
            outputs, 
            threshold=threshold, 
            mask_threshold=0.5, 
            target_sizes=inputs["original_sizes"].tolist()
        )[0]
        masks = []
        if "masks" in results:
            for i, mask_tensor in enumerate(results["masks"]):
                mask_np = (mask_tensor.cpu().numpy() * 255).astype(np.uint8)
                mask_pil = Image.fromarray(mask_np)
                masks.append(mask_pil)
        return masks
engine = Sam3PrivacyEngine()

Vediamo come questo motore si inserisce nella pipeline:

  • Sam3PrivacyEngine.init(): questo initializer seleziona il miglior device (CUDA se disponibile, altrimenti CPU), carica i pesi facebook/sam3 e il relativo Sam3Processor, e sposta il modello sul device scelto così che l'inferenza sia efficiente.
  • Sam3PrivacyEngine.predict_masks(): questo metodo costruisce gli input del modello da un'immagine PIL e un prompt testuale, esegue il forward sotto torch.no_grad() per evitare l'overhead dei gradienti e post-processa gli output con post_process_instance_segmentation usando le soglie di rilevamento e maschera fornite, oltre alle dimensioni originali di destinazione per uno scaling corretto. Restituisce maschere di segmentazione per istanza convertite da tensori ad array NumPy e poi in maschere PIL “L” (immagini in scala di grigi a 8 bit, modalità "L") in cui ogni pixel ha un valore da 0 a 255) per il compositing.
  • engine = Sam3PrivacyEngine(): questa riga costruisce una singola istanza riutilizzabile del motore in modo che il modello SAM3 venga caricato una volta e possa essere richiamato ripetutamente per immagini o frame video senza reinizializzazione.

Con questo motore autonomo inizializzato, puoi trasformare qualsiasi immagine e prompt testuale in maschere di istanza. Poi applicheremo selettivamente la sfocatura usando queste maschere e incorporeremo tutto nella UI Gradio.

Passo 4: logica di sfocatura

In questa sezione prendiamo le maschere di SAM3 e applichiamo la privacy. Sfoca solo le aree mascherate preservando il resto. Partiamo con una funzione riutilizzabile di sfocatura gaussiana, poi la colleghiamo in due pipeline, una per le immagini e una per i video.

Passo 4.1: Sfocatura gaussiana

Questo helper prende un'immagine e una o più maschere PIL "L", le fonde in un'unica maschera composita e incolla una copia sfocata dell'immagine solo dove la maschera è bianca (255). 

def apply_blur_pure(image_pil, masks, blur_strength):
    if not masks:
        return image_pil
    radius = blur_strength
    blurred_image = image_pil.filter(ImageFilter.GaussianBlur(radius=radius))
    composite_mask = Image.new("L", image_pil.size, 0)
    for mask in masks:
        composite_mask.paste(255, (0, 0), mask=mask)
    final_image = image_pil.copy()
    final_image.paste(blurred_image, (0, 0), mask=composite_mask)
    return final_image

Ecco come funziona questa funzione:

  • La funzione GaussianBlur() crea prima una versione completamente sfocata dell'immagine. Mentre composite_mask è una maschera “L” (in scala di grigi) inizializzata a nero (0 = mantieni l'originale). 
  • Per ogni maschera di SAM3 la incolliamo in questa composita in modo che i pixel bianchi (255) si accumulino dove deve comparire la sfocatura. 
  • Infine incolliamo l'immagine sfocata sull'originale usando composite_mask, così solo le regioni bianche risultano sfocate.
  • Il metodo final_image.paste() sostituisce solo i pixel mascherati, lasciando intatto il resto per la massima fedeltà visiva.

Con una singola chiamata puoi sfocare qualsiasi insieme di regioni come volti, schermi, targhe, mantenendo lo sfondo com'è.

Passo 4.2: Pipeline immagini

Questo sottopasso copre il flusso end-to-end per le immagini: dalla normalizzazione dell'input all'ottenimento delle maschere da SAM3, quindi la sfocatura dei pixel mascherati e infine il risultato.

def process_image(input_img, text_prompt, blur_strength, confidence):
    if input_img is None: return None, None
    if isinstance(input_img, np.ndarray):
        image_pil = Image.fromarray(input_img).convert("RGB")
    else:
        image_pil = input_img.convert("RGB")
    masks = engine.predict_masks(image_pil, text_prompt, confidence)
    result_pil = apply_blur_pure(image_pil, masks, blur_strength)
    output_path = "privacy_image.png"
    result_pil.save(output_path)
    return np.array(result_pil), output_path

Gestiamo le immagini con la seguente pipeline passo per passo:

  • Per prima cosa convertiamo qualsiasi array NumPy di Gradio in un'immagine PIL RGB per garantire un'elaborazione coerente.
  • Poi chiamiamo engine.predict_masks() per ottenere le maschere di istanza SAM3 in base al text_prompt fornito.
  • Applichiamo quindi la funzione apply_blur_pure() con la blur_strength selezionata, così che solo le regioni mascherate vengano sfocate.
  • Dopo l'elaborazione salviamo il risultato come png e restituiamo sia un array NumPy sia un file scaricabile.

Completato il flusso per le immagini, possiamo passare alla pipeline video.

Passo 4.3: Pipeline video

Il flusso video rispecchia quello delle immagini, ma elabora in streaming fotogramma per fotogramma con imageio. Per ciascun frame, segmentiamo, sfociamo le regioni mascherate e scriviamo in un file MP4 codificato H.264.

def process_video(video_path, text_prompt, blur_strength, confidence, max_frames):
    if not video_path: return None, None
    try:
        reader = imageio.get_reader(video_path)
        meta = reader.get_meta_data()
        fps = meta.get('fps', 24)  
        output_path = "privacy_video.mp4"
        writer = imageio.get_writer(
            output_path, 
            fps=fps, 
            codec='libx264', 
            pixelformat='yuv420p',
            macro_block_size=1
        )  
        print("Starting video processing...")
        for i, frame in enumerate(reader):
            if i >= max_frames:
                break  
            frame_pil = Image.fromarray(frame).convert("RGB")
            masks = engine.predict_masks(frame_pil, text_prompt, confidence)
            processed_pil = apply_blur_pure(frame_pil, masks, blur_strength)
            writer.append_data(np.array(processed_pil))
            if i % 10 == 0:
                print(f"Processed frame {i}...")
        writer.close()
        reader.close()
        print("Video processing complete.")
        return output_path, output_path
    except Exception as e:
        print(f"Error: {e}")
        return None, None

Ecco come gestiamo i video con la seguente pipeline:

  • Apriamo prima il file con imageio.get_reader(), quindi iteriamo sui frame e leggiamo gli FPS dai metadati (predefiniti a 24 se mancanti).
  • Per ogni frame lo convertiamo in un'immagine PIL, prevediamo le maschere con SAM3 tramite il metodo engine.predict_masks() e sfociamo le regioni mascherate usando la funzione apply_blur_pure().
  • Poi aggiungiamo ciascun frame elaborato a un writer MP4 configurato con pixelformat='yuv420p' per ampia compatibilità e macro_block_size=1 per evitare artefatti di allineamento.
  • Dopo l'elaborazione, limitiamo intenzionalmente l'output fermandoci dopo un numero specifico di frame, predefinito a 60 (~2 secondi) per mantenere i test in Colab rapidi ed evitare timeout.

Con questo flusso video puoi sfocare aree sensibili in registrazioni di meeting, clip da dashcam o catture schermo usando un semplice prompt testuale.

Passo 5: inferenza con Gradio

Ora che mascheramento e sfocatura sono pronti, incapsuliamo tutto in una UI Gradio leggera così chiunque può caricare un'immagine o un video, digitare un prompt testuale e scaricare l'output.

with gr.Blocks(title="SAM3 Privacy Filter", theme=gr.themes.Soft()) as demo:
    gr.Markdown("# SAM3 Privacy Filter")
    gr.Markdown("Auto-detect and blur faces/objects.")
    with gr.Tabs():
        with gr.Tab("Image"):
            with gr.Row():
                with gr.Column():
                    im_input = gr.Image(label="Input Image", type="numpy")
                    im_prompt = gr.Textbox(label="Text Prompt", value="faces")
                    im_blur = gr.Slider(5, 100, value=30, label="Blur Strength")
                    im_conf = gr.Slider(0.1, 1.0, value=0.4, label="Confidence")
                    im_btn = gr.Button("Blur Image", variant="primary")
                with gr.Column():
                    im_output = gr.Image(label="Preview")
                    im_dl = gr.File(label="Download Image")   
            im_btn.click(process_image, [im_input, im_prompt, im_blur, im_conf], [im_output, im_dl])
        with gr.Tab("Video"):
            with gr.Row():
                with gr.Column():
                    vid_input = gr.Video(label="Input Video")
                    vid_prompt = gr.Textbox(label="Text Prompt", value="faces")
                    vid_blur = gr.Slider(5, 100, value=30, label="Blur Strength")
                    vid_conf = gr.Slider(0.1, 1.0, value=0.4, label="Confidence")
                    vid_limit = gr.Slider(10, 300, value=60, step=10, label="Max Frames")
                    vid_btn = gr.Button("Blur Video", variant="primary")
                with gr.Column():
                    vid_output = gr.Video(label="Preview")
                    vid_dl = gr.File(label="Download Video")
            vid_btn.click(process_video, [vid_input, vid_prompt, vid_blur, vid_conf, vid_limit], [vid_output, vid_dl])
demo.launch(share=True, debug=True)

L'app Gradio integra la pipeline di mascheramento e sfocatura di SAM3 in una semplice UI web usando:

  • Shell dell'app (gr.Blocks): questo blocco crea un'app Gradio a pagina singola con un titolo e due schede, una per le immagini e una per i video, così gli utenti possono cambiare modalità senza lasciare la pagina.
  • Scheda Immagine: gli input includono un uploader di immagini, una casella di testo per il prompt e slider per intensità della sfocatura e confidenza. I campi di output mostrano un'anteprima elaborata e un PNG scaricabile, mentre il pulsante Blur Image instrada tutto a process_image, che chiama SAM3 per le maschere e applica la sfocatura gaussiana solo sui pixel mascherati.
  • Scheda Video: per la sfocatura video, gli input includono un uploader di video, una casella di testo per il prompt, slider per intensità della sfocatura e confidenza, e un limite massimo di frame per demo rapide. I campi di output forniscono un'anteprima inline e un MP4 scaricabile, mentre il pulsante Blur Video richiama process_video, iterando i frame per prevedere le maschere, sfocare le regioni mascherate e codificare un video H.264.
  • Avvio: il metodo demo.launch() avvia l'app, genera un link condivisibile e mostra stack trace dettagliati quando il debug è attivo.

Ora il nostro Filtro Privacy SAM3 è pronto per caricare contenuti (immagine/video), impostare prompt e soglie ed esportare gli output sfocati.

Nota: tutte le immagini e i video in questa demo provengono da Pexels.com e sono liberi da usare.

Conclusione

In questo tutorial abbiamo creato un'app Gradio che prende un breve prompt, ottiene maschere per istanza da SAM3 e sfoca solo quelle regioni in immagini e MP4. È veloce, a vocabolario aperto e non richiede selezioni disegnate a mano o detector fissi.

I prossimi passi possono includere multi-prompt, prompt a riquadro e velocizzazioni video (salto di frame o downscaling). Puoi anche considerare di registrare le esecuzioni e offrire redazioni alternative come la pixelatura. Tuttavia, è molto importante rivedere sempre gli output prima di condividerli, perché i filtri privacy riducono il rischio, ma non sostituiscono il consenso.

Aashi Dutt

Autore

Aashi Dutt

Sono una Google Developers Expert in ML (Gen AI), una Kaggle 3x Expert e una Women Techmakers Ambassador con oltre 3 anni di esperienza nel tech. Ho co-fondato una startup health-tech nel 2020 e sto conseguendo un master in informatica al Georgia Tech, con specializzazione in machine learning.

Argomenti

Correlato