zoukankan      html  css  js  c++  java
  • 离散傅里叶变换DFT应用

    #include <opencv2/opencv.hpp>
    
    const int PIXEL_EXCLUDED = 64;
    const cv::Size PATCH_SIZE = cv::Size(256, 256);
    const float STEP = 0.5;
    
    bool SortBySumFFT(const std::pair<cv::Point, double> &a,
    	const std::pair<cv::Point, double> &b)
    {
    	return (a.second > b.second);
    }
    
    cv::Mat CvtImgs16To8(cv::Mat img)
    {
    	cv::Mat imgs_8bit;
    	normalize(img, imgs_8bit, 0, 255, cv::NORM_MINMAX, CV_8U);
    	return imgs_8bit;
    }
    
    void Recomb(cv::Mat &src, cv::Mat &dst)
    {
    	int cx = src.cols >> 1;
    	int cy = src.rows >> 1;
    	cv::Mat tmp;
    	tmp.create(src.size(), src.type());
    	src(cv::Rect(0, 0, cx, cy)).copyTo(tmp(cv::Rect(cx, cy, cx, cy)));
    	src(cv::Rect(cx, cy, cx, cy)).copyTo(tmp(cv::Rect(0, 0, cx, cy)));
    	src(cv::Rect(cx, 0, cx, cy)).copyTo(tmp(cv::Rect(0, cy, cx, cy)));
    	src(cv::Rect(0, cy, cx, cy)).copyTo(tmp(cv::Rect(cx, 0, cx, cy)));
    	dst = tmp;
    }
    
    void ForwardFFT(cv::Mat &src, cv::Mat *FImg, bool do_recomb = true)
    {
    	int M = cv::getOptimalDFTSize(src.rows);
    	int N = cv::getOptimalDFTSize(src.cols);
    	cv::Mat padded;
    	copyMakeBorder(src, padded, 0, M - src.rows, 0, N - src.cols, cv::BORDER_CONSTANT, cv::Scalar::all(0));
    	cv::Mat planes[] = { cv::Mat_<float>(padded), cv::Mat::zeros(padded.size(), CV_32F) };
    	cv::Mat complexImg;
    	merge(planes, 2, complexImg);
    	cv::dft(complexImg, complexImg);
    	split(complexImg, planes);
    	planes[0] = planes[0](cv::Rect(0, 0, planes[0].cols & -2, planes[0].rows & -2));
    	planes[1] = planes[1](cv::Rect(0, 0, planes[1].cols & -2, planes[1].rows & -2));
    	if (do_recomb)
    	{
    		Recomb(planes[0], planes[0]);
    		Recomb(planes[1], planes[1]);
    	}
    	planes[0] /= float(M*N);
    	planes[1] /= float(M*N);
    	FImg[0] = planes[0].clone();
    	FImg[1] = planes[1].clone();
    }
    
    void AutoRegistration(cv::Mat img, std::vector<cv::Rect> &patches)
    {
    	if (img.type() == CV_16UC1)
    		img = CvtImgs16To8(img);
    
    	cv::Rect roi(PIXEL_EXCLUDED, PIXEL_EXCLUDED, img.cols - 2 * PIXEL_EXCLUDED, img.rows - 2 * PIXEL_EXCLUDED);
    	cv::Mat image_roi = img(roi).clone();
    
    	std::vector<std::pair<cv::Point, float>> Fourier_result;
    
    	for (int j = 0; j < ceil(((float)image_roi.rows / PATCH_SIZE.height - 1) / STEP) + 1; j++)
    	{
    		for (int i = 0; i < ceil(((float)image_roi.cols / PATCH_SIZE.height - 1) / STEP) + 1; i++)
    		{
    			cv::Rect PATCH(i * PATCH_SIZE.width * STEP, j * PATCH_SIZE.height * STEP, PATCH_SIZE.width, PATCH_SIZE.height);
    			cv::Mat img_rect = image_roi(PATCH).clone();
    
    			cv::Mat F0[2];
    			cv::Mat f0;
    			ForwardFFT(img_rect, F0);
    			cv::magnitude(F0[0], F0[1], f0);
    
    			cv::Mat f0_LPF;
    			cv::Mat GaussianX = cv::getGaussianKernel(256, 15, CV_32F);
    			cv::Mat GaussianY = cv::getGaussianKernel(256, 15, CV_32F);
    			cv::Mat Gaussian_LPF = GaussianX * GaussianY.t();
    			float center = Gaussian_LPF.ptr<float>(127)[127];
    			Gaussian_LPF /= center;
    			f0_LPF = f0.mul(Gaussian_LPF);
    
    			cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3));
    			cv::morphologyEx(f0_LPF, f0_LPF, cv::MORPH_OPEN, kernel);
    
    			float sum_mag = cv::sum(f0_LPF)[0];
    			cv::Point sum_mag_idx = cv::Point(i, j);
    			Fourier_result.push_back(std::make_pair(cv::Point(i, j), sum_mag));
    		}
    	}
    
    	std::sort(Fourier_result.begin(), Fourier_result.end(), SortBySumFFT);
    
    	for (int i = 0; i < 3; i++)
    	{
    		patches.push_back(cv::Rect(Fourier_result[i].first.x * PATCH_SIZE.width * STEP + PIXEL_EXCLUDED,
    			Fourier_result[i].first.y * PATCH_SIZE.height * STEP + PIXEL_EXCLUDED, PATCH_SIZE.width, PATCH_SIZE.height));
    	}
    }
    
    int main()
    {
    	const char* filename = "C:\Zmg12161632-1-3.tif";
    	cv::Mat img = imread(filename, cv::IMREAD_UNCHANGED);
    
    	std::vector<cv::Rect> patches;
    	AutoRegistration(img, patches);
    
    	return 0;
    }
    

    推荐阅读:

    OpenCV核心模块(7)DFT离散傅里叶变换

      

  • 相关阅读:
    JavaScript之arguments对象讲解
    JavaScript之工厂方式 构造函数方式 原型方式讲解
    JavaScript之常用方法讲解
    JavaScript之引用类型讲解
    JavaScript之数据类型讲解
    JavaScript之Cookie讲解
    __cdecl __stdcall __fastcall之函数调用约定讲解
    xp/2003开关3389指令
    php源码安装常用配置参数和说明
    用yum查询想安装的软件
  • 原文地址:https://www.cnblogs.com/carsonzhu/p/12620901.html
Copyright © 2011-2022 走看看