2.2 傅里叶特征算子
傅里叶特征算子,又称傅里叶形状描述子,主要作用是通过对目标边界的轮廓进行离散傅里叶变换得到目标边界形状的定量表达。可以将图像的信号从时域转换到频域。
- 傅里叶形状描述子
当确定了图像中的目标区域的起始点以及方向之后,可以利用一系列的坐标对来描述边界的信息了。假设边界上有个边界点,起始点为,按照顺时针方向可以表示为一个坐标序列:
一般来说,如果将目标边界看成是从某一个点出发,则沿着该边界顺时针旋转一周的周边长可以用一个复函数来表示。换句话说就是,边界上点的坐标可以用如下复数来表示:
通过这种方式,可以成功地将坐标序列的二维表示转换为一维表示。对于复数,可以用一个一维离散傅里叶变换系数来表示:
这里的是图像边界的傅里叶描述子。同理,如果对进行傅里叶反变换,则可以得到最开始的坐标序列的表达式(仅选取前L个傅里叶变换系数近似):
低阶系数表示的是边界的大致形状,高阶系数表示的是边界的细节特征。傅里叶描述子在描述边界时,对旋转、平移、尺度变化等均不敏感。
# -*- coding: utf-8 -*- import sys import numpy as np import cv2 import math # 快速傅里叶变换 def fft2Image(src): # 得到行、列 r, c = src.shape[:2] # 得到快速傅里叶变换最优扩充 rPadded = cv2.getOptimalDFTSize(r) cPadded = cv2.getOptimalDFTSize(c) # 边缘扩充,下边缘和右边缘扩充值为零 fft2 = np.zeros((rPadded, cPadded, 2), np.float32) fft2[:r, :c, 0] = src # 快速傅里叶变换 cv2.dft(fft2, fft2, cv2.DFT_COMPLEX_OUTPUT) return fft2 # 傅里叶幅度谱 def amplitudeSpectrum(fft2): # 求幅度 real2 = np.power(fft2[:, :, 0], 2.0) Imag2 = np.power(fft2[:, :, 1], 2.0) amplitude = np.sqrt(real2 + Imag2) return amplitude # 幅度谱的灰度级显示 def graySpectrum(amplitude): # 对比度拉伸 # cv2.log(amplitude+1.0,amplitude) amplitude = np.log(amplitude + 1.0) # 归一化,傅里叶谱的灰度级显示 spectrum = np.zeros(amplitude.shape, np.float32) cv2.normalize(amplitude, spectrum, 0, 1, cv2.NORM_MINMAX) return spectrum # 相位谱 def phaseSpectrum(fft2): # 得到行数、列数 rows, cols = fft2.shape[:2] # 计算相位角 phase = np.arctan2(fft2[:, :, 1], fft2[:, :, 0]) # 相位角转换为 [ -180 , 180] spectrum = phase / math.pi * 180 return spectrum # 主函数 if __name__ == "__main__": image = cv2.imread('../picture/fuliye.png', 0) # 显示原图 cv2.imshow("image", image) # cv2.imwrite("img1.jpg",image) # 快速傅里叶变换 fft2 = fft2Image(image) # 求幅度谱 amplitude = amplitudeSpectrum(fft2) amc = np.copy(amplitude) amc[amc > 255] = 255 amc = amc.astype(np.uint8) # cv2.imshow("originam",amc) # cv2.imwrite("orAmp.jpg",amc) # 幅度谱的灰度级显示 ampSpectrum = graySpectrum(amplitude) ampSpectrum *= 255 ampSpectrum = ampSpectrum.astype(np.uint8) cv2.imshow("amplitudeSpectrum", ampSpectrum) # cv2.imwrite("ampSpectrum.jpg",ampSpectrum) # 相位谱的灰度级显示 phaseSpe = phaseSpectrum(fft2) cv2.imshow("phaseSpectrum", phaseSpe) # cv2.imwrite("phaseSpe.jpg",phaseSpe) ''' 傅里叶幅度谱的中心化 ''' # 第一步:图像乘以(-1)^(r+c) rows, cols = image.shape fimg = np.copy(image) fimg = fimg.astype(np.float32) for r in range(rows): for c in range(cols): if (r + c) % 2: fimg[r][c] = -1 * image[r][c] else: fimg[r][c] = image[r][c] # 第二步:快速傅里叶变换 imgfft2 = fft2Image(fimg) # 第三步:傅里叶的幅度谱 amSpe = amplitudeSpectrum(imgfft2) # 幅度谱的灰度级显示 graySpe = graySpectrum(amSpe) cv2.imshow("amSpe", graySpe) graySpe *= 255 graySpe = graySpe.astype(np.uint8) cv2.imwrite("centerAmp.jpg", graySpe) # 第四步:相位谱的灰度级显示 phSpe = phaseSpectrum(imgfft2) cv2.imshow("phSpe", phSpe) # cv2.imwrite("centerphSpe.jpg",phSpe) cv2.waitKey(0) cv2.destroyAllWindows()
原图
傅里叶变换后的图
傅里叶变换后的频谱图
2.3 形状不变矩法
形状不变矩法的主要思想是将对变换不敏感的、基于区域的几何矩特征作为形状特征。之所以称之为“不变矩”,是因为矩特征在旋转、平移、尺度缩放的环境下都不会发生改变。
详细内容可以参考《深度实践OCR——基于深度学习的文字识别》
2.4 几何参数法
几何参数法主要包括像素与邻域、位置、方向、距离、区域周长和区域面积。
详细内容可以参考《深度实践OCR——基于深度学习的文字识别》
3 基于几何分布的特征提取方法
基于几何分布的特征提取方法大致可以分为两类,1)二维直方图投影法、2)另一类是区域网格统计法。
3.1 二维直方图投影法
几何分布特征提取方法的代表之一就是二维直方图投影法,也就是获取水平以及竖直方向上各行、列黑色像素累计分布的结果,如下图所示:
二维直方图投影示意图
由于图片经过归一化后,长宽相对固定,例如32×36像素的二值字符“3”如图a所示。一般二维直方图投影法对图像的扫描顺序为从上到下、从左往右,所以得到的对应数字矩阵如图b所示。
在水平方向和竖直方向分别对原图进行投影,然后分别按照行列方向统计黑色像素的值且进行归一化,最终得到特征向量。
3.2 区域网格统计法
区域网格统计法是另一种常见的基于几何分布的特征提取方法。其主要思想是先利用一个m×n的网格将原图进行分割,然后按从上至下、从左至右的顺序依次统计每一个网格中“1”的个数,从而得到最终的特征向量。以上面的二值字符“3”为例,我们用一个3×4的网格对其进行分割,得到的结果如图所示:
区域网格统计法示例