opencv C++ 傅里叶变换及反变换

此文为本人测试代码记录。

傅里叶变换 及 高通滤波处理

 

#include 
#include
#include
#include
#include
#include "contrib.hpp"
#include 

using namespace cv;
using namespace std;

void shift_img(Mat &srcimg, Mat &dstimg);

void main()
{
    Mat img, img_std;
    Mat image1 = imread(".../ceshi.bmp");
    if (image1.channels() > 1)
        cvtColor(image1, img_std, COLOR_RGBA2GRAY);
    else
        img_std = image1.clone();


	int M = getOptimalDFTSize(img_std.rows);
	int N = getOptimalDFTSize(img_std.cols);
	Mat padded;
	copyMakeBorder(img_std, padded, 0, M - img_std.rows, 0, N - img_std.cols, BORDER_CONSTANT, Scalar::all(0));

	Mat planes[] = { Mat_(padded), Mat::zeros(padded.size(), CV_32F) };
	Mat complexImg;
	merge(planes, 2, complexImg);

	dft(complexImg, complexImg);

	split(complexImg, planes);
	magnitude(planes[0], planes[1], planes[0]);
	Mat mag = planes[0].clone();
	mag += Scalar::all(1);
	log(mag, mag);

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

	int cx = mag.cols / 2;
	int cy = mag.rows / 2;

    cv::Mat MagI;
    shift_img(mag, MagI);
	normalize(MagI, MagI, 0, 255, NORM_MINMAX);
    convertScaleAbs(MagI, MagI);
  
    imwrite("...\\dft.bmp", MagI);

    int hsize_width = 30;
    int hsize_height = 10;

    cv::Rect rect_center = Rect(cx - hsize_width, cy - hsize_height, 2 * hsize_width, 2 * hsize_height);
    cv::Mat Mask_center = Mat::ones(mag.rows, mag.cols, CV_8UC1);
    cv::Mat mag_mask = planes[0].clone();

    shift_img(mag_mask, mag_mask);
    mag_mask(rect_center).setTo(0);
    shift_img(mag_mask, mag_mask);

    cv::Mat mag_mask_x = planes[1].clone();

    shift_img(mag_mask_x, mag_mask_x);
    mag_mask_x(rect_center).setTo(0);
    shift_img(mag_mask_x, mag_mask_x);


    Mat icomplexImg;

    vector merge_img(2);
    merge_img[0] = mag_mask;
    merge_img[1] = mag_mask_x;
    merge(merge_img,icomplexImg);

    Mat iDft[] = { Mat::zeros(padded.size(),CV_32F),Mat::zeros(padded.size(),CV_32F) };
    idft(icomplexImg, icomplexImg, DFT_SCALE | DFT_REAL_OUTPUT); // IDFT进行DFT逆变换
    split(icomplexImg, iDft);
    magnitude(iDft[0], iDft[1], iDft[0]);

    Mat dst(iDft[0], Rect(0, 0, img_std.cols, img_std.rows));

    convertScaleAbs(dst, dst);


    imwrite("...\\iDFT.bmp", dst);


    waitKey(0);
}



void shift_img(&srcimg, Mat &dstimg)
{
    int cx = srcimg.cols / 2;
    int cy = srcimg.rows / 2;
    Mat tmp;
    Mat q0(srcimg, Rect(0, 0, cx, cy));
    Mat q1(srcimg, Rect(cx, 0, cx, cy));
    Mat q2(srcimg, Rect(0, cy, cx, cy));
    Mat q3(srcimg, Rect(cx, cy, cx, cy));

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

    q1.copyTo(tmp);
    q2.copyTo(q1);
    tmp.copyTo(q2);
    dstimg = srcimg.clone();
}

python代码 仿真相对方便

可参考 python 傅里叶变换 频域高通低通滤波

你可能感兴趣的:(opencv,c++)