Filtration

Filtrace obrazu slouží ke zvýraznění určité informace. Můžeme potlačit šum, vyhladit obraz, zvýraznit kontrast, nebo detekovat hrany. Předzpracování obrazu pomocí filtrace je lokální nikoli bodová operace. Pracujeme s intenzitou bodu, který je vázán na své okolí. Toto okolí může mít různé tvary, nejčasteji se jedná o čtvercové okolí. Filtry dělíme na lineární a nelineární. Lineární filtry jsou takové, které hodnotu výsledného bodu počítají jako sumu součinu intenzit s příslušnými váhami filtru v daném okolí bodu. Oproti tomu nelineární filtry nevytvářejí novou intenzitu, ale výslednou intenzitu vybírají z okolí upravovaného bodu. Filtr typu medián vybere prostřední člen z uspořádané posloupnosti v daném okolí.

Filtration with more images

avg0 avg0

Výsledek po průměrování avg

Local averaging - convolution

In [2]:
%pylab inline --no-import-all
import numpy as np
import scipy
from scipy import ndimage
import scipy.signal
import scipy.misc
import skimage.data
import skimage.io
import matplotlib.pyplot as plt
Populating the interactive namespace from numpy and matplotlib
In [4]:
# plt.imshow(scipy.misc.lena())
plt.imshow(skimage.data.astronaut())
Out[4]:
<matplotlib.image.AxesImage at 0x1f43b7d1dd8>
In [3]:
np.convolve([3, 10, 10, 1, 2, 2], [1, -2, 1])
Out[3]:
array([ 3,  4, -7, -9, 10, -1, -2,  2])

konvoluce 2d

Averaging - rovoměrné rozmazání

convolution

In [8]:
np.convolve([10, 10, 10, 10, 10, 10, 10, 10], [1, -2, 1], "valid")
Out[8]:
array([0, 0, 0, 0, 0, 0])
In [9]:
np.convolve([10, 10, 10, 10, 10, 0, 0, 0, 0, 0], [1, -2, 1], "valid")
Out[9]:
array([  0,   0,   0, -10,  10,   0,   0,   0])
In [33]:
lena = skimage.io.imread("https://i.stack.imgur.com/3T6Gc.jpg")
plt.imshow(lena)
plt.colorbar()
Out[33]:
<matplotlib.colorbar.Colorbar at 0x21e4b55afd0>
In [26]:
# lena = scipy.misc.face()
# l = lena[250:340, 530:630,0]
lena = skimage.io.imread("https://i.stack.imgur.com/3T6Gc.jpg", as_grey=True)
# print(lena.max())

l = lena[230:290, 220:320]
noisy = l + 1.6*l.std()*np.random.random(l.shape)

print(noisy.std())

plt.imshow(noisy, cmap='gray', interpolation=None)
#plt.imshow(lena)
plt.colorbar()
plt.show()
0.20064397202412135

Rozsah

In [27]:
import scipy.signal
kernel = np.ones([15,15])
output1 = scipy.signal.convolve2d(noisy, kernel)

plt.imshow(output1, cmap="gray")
plt.colorbar()
Out[27]:
<matplotlib.colorbar.Colorbar at 0x21e49ef5080>
In [28]:
kernel = np.ones([15,15])
kernel = kernel / np.sum(kernel)
output1 = scipy.signal.convolve2d(noisy, kernel)

plt.imshow(output1, cmap="gray")
plt.colorbar()
Out[28]:
<matplotlib.colorbar.Colorbar at 0x21e49f8c0b8>

Okraje

In [29]:
import scipy.signal
kernel = np.ones([15,15])
output1 = scipy.signal.convolve2d(noisy, kernel, boundary="fill", fillvalue=0)
output2 = scipy.signal.convolve2d(noisy, kernel, boundary="wrap")
output3 = scipy.signal.convolve2d(noisy, kernel, boundary="symm")
plt.figure(figsize=[10,15])
plt.subplot(131)
plt.imshow(output1, cmap="gray")
plt.subplot(132)
plt.imshow(output2, cmap="gray")
plt.subplot(133)
plt.imshow(output3, cmap="gray")
Out[29]:
<matplotlib.image.AxesImage at 0x21e4a186f60>

