離散フーリエ変換コード
10727 ワード
以下のコードは私が以前ブログでノックしたものですが、時間が長くてどのブログで見たのか分からないので、アドレスリンクを与えることができず、削除しました.私は自分の理解に従ってコードに注釈をつけた.
最初の3つの文章と結びつけて、このコードはとても理解しているはずです.ここでは、画像の周囲に0を記入する操作を行うと、画像の周波数領域サイズも大きくなりますが、0を記入しているので、周波数領域の画素値は私たちの空域値を係数としているので、係数は変化しませんが、私たちの基板のMとN値は変換されますが、変化は微小で、影響は大きくありません.
#include
#include
using namespace cv;
using namespace std;
int main()
{
Mat input = imread("C:\\Users\\dushuang\\Desktop\\lotsfiles\\bhs\\1.jpg",0);
imshow("input", input);
//FFT ,
// , n n/2
// m , , 2 (2,4,8,16,32…) ,
// 2、3、5 ( :300 = 5*5*3*2*2) 。
int w = getOptimalDFTSize(input.cols);
int h = getOptimalDFTSize(input.rows);
Mat padded;
copyMakeBorder(input, padded, 0, h - input.rows, 0, w - input.cols, BORDER_CONSTANT, Scalar::all(0));
padded.convertTo(padded, CV_32FC1);//
imshow("padded", padded);// , inshow 8U ,32F
// pow(-1,i+j) ,
for (int i = 0; i < padded.rows; i++)
{
float *ptr = padded.ptr<float>(i);
for (int j = 0; j < padded.cols; j++)
ptr[j] *= pow(-1, i + j);
}
Mat plane[] = { padded, Mat::zeros(padded.size(), CV_32F) };// Mat , Fm Mat
Mat complexImg;
merge(plane, 2, complexImg);// Mat , 。
dft(complexImg, complexImg);// , 。
/*****************gaussian*******************/
Mat gaussianBlur(padded.size(), CV_32FC2);
Mat gaussianSharpen(padded.size(), CV_32FC2);
float D0 = 2 * 10 * 10;
for (int i = 0; i < padded.rows; i++)//
{
float*p = gaussianBlur.ptr<float>(i);
float*q = gaussianSharpen.ptr<float>(i);
for (int j = 0; j < padded.cols; j++)
{
float d = pow(i - padded.rows / 2, 2) + pow(j - padded.cols / 2, 2);// d
p[2 * j] = expf(-d / D0);//gaussianBlur ,expf return float exp.
p[2 * j + 1] = expf(-d / D0);//gaussianBlur
q[2 * j] = 1 - expf(-d / D0);//gaossianShapen
q[2 * j + 1] = 1 - expf(-d / D0);//gaussianShapen
}
}
multiply(complexImg, gaussianBlur, gaussianBlur);// , ,
multiply(complexImg, gaussianSharpen, gaussianSharpen);// ( )
/*********************** **************************/
split(complexImg, plane);
magnitude(plane[0], plane[1], plane[0]);//
plane[0] += Scalar::all(1);// , log
log(plane[0], plane[0]);// , 。 1000 100 , 2 3 。
normalize(plane[0], plane[0], 1, 0, CV_MINMAX);
imshow("dft", plane[0]);
/********************* ************************/
split(gaussianBlur, plane);
magnitude(plane[0], plane[1], plane[0]);
plane[0] += Scalar::all(1);
log(plane[0], plane[0]);
normalize(plane[0], plane[0], 1, 0, CV_MINMAX);
imshow("gaussianBlur", plane[0]);
split(gaussianSharpen, plane);
magnitude(plane[0], plane[1], plane[0]);
plane[0] += Scalar::all(1);
log(plane[0], plane[0]);
normalize(plane[0], plane[0], 1, 0, CV_MINMAX);
imshow("gaussianShapen", plane[0]);
/************************idft*****************************/
idft(gaussianBlur, gaussianBlur);//
idft(gaussianSharpen, gaussianSharpen);
split(gaussianBlur, plane);
magnitude(plane[0], plane[1], plane[0]);// magnitude
normalize(plane[0], plane[0], 1, 0, CV_MINMAX);
imshow("idft-gaussianBlur", plane[0]);
split(gaussianSharpen, plane);
magnitude(plane[0], plane[1], plane[0]);
normalize(plane[0], plane[0], 1, 0, CV_MINMAX);
imshow("idft_gaussianSharpen", plane[0]);
waitKey();
return 0;
}
最初の3つの文章と結びつけて、このコードはとても理解しているはずです.ここでは、画像の周囲に0を記入する操作を行うと、画像の周波数領域サイズも大きくなりますが、0を記入しているので、周波数領域の画素値は私たちの空域値を係数としているので、係数は変化しませんが、私たちの基板のMとN値は変換されますが、変化は微小で、影響は大きくありません.