OpenCV Edge Detection i Python med cv2.Canny() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

OpenCV Edge Detection i Python med cv2.Canny()

Introduksjon

Kantdeteksjon er noe vi gjør naturlig, men det er ikke like enkelt når det gjelder å definere regler for datamaskiner. Mens ulike metoder har blitt utviklet, ble den regjerende metoden utviklet av John F. Canny i 1986., og er passende kalt Canny-metoden.

Den er rask, ganske robust og fungerer omtrent best den kan fungere for den typen teknikk det er. Mot slutten av veiledningen vil du vite hvordan du utfører sanntids kantdeteksjon på videoer, og produserer noe i stil med:

Canny Edge Detection

Hva er Canny-metoden? Den består av fire forskjellige operasjoner:

  • Gaussisk utjevning
  • Databehandlingsgradienter
  • Ikke-Maks undertrykkelse
  • Hysterese terskel

Gaussisk utjevning brukes som det første trinnet for å "stryke ut" inndatabildet og dempe støyen, noe som gjør den endelige utgangen mye renere.

Bildegradienter har vært i bruk i tidligere applikasjoner for kantdeteksjon. Mest bemerkelsesverdig er Sobel- og Scharr-filtre avhengige av bildegradienter. Sobel-filteret koker ned til to kjerner (Gx og Gy), hvor Gx oppdager horisontale endringer, mens Gy oppdager vertikale endringer:

G

x

=

[

-
1

0

+
1

-
2

0

+
2

-
1

0

+
1

]

G

y

=

[

-
1

-
2

-
1

0

0

0

+
1

+
2

+
1

]

Når du skyver dem over et bilde, vil de "plukke" opp (fremheve) linjene i sin respektive orientering. Scharr-kjerner fungerer på samme måte, med forskjellige verdier:

G

x

=

[

+
3

0

-
3

+
10

0

-
10

+
3

0

-
3

]

G

y

=

[

+
3

+
10

+
3

0

0

0

-
3

-
10

-
3

]

Disse filtrene, når de er viklet over bildet, vil produsere funksjonskart:

OpenCV Edge Detection i Python med cv2.Canny() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Bildekreditt: Davidwkennedy

For disse funksjonskartene kan du beregne gradientstørrelse og gradientorientering – dvs. hvor intens endringen er (hvor sannsynlig er det at noe er en kant) og i hvilken retning endringen peker. Siden Gy betegner den vertikale endringen (Y-gradient), og Gx betegner den horisontale endringen (X-gradient) – kan du beregne størrelsen ved ganske enkelt å bruke Pythagoras teorem, for å få hypotenusen til trekanten dannet av "venstre" og "riktige" veibeskrivelse:

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

Ved å bruke størrelsen og retningen kan du lage et bilde med kanter uthevet:

OpenCV Edge Detection i Python med cv2.Canny() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Bildekreditt: Davidwkennedy

Imidlertid kan du se hvor mye støy som også ble fanget opp fra tecturen til mursteinene! Bildegradienter er svært følsomme for støy. Dette er grunnen til at Sobel- og Scharr-filtre ble brukt som komponenten, men ikke den eneste tilnærmingen i Cannys metode. Gaussisk utjevning hjelper også her.

Ikke-Maks undertrykkelse

Et merkbart problem med Sobel-filteret er at kantene ikke er helt klare. Det er ikke som om noen tok en blyant og tegnet en linje for å lage lineart av bildet. Kantene er vanligvis ikke så tydelige i bilder, da lyset diffunderer gradvis. Imidlertid kan vi finne den felles linjen i kantene, og undertrykke resten av pikslene rundt den, og gi en ren, tynn separasjonslinje i stedet. Dette er kjent som Non-Max-undertrykkelse! Ikke-maks-piksler (de som er mindre enn den vi sammenligner dem med i et lite lokalt felt, for eksempel en 3×3-kjerne) blir undertrykt. Konseptet er anvendelig for flere oppgaver enn dette, men la oss binde det til denne konteksten for nå.

Hysterese terskel

Mange ikke-kanter kan og vil sannsynligvis bli vurdert som kanter, på grunn av lysforhold, materialene i bildet osv. På grunn av de ulike årsakene til disse feilberegningene er det vanskelig å foreta en automatisert vurdering av hva en kant absolutt er og ikke er. 't. Du kan terskel gradienter, og bare inkludere de sterkere, forutsatt at "ekte" kanter er mer intense enn "falske" kanter.

Terskelverdi fungerer omtrent på samme måte som vanlig – hvis gradienten er under en lavere terskel, fjern den (nullstill den), og hvis den er over en gitt toppterskel, behold den. Alt mellom nedre og øvre grense er i "gråsonen". Hvis en kant mellom tersklene er koblet til en definitiv kant (de over terskelen) – de regnes også som kanter. Hvis de ikke er tilkoblet, er de sannsynligvis arficater av en feilberegnet kant.

Det er hysterese-terskel! Faktisk hjelper det med å rydde opp i det endelige resultatet og fjerne falske kanter, avhengig av hva du klassifiserer som en falsk kant. For å finne gode terskelverdier vil du vanligvis eksperimentere med forskjellige nedre og øvre grenser for terskelverdiene, eller bruke en automatisert metode som Otsus metode eller Triangle-metoden.

La oss laste inn et bilde og gråtone det (Canny, akkurat som Sobel/Scharr krever at bilder skal være gråskala):

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

Nærbildet av en finger vil tjene som et godt testområde for kantdeteksjon – det er ikke lett å skjelne et fingeravtrykk fra bildet, men vi kan anslå et.