Rozměr konvoluce

In [30]:
import scipy.signal
kernel = np.ones([15,15])
output1 = scipy.signal.convolve2d(noisy, kernel, mode="full", boundary="fill")
output2 = scipy.signal.convolve2d(noisy, kernel, mode="same", boundary="fill")
output3 = scipy.signal.convolve2d(noisy, kernel, mode="valid", boundary="fill")
plt.figure(figsize=[10,15])
plt.subplot(131)
plt.imshow(output1, cmap="gray")
plt.subplot(132)
plt.imshow(output2, cmap="gray")
plt.subplot(133)
plt.imshow(output3, cmap="gray")
Out[30]:
<matplotlib.image.AxesImage at 0x21e4a25be48>
In [31]:
local_mean = ndimage.uniform_filter(noisy, size=15)
plt.imshow(local_mean, cmap='gray', interpolation=None)
plt.show()

Gaussian filter

In [32]:
blurred_lena = ndimage.gaussian_filter(noisy, sigma=1)
very_blurred = ndimage.gaussian_filter(noisy, sigma=5)
plt.imshow(blurred_lena, cmap='gray')
plt.figure()
plt.imshow(very_blurred, cmap='gray')
Out[32]:
<matplotlib.image.AxesImage at 0x21e4b54b518>

Remove noise

Zašumněný obraz odstranění šumu

mince mince

mince mince

Quantiles (median)

In [26]:
med_denoised = ndimage.median_filter(noisy, 3)
plt.imshow(noisy, cmap='gray')
plt.show()
plt.figure()
plt.imshow(med_denoised, cmap='gray')
plt.show()

Další filtry

Další kvantilové filtry

ndimage.maximum_filter, ndimage.percentile_filter

Nelineární filtry

scipy.signal.wiener

Gradient filters

In [8]:
import scipy
import scipy.ndimage
import matplotlib.pyplot as plt
In [27]:
img = np.zeros([50, 50])
img[20:30,20:30] = 50

plt.imshow(img, cmap='gray')

sob = scipy.ndimage.filters.sobel(img, 0)
plt.imshow(sob, cmap='gray')
Out[27]:
<matplotlib.image.AxesImage at 0x7f765e633990>
In [10]:
img = np.zeros([50,50,50])
img[20:30,20:30,20:30] = 50

plt.imshow(img[:,:,20], cmap='gray')

sob = scipy.ndimage.filters.sobel(img,2)
plt.imshow(sob[:,:,20], cmap='gray')
Out[10]:
<matplotlib.image.AxesImage at 0x7f768031af10>

Roberts

In [11]:
import matplotlib.pyplot as plt

import  skimage.data
import  skimage.filter 
# import roberts, sobel


image = skimage.data.camera()
edge_roberts = skimage.filter.roberts(image)

plt.imshow(edge_roberts, cmap='gray')
Out[11]:
<matplotlib.image.AxesImage at 0x7f767d47fa50>

Sobel

In [12]:
edg_sobel = skimage.filter.sobel(image)

plt.imshow(edg_sobel, cmap='gray')
Out[12]:
<matplotlib.image.AxesImage at 0x7f767d3b9dd0>
In [13]:
import pylab as pl
sx=ndimage.sobel(image,axis=0,mode='constant')
sy=ndimage.sobel(image,axis=1,mode='constant')
# sob=np.hypot(sx,sy)
# pl.quiver(sx, sy)
plt.imshow(sx)
plt.figure()
plt.imshow(sy)
Out[13]:
<matplotlib.image.AxesImage at 0x7f767c085050>