《OpenCv视觉之眼》Python图像处理七 :Opencv图像处理之高通滤波和低通滤波原理及构造

本专栏主要介绍若是经过OpenCv-Python进行图像处理,经过原理理解OpenCv-Python的函数处理原型,在具体状况中,针对不一样的图像进行不一样等级的、不一样方法的处理,以达到对图像进行去噪、锐化等一系列的操做。同时,但愿观看本专栏的小伙伴能够理解到OpenCv进行图像处理的强大哦,若有转载,请注明出处(原文连接和做者署名),感谢各位小伙伴啦!python

前文参考:
《OpenCv视觉之眼》Python图像处理一 :Opencv-python的简介及Python环境搭建
《OpenCv视觉之眼》Python图像处理二 :Opencv图像读取、显示、保存基本函数原型及使用
《OpenCv视觉之眼》Python图像处理三 :Opencv图像属性、ROI区域获取及通道处理
《OpenCv视觉之眼》Python图像处理四 :Opencv图像灰度处理的四种方法及原理
《OpenCv视觉之眼》Python图像处理五 :Opencv图像去噪处理之均值滤波、方框滤波、中值滤波和高斯滤波
《OpenCv视觉之眼》Python图像处理六 :Opencv图像傅里叶变换和傅里叶逆变换原理及实现





编程

上一章节,林君学长介绍了图像的傅里叶变换和逆变换,图傅里叶变换和逆变换并非对图像处理的目的,只是图像处理过程的中间步骤,而咱们须要经过图像的傅里叶变换获得图像的频域图,而后对图像的频域进行操做,例如构造高通滤波和低通滤波对图像频域进行过滤,而后再经过傅里叶逆变换将频域图还原为时域图进行显示,达到图像去噪、图像轮廓提取、图像锐化的目的。dom

本次博客,林君学长主要介绍在傅里叶变换的基础上,如何构造高通滤波和低通滤波来进行图像简单轮廓提取和图像去噪,高通和低通滤波的主要难点理解就是傅里叶变换和逆变换,上次博客已经介绍过,而对于高通和低通滤波的构造仍是比较简单的,一块儿学习吧!

函数

1、高通滤波

  • 高通滤波通常用来提取图像轮廓

一、高通滤波简介

高通滤波(high-pass filter) 是一种过滤方式,规则为高频信号能正常经过,而低于设定临界值的低频信号则被阻隔、减弱。可是阻隔、减弱的幅度则会依据不一样的频率以及不一样的滤波程序(目的)而改变。它有的时候也被叫作低频去除过滤(low-cut filter)学习

二、图像高通滤波原理

1)、图像高通滤波原理首先应该了解高通滤波应该除掉的是什么滤波,高通滤波,意思就是让高频部分经过,留下低频部分;而衍生到图像上面来理解,一张图片的像素通常来讲,在轮廓的地方像素值高,而在其余部分像素值低,例如一张图像上面的人像,人像的轮廓之因此咱们可以看出来就是由于与周围像素值相差过大,频率高,周围像素值低,频率低,造成像素差,从而咱们肉眼能够分辨;
2)、而对于傅里叶变换来讲,它将一张图像高频部分显示在外围,而低频部分显示在中间;所以,高通滤波就是将傅里叶变换以后的频谱图的中间部分过滤;过滤方法就是将中间部分区域的低频对应的像素值给设置为0,设置为黑色,以下图所示:
在这里插入图片描述
而这个黑色区域就是须要咱们构造的区域,尺寸是经过咱们自定义的,接下来,了解如何构造高通滤波吧!


ui

注意:该出是将低频处对应的像素值设置为黑色,而不是将频域图的中间部分变黑,相反的,频域图而言,像素值越低,频率越低,中间部分也就越亮spa

三、图像高通滤波构造

1)、构造高通滤波函数.net

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
#高通滤波构造
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)、步骤一:读取一张图像,转化为灰度图,而后经过傅里叶变换获得频谱图,而后调用高通滤波函数进行过滤,最后进行傅里叶逆变换观察结果设计

这里傅里叶变换咱们直接用Numpy的傅里叶变换,用法比较简单code

