OpenCV Edge Detection în Python cu cv2.Canny() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

OpenCV Edge Detection în Python cu cv2.Canny()

Introducere

Detectarea marginilor este ceva ce facem în mod natural, dar nu este la fel de ușor când vine vorba de definirea regulilor pentru computere. În timp ce au fost concepute diferite metode, metoda dominantă a fost dezvoltată de John F. Canny în 1986 și este numită în mod adecvat metoda Canny.

Este rapid, destul de robust și funcționează cam cel mai bine pentru tipul de tehnică care este. Până la sfârșitul ghidului, veți ști cum să efectuați detectarea marginilor în timp real pe videoclipuri și să produceți ceva de genul:

Canny Edge Detection

Ce este metoda Canny? Constă din patru operații distincte:

  • netezire gaussiană
  • Calcularea gradienților
  • Suprimare non-max
  • Limitarea histerezisului

netezire gaussiană este folosit ca prim pas pentru a „calca” imaginea de intrare și a atenua zgomotul, făcând rezultatul final mult mai curat.

Gradienți de imagine au fost utilizate în aplicații anterioare pentru detectarea marginilor. În special, filtrele Sobel și Scharr se bazează pe gradienți de imagine. Filtrul Sobel se reduce la două sâmburi (Gx și Gy), Unde Gx detectează modificări orizontale, în timp ce Gy detectează modificări verticale:

G

x

=

[

-
1

0

+
1

-
2

0

+
2

-
1

0

+
1

]

G

y

=

[

-
1

-
2

-
1

0

0

0

+
1

+
2

+
1

]

Când le glisați peste o imagine, fiecare va „prinde” (subliniază) liniile în orientarea lor respectivă. Nuezele Scharr funcționează în același mod, cu valori diferite:

G

x

=

[

+
3

0

-
3

+
10

0

-
10

+
3

0

-
3

]

G

y

=

[

+
3

+
10

+
3

0

0

0

-
3

-
10

-
3

]

Aceste filtre, odată transformate peste imagine, vor produce hărți de caracteristici:

OpenCV Edge Detection în Python cu cv2.Canny() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Credit imagine: Davidwkennedy

Pentru aceste hărți de caracteristici, puteți calcula magnitudinea gradientului și orientarea gradientului – adică cât de intensă este schimbarea (cât de probabil este ca ceva să fie o margine) și în ce direcție este îndreptată schimbarea. Deoarece Gy denotă schimbarea verticală (gradient Y), iar Gx reprezintă schimbarea orizontală (gradient X) – puteți calcula mărimea prin simpla aplicare a teoremei lui Pitagora, pentru a obține ipotenuza triunghiului format de „stânga” și direcții „corecte”:

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

Folosind mărimea și orientarea, puteți produce o imagine cu marginile evidențiate:

OpenCV Edge Detection în Python cu cv2.Canny() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Credit imagine: Davidwkennedy

Totuși – puteți vedea cât de mult zgomot s-a prins și din structura cărămizilor! Gradienții de imagine sunt foarte sensibili la zgomot. Acesta este motivul pentru care filtrele Sobel și Scharr au fost folosite ca componentă, dar nu singura abordare în metoda lui Canny. Netezirea gaussiană ajută și aici.

Suprimare non-max

O problemă notabilă cu filtrul Sobel este că marginile nu sunt chiar clare. Nu este ca și cum cineva a luat un creion și a tras o linie pentru a crea o imagine liniară a imaginii. Marginile de obicei nu sunt atât de clare în imagini, deoarece lumina difuzează treptat. Cu toate acestea, putem găsi linia comună în margini și suprimăm restul pixelilor din jurul ei, obținând în schimb o linie de separare curată și subțire. Acest lucru este cunoscut sub numele de Suprimare Non-Max! Pixelii non-max (cei mai mici decât cel cu care îi comparăm într-un câmp local mic, cum ar fi un nucleu 3×3) sunt suprimați. Conceptul este aplicabil la mai multe sarcini decât aceasta, dar să-l legăm de acest context pentru moment.

Limitarea histerezisului

Multe non-marchii pot și probabil vor fi evaluate ca margini, din cauza condițiilor de iluminare, a materialelor din imagine etc. Din cauza diferitelor motive pentru care apar aceste calcule greșite – este greu să faci o evaluare automată a ceea ce este și nu este o muchie. 't. Puteți limita gradienții și includeți doar pe cei mai puternici, presupunând că marginile „adevărate” sunt mai intense decât marginile „false”.

Limitarea funcționează în același mod ca de obicei – dacă gradientul este sub un prag mai mic, eliminați-l (reduceți-l la zero), iar dacă este peste un anumit prag superior, păstrați-l. Tot ceea ce este între limita inferioară și limita superioară se află în „zona gri”. Dacă orice margine dintre praguri este conectată la a marginea definitivă (cele peste prag) – sunt considerate și margini. Dacă nu sunt conectate, probabil ar fi arficate cu o margine greșit calculată.

