opencv-python图像高通滤波与低通滤波

opencv-python图像高通滤波与低通滤波

一、高通滤波

高通滤波原理

​ 高通滤波意思就是让频率高的部分通过,衍生到图像上面来理解,一张图片的像素一般来说,在轮廓的地方频率高,而在其他部分频率低。

​ 对于傅里叶变换而言,它将一张图像高频部分显示在外围,而低频部分显示在中间;因此,高通滤波就是将傅里叶变换之后的频谱图的中间部分过滤;过滤方法就是将中间部分区域的低频对应的像素值给设置为0,设置为黑色。如图所示:

在这里插入图片描述

这个黑色区域就是需要我们构造的区域,尺寸是通过我们自定义的。

具体代码描述

1.构造高通滤波范围。

def highPassFiltering(img,size):#传递参数为傅里叶变换后的频谱图和滤波尺寸
    h, w = img.shape[0:2]#获取图像属性
    h1,w1 = int(h/2), int(w/2)#找到傅里叶频谱图的中心点
    img[h1-int(size/2):h1+int(size/2), w1-int(size/2):w1+int(size/2)] = 0#中心点加减滤波尺寸的一半,刚好形成一个定义尺寸的滤波大小,然后设置为0
    return img

2.现将一张灰度图进行傅里叶变换,获取该图片的频谱图,然后再调用高通滤波函数进行滤波,最后再通过傅里叶逆变换查看结果。

def cv2_imread(file_path, flag=1):
    # 读取图片数据
    return cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), flag)


gray = cv2_imread("C://Users//小白二号//Desktop//dd.png", 1)
gray = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY)
gray = cv2.resize(gray, (640, 420))

# 傅里叶变换
img_dft = np.fft.fft2(gray)
dft_shift = np.fft.fftshift(img_dft)  # 将频域从左上角移动到中间

#高通滤波
dft_shift=highPassFiltering(dft_shift,200)
res = np.log(np.abs(dft_shift))


# 傅里叶逆变换
idft_shift = np.fft.ifftshift(dft_shift)  #将频域从中间移动到左上角
ifimg = np.fft.ifft2(idft_shift)  # 傅里叶库函数调用
ifimg = np.abs(ifimg)
cv2.imshow("ifimg",np.int8(ifimg))
cv2.imshow("gray",gray)


# 绘制图片
plt.subplot(131), plt.imshow(gray, 'gray'), plt.title('原图像')
plt.axis('off')
plt.subplot(132), plt.imshow(res, 'gray'), plt.title('高通滤波')
plt.axis('off')
plt.subplot(133), plt.imshow(np.int8(ifimg), 'gray'), plt.title('滤波后效果')
plt.axis('off')
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()

运行效果:

opencv-python图像高通滤波与低通滤波_第1张图片

二、低通滤波

低通滤波原理

​ 低通滤波顾名思义就是低频可以通过,过滤掉高频部分,而对于图像的噪声,包括椒盐噪声和高斯噪声,他们的频率都是比较高的例如像素值为255,那么低通滤波就会将这些噪声过滤,但低通滤波并没有识别功能,图像中有些区域的像素同样为255,同理,低通滤波也会将其完全过滤,因此我们可以简单认为,低通滤波其实就是将频域图中心部分保留,将外围部分过滤,衍生到图像中就是将高频区域对应的像素值设置为0(黑色)。

​ 其实现方式大致思路如下图:

opencv-python图像高通滤波与低通滤波_第2张图片

具体代码实例

1.构造低通滤波范围

def lowPassFiltering(img,size):#传递参数为傅里叶变换后的频谱图和滤波尺寸
    h, w = img.shape[0:2]#获取图像属性
    h1,w1 = int(h/2), int(w/2)#找到傅里叶频谱图的中心点
    img2 = np.zeros((h, w), np.uint8)#定义空白黑色图像,和傅里叶变换传递的图尺寸一致
    img2[h1-int(size/2):h1+int(size/2), w1-int(size/2):w1+int(size/2)] = 1#中心点加减滤波尺寸的一半,刚好形成一个定义尺寸的滤波大小,然后设置为1,保留低频部分
    img3=img2*img #将定义的低通滤波与传入的傅里叶频谱图一一对应相乘,得到低通滤波
    return img3

2.读取图像添加噪声并灰度化,进行傅里叶变换后调用低通滤波函数,然后通过傅里叶逆变换还原观察图像变化

def cv2_imread(file_path, flag=1):
    # 读取图片数据
    return cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), flag)


gray = cv2_imread("C://Users//小白二号//Desktop//dd.png", 1)
gray = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY)
gray = cv2.resize(gray, (1280, 720))

h,w =gray.shape

for i in range(3000):    #添加3000个噪声点
    x = np.random.randint(0, h)
    y = np.random.randint(0, w)
    gray[x,y] = 255

# 傅里叶变换
img_dft = np.fft.fft2(gray)
dft_shift = np.fft.fftshift(img_dft)  # 将频域从左上角移动到中间

# 低通滤波
dft_shift = lowPassFiltering(dft_shift, 200)
res = np.log(np.abs(dft_shift))

# 傅里叶逆变换
idft_shift = np.fft.ifftshift(dft_shift)  # 将频域从中间移动到左上角
ifimg = np.fft.ifft2(idft_shift)  # 傅里叶库函数调用
ifimg = np.abs(ifimg)
cv2.imshow("ifimg", np.int8(ifimg))
cv2.imshow("gray", gray)

# 绘制图片
plt.subplot(131), plt.imshow(gray, 'gray'), plt.title('原图像')
plt.axis('off')
plt.subplot(132), plt.imshow(res, 'gray'), plt.title('低通滤波')
plt.axis('off')
plt.subplot(133), plt.imshow(np.int8(ifimg), 'gray'), plt.title('滤波后效果')
plt.axis('off')
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()

运行效果:
opencv-python图像高通滤波与低通滤波_第3张图片

图像的噪声基本去掉,也就是说,低通滤波消除噪声的强度取决于你构造低通滤波的尺寸大小,尺寸越大,消除越不好,图像越清晰;尺寸越小,消除越好,图像越模糊

你可能感兴趣的:(opencv,python,计算机视觉)