OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

OpenCV Thresholding i Python med cv2.threshold()

Introduksjon

Thresholding er en enkel og effektiv teknikk for å utføre grunnleggende segmentering i et bilde, og for å binarisere det (gjøre det om til et binært bilde) der piksler er enten 0 or 1 (eller 255 hvis du bruker heltall for å representere dem).

Vanligvis kan du bruke terskelverdi til å utføre enkel bakgrunns-forgrunnssegmentering i et bilde, og det koker ned til varianter av en enkel teknikk for hver piksel:

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

Denne essensielle prosessen er kjent som Binær terskelverdi. Nå – det er forskjellige måter du kan justere denne generelle ideen på, inkludert å invertere operasjonene (ved å bytte > skilt med a < tegn), innstilling av pixel_value til threshold i stedet for en maksimal verdi/0 (kjent som trunkering), beholder du pixel_value selv hvis det er over threshold eller hvis det er under threshold.

Alle disse er praktisk implementert i OpenCV som:

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

… henholdsvis. Dette er relativt "naive" metoder ved at de er ganske enkle, ikke tar hensyn til kontekst i bilder, har kunnskap om hvilke former som er vanlige, osv. For disse egenskapene - må vi bruke mye mer beregningsmessig dyrere og kraftigere teknikker.

Nå, selv med de "naive" metodene – noen heuristikk kan settes på plass for å finne gode terskler, og disse inkluderer Otsu-metoden og Triangelmetoden:

  • cv2.THRESH_OTSU
  • cv2.THRESH_TRIANGLE

OBS: OpenCV-terskeling er en rudimentær teknikk, og er følsom for lysendringer og gradienter, fargeheterogenitet, etc. Den brukes best på relativt rene bilder, etter å ha sløret dem for å redusere støy, uten mye fargevariasjon i objektene du vil segmentere.

En annen måte å overvinne noen av problemene med grunnleggende terskelverdi med en enkelt terskelverdi er å bruke adaptiv terskel som bruker en terskelverdi på hver liten region i et bilde, i stedet for globalt.

Enkel terskelverdi med OpenCV

Terskeling i OpenCVs Python API gjøres via cv2.threshold() metode – som aksepterer et bilde (NumPy-matrise, representert med heltall), terskel, maksimumsverdi og terskelmetode (hvordan threshold og maximum_value er brukt):

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)

Returkoden er bare den anvendte terskelen:

print(f"Threshold: {ret}") 

Her, siden terskelen er 220 og vi har brukt THRESH_BINARY metode – hver pikselverdi ovenfor 220 vil økes til 255, mens hver pikselverdi under 220 vil bli senket til 0, lage et svart-hvitt-bilde, med en "maske", som dekker forgrunnsobjektene.

Hvorfor 220? Når du vet hvordan bildet ser ut, kan du gjøre noen omtrentlige gjetninger om hvilken terskel du kan velge. I praksis vil du sjelden angi en manuell terskel, og vi vil dekke automatisk terskelvalg på et øyeblikk.

La oss plotte resultatet! OpenCV-vinduer kan være litt kresne, så vi plotter det originale bildet, det uskarpe bildet og resultatene ved å bruke Matplotlib:

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

Terskelmetoder

Som nevnt tidligere er det ulike måter du kan bruke terskelen og maksimumsverdien i en funksjon. Vi har tatt en titt på den binære terskelen innledningsvis. La oss lage en liste over metoder, og bruke dem én etter én, og plotte resultatene:

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 og THRESH_BINARY_INV er omvendt av hverandre, og binariserer et bilde mellom 0 og 255, tilordne dem til henholdsvis bakgrunnen og forgrunnen, og omvendt.

THRESH_TRUNC binariserer bildet mellom threshold og 255.

THRESH_TOZERO og THRESH_TOZERO_INV binarisere mellom 0 og gjeldende pikselverdi (src(x, y)). La oss ta en titt på de resulterende bildene:

OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Sjekk ut vår praktiske, praktiske guide for å lære Git, med beste praksis, bransjeaksepterte standarder og inkludert jukseark. Slutt å google Git-kommandoer og faktisk lære den!

OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.
OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.
OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.
OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Disse metodene er intuitive nok - men hvordan kan vi automatisere en god terskelverdi, og hva betyr egentlig en "god terskelverdi"? De fleste resultatene så langt hadde ikke-ideelle masker, med merker og flekker i seg. Dette skjer på grunn av forskjellen i de reflekterende overflatene til myntene - de er ikke jevnt farget på grunn av forskjellen i hvordan rygger reflekterer lys.

Vi kan til en viss grad kjempe mot dette ved å finne en bedre global terskel.

Automatisk/optimalisert terskelverdi med OpenCV

OpenCV bruker to effektive globale terskelsøkemetoder – Otsus metode og Triangle-metoden.

Otsus metode forutsetter at den jobber videre bi-modal Bilder. Bi-modale bilder er bilder hvis fargehistogrammer bare inneholder to topper (dvs. har bare to distinkte pikselverdier). Tatt i betraktning at toppene hver tilhører en klasse som en "bakgrunn" og "forgrunn" - den ideelle terskelen er rett i midten av dem.

OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.
Bilde kreditt: https://scipy-lectures.org/

Du kan gjøre noen bilder mer bi-modale med gaussisk uskarphet, men ikke alle.

En alternativ, ofte bedre algoritme, er trekantalgoritmen, som beregner avstanden mellom maksimum og minimum av grånivåhistogrammet og tegner en linje. Punktet der den linjen er maksimalt langt unna resten av histogrammet er valgt som terskel:

OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Begge disse antar et gråskalabilde, så vi må konvertere inndatabildet til grått via 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)

La oss kjøre gjennom bildet med begge metodene og visualisere resultatene:

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 i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.
OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Her overgår trekantmetoden Otsus metode, fordi bildet ikke er bi-modalt:

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 i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Det er imidlertid tydelig hvordan trekantmetoden var i stand til å jobbe med bildet og gi et mer tilfredsstillende resultat.

Begrensninger for OpenCV-terskelverdi

Terskeling med OpenCV er enkelt, enkelt og effektivt. Likevel er det ganske begrenset. Så snart du introduserer fargerike elementer, uensartede bakgrunner og skiftende lysforhold – blir global terskel som konsept for rigid.

Bilder er vanligvis for komplekse til at en enkelt terskel er nok, og dette kan delvis løses gjennom adaptiv terskel, der mange lokale terskler brukes i stedet for en enkelt global. Selv om den også er begrenset, er adaptiv terskeling mye mer fleksibel enn global terskel.

konklusjonen

I de siste årene har binær segmentering (som det vi gjorde her) og multi-label segmentering (hvor du kan få kodet et vilkårlig antall klasser) blitt modellert med suksess med dyplæringsnettverk, som er mye kraftigere og mer fleksible. I tillegg kan de kode global og lokal kontekst inn i bildene de segmenterer. Ulempen er – du trenger data for å trene dem, samt tid og ekspertise.

For enkel terskeling underveis kan du bruke OpenCV. For nøyaktig segmentering på produksjonsnivå, bør du bruke nevrale nettverk.

Gå videre – praktisk dyp læring for datasyn

Din nysgjerrige natur gjør at du ønsker å gå lenger? Vi anbefaler å sjekke ut vår Kurs: "Praktisk dyplæring for datasyn med Python".

OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Et annet datasynskurs?

Vi kommer ikke til å klassifisere MNIST-sifre eller MNIST-mote. De tjente sin del for lenge siden. For mange læringsressurser fokuserer på grunnleggende datasett og grunnleggende arkitekturer før de lar avanserte svartboksarkitekturer bære byrden av ytelse.

Vi ønsker å fokusere på avmystifisering, praktisk, forståelse, intuisjon og ekte prosjekter. Vil lære hvordan du kan gjøre en forskjell? Vi tar deg med på en tur fra måten hjernen vår behandler bilder på til å skrive en dyplæringsklassifiser for brystkreft til dyplæringsnettverk som "hallusinerer", lærer deg prinsippene og teorien gjennom praktisk arbeid, og utstyrer deg med kunnskap og verktøy for å bli en ekspert på å bruke dyp læring for å løse datasyn.

Hva er inni?

  • De første prinsippene for visjon og hvordan datamaskiner kan læres å "se"
  • Ulike oppgaver og anvendelser av datasyn
  • Verktøyene i bransjen som vil gjøre arbeidet ditt enklere
  • Finne, lage og bruke datasett for datasyn
  • Teorien og anvendelsen av konvolusjonelle nevrale nettverk
  • Håndtering av domeneskift, samtidig forekomst og andre skjevheter i datasett
  • Overfør Læring og bruk av andres treningstid og beregningsressurser til din fordel
  • Bygge og trene en toppmoderne brystkreftklassifiser
  • Hvordan bruke en sunn dose skepsis til mainstream ideer og forstå implikasjonene av vidt vedtatte teknikker
  • Visualisere et ConvNets "konseptrom" ved hjelp av t-SNE og PCA
  • Kasusstudier av hvordan bedrifter bruker datasynsteknikker for å oppnå bedre resultater
  • Riktig modellevaluering, latent romvisualisering og identifisering av modellens oppmerksomhet
  • Utføre domeneforskning, behandle egne datasett og etablere modelltester
  • Nyskapende arkitekturer, utviklingen av ideer, hva som gjør dem unike og hvordan de implementeres
  • KerasCV – et WIP-bibliotek for å lage toppmoderne rørledninger og modeller
  • Hvordan analysere og lese artikler og implementere dem selv
  • Velge modeller avhengig av din applikasjon
  • Opprette en ende-til-ende maskinlæringspipeline
  • Landskap og intuisjon på objektdeteksjon med raskere R-CNN, RetinaNets, SSD og YOLO
  • Forekomst og semantisk segmentering
  • Objektgjenkjenning i sanntid med YOLOv5
  • Trening av YOLOv5-objektdetektorer
  • Arbeide med transformatorer ved å bruke KerasNLP (bransjesterkt WIP-bibliotek)
  • Integrering av transformatorer med ConvNets for å generere bildetekster
  • Deepdream
  • Deep Learning-modelloptimalisering for datasyn

Tidstempel:

Mer fra Stackabuse