OpenCV Thresholding în Python cu cv2.threshold() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

OpenCV Thresholding în Python cu cv2.threshold()

Introducere

Thresholdingul este o tehnică simplă și eficientă pentru a efectua segmentarea de bază într-o imagine și pentru a o binariza (transforma-o într-o imagine binară) în cazul în care pixelii sunt fie 0 or 1 (Sau 255 dacă folosiți numere întregi pentru a le reprezenta).

În mod obișnuit, puteți utiliza thresholding pentru a efectua o segmentare simplă de fundal-prim-plan într-o imagine și se reduce la variante ale unei tehnici simple pentru fiecare pixel:

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

Acest proces esențial este cunoscut ca Limitarea binară. Acum – există diferite moduri în care puteți modifica această idee generală, inclusiv inversarea operațiunilor (comutarea > semnează cu a < semn), stabilirea pixel_value la threshold în loc de o valoare maximă/0 (cunoscută ca trunchiere), păstrând pixel_value în sine dacă este deasupra threshold sau dacă este sub threshold.

Toate acestea au fost implementate convenabil în OpenCV ca:

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

… respectiv. Acestea sunt metode relativ „naive” prin aceea că sunt destul de simple, nu țin cont de contextul din imagini, nu au cunoștințe despre formele comune etc. Pentru aceste proprietăți – ar trebui să folosim mult mai costisitoare și mai puternice din punct de vedere computațional. tehnici.

Acum, chiar și cu metodele „naive” – unele pot fi puse în aplicare euristici, pentru a găsi praguri bune, iar acestea includ metoda Otsu și metoda Triunghiului:

  • cv2.THRESH_OTSU
  • cv2.THRESH_TRIANGLE

Notă: Limitarea OpenCV este o tehnică rudimentară și este sensibilă la schimbările și gradienții de iluminare, eterogenitatea culorilor etc. Se aplică cel mai bine pe imagini relativ curate, după ce le estompează pentru a reduce zgomotul, fără prea multă variație de culoare în obiectele pe care doriți să le segmentați.

O altă modalitate de a depăși unele dintre problemele legate de pragurile de bază cu o singură valoare de prag este utilizarea pragării adaptive care aplică o valoare de prag pentru fiecare regiune mică dintr-o imagine, mai degrabă decât la nivel global.

Limitare simplă cu OpenCV

Limitarea în API-ul Python al OpenCV se face prin intermediul cv2.threshold() metoda – care acceptă o imagine (matrice NumPy, reprezentată cu numere întregi), pragul, valoarea maximă și metoda de prag (cum este threshold și maximum_value sunt folosite):

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)

Codul de returnare este doar pragul aplicat:

print(f"Threshold: {ret}") 

Aici, din moment ce pragul este 220 iar noi am folosit THRESH_BINARY metoda – fiecare valoare de pixel de mai sus 220 va fi mărită la 255, în timp ce fiecare valoare de pixel de mai jos 220 va fi coborât la 0, creând o imagine alb-negru, cu o „mască”, acoperind obiectele din prim-plan.

De ce 220? Știind cum arată imaginea vă permite să faceți câteva ghiciri aproximative despre pragul pe care îl puteți alege. În practică, rareori veți dori să setați un prag manual și vom acoperi selecția automată a pragului într-un moment.

Să reprezentăm rezultatul! Ferestrele OpenCV pot fi puțin capricioase, așa că vom reprezenta imaginea originală, imaginea neclară și rezultatele folosind Matplotlib:

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

Metode de prag

După cum am menționat mai devreme, există diferite moduri în care puteți utiliza pragul și valoarea maximă într-o funcție. Am aruncat o privire inițial asupra pragului binar. Să creăm o listă de metode și să le aplicăm una câte una, reprezentând rezultatele:

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 și THRESH_BINARY_INV sunt inverse unul față de celălalt și binarizează o imagine între 0 și 255, atribuindu-le fundalului și, respectiv, prim-planului și invers.

THRESH_TRUNC binarizează imaginea între threshold și 255.

