zoukankan      html  css  js  c++  java
  • 傅里叶变换 高通滤波 低通滤波

    为何很多地方要用傅里叶变换?

    很多在时域看似不可能做到的数学操作,在频域相反很容易,这就是需要傅里叶变换的地方。

    尤其是从某条曲线中去除一些特定的频率成分,这在工程上称为滤波,是信号处理最重要的概念之一,只有在频域才能轻松的做到。

    幅值谱:频率和幅值的关系。中心为频率最小点。因此幅值谱中心部分代表的是低频信息,即空间域的平缓的部分。越往外代表的是高频信息,空间域的边缘啊噪声等

    频率:以正弦波为例,就是周期的倒数

    幅值:周期内最大值

    幅值高(幅值谱越亮的部分)代表像素越多。一幅图像经过傅里叶变换之后一定是中心较亮,四周较暗(低频像素多,高频像素少),因为一般一幅图像中高频信息(边缘等)是很少的,多的是背景。

    """

    二维坐标系中向量点的图示由于正交基(即坐标系)的建立, 可以写成向量坐标(如(2,1))数值格式;同理已知坐标系和向量坐标可以变换推出图示意的样子。(这个类比很棒了)

    傅里叶变换也是一样:将连续的周期性函数写成无数个正交的正(余)弦函数的和,其中引入了振幅f, 周期函数的最大值),相位q,0时刻周期函数曲线的进入点),频率w,反应周期性大小)。

    同坐标变换一样,已知了这些相互正交的周期函数(即空间中一组完备的正交基),可以由傅里叶变换后的坐标结果(即fw, q反变换得到之前的图示结果---即原始的那条周期性曲线

    变声,美颜都可以用傅里叶变换及反变换得到。

    比如美颜,一张人物图片傅里叶变换后就是一张类似衍射图的东西,然后低频代表人物轮廓,高频代表人物细节如皱纹等,我们只需要抹掉高频,然后反变换回图片空间即得到磨皮的结果。

    变声也是:发现嘈杂的声音傅里叶变换后,发现有具有低频的部分,以及仅高频的部分,还有一些噪音。大脑自动发现了男声处在低频部分,女声在高频部分。

    只要将一个变换后的声音的低频抹掉,再反变换回去就得到了女声,同样的根据某个人的变换后的频率相位图反变换就得到变声。

    世界上所有的信号都具有波粒二象性,耳朵接收声波,眼睛接受光波,正是因为大脑能进行快速傅里叶变换处理信号,所以人类才这么高级方便。

    """


    高通滤波,低通滤波是按频率划分的。对于正弦曲线,振幅变化快就是高频,变化慢就是低频。那么对于图像,像素值变化快就是高频(噪声啦,边缘啦、边缘及噪声在局部像素值变化较大),像素值变化慢就是低频。所以一幅图像低频较多,高频较少。那么保留高频就是高通滤波器(边缘提取),保留低频就是低通录波器(图像平滑)。
    傅里叶变换将图像转换成幅值谱(magnitude_spectrum):按频率从小到大由中心向四周扩散,幅值谱越亮说明像素越多,反之则越少。
    上代码:

     1 import cv2
     2 import numpy as np
     3 import matplotlib.pyplot as plt
     4 img=cv2.imread('../images/example_01.jpg',0)
     5 # 高通滤波 numpy 用的多
     6 # 正变换
     7 f=np.fft.fft2(img)
     8 fshift=np.fft.fftshift(f)
     9 magnitude_spectrum=20*np.log(np.abs(fshift))
    10 
    11 
    12 plt.subplot(121),plt.imshow(img,cmap='gray'),plt.title('Input Image'),plt.xticks([]),plt.yticks([])
    13 plt.subplot(122),plt.imshow(magnitude_spectrum,cmap='gray'),plt.title('magnitude_spectrum')
    14 plt.show()


    上效果:

    那么像提取图像的边缘就是去掉低频保留高频:先通过傅里叶正变换得到幅值谱,去掉低频像素,然后再通过傅里叶逆变换得到图像边缘。上代码:

     1 import cv2
     2 import numpy as np
     3 import matplotlib.pyplot as plt
     4 # img=cv2.imread('../images/can.jpg',0)
     5 # img=cv2.imread('../images/qin.jpg',0)
     6 img=cv2.imread('../images/example_01.jpg',0)
     7 # 高通滤波 numpy 用的多
     8 # 正变换
     9 f=np.fft.fft2(img)
    10 fshift=np.fft.fftshift(f)
    11 magnitude_spectrum=20*np.log(np.abs(fshift))
    12 
    13 
    14 rows,cols=img.shape
    15 crow,ccol=int(rows/2),int(cols/2)
    16 print('img.shape',img.shape)
    17 # 低频过滤
    18 fshift[(crow-30):(crow+30),(ccol-30):(ccol+30)]=0
    19 #逆变换
    20 f_ishift=np.fft.ifftshift(fshift)
    21 img_back=np.abs(np.fft.ifft2(f_ishift))
    22 
    23 
    24 plt.subplot(121),plt.imshow(img,cmap='gray'),plt.title('Input Image'),plt.xticks([]),plt.yticks([])
    25 plt.subplot(122),plt.imshow(img_back,cmap='gray'),plt.title('img_back'),plt.xticks([]),plt.yticks([])
    26 plt.show()


    上效果:


    那么均值滤波,高斯滤波,sobel,scharr,拉普拉斯滤波器是低通滤波器还高通滤波器呢?我们通过幅值谱来判
    断,上代码:

     1 import cv2
     2 import numpy as np
     3 from matplotlib import pyplot as plt
     4 
     5 
     6 # simple averaging filter without scaling parameter
     7 # 低通
     8 mean_filter = np.ones((3,3))
     9 
    10 
    11 # creating a guassian filter
    12 # 低通
    13 x = cv2.getGaussianKernel(5,10)
    14 gaussian = x*x.T
    15 
    16 
    17 # different edge detecting filters
    18 # scharr in x-direction
    19 # 高通
    20 scharr = np.array([[-3, 0, 3],
    21                    [-10,0,10],
    22                    [-3, 0, 3]])
    23 # sobel in x direction
    24 # 高通
    25 sobel_x= np.array([[-1, 0, 1],
    26                    [-2, 0, 2],
    27                    [-1, 0, 1]])
    28 # sobel in y direction
    29 # 高通
    30 sobel_y= np.array([[-1,-2,-1],
    31                    [0, 0, 0],
    32                    [1, 2, 1]])
    33 # laplacian
    34 # 高通
    35 laplacian=np.array([[0, 1, 0],
    36                     [1,-4, 1],
    37                     [0, 1, 0]])
    38 
    39 
    40 filters = [mean_filter, gaussian, laplacian, sobel_x, sobel_y, scharr]
    41 filter_name = ['mean_filter', 'gaussian','laplacian', 'sobel_x', 
    42                 'sobel_y', 'scharr_x']
    43 fft_filters = [np.fft.fft2(x) for x in filters]
    44 fft_shift = [np.fft.fftshift(y) for y in fft_filters]
    45 mag_spectrum = [np.log(np.abs(z)+1) for z in fft_shift]
    46 
    47 
    48 for i in range(6):
    49     plt.subplot(2,3,i+1),plt.imshow(mag_spectrum[i],cmap = 'gray')
    50     plt.title(filter_name[i]), plt.xticks([]), plt.yticks([])
    51 plt.show()


    上效果:


    前面讨论过,幅值谱中间为低频,四周为高频且越亮像素越多,就是被滤波器保存下来了。不难发现,均值与高斯滤波器幅值谱中间亮,为低通滤波器(平滑),拉普拉斯、sobel、scharr四周较亮为高通滤波器(边缘提取),边缘提取又分垂直边缘与水平边缘~这个从图上看就一目了然啦。
     

  • 相关阅读:
    面向对象基础小结
    异常应用场景
    集合应用场景1:迭代器
    集合应用场景2——数据结构
    华为ce交换机 Bridge-Domain NVE
    linux 内核内置模块
    linux bridge 转发 ip
    iptables nat&conntrack
    loopback
    配置集中式网关部署方式的VXLAN示例(静态方式)
  • 原文地址:https://www.cnblogs.com/Henry-ZHAO/p/12725136.html
Copyright © 2011-2022 走看看