Soglia OpenCV in Python con cv2.threshold() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Soglia OpenCV in Python con cv2.threshold()

Introduzione

La soglia è una tecnica semplice ed efficiente per eseguire la segmentazione di base in un'immagine e per binarizzarla (trasformarla in un'immagine binaria) in cui i pixel sono sia 0 or 1 (o 255 se stai usando numeri interi per rappresentarli).

In genere, puoi utilizzare la soglia per eseguire una semplice segmentazione dello sfondo in primo piano in un'immagine e si riduce a varianti su una tecnica semplice per ogni pixel:

if pixel_value > threshold:
    pixel_value = MAX
else:
    pixel_value = 0

Questo processo essenziale è noto come Soglia binaria. Ora, ci sono vari modi in cui puoi modificare questa idea generale, inclusa l'inversione delle operazioni (cambiando il file > firmare con a < segno), impostando il pixel_value Vai all’email threshold invece di un valore massimo/0 (noto come troncamento), mantenendo il pixel_value stesso se è al di sopra del threshold o se è al di sotto del threshold.

Tutti questi sono stati convenientemente implementati in OpenCV come:

  • cv2.THRESH_BINARY
  • cv2.THRESH_BINARY_INV
  • cv2.THRESH_TRUNC
  • cv2.THRESH_TOZERO
  • cv2.THRESH_TOZERO_INV

… rispettivamente. Questi sono metodi relativamente "ingenuo" in quanto sono abbastanza semplici, non tengono conto del contesto nelle immagini, hanno conoscenza di quali forme sono comuni, ecc. Per queste proprietà, dovremmo impiegare molto più potente e dispendioso dal punto di vista computazionale tecniche.

Ora, anche con i metodi “ingenuo” – alcuni è possibile mettere in atto euristiche, per trovare buone soglie, e queste includono il metodo Otsu e il metodo del triangolo:

  • cv2.THRESH_OTSU
  • cv2.THRESH_TRIANGLE

Nota: La soglia di OpenCV è una tecnica rudimentale ed è sensibile ai cambiamenti e alle sfumature dell'illuminazione, all'eterogeneità del colore, ecc. È meglio applicarla su immagini relativamente pulite, dopo averle sfocate per ridurre il rumore, senza molta variazione di colore negli oggetti che si desidera segmentare.

Un altro modo per superare alcuni dei problemi con la soglia di base con un singolo valore di soglia consiste nell'utilizzare soglia adattiva che applica un valore di soglia su ogni piccola regione in un'immagine, piuttosto che a livello globale.

Soglia semplice con OpenCV

La soglia nell'API Python di OpenCV viene eseguita tramite il file cv2.threshold() metodo – che accetta un'immagine (array NumPy, rappresentato con numeri interi), la soglia, il valore massimo e il metodo di soglia (come il threshold ed maximum_value sono usati):

img = cv2.imread('objects.jpg')

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)


blurred = cv2.GaussianBlur(img, (7, 7), 0)

ret, img_masked = cv2.threshold(blurred, 220, 255, cv2.THRESH_BINARY)

Il codice di ritorno è solo la soglia applicata:

print(f"Threshold: {ret}") 

Ecco, poiché la soglia è 220 e abbiamo usato il THRESH_BINARY metodo: ogni valore di pixel sopra 220 sarà aumentato a 255, mentre ogni pixel ha un valore inferiore 220 sarà abbassato a 0, creando un'immagine in bianco e nero, con una “maschera”, che copre gli oggetti in primo piano.

Perché 220? Sapere come appare l'immagine ti consente di fare alcune ipotesi approssimative su quale soglia puoi scegliere. In pratica, raramente vorrai impostare una soglia manuale e tratteremo la selezione automatica della soglia tra un momento.

Tracciamo il risultato! Le finestre di OpenCV possono essere un po' schizzinose, quindi tracciamo l'immagine originale, l'immagine sfocata e i risultati usando Matplotlib:

fig, ax = plt.subplots(1, 3, figsize=(12, 8))
ax[0].imshow(img)
ax[1].imshow(blurred)
ax[2].imshow(img_masked)

Metodi di soglia

Come accennato in precedenza, esistono vari modi per utilizzare la soglia e il valore massimo in una funzione. Inizialmente abbiamo dato un'occhiata alla soglia binaria. Creiamo un elenco di metodi e li applichiamo uno per uno, tracciando i risultati:

methods = [cv2.THRESH_BINARY, cv2.THRESH_BINARY_INV, cv2.THRESH_TRUNC, cv2.THRESH_TOZERO, cv2.THRESH_TOZERO_INV]
names = ['Binary Threshold', 'Inverse Binary Threshold', 'Truncated Threshold', 'To-Zero Threshold', 'Inverse To-Zero Threshold']

