OpenCV Edge Detection in Python con cv2.Canny() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Rilevamento di bordi OpenCV in Python con cv2.Canny()

Introduzione

Il rilevamento dei bordi è qualcosa che facciamo naturalmente, ma non è così facile quando si tratta di definire regole per i computer. Sebbene siano stati ideati vari metodi, il metodo regnante è stato sviluppato da John F. Canny nel 1986 ed è giustamente chiamato metodo Canny.

È veloce, abbastanza robusto e funziona al meglio per il tipo di tecnica che è. Alla fine della guida, saprai come eseguire il rilevamento dei bordi in tempo reale sui video e produrre qualcosa sulla falsariga di:

Rilevamento Canny Edge

Qual è il metodo Canny? Si compone di quattro operazioni distinte:

  • Livellamento gaussiano
  • Calcolo dei gradienti
  • Soppressione non massima
  • Soglia di isteresi

Livellamento gaussiano viene utilizzato come primo passaggio per "stirare" l'immagine in ingresso e attenuare il rumore, rendendo l'output finale molto più pulito.

Sfumature dell'immagine sono stati utilizzati in precedenti applicazioni per il rilevamento dei bordi. In particolare, i filtri Sobel e Scharr si basano sui gradienti dell'immagine. Il filtro Sobel si riduce a due chicchi (Gx ed Gy), dove Gx rileva i cambiamenti orizzontali, mentre Gy rileva i cambiamenti verticali:

G

x

=

[

-
1

0

+
1

-
2

0

+
2

-
1

0

+
1

]

G

y

=

[

-
1

-
2

-
1

0

0

0

+
1

+
2

+
1

]

Quando li fai scorrere su un'immagine, ciascuno "raccoglierà" (enfatizza) le linee nel rispettivo orientamento. I kernel Scharr funzionano allo stesso modo, con valori diversi:

G

x

=

[

+
3

0

-
3

+
10

0

-
10

+
3

0

-
3

]

G

y

=

[

+
3

+
10

+
3

0

0

0

-
3

-
10

-
3

]

Questi filtri, una volta convolti sull'immagine, produrranno mappe delle caratteristiche:

OpenCV Edge Detection in Python con cv2.Canny() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Credito immagine: Davidwkennedy

Per queste mappe delle caratteristiche, puoi calcolare il magnitudo del gradiente ed orientamento del gradiente – cioè quanto è intenso il cambiamento (quanto è probabile che qualcosa sia un bordo) e in quale direzione sta puntando il cambiamento. Poiché Gy denota la variazione verticale (gradiente Y) e Gx denota la variazione orizzontale (gradiente X) – puoi calcolare la grandezza semplicemente applicando il teorema di Pitagora, per ottenere l'ipotenusa del triangolo formato dalla “sinistra” e direzioni “giuste”:

$$
{G} ={quadrato {{{G} _{x}}^{2}+{{G} _{y}}^{2}}}
$$

Usando la grandezza e l'orientamento, puoi produrre un'immagine con i bordi evidenziati:

OpenCV Edge Detection in Python con cv2.Canny() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Credito immagine: Davidwkennedy

Tuttavia, puoi vedere quanto rumore è stato catturato anche dalla struttura dei mattoni! I gradienti dell'immagine sono molto sensibili al rumore. Questo è il motivo per cui i filtri Sobel e Scharr sono stati utilizzati come componente, ma non l'unico approccio nel metodo di Canny. Anche il livellamento gaussiano aiuta qui.

Soppressione non massima

Un problema notevole con il filtro Sobel è che i bordi non sono molto chiari. Non è che qualcuno abbia preso una matita e disegnato una linea per creare lineart dell'immagine. I bordi di solito non sono così netti nelle immagini, poiché la luce si diffonde gradualmente. Tuttavia, possiamo trovare la linea comune nei bordi e sopprimere il resto dei pixel attorno ad essa, ottenendo invece una linea di separazione pulita e sottile. Questo è noto come soppressione non massima! I pixel non massimi (quelli più piccoli di quello con cui li stiamo confrontando in un piccolo campo locale, come un kernel 3×3) vengono soppressi. Il concetto è applicabile a più compiti di questo, ma per ora leghiamolo a questo contesto.

Soglia di isteresi

Molti non bordi possono e probabilmente saranno valutati come bordi, a causa delle condizioni di illuminazione, dei materiali nell'immagine, ecc. A causa delle varie ragioni per cui si verificano questi errori di calcolo, è difficile effettuare una valutazione automatizzata di cosa sia e cosa sia certamente un bordo 't. Puoi limitare i gradienti e includere solo quelli più forti, supponendo che i bordi "reali" siano più intensi dei bordi "falsi".

La soglia funziona più o meno allo stesso modo del solito: se il gradiente è al di sotto di una soglia inferiore, rimuoverlo (azzerarlo) e se è al di sopra di una determinata soglia superiore, mantenerlo. Tutto ciò che si trova tra il limite inferiore e il limite superiore è nella "zona grigia". Se un qualsiasi fronte tra le soglie è collegato a a margine definitivo (quelli sopra la soglia) – sono anche considerati bordi. Se non sono collegati, sono probabilmente arficat di un bordo calcolato male.

Questa è la soglia di isteresi! In effetti, aiuta a ripulire l'output finale e rimuovere i falsi bordi, a seconda di ciò che classifichi come falso bordo. Per trovare buoni valori di soglia, generalmente sperimenterai diversi limiti inferiore e superiore per le soglie o utilizzerai un metodo automatizzato come il metodo di Otsu o il metodo del triangolo.

Carichiamo un'immagine in scala di grigi (Canny, proprio come Sobel/Scharr richiede che le immagini siano in scala di grigi):

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('finger.jpg', cv2.IMREAD_GRAYSCALE)
img_blur = cv2.GaussianBlur(img, (3,3), 0)

plt.imshow(img_blur, cmap='gray')

OpenCV Edge Detection in Python con cv2.Canny() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

L'immagine in primo piano di un dito servirà come un buon banco di prova per il rilevamento dei bordi: non è facile distinguere un'impronta digitale dall'immagine, ma possiamo approssimarne una.

Rilevamento bordi su immagini con cv2.Canny()

L'algoritmo di Canny può essere applicato utilizzando OpenCV Canny() Metodo:

cv2.Canny(input_img, lower_bound, upper_bound)

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!

Trovare il giusto equilibrio tra il limite inferiore e il limite superiore può essere complicato. Se entrambi sono bassi, avrai pochi margini. Se il limite inferiore è basso e quello superiore è alto, avrai del rumore. Se entrambi sono alti e vicini l'uno all'altro, avrai pochi spigoli. Il punto giusto ha uno spazio sufficiente tra i limiti e li ha sulla scala giusta. Sperimentare!

L'immagine di input sarà sfocata con il metodo Canny, ma spesso trarrai vantaggio dalla sfocatura prima entra anche lui. Il metodo applica una sfocatura gaussiana 5×5 all'input prima di eseguire il resto delle operazioni, ma anche con questa sfocatura, del rumore può ancora filtrare, quindi abbiamo sfocato l'immagine prima di inserirla nell'algoritmo:


edge = cv2.Canny(img_blur, 20, 30)

fig, ax = plt.subplots(1, 2, figsize=(18, 6), dpi=150)
ax[0].imshow(img, cmap='gray')
ax[1].imshow(edge, cmap='gray')

Questo risulta in:

OpenCV Edge Detection in Python con cv2.Canny() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

I valori di 20 ed 30 qui non sono arbitrari: ho testato il metodo su vari parametri e ho scelto un set che sembrava produrre un risultato decente. Possiamo provare ad automatizzare questo?

Soglia automatizzata per cv2.Canny()?

Riesci a trovare un insieme ottimale di valori di soglia? Sì, ma non sempre funziona. Puoi fare il tuo calcolo per un buon valore, quindi regolare l'intervallo con a sigma intorno a quella soglia:

lower_bound = (1-sigma)*threshold
upper_bound = (1+sigma)*threshold

Quando sigma, è dire, 0.33 – i limiti saranno 0.66*threshold ed 1.33*threshold, consentendo un intervallo di ~1/3 attorno ad esso. Tuttavia, trovare il threshold è ciò che è più difficile. OpenCV ci fornisce il metodo di Otsu (funziona benissimo per le immagini bimodali) e il metodo Triangle. Proviamo entrambi, oltre a prendere una semplice mediana dei valori dei pixel come terza opzione:

otsu_thresh, _ = cv2.threshold(img_blur, 0, 255, cv2.THRESH_OTSU)
triangle_thresh, _ = cv2.threshold(img_blur, 0, 255, cv2.THRESH_TRIANGLE)
manual_thresh = np.median(img_blur)

def get_range(threshold, sigma=0.33):
    return (1-sigma) * threshold, (1+sigma) * threshold

otsu_thresh = get_range(otsu_thresh)
triangle_thresh = get_range(triangle_thresh)
manual_thresh = get_range(manual_thresh)

print(f"Otsu's Threshold: {otsu_thresh} nTriangle Threshold: {triangle_thresh} nManual Threshold: {manual_thresh}")

Questo risulta in:

Otsu's Threshold: (70.35, 139.65) 
Triangle Threshold: (17.419999999999998, 34.58) 
Manual Threshold: (105.18999999999998, 208.81)

Questi sono piuttosto diversi! Dai valori che abbiamo visto prima, possiamo anticipare che il metodo del triangolo funziona meglio qui. La soglia manuale non è molto informata, poiché prende solo il valore mediano dei pixel e finisce per avere una soglia di base alta che viene ulteriormente moltiplicata in un ampio intervallo per questa immagine. Il metodo di Otsu ne soffre meno, ma soffre comunque.

