Har du någonsin stött på en högljudd bild? Jag menar en bild som inte var så klar när man såg den? Jag tror att vi stöter på sådana bilder mycket ofta, särskilt när många bilder idag tas av våra mobiltelefonkameror eller digitalkameror med låg upplösning.
Om du bara hade den bullriga bilden som betyder något för dig, men problemet är att det inte kan ses korrekt, skulle det finnas en lösning att återhämta sig från sådant brus?
Det är här bildfiltrering spelar in, och det är vad jag kommer att beskriva i denna handledning. Låt oss börja!
Bildfiltrering är ett populärt verktyg som används vid bildbehandling. I slutet av dagen använder vi bildfiltrering för att ta bort ljud och oönskade egenskaper från en bild, skapa en bättre och en förbättrad version av den bilden. Två typer av filter finns: linjär och icke-linjär. Exempel på linjära filter är medel- och laplacianfilter. Icke-linjära filter utgör filter som median-, minimi-, maximi- och Sobel-filter.
Vart och ett av dessa filter har ett specifikt syfte och är utformat för att antingen ta bort ljud eller förbättra vissa aspekter i bilden. Men hur går filtreringen ut? Det här är vad vi kommer att se i nästa avsnitt.
För att utföra en bildfiltreringsprocess behöver vi en filtrera, kallas också a mask. Detta filter är vanligtvis ett tvådimensionellt kvadratfönster, det vill säga ett fönster med lika stora dimensioner (bredd och höjd).
Filtret kommer att innehålla siffror. Dessa nummer heter koefficienter, och de är vad som faktiskt bestämmer effekten av filtret och hur utmatningsbilden kommer att se ut. Figuren nedan visar ett exempel på a 3x3
filter, med nio värden (koefficienter).
För att applicera filtret, 3x3
fönstret glider över bilden. Denna process att skjuta ett filterfönster över en bild heter konvolvering i den rumsliga domänen. Fönstret placeras på varje pixel (dvs tänk på det som en cell i en matris) i bilden, där filtrets mittpunkt skulle överlappa den pixeln.
När denna överlappning inträffar multipliceras pixlarna i den underbild som filtret är ovanpå multiplicerat med motsvarande koefficienter för filtret. I det här fallet kommer vi att ha en ny matris med nya värden som liknar storleken på filtret (dvs.. 3x3
). Slutligen kommer det centrala pixelvärdet att ersättas med ett nytt värde med användning av en specifik matematisk ekvation beroende på vilken typ av filter som används (dvs medianfilter).
Jag vet att ovanstående stycke är lite ordig. Låt oss ta ett exempel för att visa hur ett bildfilter tillämpas i åtgärd. Antag att vi har följande underbild där vårt filter överlappades (jag
och j
hänvisa till pixelplatsen i underbilden och jag
hänvisar till bilden):
Konfolutionen av vårt filter som visas i den första bilden med ovanstående underbild kommer att se som visas nedan, var I_new (i, j)
representerar resultatet på plats (I j)
.
I-1, j) + v3 x I (i-1, j + 1) + v4 x I (i, j-1) + v5xI (i, j) + v6xI (i, j + 1) + v7xI (i + 1, j-1) + v8xI (i + 1, j) + v9 xi (i + 1, j + 1)
Processen upprepas för varje pixel i bilden, inklusive pixlarna vid bildens gräns. Men som du kan gissa kommer en del av filtret att ligga utanför bilden när du placerar filtret vid gränspixlarna. I det här fallet utför vi stoppning.
Denna process innebär helt enkelt att vi lägger in nya pixelvärden i underbilden under den del av filtret som kommer utanför bilden innan konvolutionsprocessen, eftersom den delen uppenbarligen inte innehåller några pixelvärden. Det ligger utanför bilden! De vadderade pixlarna kan vara nollor eller ett konstant värde. Det finns andra metoder för att ställa in vadderingsvärdena, men de ligger utanför ramen för denna handledning.
Jag tycker att det finns tillräckligt med teori för nu, så låt oss gå och få våra händer smutsiga med kodning! I denna handledning kommer jag att förklara medianfiltret (dvs icke-linjärt) och medelfiltret (dvs linjärt) och hur vi kan implementera dem i Python.
I medianfiltret väljer vi ett skjutfönster som kommer att flytta över alla bildpixlarna. Vad vi gör här är att vi samlar pixelvärdena som kommer under filtret och tar medianen av dessa värden. Resultatet kommer att tilldelas mittpunkten.
Säg vårt 3x3
filtret hade följande värden efter att ha placerat det på en underbild:
Låt oss se hur man beräknar medianen. Medianen är i sin essens den mitten nummer av en sorterad lista med siffror. Således, för att hitta medianen för ovanstående filter, sorterar vi helt enkelt numren från lägsta till högsta, och mitten av dessa tal kommer att vara vårt medianvärde. Sortera värdena i vår 3x3
fönstret kommer att ge oss följande:
17 29 43 57 59 63 65 84 98
För att hitta mittnumret (medianen) räknar vi helt enkelt antalet värden vi har, lägg till 1 till det numret och dela med 2. Detta ger oss placeringen av mittvärdet i fönstret, vilket är vårt medianvärde. Så medianvärdet kommer att vara på plats 9 + 1/2 = 5
, vilket är 59
. Detta värde kommer att vara det nya värdet av pixeln under vårt centrum 3x3
fönster.
Denna typ av filter används för att ta bort brus och fungerar bäst med bilder som lider av salt och peppar ljud. Bilden nedan visar ett exempel på en bild som lider av sådant ljud:
Låt oss nu skriva ett Python-skript som kommer att applicera medianfiltret på ovanstående bild. För detta exempel använder vi OpenCV-biblioteket. Vänligen kolla på Install OpenCV-Python i Windows och installera OpenCV 3.0 och Python 2.7+ på Ubuntu för att installera OpenCV.
För att applicera medianfiltret använder vi helt enkelt OpenCVs cv2.medianBlur ()
fungera. Vårt skript kan således se ut som följer:
importera cv2 import argparse # skapa argumentet parser och analysera argumenten ap = argparse.ArgumentParser () ap.add_argument ('- i', '--image', required = True, help = 'Path to input image') args = vars (ap.parse_args ()) # läs bildbilden = cv2.imread (args ['image']) # använd 3x3-medianfiltret på bilden processed_image = cv2.medianBlur (image, 3) # display image cv2. imshow ('Median Filter Processing', processed_image) # Spara bild till disk cv2.imwrite ('processed_image.png', processed_image) # pausa exekveringen av manuset tills en tangent på tangentbordet trycks in cv2.waitKey (0)
Observera att jag har använt argparse
, eftersom det är en bra övning att vara flexibel här och använd kommandoraden för att passera bilden vi vill använda medianfiltret på som ett argument till vårt program.
Efter att ha överfört vår bild som ett kommandoradsargument läser vi den bilden med hjälp av cv2.imread ()
fungera. Vi applicerar sedan medianfiltret med hjälp av medianBlur ()
funktion, passerar vår bild och filterstorlek som parametrar. Bilden visas med hjälp av cv2.imshow ()
funktionen och sparas på skivan med cv2.imwrite ()
.
Resultatet av ovanstående skript är följande:
Tja, vad tycker du? Mycket vacker-en fin och ren bild utan ljud.
Du kan ladda ner ovanstående kod från mitt medianfilterförvar på GitHub.
Medelfilteret är ett exempel på ett linjärt filter. Det ersätter i grunden varje pixel i utmatningsbilden med medelvärdet (medelvärdet) i kvarteret. Detta medför att utjämna bilden (reducerar intensitetsvariationerna mellan en pixel och nästa), tar bort brus från bilden och lyser bilden.
Under medelfiltrering kommer således varje pixel av bilden att ersättas med medelvärdet för sina grannar, inklusive själva pixeln. De 3x3
Kärnan som används för medelfiltrering är som visas i figuren nedan, även om andra kärnstorlekar kan användas (dvs 5x5):
Vad den här kärnan faktiskt försöker berätta för oss är att vi summerar alla element i kärnan och tar medeltalet (medelvärdet) av den totala.
En viktig punkt att nämna här är att alla element i medelkärnan ska:
Låt oss ta ett exempel för att göra saker tydligare. Säg att vi har följande underbild:
Vid tillämpning av medelfilteret skulle vi göra följande:
(7 + 9 + 23 + 76 + 91 + 7 + 64 + 90 + 32) / 9 = 44
Det exakta resultatet är 44,3
, men jag avrundade resultatet till 44
. Så det nya värdet för mittpunkten är 44
istället för 91
.
Nu till kodningsdelen. Låt oss säga att vi har följande högljudda bild:
Vad vi vill göra vid denna punkt är att använda medelfiltret på bilden ovan och se effekterna av att applicera ett sådant filter.
Koden för att göra denna operation är som följer:
importera cv2 import numpy som np import argparse # skapa argumentet parser och analysera argumenten ap = argparse.ArgumentParser () ap.add_argument ('- i', '--image', required = True, help = 'Vägen till inmatningen bild ") args = vars (ap.parse_args ()) # läs bildbilden = cv2.imread (args ['image']) # använd 3x3 medelfilen på bildkärnan = np.ones ((3,3) , np.float32) / 9 processed_image = cv2.filter2D (bild, -1, kärna) # visa bild cv2.imshow ('Mean Filter Processing', processed_image) # spara bild till disk cv2.imwrite ('processed_image.png' processed_image) # pausa exekveringen av manuset tills en tangent på tangentbordet trycks in cv2.waitKey (0)
Notera från koden som vi har använt a 3x3
kärna för vårt genomsnittliga filter. Vi har också använt filter2D ()
funktion för att applicera medelfilteret. Den första parametern för denna funktion är vår inmatningsbild, den andra är önskat djup på utmatningsbilden ddepth
, och den tredje parametern är vår kärna. tilldela -1
för ddepth
parameter betyder att utdata bilden kommer att ha samma djup som ingående bild.
Efter att ha kört koden på vår bullriga bild var det resultatet jag fick:
Om du observerar utmatningsbilden kan vi se att den är mjukare än den högljudda bilden. Uppdrag gjort!
Du kan ladda ner ovanstående kod från mitt genomsnittliga filterförvar på GitHub.
Som vi har sett i den här handledningen tillåter Python oss att utföra avancerade uppgifter som bildfiltrering, särskilt via sitt OpenCV-bibliotek, på ett enkelt sätt.
Tveka inte att se vad vi har till salu och studera på marknaden, och tveka inte att ställa några frågor och ge din värdefulla feedback genom att använda foderet nedan.