def thresh(img_path, method, index):
    img = cv2.imread(img_path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    blurred = cv2.GaussianBlur(img, (7, 7), 0)
    ret, img_masked = cv2.threshold(blurred, 220, 255, method)

    fig, ax = plt.subplots(1, 3, figsize=(12, 4))
    fig.suptitle(names[index], fontsize=18)
    ax[0].imshow(img)
    ax[1].imshow(blurred)
    ax[2].imshow(img_masked)
    plt.tight_layout()

for index, method in enumerate(methods):
    thresh('coins.jpeg', method, index)

THRESH_BINARY ed THRESH_BINARY_INV sono inversi tra loro e binarizzano un'immagine tra 0 ed 255, assegnandoli rispettivamente allo sfondo e al primo piano e viceversa.

THRESH_TRUNC binarizza l'immagine tra threshold ed 255.

THRESH_TOZERO ed THRESH_TOZERO_INV binarizzare tra 0 e il valore pixel corrente (src(x, y)). Diamo un'occhiata alle immagini risultanti:

Soglia OpenCV in Python con cv2.threshold() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Dai un'occhiata alla nostra guida pratica e pratica per l'apprendimento di Git, con le migliori pratiche, gli standard accettati dal settore e il cheat sheet incluso. Smetti di cercare su Google i comandi Git e in realtà imparare esso!

Soglia OpenCV in Python con cv2.threshold() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Soglia OpenCV in Python con cv2.threshold() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Soglia OpenCV in Python con cv2.threshold() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Soglia OpenCV in Python con cv2.threshold() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Questi metodi sono abbastanza intuitivi, ma come possiamo automatizzare un buon valore di soglia e cosa significa anche un valore di "buona soglia"? Finora la maggior parte dei risultati aveva maschere non ideali, con segni e macchie. Ciò accade a causa della differenza nelle superfici riflettenti delle monete: non sono colorate in modo uniforme a causa della differenza nel modo in cui le creste riflettono la luce.

Possiamo, in una certa misura, combattere questo problema trovando una soglia globale migliore.

Soglia automatica/ottimizzata con OpenCV

OpenCV utilizza due metodi efficaci di ricerca della soglia globale: il metodo di Otsu e il metodo del triangolo.

Il metodo di Otsu presuppone che stia funzionando bimodale immagini. Le immagini bimodali sono immagini i cui istogrammi di colore contengono solo due picchi (cioè hanno solo due distinti valori di pixel). Considerando che i picchi appartengono ciascuno a una classe come "sfondo" e "primo piano", la soglia ideale è proprio nel mezzo di essi.

Soglia OpenCV in Python con cv2.threshold() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Image credit: https://scipy-lectures.org/

Puoi rendere alcune immagini più bimodali con sfocature gaussiane, ma non solo.

Un algoritmo alternativo, spesso con prestazioni migliori, è l'algoritmo del triangolo, che calcola la distanza tra il massimo e il minimo dell'istogramma del livello di grigio e traccia una linea. Il punto in cui quella linea è al massimo distante dal resto dell'istogramma viene scelto come soglia:

Soglia OpenCV in Python con cv2.threshold() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Entrambi presuppongono un'immagine in scala di grigi, quindi dovremo convertire l'immagine di input in grigio tramite cv2.cvtColor():

img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (7, 7), 0)

ret, mask1 = cv2.threshold(blurred, 0, 255, cv2.THRESH_OTSU)
ret, mask2 = cv2.threshold(blurred, 0, 255, cv2.THRESH_TRIANGLE)

masked = cv2.bitwise_and(img, img, mask=mask1)

Eseguiamo l'immagine con entrambi i metodi e visualizziamo i risultati:

methods = [cv2.THRESH_OTSU, cv2.THRESH_TRIANGLE]
names = ['Otsu Method', 'Triangle Method']

def thresh(img_path, method, index):
    img = cv2.imread(img_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (7, 7), 0)

    ret, img_masked = cv2.threshold(blurred, 0, 255, method)
    print(f"Threshold: {ret}")

    fig, ax = plt.subplots(1, 3, figsize=(12, 5))
    fig.suptitle(names[index], fontsize=18)
    ax[0].imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    ax[1].imshow(cv2.cvtColor(gray, cv2.COLOR_BGR2RGB))
    ax[2].imshow(cv2.cvtColor(img_masked, cv2.COLOR_BGR2RGB))

for index, method in enumerate(methods):
    thresh('coins.jpeg', method, index)

Soglia OpenCV in Python con cv2.threshold() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Soglia OpenCV in Python con cv2.threshold() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Qui, il metodo del triangolo supera il metodo di Otsu, perché l'immagine non è bimodale:

import numpy as np

