Rimozione dello sfondo
La rimozione dello sfondo separa un soggetto da tutto quello che gli sta dietro. LibreYOLO la espone come il task matte, che restituisce un valore alfa morbido per pixel invece di una maschera binaria di primo piano.
Definizione
Il task matte predice un valore alfa per pixel a partire da una singola
immagine RGB: 1 è primo piano pieno e 0 è sfondo pieno. Il valore è continuo
anziché binario, ed è questo il punto del task. Per una maschera netta basta una
soglia, a 0.5, mentre il matte morbido porta con sé anche la copertura parziale
su capelli, pelo e bordi sfocati dal movimento che una maschera binaria butta
via.
Una predizione riempie result.matte, un payload Matte che contiene un array
float32 (H, W) in [0, 1] sul canvas dell'immagine originale, raggiungibile
come NumPy tramite .array. result.cutout() compone l'immagine di partenza
con quell'alfa in un array RGBA uint8 (H, W, 4), e result.save(path) scrive
la stessa cosa in un PNG con sfondo trasparente. result.boxes resta vuoto,
quindi conf, iou e max_det non hanno effetto.
Modelli
Due famiglie coprono matte, e condividono lo stesso forward path.
BiRefNet è la rete a riferimento bilaterale attorno a cui è costruito il task, pubblicata qui come un unico checkpoint di livello Swin-L.
FeyNobg è la variante resa più profonda da Feyn Inc.: l'architettura di BiRefNet con il terzo stage Swin cresciuto da 18 a 24 blocchi, poi riaddestrata. Per questa famiglia LibreYOLO riusa il forward path, il preprocessing e l'output a logit singolo di BiRefNet, quindi predizione, validazione e gestione dei checkpoint si comportano in modo identico; i pesi e l'identità della famiglia sono di FeyNobg.
Le due famiglie hanno licenze dei pesi diverse. Entrambe sono indicate nelle pagine dei modelli, e la licenza sul repository Hugging Face dello specifico checkpoint è quella che fa fede.
Predizione
I pesi vengono scaricati da Hugging Face al primo utilizzo e restano in cache in locale.
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreBiRefNetl-matte.pt")result = model(SAMPLE_IMAGE) matte = result.matteprint(matte.array.shape, matte.array.dtype) # (H, W) float32 in [0, 1]from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreBiRefNetl-matte.pt")result = model(SAMPLE_IMAGE) # save() compone l'immagine di partenza con il matte come canale alfa.result.save("subject.png") rgba = result.cutout() # lo stesso array (H, W, 4) uint8 in memoriaprint(rgba.shape)import numpy as npfrom libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreBiRefNetl-matte.pt")result = model(SAMPLE_IMAGE) rgba = result.cutout()alpha = rgba[..., 3:4].astype(np.float32) / 255.0backdrop = np.full_like(rgba[..., :3], 255) # biancocomposited = (rgba[..., :3] * alpha + backdrop * (1 - alpha)).astype(np.uint8)print(composited.shape)Entrambe le famiglie lavorano su un canvas nativo fisso di 1024x1024 e riportano
il matte alla dimensione dell'immagine originale. Una risoluzione diversa non è
supportata, perché le tabelle di posizione relativa del backbone Swin sono
legate a quella dimensione, e una discrepanza le interpola male invece di
sollevare un errore. Results.save() è definito solo per i risultati matte e ha
bisogno dell'immagine di partenza, che ricarica da Results.path a meno che tu
non ne passi una. Vedi predizione per sorgenti, streaming e
gestione dei risultati.
Formato del dataset
La validazione matte associa a ogni immagine RGB un matte alfa di ground truth a canale singolo con lo stesso stem, dove 0 è sfondo e 255 è primo piano.
my-matte-dataset/
images/
subject.jpg
mattes/
subject.pngBasta passare quella radice come data=: la directory dei matte viene rilevata
automaticamente tra mattes/, matte/, gt/, masks/, mask/ e alpha/.
L'alternativa è un YAML di dataset, con path più val_images e val_mattes
che indicano le directory relative a path:
path: my-matte-dataset
val_images: images
val_mattes: mattes
nc: 1
names: {0: matte}nc e names sono segnaposto dello schema; un modello matte restituisce
Results.matte, non rilevamenti. I valori del matte vengono letti come alfa in
[0, 1] dividendo per 255, e un matte la cui forma differisce dal canvas di
predizione viene ridimensionato bilinearmente per farlo combaciare. Vedi
formati dei dataset per il contratto completo.
Addestramento
Nessuna delle due famiglie matte ha un'implementazione dell'addestramento:
train() solleva NotImplementedError su entrambe, e il supporto matte copre
solo predizione, validazione ed esportazione. Ogni pagina di modello indica il
progetto upstream che distribuisce il codice di addestramento e lo script di
conversione che riporta indietro un checkpoint.
Validazione
val() pilota il predict del modello stesso, quindi la validazione usa
esattamente il preprocessing della famiglia, ed entrambe le metriche sono
calcolate sul canvas dell'immagine originale.
from libreyolo import LibreYOLO model = LibreYOLO("LibreBiRefNetl-matte.pt") # Una directory con images/ e una directory di matte funziona al posto# di un YAML di dataset.metrics = model.val(data="my-matte-dataset/") print(metrics["metrics/MAE"]) # più basso è meglioprint(metrics["metrics/Smeasure"]) # fitness, più alto è megliometrics/MAE è l'errore assoluto medio rispetto all'alfa di ground truth, in
[0, 1], e più basso è meglio. metrics/Smeasure è la S-measure di Fan et al.
(ICCV 2017), una similarità strutturale che premia la resa corretta della forma
del soggetto e dei suoi buchi, cosa che una media per pixel da sola non coglie;
più alto è meglio. La S-measure è anche fitness, il numero che legge la
selezione del checkpoint migliore. Nessuna delle due metriche dipende dalla
risoluzione.
Esportazione
Un modello matte esportato si ricarica tramite LibreYOLO() in base al suffisso
del file, quindi l'artefatto si comporta come un checkpoint e restituisce lo
stesso Results.
from libreyolo import LibreYOLO model = LibreYOLO("LibreBiRefNetl-matte.pt")model.export(format="torchscript")from libreyolo import LibreYOLO, SAMPLE_IMAGE # La factory usa il suffisso del file: un artefatto esportato si carica# come qualsiasi checkpoint e restituisce lo stesso oggetto Results.model = LibreYOLO("LibreBiRefNetl-matte.torchscript")result = model(SAMPLE_IMAGE) print(result.matte.array.shape)TorchScript è il percorso validato per questo task. La conversione ONNX funziona ma non ha superato la stessa asticella di parità, e i formati restanti non sono disponibili. La copertura per formato è nelle pagine BiRefNet e FeyNobg e nella matrice completa delle esportazioni.