Asta este prag de histerezis! De fapt, ajută la curățarea rezultatului final și la eliminarea marginilor false, în funcție de ceea ce clasificați drept margine falsă. Pentru a găsi valori de prag bune, veți experimenta în general cu diferite limite inferioare și superioare pentru praguri sau veți folosi o metodă automată, cum ar fi metoda lui Otsu sau metoda Triunghiului.

Să încărcăm o imagine și să o facem în tonuri de gri (Canny, la fel cum Sobel/Scharr necesită ca imaginile să fie în tonuri de gri):

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 în Python cu cv2.Canny() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Imaginea de aproape a unui deget va servi ca un bun teren de testare pentru detectarea marginilor – nu este ușor să discerneți o amprentă din imagine, dar putem aproxima una.

Detectarea marginilor pe imagini cu cv2.Canny()

Algoritmul lui Canny poate fi aplicat folosind OpenCV Canny() metodă:

cv2.Canny(input_img, lower_bound, upper_bound)

Consultați ghidul nostru practic și practic pentru a învăța Git, cu cele mai bune practici, standarde acceptate de industrie și fisa de cheat incluse. Opriți căutarea pe Google a comenzilor Git și de fapt învăţa aceasta!

Găsirea echilibrului corect între limita inferioară și limita superioară poate fi dificilă. Dacă ambele sunt scăzute - veți avea puține margini. Dacă limita inferioară este scăzută și superioară este ridicată, veți avea zgomot. Dacă ambele sunt înalte și apropiate unul de celălalt, veți avea puține margini. Locul potrivit are suficient spațiu între limite și le are pe scara potrivită. Experiment!

Imaginea de intrare va fi neclară prin metoda Canny, dar de multe ori, veți beneficia de estomparea acesteia înainte intra si el. Metoda aplică o estompare gaussiană de 5×5 la intrare înainte de a trece prin restul operațiunilor, dar chiar și cu această neclaritate, ceva zgomot poate trece, așa că am estompat imaginea înainte de a o introduce în algoritm:


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')

Rezultă:

OpenCV Edge Detection în Python cu cv2.Canny() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Valorile 20 și 30 aici nu sunt arbitrare – am testat metoda pe diverși parametri și am ales un set care părea să producă un rezultat decent. Putem încerca să automatizăm asta?

Limitare automată pentru cv2.Canny()?

Puteți găsi un set optim de valori de prag? Da, dar nu funcționează întotdeauna. Puteți face propriul calcul pentru o valoare bună și apoi ajustați intervalul cu a sigma în jurul acestui prag:

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

Cand sigma, este să spunem, 0.33 – limitele vor fi 0.66*threshold și 1.33*threshold, permițând un interval de ~1/3 în jurul acestuia. Cu toate acestea, găsirea threshold este ceea ce este mai dificil. OpenCV ne oferă metoda lui Otsu (funcționează excelent pentru imagini bi-modale) și metoda Triunghi. Să le încercăm pe ambele, precum și să luăm o mediană simplă a valorilor pixelilor ca a treia opțiune:

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}")

Rezultă:

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

Acestea sunt destul de diferite! Din valorile pe care le-am văzut înainte, putem anticipa metoda Triunghiului care funcționează cel mai bine aici. Pragul manual nu este foarte informat, deoarece ia doar valoarea mediană a pixelilor și ajunge să aibă un prag de bază ridicat, care este înmulțit în continuare într-o gamă largă pentru această imagine. Metoda lui Otsu suferă mai puțin din cauza asta, dar suferă totuși.

Dacă rulăm Canny() metoda cu aceste intervale de prag:

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')

Notă: Funcția așteaptă mai multe argumente, iar pragurile noastre sunt un singur tuplu. Noi putem destructură tuplu în mai multe argumente prefixându-l cu *. Acest lucru funcționează și pe liste și seturi și este o modalitate excelentă de a furniza mai multe argumente după obținerea lor prin mijloace programatice.

Rezultă:

OpenCV Edge Detection în Python cu cv2.Canny() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Metoda Triunghiului a funcționat destul de bine aici! Aceasta nu este o garanție că va funcționa bine și în alte cazuri.

Detectarea marginilor în timp real pe videoclipuri cu cv2.Canny()

În cele din urmă, să aplicăm detectarea marginilor Canny unui videoclip în timp real! Vom afișa videoclipul în curs de procesare (fiecare cadru așa cum este gata) folosind cv2.imshow() care afișează o fereastră cu cadrul pe care dorim să-l afișam. Cu toate acestea, vom salva și videoclipul într-un fișier MP4 care poate fi ulterior inspectat și partajat.

Pentru a încărca un videoclip folosind OpenCV, folosim VideoCapture() metodă. Dacă trecem înăuntru 0 – va înregistra de pe camera web curentă, astfel încât să puteți rula codul și pe camera dvs. web! Dacă introduceți un nume de fișier, acesta va încărca fișierul:

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')

VideoWriter acceptă mai mulți parametri – numele fișierului de ieșire, FourCC (patru coduri de codec, care indică codecul folosit pentru a codifica videoclipul), framerate și rezoluția ca tuplu. Pentru a nu ghici sau redimensiona videoclipul – am folosit lățimea și înălțimea videoclipului original, obținute prin VideoCapture instanță care conține date despre videoclipul în sine, cum ar fi lățimea, înălțimea, numărul total de cadre etc.