img = cv2.imread('coins.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (7, 7), 0)

histogram_gray, bin_edges_gray = np.histogram(gray, bins=256, range=(0, 255))
histogram_blurred, bin_edges_blurred = np.histogram(blurred, bins=256, range=(0, 255))

fig, ax = plt.subplots(1, 2, figsize=(12, 4))

ax[0].plot(bin_edges_gray[0:-1], histogram_gray)
ax[1].plot(bin_edges_blurred[0:-1], histogram_blurred)

Soglia OpenCV in Python con cv2.threshold() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Tuttavia, è chiaro come il metodo del triangolo sia stato in grado di lavorare con l'immagine e produrre un risultato più soddisfacente.

Limitazioni della soglia OpenCV

La soglia con OpenCV è semplice, facile ed efficiente. Eppure, è abbastanza limitato. Non appena vengono introdotti elementi colorati, sfondi non uniformi e condizioni di illuminazione mutevoli, la soglia globale come concetto diventa troppo rigida.

Le immagini sono generalmente troppo complesse perché una singola soglia sia sufficiente e questo può essere parzialmente affrontato soglia adattiva, dove vengono applicate molte soglie locali invece di una singola globale. Anche se limitata, la soglia adattiva è molto più flessibile della soglia globale.

Conclusione

Negli ultimi anni, la segmentazione binaria (come quella che abbiamo fatto qui) e la segmentazione multi-etichetta (in cui è possibile avere un numero arbitrario di classi codificate) sono state modellate con successo con reti di deep learning, che sono molto più potenti e flessibili. Inoltre, possono codificare il contesto globale e locale nelle immagini che stanno segmentando. Lo svantaggio è che sono necessari dati per addestrarli, oltre a tempo e competenze.

Per una soglia semplice e immediata, puoi utilizzare OpenCV. Per una segmentazione accurata a livello di produzione, ti consigliamo di utilizzare le reti neurali.

Andare oltre - Apprendimento profondo pratico per la visione artificiale

La tua natura curiosa ti fa venire voglia di andare oltre? Ti consigliamo di dare un'occhiata al nostro Portata: "Apprendimento profondo pratico per la visione artificiale con Python".

Soglia OpenCV in Python con cv2.threshold() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Un altro corso di visione artificiale?

Non faremo la classificazione delle cifre MNIST o della moda MNIST. Hanno servito la loro parte molto tempo fa. Troppe risorse di apprendimento si stanno concentrando su set di dati di base e architetture di base prima di lasciare che le architetture black-box avanzate si assumano il peso delle prestazioni.

Vogliamo concentrarci demistificazione, praticità, e una comprensione reciproca, intuizione ed progetti reali. Vuoi imparare come Puoi fare la differenza? Ti porteremo in un viaggio dal modo in cui il nostro cervello elabora le immagini alla scrittura di un classificatore di apprendimento profondo per la ricerca per il cancro al seno alle reti di apprendimento profondo che "allucinano", insegnandoti i principi e la teoria attraverso il lavoro pratico, fornendoti il know-how e strumenti per diventare un esperto nell'applicazione del deep learning per risolvere la visione artificiale.

Cosa c'è dentro?

  • I primi principi della visione e come si può insegnare ai computer a "vedere"
  • Diversi compiti e applicazioni della visione artificiale
  • Gli strumenti del mestiere che ti semplificheranno il lavoro
  • Trovare, creare e utilizzare set di dati per la visione artificiale
  • La teoria e l'applicazione delle reti neurali convoluzionali
  • Gestione del cambio di dominio, della co-occorrenza e di altri pregiudizi nei set di dati
  • Trasferisci l'apprendimento e utilizza il tempo di formazione e le risorse di calcolo degli altri a tuo vantaggio
  • Costruire e formare un classificatore di cancro al seno all'avanguardia
  • Come applicare una sana dose di scetticismo alle idee tradizionali e comprendere le implicazioni delle tecniche ampiamente adottate
  • Visualizzazione dello "spazio concettuale" di una ConvNet utilizzando t-SNE e PCA
  • Casi di studio su come le aziende utilizzano le tecniche di visione artificiale per ottenere risultati migliori
  • Valutazione corretta del modello, visualizzazione dello spazio latente e identificazione dell'attenzione del modello
  • Esecuzione di ricerche di dominio, elaborazione dei propri set di dati e creazione di test di modello
  • Architetture all'avanguardia, la progressione delle idee, cosa le rende uniche e come realizzarle
  • KerasCV – una libreria WIP per la creazione di pipeline e modelli all'avanguardia
  • Come analizzare e leggere documenti e implementarli da soli
  • Selezione dei modelli in base all'applicazione
  • Creazione di una pipeline di machine learning end-to-end
  • Paesaggio e intuizione sul rilevamento di oggetti con R-CNN, RetinaNet, SSD e YOLO più veloci
  • Istanza e segmentazione semantica
  • Riconoscimento di oggetti in tempo reale con YOLOv5
  • Formazione dei rilevatori di oggetti YOLOv5
  • Utilizzo di Transformers tramite KerasNLP (libreria WIP di livello industriale)
  • Integrazione di Transformers con ConvNets per generare didascalie di immagini
  • Deepdream
  • Ottimizzazione del modello di deep learning per la visione artificiale

Timestamp:

Di più da Impilamento