Hi, I'm Ramu. This time, we will implement a Gaussian filter that removes noise in the image.
The Gaussian filter is a filter that smoothes images. By applying this filter, you can make the entire image look blurry.
In this filter, the peripheral pixels of the pixel of interest are weighted by a Gaussian distribution, and the closer to the center pixel of the filter, the greater the weight. Weighting by Gaussian distribution is defined as follows.
g(x,y) = \frac{1}{2\pi\sigma^2}e^{-\frac{x^2+y^2}{2\sigma^2}}
For example, the following filters are often used for 3x3 and 5x5 Gaussian filters. Probably, if you specify around $ σ = 0.85 $ for the argument s, it will be this value.
Assuming that the pixel of interest is the center, the sum of the products of the peripheral pixels and the corresponding filter values should be substituted for the pixel of interest. For a 3 × 3 filter, $ I (x_0, y_0) × \ frac {1} {16} + I (x_0, y_1) × \ frac {2} {16} + ... I (x_2, y_2) × Substitute the value of \ frac {1} {16} $ for the pixel of interest.
Also, since the edge of the image cannot be filtered, 0 is used for non-existent pixels. This is called 0 padding.
gaussianFilter.py
import numpy as np
import cv2
import matplotlib.pyplot as plt
def gaussianFilter(img,k,s):
w,h,c = img.shape
size = k // 2
#0 padding process
_img = np.zeros((w+2*size,h+2*size,c), dtype=np.uint8)
_img[size:size+w,size:size+h] = img.copy().astype(np.uint8)
dst = _img.copy()
#Create filter
ker = np.zeros((k,k), dtype=np.float)
for x in range(-1*size,k-size):
for y in range(-1*size,k-size):
ker[x+size,y+size] = (1/(2*np.pi*(s**2)))*np.exp(-1*(x**2+y**2)/(2*(s**2)))
ker /= ker.sum()
#Filtering process
for x in range(w):
for y in range(h):
for z in range(c):
dst[x+size,y+size,z] = np.sum(ker*_img[x:x+k,y:y+k,z])
dst = dst[size:size+w,size:size+h].astype(np.uint8)
return dst
#Image reading
img = cv2.imread('image.jpg')
#Gaussian filter
#2nd argument: filter size, 3rd argument: standard deviation(σ)
img = gaussianFilter(img,21,2)
#Save image
cv2.imwrite('result.jpg', img)
#Image display
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
The image on the left is the input image, and the image on the right is the output image. You can see that the point noise is reduced.
If you have any questions, please feel free to contact us. imori_imori's Github has the official answer, so please check that as well. .. Also, since python is a beginner, please kindly point out any mistakes.
Recommended Posts