În timp ce captura este deschisă, încercăm să citim următorul cadru cu cap.read(), care returnează un cod de rezultat și următorul cadru. Codul rezultat este True or False, care denotă prezența cadrului următor sau o lipsă a acestuia. Numai când există un cadru, vom încerca să-l procesăm în continuare, altfel, vom întrerupe bucla. Pentru fiecare cadru valid, îl rulăm printr-o neclaritate gaussiană, îl convertim în tonuri de gri, rulăm cv2.Canny() pe el și scrieți-l folosind VideoWriter pe disc și afișați folosind cv2.imshow() pentru o vizionare live.

În cele din urmă, lansăm captarea și writerul video, deoarece ambele lucrează cu fișiere de pe disc și distrug toate ferestrele existente.

Când rulați metoda cu a secret_video.mp4 intrare - veți vedea o fereastră pop-up și odată ce este terminată, un fișier în directorul dvs. de lucru:

OpenCV Edge Detection în Python cu cv2.Canny() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Concluzie

În acest ghid, am aruncat o privire asupra modului în care funcționează detectarea marginilor Canny și a părților sale constitutive – netezire gaussiană, filtre Sobel și gradienți de imagine, suprimare non-max. și prag de histerezis. În cele din urmă, am explorat metode de căutare automată a intervalului de prag pentru detectarea marginilor Canny cu cv2.Canny(), și a folosit tehnica pe un videoclip, oferind detectarea marginilor în timp real și salvând rezultatele într-un fișier video.

Mergând mai departe – Învățare profundă practică pentru viziunea computerizată

Natura ta curios te face să vrei să mergi mai departe? Vă recomandăm să verificați Curs: „Învățare profundă practică pentru viziunea computerizată cu Python”.

OpenCV Edge Detection în Python cu cv2.Canny() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Un alt curs de Computer Vision?

Nu vom face clasificarea cifrelor MNIST sau a modei MNIST. Și-au servit rolul cu mult timp în urmă. Prea multe resurse de învățare se concentrează pe seturile de date de bază și pe arhitecturile de bază înainte de a lăsa arhitecturile avansate de tip cutie neagră să asume povara performanței.

Vrem să ne concentrăm asupra demistificare, practic, înţelegere, intuiţie și proiecte reale. Vreau sa invat cum poți face o diferență? Vă vom duce într-o plimbare de la modul în care creierul nostru procesează imaginile până la scrierea unui clasificator de învățare profundă de nivel de cercetare pentru cancerul de sân la rețele de învățare profundă care „halucinează”, învățându-vă principiile și teoria prin muncă practică, echipându-vă cu know-how și instrumente pentru a deveni un expert în aplicarea învățării profunde pentru a rezolva viziunea computerizată.

Ce e inauntru?

  • Primele principii ale vederii și modul în care computerele pot fi învățate să „vadă”
  • Diferite sarcini și aplicații ale vederii computerizate
  • Instrumentele meseriei care vă vor ușura munca
  • Găsirea, crearea și utilizarea seturilor de date pentru viziune computerizată
  • Teoria și aplicarea rețelelor neuronale convoluționale
  • Gestionarea deplasării de domeniu, apariției concomitente și a altor părtiniri în seturile de date
  • Transfer Învățați și utilizați timpul de instruire și resursele de calcul ale altora în beneficiul dumneavoastră
  • Construirea și formarea unui clasificator de ultimă generație pentru cancerul de sân
  • Cum să aplicați o doză sănătoasă de scepticism ideilor principale și să înțelegeți implicațiile tehnicilor adoptate pe scară largă
  • Vizualizarea unui „spațiu conceptual” al unui ConvNet folosind t-SNE și PCA
  • Studii de caz despre modul în care companiile folosesc tehnicile de viziune computerizată pentru a obține rezultate mai bune
  • Evaluarea corectă a modelului, vizualizarea spațiului latent și identificarea atenției modelului
  • Efectuarea cercetărilor de domeniu, procesarea propriilor seturi de date și stabilirea de teste de model
  • Arhitecturi de ultimă oră, progresul ideilor, ce le face unice și cum să le implementăm
  • KerasCV – o bibliotecă WIP pentru crearea de conducte și modele de ultimă generație
  • Cum să analizați și să citiți lucrările și să le implementați singur
  • Selectarea modelelor în funcție de aplicația dvs
  • Crearea unui canal de învățare automată de la capăt la capăt
  • Peisaj și intuiție în detectarea obiectelor cu R-CNN-uri mai rapide, RetinaNets, SSD-uri și YOLO
  • Instanță și segmentare semantică
  • Recunoașterea obiectelor în timp real cu YOLOv5
  • Instruirea detectoarelor de obiecte YOLOv5
  • Lucrul cu Transformers folosind KerasNLP (bibliotecă WIP puternică în industrie)
  • Integrarea Transformers cu ConvNets pentru a genera subtitrări ale imaginilor
  • Deepdream
  • Optimizarea modelului de Deep Learning pentru viziunea computerizată

Timestamp-ul:

Mai mult de la Stackabuse