#Numpy库的傅里叶变换
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取图像
img = cv.imread('my.jpg',0)
#傅里叶变换
f = np.fft.fft2(img)
#将左上角低频部分移动到中间
fshift = np.fft.fftshift(f)
#调用高通滤波函数
img1=highPassFiltering(fshift,80)
#复数化整,方便观察频谱图
res = np.log(np.abs(img1))
#傅里叶逆变换
ishift = np.fft.ifftshift(img1)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)
#展现结果
plt.subplot(131), plt.imshow(img,'gray'), plt.title('原图像')
plt.axis('off')
plt.subplot(132), plt.imshow(res,'gray'), plt.title('高通滤波')
plt.axis('off')
plt.subplot(133), plt.imshow(iimg,'gray'), plt.title('高通滤波结果')
plt.axis('off')
plt.show()

在这里插入图片描述
咱们能够看到,经过调节尺寸的大小,咱们能够提取明显度不一样的图像轮廓,对于高通滤波的尺寸大小,主要看实际操做中对图像的要求而设置

注意:该出是将低频处对应的像素值设置为黑色,而不是将频域图的中间部分变黑,相反的,频域图而言,像素值越低,频率越低,中间部分也就越亮
3)、以上咱们是对灰度图像进行高通滤波处理,那么不少小伙伴会疑惑,如何对彩色图像进行高通滤波处理呢?步骤也是一样如此,只不过,咱们须要用到的傅里叶变换为彩色图像的傅里叶变换而已,上次博客林君学长也已经讲过哦,只不过,在现实的图像处理中,傅里叶变换通常是针对灰度图像而言,由于对弈灰度图像,有较好的频域,比较可观的频域图像,通常的图像图像不论是提取轮廓、仍是阈值化都是转化为灰度图像进行处理的哈,完整代码以下:

#彩色图像的高通滤波
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#自定义傅里叶变换功能函数
def dft(img):
    #获取图像属性
    H,W,channel=img.shape
    #定义频域图,从公式能够看出为求出结果为复数,所以,须要定义为复数矩阵
    F = np.zeros((H, W,channel), dtype=np.complex)
    # 准备与原始图像位置相对应的处理索引
    x = np.tile(np.arange(W), (H, 1))
    y = np.arange(H).repeat(W).reshape(H, -1)
    #经过公式遍历
    for c in range(channel):
        for u in range(H):
            for v in range(W):
                F[u, v, c] = np.sum(img[..., c] * np.exp(-2j * np.pi * (x * u / W + y * v / H))) / np.sqrt(H * W)
    return F
#傅里叶反变换
def idft(G):
    H, W, channel = G.shape
    #定义空白时域图像
    out = np.zeros((H, W, channel), dtype=np.float32)
    # 准备与原始图像位置相对应的处理索引
    x = np.tile(np.arange(W), (H, 1))
    y = np.arange(H).repeat(W).reshape(H, -1)
    #经过公式遍历
    for c in range(channel):
        for u in range(H):
            for v in range(W):
                out[u, v, c] = np.abs(np.sum(G[..., c] * np.exp(2j * np.pi * (x * u / W + y * v / H)))) / np.sqrt(W * H)
    # 剪裁
    out = np.clip(out, 0, 255)
    out = out.astype(np.uint8)
    return out
#高通滤波构造
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
#读取图像
img=cv2.imread("my.jpg")
#进行图像裁剪,加快傅里叶运算速率。将原始尺寸缩放为100*100的尺寸
img = cv2.resize(img, (100, 100), interpolation=cv2.INTER_CUBIC)
#BGR转换为RGB显示格式,方便经过matplotlib进行图像显示
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
#调用傅里叶变换函数
result =dft(img)
#将傅里叶频谱图从左上角移动到中心位置
fshift = np.fft.fftshift(result)
img1=highPassFiltering(fshift,30)
#将复数转为浮点数进行傅里叶频谱图显示
fimg = np.log(np.abs(img1))#复数转为整数,方便显示傅里叶频谱图
#将傅里叶频谱图从中心还原到左上角位置
ishift = np.fft.ifftshift(img1)
#调用傅里叶逆变换函数
result2=idft(ishift)
#图像显示
plt.subplot(131), plt.imshow(img), plt.title('原图像')
plt.axis('off')
plt.subplot(132), plt.imshow(fimg), plt.title('高通滤波')
plt.axis('off')
plt.subplot(133), plt.imshow(result2), plt.title('高通滤波结果')
plt.axis('off')
plt.show()

