OpenCV之离散傅里叶变换


离散傅里叶变换是指傅里叶变换在时域和频域上都呈现出离散的形式,将时域信号的采样变换成为在离散时间傅里叶变换频域的采样。


简单来说,对一张图像使用傅里叶变换就是将它分解成正弦和余弦两部分,也就是将图像从空间域转换到频域。在频域里,高频部分代表了图像的细节、纹理信息,而低频部分代表了图像的轮廓信息。


傅里叶变换在图像处理中的应用:图像的增强与图像去噪、图像分割之边缘检测、图像特征提取、图像压缩等。


关于傅里叶变换的帖子:https://zhuanlan.zhihu.com/p/19763358?columnSlug=wille 能很好的帮助理解傅里叶变换。


下面举一个opencv里面的实例:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;

int main(int argc,char** argv)
{
	const char* filename = argc >= 2 ? argv[1] : "active-1807533_960_720.jpg";

	Mat J,I;
	J = imread(filename,CV_LOAD_IMAGE_COLOR);//读入图像
	cvtColor(J,I,CV_BGR2GRAY);
	int m = getOptimalDFTSize(I.rows); //为了计算速度考虑,图像尺寸为2^n时计算最快,其次是如果是2,3,5的倍数的话也能更有效率的傅里叶转换。
	int n = getOptimalDFTSize(I.cols); //cvGetOptimalDFTSize是寻找最接近的一个符合2^n次方的数,或者可以分解为2,3,5的数。

	Mat padded;
	copyMakeBorder(I,padded,0,m - I.rows,0,n-I.cols,BORDER_CONSTANT,Scalar::all(0));//扩展一个图像的边界
	//第一个参数:输入图像
	//第二个参数:输出图像
	//第3-6个参数:分别表示在源图像的上下左右四个方向上扩充多少个像素
	//第七个参数:边界类型,常取值为BORDER_CONSTANT
	//第八个参数:扩充部分的像素值

	Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};//新建一个Mat类型的数组,第一个元素存放扩展边界后的图像,第二个元素初始化为零。

	Mat complexI;
	merge(planes,2,complexI);//该函数是把多个单通道数组连接成1个多通道数组,这里把planes的两个元素合成一个2通道的图像。

	dft(complexI,complexI);//dft()的主要作用是对一维或二维浮点数组进行傅里叶变换或反变换。
	
	Mat magI;
	split(complexI,planes);//split()函数,把1个多通道函数分解成多个单通道函数。
	magnitude(planes[0],planes[1],magI);//该函数是计算输入矩阵x和y对应该的每个像素平方求和后开根号保存在输出矩阵magnitude中。

	magI += Scalar::all(1);//见图1
	log(magI,magI);

	magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2));
	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("原图",J);
	imshow("padded",padded);
	imshow("planes[0]",planes[0]);
	imshow("planes[1]",planes[1]);
	imshow("magI",magI);

	waitKey(0);
	return 0;
}



原始图像:



灰度+边界:



频域实部:

频域虚部:


频域图像:



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值