本专栏主要介绍若是经过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
本次博客,林君学长主要介绍在傅里叶变换的基础上,如何构造高通滤波和低通滤波来进行图像简单轮廓提取和图像去噪,高通和低通滤波的主要难点理解就是傅里叶变换和逆变换,上次博客已经介绍过,而对于高通和低通滤波的构造仍是比较简单的,一块儿学习吧!
函数
[Python图像处理七] :Opencv图像处理之高通滤波和低通滤波原理及构造
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的人和物;趁咱们都还年轻,多说些浪漫的话语,多作些幼稚的事情,不要嫌人笑话错过了生命中最美好的片断和场合;趁咱们都还年轻,把距离缩短,把时间延长。趁咱们都还年轻,多作些咱们想要作的任何事
陈一月的又一天编程岁月^ _ ^