在这里插入图片描述
能够看到,高通滤波以后的结果,周围是存在BGR三通道的像素值的,这对咱们须要达到目的也就是轮廓提取是干扰的,所以,在大多数状况下,高通滤波和低通滤波针对的对象都是灰度图像,对灰度图像提取轮廓!

1、低通滤波

  • 低通滤波通常用做图像去噪(模糊)

一、低通滤波简介

低通滤波能够简单的认为:设定一个频率点,当信号频率高于这个频率时不能经过,在数字信号中,这个频率点也就是截止频率,当频域高于这个截止频率时,则所有赋值为0。由于在这一处理过程当中,让低频信号所有经过,因此称为低通滤波。低经过滤的概念存在于各类不一样的领域,诸如电子电路,数据平滑,声学阻挡,图像模糊等领域常常会用到。在数字图像处理领域,从频域看,低通滤波能够对图像进行平滑去噪处理。

二、低通滤波原理

1)、低通滤波顾名思义就是低频能够经过,过滤掉高频部分,而对于图像的噪声,包括椒盐噪声和高斯噪声,他们的频率都是比较高的例如像素值为255,那么低通滤波就会将这些噪声过滤,但低通滤波并无识别功能,图像中有些区域的像素一样为255,同理,低通滤波也会将其彻底过滤,所以,经过这个原理,咱们就能够简单了解,低通滤波其实就是将频域图中心部分保留,将外围部分过滤,衍生到图像中就是将高频区域对应的像素值设置为0,黑色,低频区域对应的像素值不改变
2)、那么如何实现呢?就须要和原图如出一辙大小的黑色图像,将中间区域设置为白色,而后与频谱图一 一对应相乘,这样获得的结果就是中间部分不改变而过滤掉边上部分,以下图所示:
在这里插入图片描述
经过该原理,就能够构造图像的低频滤波了,一块儿来看吧!
注意:该出是将高频处对应的像素值设置为黑色,而不是将频域图的周围变黑,相反的,频域图而言,像素值越高,频率越高,周围部分也就越亮



三、图像低通滤波构造

1)、构造图像低频滤波函数

#低通滤波构造
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
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)、读取图像添加噪声并灰度化,进行傅里叶变换后调用低通滤波函数,而后经过傅里叶逆变换还原观察图像变化

#Numpy库的傅里叶变换
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取图像
img = cv.imread('my.jpg')
h, w = img.shape[0:2]#获取图像属性
#加噪声
for i in range(3000):    #添加3000个噪声点
    x = np.random.randint(0, h) 
    y = np.random.randint(0, w)    
    img[x,y] = 255
#图像灰度化
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#傅里叶变换
f = np.fft.fft2(img)
#将左上角低频部分移动到中间
fshift = np.fft.fftshift(f)
#调用低通滤波函数
img1=lowPassFiltering(fshift,100)
#复数化整,方便观察频谱图
res = np.log(np.abs(img1))
#傅里叶逆变换
ishift = np.fft.ifftshift(img1)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)
#展现结果
plt.subplot(131), plt.imshow(img,'gray'), plt.title('原图像')
plt.axis('off')
plt.subplot(132), plt.imshow(res,'gray'), plt.title('低通滤波')
plt.axis('off')
plt.subplot(133), plt.imshow(iimg,'gray'), plt.title('低通滤波结果')
plt.axis('off')
plt.show()

在这里插入图片描述
注意:该出是将高频处对应的像素值设置为黑色,而不是将频域图的周围变黑,相反的,频域图而言,像素值越高,频率越高,周围部分也就越亮

上图可能不是太明显,这是因为jupyter经过matplotlib显示图像不是太大,并且设置的1行3张,当咱们只对比原图和低通滤波结果时,就会发现仍是很明显的,以下所示:
在这里插入图片描述
经过上图能够知道,图像的噪声基本去掉,也就是说,低通滤波消除噪声的强度取决于你构造低通滤波的尺寸大小,尺寸越大,消除越很差,图像越清晰;尺寸越小,消除越好,图像越模糊
3)、一样的,彩色图像低通滤波无心义,但这里给一个显示结果,不要陷入太深哦;值得注意的是,彩色图像低通滤波的构造方法有点不同,由于彩色是3通道图,所以,在构造低通滤波时,应该将滤波模板设置为3通道img2 = np.zeros((h, w,3), np.uint8),彩色图像低通滤波完整代码以下所示:


