1. Image Filter 图像滤波
滤波
中值滤波(非线性滤波):
- kernel为奇数,对kernel的pixel进行排序,选取中值
- 代码实现:
def median_filter(image,kernel_size):
if(kernel_size%2==0):
return ValueError("kernel_size must be odd!")
if(len(image.shape)>2):
image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
rows,cols = image.shape
out_image = image.copy()
for i in range(kernel_size//2, rows-kernel_size//2):
for j in range(kernel_size//2, cols-kernel_size//2):
window = image[i-kernel_size//2 : i+kernel_size//2+1, j-kernel_size//2 : j+kernel_size//2+1]
flatten_ = window.flatten()
flatten_.sort()
out_image[i,j] = flatten_[kernel_size**2//2]
return out_image
- 注意事项:
卷积完图像的大小: out_size = (input_size - core_size + padding * 2) / stride + 1
所以,在中值滤波时,padding = 0, stride = 1。完成卷积后,左右上下刚好会少一列/行像素,这引申出 Boundary issues
为了图像能和原来大小一致,直接将图像边缘处的行列直接进行赋值了。当然,也可以通过以下方法进行操作:
- clip filter (black)
- wrap around 环绕
- copy edge (*)
- reflect across edge 以此为边界做镜像
均值滤波:
- 对kernel相加求平均
- 代码实现:
def mean_filter(image,kernel_size):
if(kernel_size%2==0):
return ValueError("kernel_size must be odd!")
if(len(image.shape)>2):
image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
rows,cols = image.shape
out_image = image.copy()
k = kernel_size // 2 # 计算卷积核大小的一半
for i in range(k, rows - k):
for j in range(k, cols - k):
window = image[i-k : i+k+1, j-k : j+k+1]
out_image[i, j] = window.sum() // (kernel_size ** 2)
return out_image
高斯滤波
-
高斯公式
-
高斯图
-
高斯核
高斯核是对高斯函数进行离散化,在离散空间坐标上取值,并形成一个离散的权重矩阵(卷积核),再进行归一化。 -
代码实现
def gaussian_kernel_2d(size, sigma_x, sigma_y=None):
if sigma_y is None:
sigma_y = sigma_x
x, y = np.meshgrid(np.linspace(-sigma_x, sigma_x, size),
np.linspace(-sigma_y, sigma_y, size))
print(x.shape, y.shape)
kernel_2d = (1 / (2 * np.pi * sigma_x * sigma_y)) * np.exp(-(x ** 2 / (2 * sigma_x ** 2) + y ** 2 / (2 * sigma_y ** 2)))
# 归一化核
kernel_2d /= kernel_2d.sum()
return kernel_2d
然后用生成的卷积核对图像进行卷积这就是高斯滤波。