THRESH_TOZERO și THRESH_TOZERO_INV binariza între 0 și valoarea actuală a pixelilor (src(x, y)). Să aruncăm o privire la imaginile rezultate:

OpenCV Thresholding în Python cu cv2.threshold() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

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!

OpenCV Thresholding în Python cu cv2.threshold() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.
OpenCV Thresholding în Python cu cv2.threshold() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.
OpenCV Thresholding în Python cu cv2.threshold() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.
OpenCV Thresholding în Python cu cv2.threshold() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Aceste metode sunt destul de intuitive – dar, cum putem automatiza o valoare prag bună și ce înseamnă chiar o valoare „prag bună”? Majoritatea rezultatelor de până acum au avut măști neideale, cu urme și pete în ele. Acest lucru se întâmplă din cauza diferenței dintre suprafețele reflectorizante ale monedelor – acestea nu sunt colorate uniform din cauza diferenței în modul în care crestele reflectă lumina.

Putem, într-o anumită măsură, să luptăm cu acest lucru prin găsirea unui prag global mai bun.

Limitare automată/optimizată cu OpenCV

OpenCV folosește două metode eficiente de căutare a pragului global – metoda lui Otsu și metoda Triunghiului.

Metoda lui Otsu presupune că funcționează bi-modal imagini. Imaginile bimodale sunt imagini ale căror histograme de culoare conțin doar două vârfuri (adică au doar două valori distincte de pixeli). Având în vedere că vârfurile aparțin fiecare unei clase precum „fondul” și „primul plan” – pragul ideal este chiar în mijlocul lor.

OpenCV Thresholding în Python cu cv2.threshold() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.
Imagine de credit: https://scipy-lectures.org/

Puteți face unele imagini mai bi-modale cu estompări gaussiene, dar nu toate.

Un algoritm alternativ, de multe ori mai performant este algoritmul triunghi, care calculează distanța dintre maximul și minimul histogramei la nivel de gri și trasează o linie. Punctul în care acea linie este la maxim distanță de restul histogramei este ales ca prag:

OpenCV Thresholding în Python cu cv2.threshold() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Ambele presupun o imagine în tonuri de gri, așa că va trebui să convertim imaginea de intrare în gri prin intermediul 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)

Să parcurgem imaginea cu ambele metode și să vizualizăm rezultatele:

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)

OpenCV Thresholding în Python cu cv2.threshold() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.
OpenCV Thresholding în Python cu cv2.threshold() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Aici, metoda triunghiului depășește metoda lui Otsu, deoarece imaginea nu este bimodală:

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)

OpenCV Thresholding în Python cu cv2.threshold() PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Cu toate acestea, este clar cum metoda triunghiului a reușit să funcționeze cu imaginea și să producă un rezultat mai satisfăcător.

Limitări ale pragului OpenCV

Limitarea cu OpenCV este simplă, ușoară și eficientă. Cu toate acestea, este destul de limitat. De îndată ce introduceți elemente colorate, fundaluri neuniforme și condiții de iluminare în schimbare – limitarea globală ca concept devine prea rigidă.

Imaginile sunt de obicei prea complexe pentru ca un singur prag să fie suficient și acest lucru poate fi parțial rezolvat pragării adaptive, unde se aplică mai multe praguri locale în loc de unul global unic. Deși este limitată, limitarea adaptivă este mult mai flexibilă decât limitarea globală.

Concluzie

În ultimii ani, segmentarea binară (ca ceea ce am făcut aici) și segmentarea cu mai multe etichete (unde puteți avea un număr arbitrar de clase codificate) au fost modelate cu succes cu rețele de învățare profundă, care sunt mult mai puternice și mai flexibile. În plus, pot codifica contextul global și local în imaginile pe care le segmentează. Dezavantajul este că aveți nevoie de date pentru a-i instrui, precum și de timp și expertiză.

Pentru un prag simplu, din mers, puteți utiliza OpenCV. Pentru o segmentare precisă, la nivel de producție, veți dori să utilizați rețele neuronale.

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 Thresholding în Python cu cv2.threshold() 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