#彩色图像低通滤波
#彩色图像的高通滤波
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#自定义傅里叶变换功能函数
def dft(img):
    #获取图像属性
    H,W,channel=img.shape
    #定义频域图,从公式能够看出为求出结果为复数,所以,须要定义为复数矩阵
    F = np.zeros((H, W,channel), dtype=np.complex)
    # 准备与原始图像位置相对应的处理索引
    x = np.tile(np.arange(W), (H, 1))
    y = np.arange(H).repeat(W).reshape(H, -1)
    #经过公式遍历
    for c in range(channel):
        for u in range(H):
            for v in range(W):
                F[u, v, c] = np.sum(img[..., c] * np.exp(-2j * np.pi * (x * u / W + y * v / H))) / np.sqrt(H * W)
    return F
#傅里叶反变换
def idft(G):
    H, W, channel = G.shape
    #定义空白时域图像
    out = np.zeros((H, W, channel), dtype=np.float32)
    # 准备与原始图像位置相对应的处理索引
    x = np.tile(np.arange(W), (H, 1))
    y = np.arange(H).repeat(W).reshape(H, -1)
    #经过公式遍历
    for c in range(channel):
        for u in range(H):
            for v in range(W):
                out[u, v, c] = np.abs(np.sum(G[..., c] * np.exp(2j * np.pi * (x * u / W + y * v / H)))) / np.sqrt(W * H)
    # 剪裁
    out = np.clip(out, 0, 255)
    out = out.astype(np.uint8)
    return out
#低通滤波构造
def lowPassFiltering(img,size):#传递参数为傅里叶变换后的频谱图和滤波尺寸
    h, w = img.shape[0:2]#获取图像属性
    h1,w1 = int(h/2), int(w/2)#找到傅里叶频谱图的中心点
    img2 = np.zeros((h, w,3), 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
#读取图像
img=cv2.imread("my.jpg")
h, w = img.shape[0:2]#获取图像属性
#加噪声
for i in range(3000):    #添加3000个噪声点
    x = np.random.randint(0, h) 
    y = np.random.randint(0, w)    
    img[x,y,:] = 255
#进行图像裁剪,加快傅里叶运算速率。将原始尺寸缩放为100*100的尺寸
img = cv2.resize(img, (100, 100), interpolation=cv2.INTER_CUBIC)
#BGR转换为RGB显示格式,方便经过matplotlib进行图像显示
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
#调用傅里叶变换函数
result =dft(img)
#将傅里叶频谱图从左上角移动到中心位置
fshift = np.fft.fftshift(result)
img1=lowPassFiltering(fshift,30)
#将复数转为浮点数进行傅里叶频谱图显示
fimg = np.log(np.abs(img1))#复数转为整数,方便显示傅里叶频谱图
#将傅里叶频谱图从中心还原到左上角位置
ishift = np.fft.ifftshift(img1)
#调用傅里叶逆变换函数
result2=idft(ishift)
#图像显示
plt.subplot(131), plt.imshow(img), plt.title('原图像')
plt.axis('off')
plt.subplot(132), plt.imshow(fimg), plt.title('低通滤波')
plt.axis('off')
plt.subplot(133), plt.imshow(result2), plt.title('低通滤波结果')
plt.axis('off')
plt.show()

在这里插入图片描述
上面能够看出,彩色图像的低通滤波处理去噪效果比较明显啦,就是图像模糊较快,多用于图像平滑、去噪!

注意:在尺寸的设计中,不要超过图像的原尺寸,不然没有效果哦,以上代码本身将原图缩小成100x100尺寸的,只为了加快代码运行速度哦,你们记得对照修改!

以上就是本次博客的所有内容,遇到问题的小伙伴记得留言评论,学长看到会为你们进行解答的,这个学长不太冷!

趁咱们都还年轻bai,多走几步路,多欣赏下沿途du的风景,zhi不要急于抵达目的地而错过了流年里温暖dao的人和物;趁咱们都还年轻,多说些浪漫的话语,多作些幼稚的事情,不要嫌人笑话错过了生命中最美好的片断和场合;趁咱们都还年轻,把距离缩短,把时间延长。趁咱们都还年轻,多作些咱们想要作的任何事

陈一月的又一天编程岁月^ _ ^

相关文章
相关标签/搜索