【图像处理-滤波】python实现基本的空域、频域滤波操作(中值滤波、均值滤波、FFT_陷波器)

这是在上课时老师留的第一个大作业,不愧是我,总是赶到ddl。

中值滤波

中值滤波的原理很简单,就是滑动窗在原图上滑动,然后将滑动窗的内容的中值,作为新图中该坐标的像素值,比较适用于 椒盐噪声。从原理来说,如果没有对原图进行拓展的话,滤波后的新图的大小与原图是不一样的,原图的边缘部分是没有参与运算的。所以下面是利用了padding的技巧,确保原图的边缘部分也可以滤波。
代码如下:

import numpy as np
import cv2
import glob
from matplotlib import pyplot as plt

img = cv2.imread(r'F:\something_useful\Image_processing\homework01\Circuit_noise.jpg',0)

img_copy = img.copy()
width = img.shape[0] #宽
length = img.shape[1] #高
kernel = 5 #卷积核大小 / 滑动窗大小
mid = (kernel-1)//2 
padding = (kernel - 1)//2 #扩展操作,为了对原图所有的点都操作
img_new = np.zeros([width + 2*padding,length + 2*padding],dtype = np.uint8) #扩展原图,补零
#将原图 铺在 新图上
for i in range(width):
    for j in range(length):
        img_new[padding + i,padding + j] = img[i,j]

slide_window = [] #滑动窗的内容
for i in range(width):
    for j in range(length):
        for m in range(kernel):
            for n in range(kernel):
                slide_window.append(img_new[i+m,j+n])                        
        slide_window.sort()        
        img_copy[i ,j] = slide_window[(len(slide_window)+1)//2]     #取中值  
        del slide_window[:]
        
print('okok---------')
cv2.imshow('img_after_Circuit_noise',img_copy)
print(img_copy.shape)  
cv2.waitKey(0)
cv2.destroyAllWindows()

效果图如下:
【图像处理-滤波】python实现基本的空域、频域滤波操作(中值滤波、均值滤波、FFT_陷波器)_第1张图片

均值滤波

与中值滤波相似,其实只是将取中值的操作换成取均值即可。均值滤波是用于去除高斯噪声,那种“米花类型”的噪音。代码如下:

import numpy as np
import cv2
import glob
from matplotlib import pyplot as plt

img = cv2.imread(r'F:\something_useful\Image_processing\homework01\california_22_13.bmp',0)
cv2.imshow('img',img)
img_copy = img.copy()
width = img.shape[0] #宽
length = img.shape[1] #高
kernel = 5 #卷积核大小 / 滑动窗大小
padding = (kernel - 1)//2 #扩展操作,为了对原图所有的点都操作
img_new = np.zeros([width + 2*padding,length + 2*padding],dtype = np.uint8) #扩展原图,补零
#将原图 铺在 新图上
for i in range(width):
    for j in range(length):
        img_new[padding + i,padding + j] = img[i,j]

slide_window = [] #滑动窗的内容
for i in range(width):
    for j in range(length):
        window_sum = 0 #滑动窗的和
        for m in range(kernel):
            for n in range(kernel):
                slide_window.append(img_new[i+m,j+n])  
                window_sum += img_new[i+m,j+n]             
        window_average = window_sum / len(slide_window)
        img_copy[i ,j] = window_average    #取均值  
        del slide_window[:]
        
print('okok---------')
cv2.imshow('img_after',img_copy)
print(img_copy.shape)  
cv2.waitKey(0)
cv2.destroyAllWindows()

效果图如下:可以就看出 均值滤波去除高斯噪声,还是很容易把边缘给模糊了的
【图像处理-滤波】python实现基本的空域、频域滤波操作(中值滤波、均值滤波、FFT_陷波器)_第2张图片

FFT_陷波器

这里首先看一下给的带噪音的原图。
【图像处理-滤波】python实现基本的空域、频域滤波操作(中值滤波、均值滤波、FFT_陷波器)_第3张图片
发现噪音很明显是带有特定频率的,这里把它称为正弦噪音,所以考虑在频域进行处理。首先试了频域下的低通滤波器,发现通过控制滤波的半径,可以去除正弦噪音,但是一些更加高频的细节并不能够被保留下来,效果如下:

【图像处理-滤波】python实现基本的空域、频域滤波操作(中值滤波、均值滤波、FFT_陷波器)_第4张图片

所以考虑使用 陷波器,即去除特定频率的噪音,而不是去破坏图像的其他细节。代码如下:

def boy_noisy_process():    
    #读图片,噪音类型只要是正弦,利用fft变换,从频谱去除噪音
    img_boy_noisy = Image.open(r'.\boy_noisy.gif')
    img_boy_noisy = np.array(img_boy_noisy)
    cv2.imshow('img_boy_noisy',img_boy_noisy)
    #FFT
    f = np.fft.fft2(img_boy_noisy)
    #中心化
    fshift = np.fft.fftshift(f)
    
    fft_show = np.array(np.log(np.abs(fshift)),dtype = np.uint8)
    plt.subplot(1,2,1),plt.imshow(fft_show,'gray'),plt.title('img fft')
    
    #构建滤波器(陷波器)
    kernel = np.ones(fshift.shape,dtype = np.uint8)
    width_center = fshift.shape[0] // 2
    length_center = fshift.shape[1] // 2
    radius = 32 #滤波器半径
    for i in range(width_center - radius,width_center + radius):
        kernel[i,length_center - radius] = 0
        kernel[i,length_center + radius] = 0
    for j in range(length_center - radius,length_center + radius):
        kernel[width_center - radius,j] = 0
        kernel[width_center -+ radius,j] = 0
    
    #频域滤波
    fshift_new = fshift * kernel
    fft_show_new = np.array(np.log(np.abs(fshift_new)),dtype = np.uint8)
    plt.subplot(1,2,2),plt.imshow(fft_show_new,'gray'),plt.title('img fft new')
    
    # 逆变换
    f1shift = np.fft.ifftshift(fshift_new)
    img_after_boy_noisy = np.fft.ifft2(f1shift)
    #出来的是复数,无法显示
    img_after_boy_noisy = np.array(np.abs(img_after_boy_noisy),dtype = np.uint8)
    cv2.imshow('img_after_boy_noisy',img_after_boy_noisy)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()

结果是比较满意的,高频的细节也可以保留下来。最终效果如下:
【图像处理-滤波】python实现基本的空域、频域滤波操作(中值滤波、均值滤波、FFT_陷波器)_第5张图片

你可能感兴趣的:(信号处理算法,python)