Se eseguiamo il Canny() metodo con questi intervalli di soglia:

edge_otsu = cv2.Canny(img_blur, *otsu_thresh)
edge_triangle = cv2.Canny(img_blur, *triangle_thresh)
edge_manual = cv2.Canny(img_blur, *manual_thresh)

fig, ax = plt.subplots(1, 3, figsize=(18, 6), dpi=150)
ax[0].imshow(edge_otsu, cmap='gray')
ax[1].imshow(edge_triangle, cmap='gray')
ax[2].imshow(edge_manual, cmap='gray')

Nota: La funzione prevede più argomenti e le nostre soglie sono una singola tupla. Noi possiamo destrutturare la tupla in più argomenti anteponendola con *. Funziona anche su elenchi e insiemi ed è un ottimo modo per fornire più argomenti dopo averli ottenuti con mezzi programmatici.

Questo risulta in:

OpenCV Edge Detection in Python con cv2.Canny() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Il metodo Triangolo ha funzionato abbastanza bene qui! Questa non è una garanzia che funzionerà bene anche in altri casi.

Rilevamento dei bordi in tempo reale sui video con cv2.Canny()

Infine, applichiamo il rilevamento dei bordi di Canny a un video in tempo reale! Visualizzeremo il video in elaborazione (ogni fotogramma come è stato fatto) utilizzando cv2.imshow() che mostra una finestra con la cornice che vorremmo visualizzare. Tuttavia, salveremo anche il video in un file MP4 che potrà essere successivamente ispezionato e condiviso.

Per caricare un video utilizzando OpenCV, utilizziamo il file VideoCapture() metodo. Se entriamo 0 – registrerà dalla webcam corrente, quindi puoi eseguire il codice anche sulla tua webcam! Se passi un nome file, caricherà il file:

def edge_detection_video(filename):
    cap = cv2.VideoCapture(filename)
    
    fourcc = cv2.VideoWriter_fourcc(*'MP4V')
    out = cv2.VideoWriter('output.mp4', fourcc, 30.0, (int(cap.get(3)), int(cap.get(4))), isColor=False)
    
    while cap.isOpened():
        (ret, frame) = cap.read()
        if ret == True:
            frame = cv2.GaussianBlur(frame, (3, 3), 0)
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            edge = cv2.Canny(frame, 50, 100)
            out.write(edge)
            cv2.imshow('Edge detection', edge)
        else:
            break

        if cv2.waitKey(10) & 0xFF == ord('q'):
            break

    cap.release()
    out.release()
    cv2.destroyAllWindows()

edge_detection_video('secret_video.mp4')

Il VideoWriter accetta diversi parametri: il nome del file di output, il FourCC (quattro codici codec, che denotano il codec utilizzato per codificare il video), il framerate e la risoluzione come una tupla. Per non indovinare o ridimensionare il video, abbiamo utilizzato la larghezza e l'altezza del video originale, ottenute tramite il VideoCapture istanza che contiene dati sul video stesso, come la larghezza, l'altezza, il numero totale di fotogrammi, ecc.

Mentre l'acquisizione è aperta, proviamo a leggere il fotogramma successivo con cap.read(), che restituisce un codice risultato e il frame successivo. Il codice del risultato è True or False, denotando la presenza del frame successivo o la sua mancanza. Solo quando c'è un frame, cercheremo di elaborarlo ulteriormente, altrimenti interromperemo il ciclo. Per ogni fotogramma valido, lo eseguiamo attraverso una sfocatura gaussiana, lo convertiamo in scala di grigi, esegui cv2.Canny() su di esso e scrivilo usando il VideoWriter sul disco e visualizzare utilizzando cv2.imshow() per una vista dal vivo.

Infine, rilasciamo l'acquisizione e il video writer, poiché entrambi lavorano con i file sul disco e distruggono tutte le finestre esistenti.

Quando esegui il metodo con a secret_video.mp4 input – vedrai apparire una finestra e una volta terminato, un file nella tua directory di lavoro:

OpenCV Edge Detection in Python con cv2.Canny() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Conclusione

In questa guida, abbiamo dato un'occhiata a come funziona il rilevamento dei bordi Canny e alle sue parti costitutive: smoothing gaussiano, filtri Sobel e gradienti dell'immagine, soppressione non massima e soglia di isteresi. Infine, abbiamo esplorato i metodi per la ricerca automatizzata dell'intervallo di soglia per il rilevamento dei bordi di Canny con cv2.Canny()e ha utilizzato la tecnica su un video, fornendo il rilevamento dei bordi in tempo reale e salvando i risultati in un file video.

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".

OpenCV Edge Detection in Python con cv2.Canny() 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