对于二维图片,可以对其进行傅里叶变换,获取图片的频谱信息。频谱有很多应用,包括显著性检测,卷积定理,频率域滤波等,下面是图片傅里叶变换的一些基本概念:
对于M行N列的图像矩阵f(x,y),f(x, y)表示第x行y列的像素值,则存在复数矩阵F,有以下公式:
F(u,v)称为f(x, y)的傅里叶变换,f(x,y)称为F(u,v)的傅里叶逆变换
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()