openCV中的频率域变换

openCV中频率域增强的傅里叶变换已经比较成熟了,在他的官方tutorials文档里有一个完整的得到频谱图的例子,如下:

#include "opencv2/core/core.hpp"
 #include "opencv2/imgproc/imgproc.hpp"
 #include "opencv2/highgui/highgui.hpp"
 #include <iostream>
 int main(int argc, char ** argv)
 {
  const char* filename = argc >=2 ? argv[1] : "lena.jpg";

  Mat I = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);
   if( I.empty())
     return -1;

  Mat padded; //expand input image to optimal size
   int m = getOptimalDFTSize( I.rows );
   int n = getOptimalDFTSize( I.cols ); // on the border add zero values
   copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, BORDER_CONSTANT, Scalar::all(0));

  Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
   Mat complexI;
   merge(planes, 2, complexI); // Add to the expanded another plane with zeros

  dft(complexI, complexI); // this way the result may fit in the source matrix

   // compute the magnitude and switch to logarithmic scale
   // => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
   split(complexI, planes); // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
   magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude
   Mat magI = planes[0];

  magI += Scalar::all(1); // switch to logarithmic scale
   log(magI, magI);

  // crop the spectrum, if it has an odd number of rows or columns
   magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2));

  // rearrange the quadrants of Fourier image so that the origin is at the image center
   int cx = magI.cols/2;
   int cy = magI.rows/2;

  Mat q0(magI, Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrant
   Mat q1(magI, Rect(cx, 0, cx, cy)); // Top-Right
   Mat q2(magI, Rect(0, cy, cx, cy)); // Bottom-Left
   Mat q3(magI, Rect(cx, cy, cx, cy)); // Bottom-Right

  Mat tmp; // swap quadrants (Top-Left with Bottom-Right)
   q0.copyTo(tmp);
   q3.copyTo(q0);
   tmp.copyTo(q3);

  q1.copyTo(tmp); // swap quadrant (Top-Right with Bottom-Left)
   q2.copyTo(q1);
   tmp.copyTo(q2);

  normalize(magI, magI, 0, 1, CV_MINMAX); // Transform the matrix with float values into a
   // viewable image form (float between values 0 and 1).

  imshow("Input Image" , I ); // Show the result
   imshow("spectrum magnitude", magI);
   waitKey();

  return 0;
 }

写的很好,但是不够完整。完整的频率域处理流程应该是家在图像-->傅里叶变换-->滤波-->傅里叶逆变换-->保存图像,其中滤波是在频谱图的基础上去处理的。他的例子中只完成了前两个步骤。由于某些原因,本人不便于贴出完整流程的代码,所以下面将只贴出后三步的核心代码。

1.滤波

  频率域滤波器常用的有低通滤波器(理想低通、布特沃斯低通、高斯低通)、高通滤波器(理想高通、布特沃斯高通、高斯高通)、选择性滤波(带阻滤波器、带通滤波器、限波滤波器)等,各滤波器的原理可查阅相关的书籍,强烈推荐冈萨雷斯的《数字图像处理》。这里仅以高斯高通滤波器为例,代码如下:

void createGHPF( Mat *dst, float D0)
{
  //center position
  int cx = dst->cols/2;
  int cy = dst->rows/2;
  for( int i=0; i<dst->cols; i++)
  {
    for( int j=0; j<dst->rows; j++)
    {
      float X = i - cx + 1;
      float Y = j - cy + 1;
      float D = sqrt(X*X + Y*Y);
      float param = exp(-pow(D,2)/(2*pow(D0,2)));
      float parami = 1-param;
      dst->at<float>(Point(i,j)) = parami;
    }
  }
  return;
}

  dst中存储的就是滤波器,由于傅里叶变换得到的频率是复数概念的,用Mat保存是用两个通道表示的,所以也要将此滤波器保存为表示复数的双通道形式。

  shift(filter);  //中心化处理,这个上面的tutorials代码里是有的,可以提出来单独作为一个函数
  Mat f_planes[] = { Mat::zeros( complexI.size(), CV_32F), Mat::zeros( complexI.size(), CV_32F)};
  f_planes[0] = filter;
  f_planes[1] = filter;
  Mat f_filter;
  merge( f_planes, 2, f_filter);

  mulSpectrums(complex, f_filter, complex, DFT_ROWS);  //only DFT_ROWS accepted

最后一句是两个矩阵对应位置相乘的操作(区别于矩阵的乘法),就地转换后频谱图中存放的就是滤波后的频谱图了。

2.傅里叶逆变换

  上面得到滤波后的频谱图,

时间: 2024-10-07 00:50:02

openCV中的频率域变换的相关文章

在频率域中直接生成滤波器

除了之前说的从空间滤波器中获得频率域滤波器,还可以从频率域中直接生成滤波器,这些滤波器被规定为距滤波器中心点的距离不同的函数.可以创建一个用于实现频率滤波器的网格数组,最主要的是需要计算任何点到频率矩形中一个指定点的距离函数,FFT(快速傅里叶)算法是假设变换的原点位于频率矩形的左上角,因此需要将原点平移到频率矩形的中心,用fftshift.网格数组如下: %(频域滤波函数) 提供了距离计算及其所需的网格数组 function [U,V] = dftuv(M,N) u=0:(M-1); v=0:

频率域滤波_滤波基础

