5.14. Gaussisk utjämning och kanter¶
Två uppgifter dominerar vad grannskapsfönster används till i klassiskt maskinseende: att jämna ut variation mellan pixlar på ett rent sätt, och att hitta de kanter där bilden ändras skarpt. Det Gaussiska filtret är standardverktyget för det första, de Laplace-baserade detektorerna standardverktyget för det andra – och de två kombineras, eftersom varje kantdetektor fungerar bättre på en lätt utjämnad indata.
5.14.1. Det Gaussiska filtret¶
gaussian() är den centrumviktade kusinen till mean(). Båda beräknar ett medelvärde över varje pixels grannskap, men det Gaussiska filtrets vikter är inte enhetliga: pixlar närmare grannskapets centrum räknas mer, pixlar vid grannskapets kant räknas mindre, med vikterna som följer den välbekanta klockkurvan som ger filtret dess namn.
Den klockformade viktningen är vad som gör ett Gaussiskt filter jämnare än ett lådmedelvärde. Medelvärdesfiltrering kan producera synliga artefakter vid objektens kanter – en hård avgränsning i viktningen introducerar små ringningsmönster vid skarpa övergångar. Det Gaussiska filtrets jämnt avtagande vikter undviker den ringningen och producerar ett resultat som ser närmare ut vad ”suddigt” borde se ut. Kostnaden är mer beräkning per pixel än medelvärdesfiltret, men inte dramatiskt så – kostnaden per pixel är fortfarande mycket lägre än för det bilaterala filtret.
img.gaussian(1) # 3x3 Gaussian -- a clean light blur
img.gaussian(2) # 5x5 Gaussian -- stronger smoothing
Gaussisk utjämning är det vanliga första steget i nästan varje kantdetekteringspipeline. Kantdetektorerna nedan förstärker alla högfrekvent innehåll, inklusive det sensorbrus som algoritmen egentligen inte vill detektera. Att köra en lätt Gaussisk filtrering först dämpar det bruset utan att mjuka upp verkliga kanter särskilt mycket, vilket lämnar kantdetektorn att hitta verkliga kanter i stället för fläckar.
5.14.2. Oskärpemaskning¶
En Gaussiskt suddad kopia av en bild är råmaterialet som tekniken unsharp mask använder för klassisk skärpning. Att sätta unsharp=True på filtret växlar det från ”producera den suddade bilden” till ”subtrahera den suddade bilden från originalet och lägg tillbaka skillnaden till originalet” – effekten är att högfrekventa kanter förstärks i förhållande till jämna inre ytor.
img.gaussian(1, unsharp=True)
De valfria parametrarna mul och add skalar styrkan på unsharp-resultatet; standardvärdena (mul=1.0, add=0.0) ger en måttlig skärpning som inte överdriver sensorbrus.
5.14.3. Laplace-filtret¶
laplacian() kör en diskret approximation av bildens andra rumsliga derivata. Utdata är stor där pixelvärden ändras snabbt, nära noll där de är konstanta eller ändras linjärt. Den naturliga tolkningen av resultatet är ett kantsvar: pixlar där bilden ändras snabbt lyser upp, pixlar i jämna inre ytor förblir mörka.
img.laplacian(1) # 3x3 Laplacian -- edge response
Samma parametrar som för gaussian finns tillgängliga. sharpen=True producerar en skärpt bild (Laplace-svaret adderat tillbaka till originalet i stället för returnerat för sig självt). mul och add skalar svaret.
En praktisk användning utöver kantdetektering är fokusmätning. Laplace-svaret medelvärdesberäknat över ett område ger ett ungefärligt mått på hur mycket högfrekvent innehåll området bär; på en välfokuserad bildruta är det medelvärdet högt, på en suddig bildruta sjunker det. Att jämföra Laplace-svaret mellan bildrutor är det billiga sättet att fråga ”är linsen i fokus?” utan att behöva ett dyrare kontrastmått.
5.14.4. find_edges-metoden¶
find_edges() kör en komplett kantdetekteringspipeline snarare än bara ett kantsvarsfilter. Den fungerar på gråskalebilder, och resultatet är en binär bild vars nollskilda pixlar markerar positionerna där indata har den sortens ljusstyrkeförändring som ska räknas som en kant.
Metoden tar en parameter edge_type som väljer mellan två algoritmer:
EDGE_SIMPLE kör ett högpassfilter, tillämpar ett tröskelvärde och returnerar resultatet. Snabbt, men utdata inkluderar varje ljusstyrkeförändring över tröskelvärdet, inklusive brus och textur som applikationen förmodligen inte bryr sig om. Rimligt för rena bilder och för fall där bruset kommer att rensas upp av ett senare morfologiskt svep.
EDGE_CANNY kör kantdetektorn Canny – den klassiska flerstegsalgoritmen. Den beräknar ljusstyrkegradienten, dämpar varje icke-maximalt svar längs gradientriktningen (så att varje kant är en pixel bred) och tillämpar ett hystereströskelvärde (så att en kant som är stark på ett ställe spåras även där den bleknar mellan). Resultatet är en ren, tunn, sammanhängande uppsättning kantpixlar av det slag varje klassisk kantbaserad algoritm vill ha.
Parametern threshold är en tvåelementstupel (low, high). För EDGE_CANNY är det höga värdet gränsen över vilken en pixel definitivt är en kant, och det låga värdet är gränsen över vilken en pixel är en kant endast om den är ansluten till en definitiv sådan. För EDGE_SIMPLE spelar endast det höga värdet roll; det är den enda gräns över vilken en pixel räknas som en kant. Standardvärdet (100, 200) är en utgångspunkt värd att stämma av för den specifika scenen.
img.gaussian(1) # pre-smooth
img.find_edges(image.EDGE_CANNY, threshold=(50, 100))
Canny-detektorn är det bättre valet för nästan varje applikation där kanter spelar roll. Den snabbare EDGE_SIMPLE är värd att komma ihåg för de fall där kostnaden för Canny är ett problem och brusavvisningen hos dess hysteres faktiskt inte behövs.
5.14.5. Adaptiv tröskling på Gauss¶
Liksom de statistiska filtren accepterar gaussian() nyckelordsparet threshold=True / offset=N för adaptiv tröskling. Beteendet är detsamma som med mean(): den Gaussiska statistiken vid varje position blir den lokala gränsen, och källpixeln jämförs mot statistiken plus förskjutningen för att producera ett binärt resultat.
Den Gaussiska varianten är vanligtvis det renaste valet för adaptiv tröskling när indata är rimligt brusfri. Det viktade medelvärdet ger en jämnare gräns än vad medelvärdesfiltret producerar, med färre artefakter vid skarpa belysningsövergångar.