Kantgjenkjenning på bilder med cv2.Canny()

Cannys algoritme kan brukes ved å bruke OpenCV-er Canny() metode:

cv2.Canny(input_img, lower_bound, upper_bound)

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!

Å finne den rette balansen mellom nedre og øvre grense kan være vanskelig. Hvis begge er lave – vil du ha få kanter. Hvis den nedre grensen er lav og øvre er høy - vil du ha støy. Hvis begge er høye og nær hverandre – har du få kanter. Det riktige stedet har akkurat nok gap mellom grensene, og har dem på riktig skala. Eksperiment!

Inndatabildet vil bli uskarpt med Canny-metoden, men ofte vil du ha nytte av å gjøre det uskarpt før du den går inn også. Metoden bruker en 5×5 Gaussisk uskarphet på inngangen før du går gjennom resten av operasjonene, men selv med denne uskarpheten kan noe støy fortsatt sive gjennom, så vi har gjort bildet uskarpt før vi mater det inn i algoritmen:


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

Dette resulterer i:

OpenCV Edge Detection i Python med cv2.Canny() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Verdiene av 20 og 30 her er ikke vilkårlige – jeg har testet metoden på forskjellige parametere, og valgte et sett som så ut til å gi et anstendig resultat. Kan vi prøve å automatisere dette?

Automatisert terskelverdi for cv2.Canny()?

Kan du finne et optimalt sett med terskelverdier? Ja, men det fungerer ikke alltid. Du kan lage din egen beregning for en god verdi, og deretter justere området med en sigma rundt den terskelen:

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

Når sigma, er si, 0.33 – grensene vil være 0.66*threshold og 1.33*threshold, og tillater et ~1/3-område rundt det. Skjønt å finne threshold er det som er vanskeligere. OpenCV gir oss Otsus metode (fungerer utmerket for bi-modale bilder) og Triangle-metoden. La oss prøve begge, i tillegg til å ta en enkel median av pikselverdiene som det tredje alternativet:

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

Dette resulterer i:

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

Disse er ganske forskjellige! Fra verdiene vi har sett før, kan vi forutse at Triangle-metoden fungerer best her. Den manuelle terskelen er ikke veldig informert, siden den bare tar medianpikselverdien, og ender opp med å ha en høy basisterskel som multipliseres videre til et bredt område for dette bildet. Otsus metode lider mindre av dette, men lider likevel.

Hvis vi kjører Canny() metode med disse terskelområdene:

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

OBS: Funksjonen forventer flere argumenter, og terskelverdiene våre er en enkelt tuppel. Vi kan destrukturere tuple inn i flere argumenter ved å sette den foran med *. Dette fungerer også på lister og sett, og er en fin måte å tilføre flere argumenter etter å ha fått dem med programmatiske midler.

Dette resulterer i:

OpenCV Edge Detection i Python med cv2.Canny() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Trekantmetoden fungerte ganske bra her! Dette er ingen garanti for at det vil fungere bra i andre tilfeller også.

Edge-deteksjon i sanntid på videoer med cv2.Canny()

Til slutt, la oss bruke Canny edge-deteksjon på en video i sanntid! Vi viser videoen som behandles (hver ramme etter hvert som den er ferdig) ved hjelp av cv2.imshow() som viser et vindu med rammen vi ønsker å vise. Vi vil imidlertid også lagre videoen i en MP4-fil som senere kan inspiseres og deles.

For å laste en video ved hjelp av OpenCV, bruker vi VideoCapture() metode. Hvis vi går inn 0 – den tar opp fra gjeldende webkamera, slik at du kan kjøre koden på webkameraet ditt også! Hvis du sender inn et filnavn, vil det laste inn filen:

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

De VideoWriter aksepterer flere parametere - utdatafilnavnet, FourCC (fire kodekkoder, angir kodeken som brukes til å kode videoen), bildehastigheten og oppløsningen som en tuppel. For ikke å gjette eller endre størrelsen på videoen – vi har brukt bredden og høyden til den originale videoen, hentet gjennom VideoCapture forekomst som inneholder data om selve videoen, for eksempel bredde, høyde, totalt antall bilder osv.

Mens fangsten åpnes prøver vi å lese neste ramme med cap.read(), som returnerer en resultatkode og neste ramme. Resultatkoden er True or False, som angir tilstedeværelsen av den neste rammen eller mangel på denne. Bare når det er en ramme, vil vi prøve å behandle den videre, ellers bryter vi løkken. For hver gyldig ramme kjører vi den gjennom en gaussisk uskarphet, konverterer den til gråtoner, kjører cv2.Canny() på den og skriv den med VideoWriter til disken, og vis ved hjelp av cv2.imshow() for live-visning.

Til slutt slipper vi opptaks- og videoskriveren, siden de begge jobber med filer på disken og ødelegger alle eksisterende vinduer.

Når du kjører metoden med en secret_video.mp4 input – du vil se et vindu som dukker opp og når det er ferdig, en fil i arbeidskatalogen din:

OpenCV Edge Detection i Python med cv2.Canny() PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

konklusjonen

I denne veiledningen har vi tatt en titt på hvordan Canny-kantdeteksjon fungerer, og dens bestanddeler – gaussisk utjevning, Sobel-filtre og bildegradienter, Non-Max Supression og Hysteresis Thresholding. Til slutt har vi utforsket metoder for automatisert terskelområdesøk for Canny edge-deteksjon med cv2.Canny(), og brukte teknikken på en video, og ga kantdeteksjon i sanntid og lagret resultatene i en videofil.

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 Edge Detection i Python med cv2.Canny() 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