这节来介绍一下频率域滤波. 在空间域内,我们是直接对像素进行操作以增强图像的有用信息.像高斯平滑,是取一个模板与图像进行卷积操作,得到处理后的图像.不同的变换域可以很方便的解决某种问题,例如空间域中值滤波是取一个区域的中值替代中间像素的灰度,可以很好的去除椒盐噪声例如下图中的(1)(2)(3).           (1)原图        (2)带有椒盐噪声的图像 (3)图像(2)复原之后的图像 (4)部分区域带有周期噪声 但不是所有的图像都可以在空间域进行图像的增强,有的时候都不知道用什么滤

14、频率域滤波基础——傅里叶变换计算及应用基础

1.理解傅里叶变换 如果是理工科的学生 ,在高等数学和信号处理的课程中应该就已经学习过Fourier变换 ,但是这里还是进行一个简单的基本学习和理解,为时域转频域提供一个基础理论概念. 1.什么是傅里叶级数 周期函数的fourier级数是由正弦函数和余弦函数组成的三角级数.这里首先说结论周期为T的任意周期性函数f(t),若满足以下迪利克雷条件: 在一个周期内只有有限个不连续点: 爱一个周期内只有有限个极大和极小值 积分$\int_{-\frac{-T}{2}}^{\frac{T}{2}}|f(t

[OpenCV-Python] OpenCV 中的图像处理 部分 IV (六)

部分 IVOpenCV 中的图像处理 23 图像变换 23.1 傅里叶变换目标本小节我们将要学习: ? 使用 OpenCV 对图像进行傅里叶变换 ? 使用 Numpy 中 FFT(快速傅里叶变换)函数 ? 傅里叶变换的一些用处 ? 我们将要学习的函数有:cv2.dft(),cv2.idft() 等原理 傅里叶变换经常被用来分析不同滤波器的频率特性.我们可以使用 2D 离散傅里叶变换 (DFT) 分析图像的频域特性.实现 DFT 的一个快速算法被称为快速傅里叶变换(FFT).关于傅里叶变换的细节知

频率域去噪基本实现思想

1. 频率域去噪基本实现思想:首先将原始图像通过一些积分变换,将其变换到频率域,接着再通过频率域对其进行操作,得到的结果再反变换到空间域中,进而使图像得到增强.根据傅里叶频谱的特性可得到,图像的平均灰度级对应于频率为0成分,当从傅里叶变换的原点离开时,图像的慢变化分量对应着低频滤波,比如一幅图像中较平的区域:当再进一步离开原点时,较高的频率开始对应图像中变换越来越快的灰度级,它们反映了一幅图像中物体的边缘和灰度级突发改变和噪声部分的图像成分.频率域图像增强正是基于这种原理,通过对图像的傅里叶频谱

2_Matlab图像的空间域变换操作

1. 目的:为了达到某种视觉效果,变换输入图像的像素位置,通过把输入图像的像素位置映射到一个新的位置以达到改变原图像显示效果的目的. 2. 操作包括: ? 图像插值(Interpolation) ? 图像缩放(Resizing) ? 图像旋转(Rotation) ? 图像剪切(Cropping) 3.图像差值操作 1)原因:在处理图像的过程中,比如对图像进行缩放及旋转,这时图像中每个像素的值都要发生变化.数字图像的坐标是整数,经过这些变换之后的坐标不一定是整数,使得输入图像的像素点经过空间域变换

openCV中的findHomography函数分析以及RANSAC算法的详解

本文将openCV中的RANSAC代码全部挑选出来,进行分析和讲解,以便大家更好的理解RANSAC算法.代码我都试过,可以直接运行. 在计算机视觉和图像处理等很多领域,都需要用到RANSAC算法.openCV中也有封装好的RANSAC算法,以便于人们使用.关于RANSAC算法的一些应用,可以看我的另一篇博客: 利用SIFT和RANSAC算法(openCV框架)实现物体的检测与定位,并求出变换矩阵(findFundamentalMat和findHomography的比较) 但是前几天师弟在使用op

数字信号处理中各种频率关系

4种频率及其数量关系 实际物理频率表示AD采集物理信号的频率,fs为采样频率,由奈奎斯特采样定理可以知道,fs必须≥信号最高频率的2倍才不会发生信号混叠,因此fs能采样到的信号最高频率为fs/2. 角频率是物理频率的2*pi倍,这个也称模拟频率. 归一化频率是将物理频率按fs归一化之后的结果,最高的信号频率为fs/2对应归一化频率0.5,这也就是为什么在matlab的fdtool工具中归一化频率为什么最大只到0.5的原因. 圆周频率是归一化频率的2*pi倍,这个也称数字频率. 有关FFT频率与实

【转】PCA算法学习_1(OpenCV中PCA实现人脸降维)

前言: PCA是大家经常用来减少数据集的维数,同时保留数据集中对方差贡献最大的特征来达到简化数据集的目的.本文通过使用PCA来提取人脸中的特征脸这个例子,来熟悉下在oepncv中怎样使用PCA这个类. 开发环境:ubuntu12.04+Qt4.8.2+QtCreator2.5.1+opencv2.4.2 PCA数学理论: 关于PCA的理论,资料很多,公式也一大把,本人功底有限,理论方面这里就不列出了.下面主要从应用的角度大概来讲讲具体怎么实现数据集的降维. 把原始数据中每个样本用一个向量表示,然