opencv学习-傅里叶变换体会及行方向傅里叶变换代码

本文介绍了如何通过编程实验来理解傅里叶变换,使用OpenCV库在C++中创建了一个按照固定频率变化的图像,并对其进行逐行傅里叶变换。通过对图像的离散傅立叶变换,展示了傅里叶变换如何揭示图像的频域特性,并通过归一化处理显示了变换结果。
摘要由CSDN通过智能技术生成

傅里叶变换难理解,做了个实验理解傅里叶变换。
具体过程如下:

1)建一个Mat,对于是按照固定频率 横向(沿行)正弦变化图像。

		# include <opencv2/core/core.hpp>
		# include <opencv2/highgui/highgui.hpp>
		# include <opencv2/imgproc/imgproc.hpp>
		#include <iostream>
		#include "math.h"
		using namespace cv;
		using namespace std;

	   //构造 一副  黑白间隔图像。灰度值按照正弦规律,以列数为输入变量。
	  cv::Mat blackWhiteTrip = cv::Mat::zeros(96,256,CV_8UC1);
	  for( int j =0;j< blackWhiteTrip.rows;j++)
	  {
	       for(int i=0;i<blackWhiteTrip.cols;i++)
		   {

			   double theta;
			   theta =3.1415926;
			   theta = theta*2*i/ blackWhiteTrip.cols*16;
			   theta = sin(theta)/2*255+128;
               blackWhiteTrip.at<uchar>(j,i)= uchar(theta);
		   }
	  }
	  imshow("blackWhiteTrip", blackWhiteTrip);

结果图:
在这里插入图片描述

2)调用OPENCV的函数 cv::dft(…),可以逐行(对应一维数组)做傅里叶变换。

cv::Mat DFT_1D(cv::Mat srcImage)//输入灰度值Mat,计算傅里叶变换 幅值对数值
{
	cv::Mat SignalMat;
	srcImage.copyTo(SignalMat);

    // 为傅立叶变换的结果(实部和虚部)分配存储空间
    cv::Mat planes[] = { cv::Mat_<float>(SignalMat), 
			  cv::Mat::zeros(SignalMat.size(), CV_32F)};

	Mat completeI;
	// 为延扩后的图像增添一个初始化为0的通道
	merge(planes,2,completeI);
	// 进行离散傅立叶变换
	dft(completeI,completeI);
	// 将复数转换为幅度
	split(completeI,planes);
	cv::magnitude(planes[0],planes[1],planes[0]);//计算复数的向量值(幅值)
	cv::Mat dftResultImage = planes[0]; //幅值

	// 对数尺度(logarithmic scale)缩放
	dftResultImage += 1;
	log(dftResultImage,dftResultImage);

    //cout<<dftResultImage;
    return dftResultImage;
}

3)将输入图像转为灰度图,逐行做傅里叶变换。

      cv::Mat srcGray;
	  //cvtColor(srcImage,srcGray,CV_RGB2GRAY);
	  blackWhiteTrip.copyTo(srcGray);// 第一步 代码产生的特殊图像
	  //srcGray = srcGray.t();// 矩阵转置操作
	  imshow("srcImage", srcGray);
	  static int channels = srcGray.channels();
	  static int types    = srcGray.type();
	 //数组转Mat
	   cv::Mat resultImg  =  cv::Mat::zeros(srcGray.rows,srcGray.cols, CV_32FC1) ;//放傅里叶幅值结果

	  for(int i = 0;i<srcGray.rows;i++)
	  {
		  // 提取1维向量作 傅里叶变换		   
		  cv::Mat SM  =  cv::Mat::zeros(1,srcGray.cols, CV_8UC1) ;//定义一个 行向量        
		  for(int j=0;j<srcGray.cols;j++)
		  {		 
		       SM.at<uchar>(0,j)= srcGray.at<uchar>(i,j);//取行向量
		  } 
		  cv::Mat tempImage;
		  tempImage = DFT_1D( SM);//该行向量做傅里叶变换,调用第二步函数

          for(int j=0;j<srcGray.cols;j++)
		  {
		    resultImg.at<float>(i,j) = tempImage.at<float>(0,j);//按行存储 傅里叶变换结果			 
	      }
	  }
	  
	  cv::normalize(resultImg,resultImg,0,1,CV_MINMAX);// 归一化处理

结果如图:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值