Ai întâlnit vreodată o imagine zgomotoasă? Adică o imagine care nu era atât de clară când o vizionai? Cred că întâlnim astfel de imagini foarte des, mai ales când multe imagini sunt luate astăzi de camerele noastre de telefonie mobilă sau camerele digitale cu rezoluție redusă.
Dacă ai avea doar acea imagine zgomotoasă, care înseamnă ceva pentru tine, dar problema este că nu poate fi privită în mod corespunzător, ar exista o soluție pentru a recupera de la un astfel de zgomot?
Aici se află în joc filtrarea imaginilor, și asta voi descrie în acest tutorial. Să începem!
Filtrarea imaginilor este un instrument popular utilizat în procesarea imaginilor. La sfârșitul zilei, folosim filtrarea imaginilor pentru a elimina zgomotul și orice caracteristici nedorite dintr-o imagine, creând o versiune îmbunătățită și îmbunătățită a acelei imagini. Există două tipuri de filtre: liniar și non-linear. Exemple de filtre liniare sunt medii și filtre Laplacian. Filtrele neliniare reprezintă filtre ca filtrele mediane, minime, maxime și Sobel.
Fiecare dintre filtrele respective are un scop specific și este conceput fie pentru a elimina zgomotul, fie pentru a îmbunătăți anumite aspecte ale imaginii. Dar cum se efectuează filtrarea? Așa vom vedea în secțiunea următoare.
Pentru a realiza un proces de filtrare a imaginilor, avem nevoie de a filtru, numit și a masca. Acest filtru este, de obicei, o fereastră pătrată în două dimensiuni, adică o fereastră cu dimensiuni egale (lățime și înălțime).
Filtrul va include numere. Numerele sunt numite coeficienţii, și sunt ceea ce determină efectiv efectul filtrului și ce va arăta imaginea de ieșire. Figura de mai jos prezintă un exemplu de a 3x3
filtru, având nouă valori (coeficienți).
Pentru a aplica filtrul, 3x3
fereastra este alunecată peste imagine. Se numește acest proces de alunecare a unei ferestre de filtrare peste o imagine convoluție în domeniul spațial. Fereastra va fi plasată pe fiecare pixel (adică gândiți-o ca o celulă într-o matrice) în imagine, unde centrul filtrului ar trebui să se suprapună acelui pixel.
Odată ce această suprapunere se întâmplă, pixelii din sub-imaginea pe care se află filtrul vor fi multiplicați cu coeficienții corespunzători ai filtrului. În acest caz, vom avea o nouă matrice cu noi valori similare cu dimensiunea filtrului (adică,. 3x3
). În cele din urmă, valoarea pixelului central va fi înlocuită cu o nouă valoare utilizând o ecuație matematică specifică, în funcție de tipul de filtru utilizat (adică de filtrul median).
Știu că paragraful de mai sus este un pic cam viu. Să luăm un exemplu pentru a arăta cum se aplică un filtru de imagine în acțiune. Să presupunem că avem următoarea sub-imagine în care filtrul nostru sa suprapus (eu
și j
se referă la locația pixelului din sub-imagine și eu
se referă la imagine):
Convoluția filtrului nostru prezentată în prima figură cu sub-imaginea de mai sus va arăta așa cum se arată mai jos, unde I_new (i, j)
reprezintă rezultatul la locație (I, j)
.
(I-1, j + 1) + v4 x I (i, i) (i + i, j + 1) + v5 x i (i, j) + v6 x i (i, j + 1) x I (i + 1, j + 1)
Procesul este repetat pentru fiecare pixel din imagine, inclusiv pixelii de la limita imaginii. Dar, după cum puteți ghici, o parte a filtrului va locui în afara imaginii când plasați filtrul la pixelii limită. În acest caz, efectuăm umplutură.
Acest proces înseamnă pur și simplu că introducem noi valori ale pixelilor în sub-imagine sub partea filtrului care iese în afara imaginii înainte de procesul de convoluție, deoarece acea parte aparent nu conține valori ale pixelilor. Este în afara imaginii! Acești pixeli căptușiți ar putea fi zero sau o valoare constantă. Există și alte metode pentru setarea valorilor de umplutură, dar acestea sunt în afara scopului acestui tutorial.
Cred că e suficientă teorie pentru acum, așa că haideți să mergem mai departe și să ne murdărim mâinile cu codificare! În acest tutorial, voi explica filtrul median (adică neliniar) și filtrul mediu (adică liniar) și cum le putem implementa în Python.
În filtrul median, alegem o fereastră de alunecare care se va deplasa peste toți pixelii de imagine. Ceea ce facem aici este că colectăm valorile pixelilor care se află sub filtru și ia valoarea mediană a acestor valori. Rezultatul va fi atribuit pixelului central.
Spune-ne 3x3
filtrul a avut următoarele valori după plasarea acestuia pe o sub-imagine:
Să vedem cum se calculează valoarea mediană. Mediana, în esența sa, este mijloc numărul unei liste sortate de numere. Astfel, pentru a găsi mediana pentru filtrul de mai sus, pur și simplu sortați numerele de la cea mai mică la cea mai înaltă, iar mijlocul acestor numere va fi valoarea noastră medie. Sortați valorile din lista noastră 3x3
fereastra ne va da urmatoarele:
17 29 43 57 59 63 65 84 98
Pentru a găsi numărul mediu (median), numărăm doar numărul de valori pe care le avem, adăugăm 1 la acel număr și împărțim cu 2. Aceasta ne va da locația valorii medii în fereastră, care este valoarea noastră mediană. Deci, valoarea mediană va fi localizată 9 + 1/2 = 5
, care este 59
. Această valoare va fi noua valoare a pixelului aflat sub centrul nostru 3x3
fereastră.
Acest tip de filtru este utilizat pentru eliminarea zgomotului și funcționează cel mai bine cu imaginile care suferă sare si piper zgomot. Imaginea de mai jos prezintă un exemplu de imagine care suferă de un astfel de zgomot:
Acum, să scriem un script Python care va aplica filtrul median la imaginea de mai sus. Pentru acest exemplu, vom folosi biblioteca OpenCV. Verificați instalarea OpenCV-Python în Windows și instalați OpenCV 3.0 și Python 2.7+ pe Ubuntu pentru a instala OpenCV.
Pentru a aplica filtrul median, pur și simplu folosim OpenCV cv2.medianBlur ()
funcţie. Scenariul nostru poate arata astfel:
import cv2 import argarp # crea parserul argumentului și analiza argumentele ap = argparse.ArgumentParser () ap.add_argument ('- i', '--image', required = True, help = 'Calea spre imaginea de intrare' = vars (ap.parse_args ()) # citi imaginea imaginii = cv2.imread (args ['image']) # aplică filtrul median 3x3 pe imagine processed_image = cv2.medianBlur (image, 3) # display image cv2. imshow ("procesare mediană a filtrelor", process_image) # salvați imaginea pe disc cv2.imwrite ('processed_image.png', processed_image) # întrerupeți executarea scriptului până când apăsați o tastă de pe tastatură cv2.waitKey (0)
Observați că am folosit argparse
, deoarece este o bună practică să fim flexibili aici și să folosim linia de comandă pentru a trece imaginea pe care dorim să o aplicăm filtrul median ca argument pentru programul nostru.
După ce a trecut imaginea noastră ca argument de linie de comandă, am citit acea imagine folosind cv2.imread ()
funcţie. Apoi aplicăm filtrul median folosind medianBlur ()
funcția, trecând imaginea și dimensiunea filtrului ca parametri. Imaginea este afișată utilizând cv2.imshow ()
funcția și este salvată pe disc utilizând cv2.imwrite ()
.
Rezultatul scriptului de mai sus este următorul:
Ei bine, ce crezi? Foarte frumos - o imagine frumoasă și curată fără zgomot.
Puteți descărca codul de mai sus din depozitul meu median-filtru pe GitHub.
Filtrul mediu este un exemplu de filtru liniar. În principiu, înlocuiește fiecare pixel în imaginea de ieșire cu valoarea medie (medie) a cartierului. Acest lucru are efectul de a netezi imaginea (reducerea variației intensității între un pixel și cel de-al doilea), eliminarea zgomotului din imagine și strălucirea imaginii.
Astfel, în media filtrării, fiecare pixel al imaginii va fi înlocuit cu valoarea medie a vecinilor săi, inclusiv pixelul însuși. 3x3
kernel-ul utilizat pentru filtrarea medie este prezentat în figura de mai jos, deși pot fi utilizate și alte dimensiuni ale nucleului (adică 5x5):
Ceea ce în realitate încearcă să ne spună nucleul de mai sus este că ne sumăm toate elementele de sub nucleu și luăm media (medie) a totalului.
Un aspect important care trebuie menționat aici este că toate elementele nucleului mediu ar trebui:
Să luăm un exemplu pentru a face lucrurile mai clare. Spuneți că avem următoarea sub-imagine:
Când aplicăm filtrul mediu, am face următoarele:
(7 + 9 + 23 + 76 + 91 + 7 + 64 + 90 + 32) / 9 = 44
Rezultatul exact este 44.3
, dar am rotunjit rezultatul 44
. Deci noua valoare pentru pixelul central este 44
in loc de 91
.
Acum, la partea de codificare. Să presupunem că avem următoarea imagine zgomotoasă:
Ceea ce vrem să facem în acest moment este să aplicăm filtrul mediu de pe imaginea de mai sus și să vedem efectele aplicării unui astfel de filtru.
Codul pentru efectuarea acestei operațiuni este după cum urmează:
import cv2 import numpy ca np import argpass # creare parametru parser și analiza argumentelor ap = argparse.ArgumentParser () ap.add_argument ('- i', '--image', required = True, help = image) args = vars (ap.parse_args ()) # citi imaginea imaginii = cv2.imread (args ['image']) # aplică filtrul mediu 3x3 pe kernel = np.ones ((3,3) , np.float32) / 9 process_image = cv2.filter2D (imagine, -1, kernel) # afișare imagine cv2.imshow ("Procesare medie filtru", prelucrate_image) # salvați imaginea pe disc cv2.imwrite ('processed_image.png' process_image) # întrerupe executarea scriptului până când se apasă o tastă de pe tastatură cv2.waitKey (0)
Observați din codul pe care l-am folosit a 3x3
kernel pentru filtrul nostru mediu. Am folosit de asemenea filter2D ()
pentru a aplica filtrul mediu. Primul parametru al acestei funcții este imaginea noastră de intrare, a doua este adâncimea dorită a imaginii de ieșire ddepth
, iar al treilea parametru este kernel-ul nostru. Atribuire -1
pentru ddepth
parametru înseamnă că imaginea de ieșire va avea la fel adâncime ca imaginea de intrare.
După rularea codului pe imaginea zgomotoasă, acesta a fost rezultatul pe care l-am obținut:
Dacă observați imaginea de ieșire, vedem că este mai fină decât imaginea zgomotoasă. Misiunea făcută!
Puteți descărca codul de mai sus de la magazia mea medie de filtre pe GitHub.
După cum am văzut în acest tutorial, Python ne permite să realizăm sarcini avansate, cum ar fi filtrarea imaginilor, în special prin biblioteca OpenCV, într-un mod simplu.
În plus, nu ezitați să vedeți ce avem la dispoziție pentru vânzare și pentru a studia pe piață și nu ezitați să întrebați orice întrebări și să furnizați feedback-ul valoros utilizând feedul de mai jos.