首页 > 其他 > 详细

图片DFT变换

时间:2020-03-23 22:50:58      阅读:108      评论:0      收藏:0      [点我收藏+]

今天闲着无聊,做了一下DFT变换。
原理在《数字图像处理(第3版)》P125

在opencv中处理过程为:

  1. 以灰度图像的方式读入一张图片
  2. 将灰度图片由 CV_8UC1 变换成 CV_32FC1 ,并且对图片进行填充
  3. 构建图片的复数形式 (包括添加I部分全零)
  4. 调用DFT进行变换
  5. 计算欧拉距离,作为|C| 部分
  6. log 变换 (log(1+|C|))
  7. 裁剪掉填充部分
  8. 调整频率部分,使得得到像书中那样的频谱,否则亮的部分在四个角落
  9. 展示图片

我的实验效果:
技术分享图片

我的代码地址:https://github.com/cyssmile/openCV_learning_notes/blob/master/opencv_test/opencv_028/opencv_028.cpp

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;

int main(int argc,char** argv) 
{
	//Mat original = imread("D:/images/test.jpg",IMREAD_GRAYSCALE);
	Mat original = imread("D:/opencv/sources/samples/data/lena.jpg", IMREAD_GRAYSCALE);
	namedWindow("input",WINDOW_FREERATIO);
	imshow("input",original);
	// get optimal DFT size
	int h = getOptimalDFTSize(original.rows);
	int w = getOptimalDFTSize(original.cols);
	
	//
	copyMakeBorder(original, original, 0, h-original.rows, 0, w - original.cols, BORDER_DEFAULT);
	//copyMakeBorder(original, original, 0, h - original.rows, 0, w - original.cols, BORDER_CONSTANT, Scalar::all(0));
	// CV_8UC1 to CV_32FC1
	Mat originalFloat;
	//original.convertTo(originalFloat,CV_32FC1,1.0/255.0);
	original.convertTo(originalFloat, CV_32FC1, 1.0);
	// ready dft data complex;

	Mat originalComplex[2]={originalFloat,Mat::zeros(originalFloat.size(),CV_32F)};
	Mat dftOriginal;
	merge(originalComplex, 2, dftOriginal);

	// dft
	Mat dftAfter;
	//dft(dftOriginal,dftAfter,DFT_COMPLEX_OUTPUT);
	dft(dftOriginal, dftAfter);
	// C = R + jI  , R = originalComplex[0], I = originalComplex[1] 
	split(dftAfter, originalComplex);

	//Euler distance |C| = sqart(R^2 +I^2)
	magnitude(originalComplex[0], originalComplex[1], originalComplex[0]);
	
	//log(1 + sqart(R^2 +I^2))
	Mat logReady = originalComplex[0];
	logReady += Scalar::all(1);
	log(logReady, logReady);
	// spectrum  Tailoring   to Even
	logReady = logReady(Rect(0,0,logReady.cols & -2,logReady.rows & -2));

	//draw spectrum
	int cx = logReady.cols / 2;
	int cy = logReady.rows / 2;

	Mat q0(logReady, Rect(0, 0, cx, cy));       
	Mat q1(logReady, Rect(cx, 0, cx, cy));    
	Mat q2(logReady, Rect(0, cy, cx, cy));     
	Mat q3(logReady, Rect(cx, cy, cx, cy));     

	Mat tmp;
	q0.copyTo(tmp);
	q3.copyTo(q0);
	tmp.copyTo(q3);

	q1.copyTo(tmp);
	q2.copyTo(q1);
	tmp.copyTo(q2);
	normalize(logReady, logReady, 0, 1, NORM_MINMAX);
	
	namedWindow("spectrum", WINDOW_FREERATIO);
	imshow("spectrum",logReady);
	waitKey(0);
	destroyAllWindows();
	return 0;
}

之前在计算幅度值的时候,参数调用错了

之前错误的是

magnitude(originalComplex[0], originalComplex[0], originalComplex[1]);

正确的应该是 (R,I dst)

magnitude(originalComplex[0], originalComplex[1], originalComplex[0]);

错误示范
技术分享图片

图片DFT变换

原文:https://www.cnblogs.com/cyssmile/p/12555602.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!