Eine Geschichte über die Faltungsfilterung nur durch Matrixberechnung, ohne sich auf die Bildverarbeitungsbibliothek zu verlassen. Auch mit Pythonista möglich
** Klicken Sie hier für Grundlagen **
Anstatt mich auf Open CV oder Pillow zu verlassen, werde ich tatsächlich verschiedene Bildverarbeitungen mit numpy und matplotlib schreiben. Diese Kombination kann auch mit der iOS-App Pythonista verwendet werden.
import numpy as np
import matplotlib.pyplot as plt
Darüber hinaus sind die folgenden Funktionen zum Anzeigen von Bildern praktisch. (Einzelheiten finden Sie unter Grundlagen)
def img_show(img : np.ndarray, cmap = 'gray', vmin = 0, vmax = 255, interpolation = 'none') -> None:
'''np.Zeigen Sie ein Bild mit Array als Argument an.'''
#Setzen Sie dtype auf uint8
img = np.clip(img,vmin,vmax).astype(np.uint8)
#Bild anzeigen
plt.imshow(img, cmap = cmap, vmin = vmin, vmax = vmax, interpolation = interpolation)
plt.show()
plt.close()
Räumliche Filterung ist für den Filter durch Faltung leicht zu verstehen.
Erstellen Sie zunächst eine Funktion zum Falten eines zweidimensionalen Arrays.
def convolve2d(img, kernel):
#Berechnen Sie die Größe der Submatrix
sub_shape = tuple(np.subtract(img.shape, kernel.shape) + 1)
#Da der Funktionsname lang ist, wird er einmal weggelassen
strd = np.lib.stride_tricks.as_strided
#Erstellen Sie eine Submatrix-Matrix
submatrices = strd(img,kernel.shape + sub_shape,img.strides * 2)
#Berechnen Sie die Einstein-Summe aus Submatrix und Kernel
convolved_matrix = np.einsum('ij,ijkl->kl', kernel, submatrices)
return convolved_matrix
Der obige Code wird unter Verwendung der Matrix der Submatrix von img gefaltet. Weitere Informationen finden Sie unter stackoverflow-Lehrer. Bei diesem Algorithmus kann der periphere Teil entfernt werden.
[Trimmen] 'tiger.jpeg'(http://qiita.com/secang0/items/1229212a37d8c9922901#%E5%9B%9B%E8%A7%92% E5% BD% A2% E3% 81% AB% E3% 83% 88% E3% 83% AA% E3% 83% 9F% E3% 83% B3% E3% 82% B0330% E8% BF% BD% E5% 8A% A0) Bild [gewichtete Mittelung durch NTSC-Koeffizienten](http://qiita.com/secang0/items/6fba02d7cc3ef34c0c31#ntsc-%E4%BF%82%E6%95%B0%E3%81%AB % E3% 82% 88% E3% 82% 8B% E5% 8A% A0% E9% 87% 8D% E5% B9% B3% E5% 9D% 87% E6% B3% 95) Andererseits wurden verschiedene Filter verwendet.
img = plt.imread('tiger.jpeg')[1200:1500,1400:1700]
img = (0.298912 * img[...,0] + 0.586611 * img[...,1] + 0.114478 * img[...,2])
img_show(img)
Ein Tiefpassfilter ist ein Filter, das eher einen niederfrequenten Teil als einen hochfrequenten Teil eines Bildes hinterlässt. (Hoch / Niedrig ist Frequenz) Kurz gesagt, es verwischt, indem abrupte Änderungen seltener gemacht werden. Dieser Prozess wird häufig verwendet, um Rauschen zu entfernen.
img_show(convolve2d(img, kernel))
In der folgenden Tabelle wird die Verkettung verwendet, um mit dem Originalbild übereinzustimmen.
Methodenname | Kernel / Originalbild / Filterbild | Bemerkungen |
---|---|---|
Einfacher Filter für gleitenden Durchschnitt | kernel = np.ones((5,5)/25 |
Der einfachste Tiefpassfilter |
Gaußscher Filter | kernel = gaussian_kernel(5) |
Hervorragender Tiefpassfilter bei Normalverteilung |
Im Originalbild ist der hellgraue Teil (im Farbbild gelblich grün) in der Mitte punktiert. Die Anwendung eines Tiefpassfilters erschwert jedoch die Bestätigung.
In der Tabelle wird die folgende Gaußsche Matrix verwendet. Referenz
def gaussian_kernel(n : int) -> np.ndarray:
'''(n,n)Machen Sie eine Gaußsche Matrix aus'''
#[nC0, nC1, ..., nCn]Erstellen
combs = [1]
for i in range(1,n):
ratio = (n-i)/(i)
combs.append(combs[-1]*ratio)
combs = np.array(combs).reshape(1,n)/(2**(n-1))
#Erstellen Sie eine Gaußsche Matrix mit dem Produkt aus vertikalen und horizontalen Vektoren
result = combs.T.dot(combs)
return result
Ein Hochpassfilter ist ein Filter, das dazu neigt, eher einen Hochfrequenzabschnitt als einen Niederfrequenzabschnitt eines Bildes zu hinterlassen. Dies betont die verschiedenen Bereiche und schärft das Bild.
Ein typischer Schärfungsfilter ist für $ k> 0 $
1.\hspace{5pt}
\left(
\begin{matrix}
0&-k&0\\
-k&1+4k&-k\\
0&-k&0\\
\end{matrix}
\right)
\\
\mbox{Oder}
\\
2.\hspace{5pt}
\left(
\begin{matrix}
-k&-k&-k\\
-k&1+8k&-k\\
-k&-k&-k\\
\end{matrix}
\right)
sharp_kernel_1 = lambda k : np.matrix('0,{0},0;{0},{1},{0};0,{0},0'.format(-k,1+4*k))
sharp_kernel_2 = lambda k : np.matrix('{0},{0},{0};{0},{1},{0};{0},{0},{0}'.format(-k,1+8*k))
Anruf. Referenz Je größer der Wert von k ist, desto stärker ist der Filter. Wenn k gleich ist, ist 2 auch stärker.
Das Bild ist 3 * 3-Gauß-gefiltert und die Anzeige ist wie unten beschrieben standardisiert.
img_gaussian = convolve2d(img, gaussian(3))
img_show(norm_img(convolve2d(img_gaussian, kernel)))
In der folgenden Tabelle wird die Verkettung verwendet, um mit dem Originalbild übereinzustimmen. Der hellgraue Teil darunter (gelblich grün in einem Farbbild) ist ursprünglich punktiert und weist viele Hochfrequenzkomponenten auf. Bitte achten Sie besonders darauf.
Kernel / Originalbild / Filterbild |
---|
kernel = sharp_kernel_1(1) |
kernel = sharp_kernel_1(10) |
kernel = sharp_kernel_1(1) |
kernel = sharp_kernel_2(10) |
Da der Pixelwert des Filterbildes nicht in 0 bis 255 passt, wird er durch die folgende Funktion standardisiert. Dies entspricht dem Intervall von $ Durchschnitt \ pm n_ {std} \ mal Standardabweichung $ bis 0 ~ 255. (Eigentlich $ n_ {std} = 2 $) Dies ist ein Prozess, der auch für das Originalbild zum Vergleich verwendet wird und sich geringfügig vom oberen Bild unterscheidet.
def norm_img(img_filtered,n_std):
'''img_Gefiltert standardisieren'''
mean = img_filtered.mean() #durchschnittlich
std = img_filtered.std() #Standardabweichung
img_norm = 256*((img_filtered - mean)/std + n_std)/(n_std*2)
return np.clip(img_norm,0,255).astype(np.uint8)
Differentialfilter werden zur Konturextraktion eingesetzt. Dies liegt daran, dass Sie durch Ermitteln des Unterschieds zum benachbarten Pixel herausfinden können, wo die Änderung groß ist.
Referenz: ** Die tatsächlichen Ergebnisse werden angezeigt ** ** Erklärung verschiedener Unterschiede zwischen Filtern ** wurde hinzugefügt.
Das Bild ist 3 * 3 Gauß-gefiltert. Darüber hinaus [Abschnitt Hochpassfilter](http://qiita.com/secang0/items/f3a3ff629988dc660d87#%E3%83%8F%E3%82%A4%E3%83%91%E3%82%B9 % E3% 83% 95% E3% 82% A3% E3% 83% AB% E3% 82% BF% E3% 83% BC) Das in) beschriebene Standardisierungsverfahren wurde angewendet.
img_gaussian = convolve2d(img, gaussian(3))
img_show(norm_img(convolve2d(img_gaussian, kernel)))
Inhalt | Kernel / Originalbild / Filterbild | Bemerkungen | Referenzlink |
---|---|---|---|
Einfacher Differentialfilter erster Ordnung von unten nach oben | kernel = np.matrix('0,-1,0;0,1,0;0,0,0') |
Geräuschempfindlich | MitErklärung |
Filter von unten nach oben vorschneiden | kernel = np.matrix('-1,-1,-1;0,0,0;1,1,1') |
MitErgebnisbild&MitErklärung | |
Sobel Filter von unten nach oben | kernel = np.matrix('-1,-2,-1;0,0,0;1,2,1') |
np.matrix('-1,-1,-1;0,0,0;1,1,1')*1.33 DerUnterschiedzu |
MitErgebnisbild&MitErklärung |
Laplace-Filter | kernel = np.matrix('-1,-1,-1;-1,8,-1;-1,-1,-1') |
DifferentialzweiterOrdnunginalleRichtungen |
MitErgebnisbild&MitErklärung |
Inhalt | Kernel / Originalbild / Filterbild | Bemerkungen | Referenzlink |
---|---|---|---|
Prägung | kernel = np.matrix('-2,-1,0;-1,1,1;0,1,2') |
1imZentrumvonSobel | Ergebnisbildunten |
Recommended Posts