对于二维图片,可以对其进行傅里叶变换,获取图片的频谱信息。频谱有很多应用,包括显著性检测,卷积定理,频率域滤波等,下面是图片傅里叶变换的一些基本概念:

1. 图像傅里叶变换

  对于M行N列的图像矩阵f(x,y),f(x, y)表示第x行y列的像素值,则存在复数矩阵F,有以下公式:

  F(u,v)称为f(x, y)的傅里叶变换,f(x,y)称为F(u,v)的傅里叶逆变换

  opencv提供函数dft()可以对图像进行傅里叶变换和傅里叶逆变换,函数参数如下:

dst =cv.dft(src, flags=0, nonzeroRows=0)
    src: 输入图像矩阵,只支持CV_32F或者CV_64F的单通道或双通道矩阵(单通道的代表实数矩阵,双通道代表复数矩阵)
    flags: 转换的标识符,取值包括DFT_COMPLEX_OUTPUT,DFT_REAL_OUTPUT,DFT_INVERSE,DFT_SCALE, DFT_ROWS,通常组合使用
        DFT_COMPLEX_OUTPUT: 输出复数形式
        DFT_REAL_OUTPUT: 只输出复数的实部
        DFT_INVERSE:进行傅里叶逆变换
        DFT_SCALE:是否除以M*N (M行N列的图片,共有有M*N个像素点)
        DFT_ROWS:输入矩阵的每一行进行傅里叶变换或者逆变换
        (傅里叶正变换一般取flags=DFT_COMPLEX_OUTPUT,
         傅里叶逆变换一般取flags= DFT_REAL_OUTPUT+DFT_INVERSE+DFT_SCALE)     
    nonzerosRows: 当设置为非0时,对于傅里叶正变换,表示输入矩阵只有前nonzerosRows行包含非零元素;对于傅里叶逆变换,表示输出矩阵只有前nonzerosRows行包含非零元素

返回值:
    dst: 单通道的实数矩阵或双通道的复数矩阵

 

2. 快速傅里叶变化

  对于M行N列的图像矩阵,傅里叶变换理论上需要时,opencv中的dft()会进行傅里叶变换快速算法,所以在计算时一般先对二维矩阵进行扩充补0,已满足规则,opencv提供函数getOptimalDFTSize()函数来计算需要补多少行多少列的0,其参数如下:

retval=cv.getOptimalDFTSize(vecsize)
    vecsize: 整数,图片矩阵的行数或者列数,函数返回一个大于或等于vecsize的最小整数N,且N满足N=2^p*3^q*5^r 

  快速傅里叶变换dft()使用示例代码如下:

#coding:utf-8

import cv2
import numpy as np

img_gray = cv2.imread(r"D:\data\receipt_rotate.jpg", 0)
rows, cols = img_gray.shape[:2]

#快速傅里叶变换,输出复数
rPadded = cv2.getOptimalDFTSize(rows)
cPadded = cv2.getOptimalDFTSize(cols)
imgPadded = np.zeros((rows, cols), np.float32)  # 填充
imgPadded[:rows, :cols] = img_gray
fft_img = cv2.dft(imgPadded, flags=cv2.DFT_COMPLEX_OUTPUT)
print(fft_img)

#快速傅里叶逆变换,只输出实数部分
ifft_img = cv2.dft(fft_img, flags=cv2.DFT_REAL_OUTPUT+cv2.DFT_INVERSE+cv2.DFT_SCALE)
ori_img = np.copy(ifft_img[:rows, :cols])  # 裁剪
print(img_gray)
print(ori_img)
print(np.max(ori_img-img_gray))   #9.1552734e-05,接近于0

new_gray_img = ori_img.astype(np.uint8)

cv2.imshow("img_gray", img_gray)
cv2.imshow("new_gray_img", new_gray_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
快速傅里叶变换demo

相关文章: