4

画像の dft を作成しました。フィルターを使用して調整した後、実際の画像に変換したいのですが、そのたびに間違った結果が得られます..元に変換していないようです。 ForierTransformそしてcreateGaussianHighPassFilter、実際の画像に戻すために以下のように使用しているコードの残りの部分は、私自身の関数です。

Mat fft = ForierTransform(HeightPadded,WidthPadded);
Mat ghpf = createGaussianHighPassFilter(Size(WidthPadded, HeightPadded), db);
Mat res;
cv::multiply(fft,ghpf,res);
imshow("fftXhighpass1", res);
idft(res,res,DFT_INVERSE,res.rows);
cv::Mat croped = res(cv::Rect(0, 0, img.cols,img.rows));

//res.convertTo(res,CV_32S);
imshow("fftXhighpass", res);

フィルターを適用しなくても、dft結果を元に戻すことはできません...これが私のdftコードです.dftを通常の画像に戻すサンプルが見つかりませんでした..

Mat ForierTransform(int M,int N)
{
    Mat img = imread("thumb1-small-test.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    Mat padded;
    copyMakeBorder(img, padded, 0, M - img.rows, 0, N - img.cols, BORDER_CONSTANT, Scalar::all(0));

    Mat planes[] = {Mat_<float>(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];
    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));


    normalize(mag, mag, 0, 1, CV_MINMAX);
    return mag;
}

親切に助けて

[編集: メバトロンの助けを借りて解決策を見つけた後] (以下は正しいコードです)

 Mat ForierTransform(int M,int N)
{
    Mat img = imread("thumb1-small-test.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    Mat padded;
    copyMakeBorder(img, padded, 0, M - img.rows, 0, N - img.cols, BORDER_CONSTANT, Scalar::all(0));

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

    dft(complexImg, complexImg);

    return complexImg;
}

Mat img = imread("thumb1-small-test.jpg",CV_LOAD_IMAGE_GRAYSCALE);
int WidthPadded=0,HeightPadded=0;
WidthPadded=img.cols*2;
HeightPadded=img.rows*2;
int M = getOptimalDFTSize( img.rows );
//Create a Gaussian Highpass filter 5% the height of the Fourier transform
double db  = 0.05 * HeightPadded;


Mat fft = ForierTransform(HeightPadded,WidthPadded);
Mat ghpf = createGaussianHighPassFilter(Size(WidthPadded, HeightPadded), db);
Mat res;

cv::mulSpectrums(fft,ghpf,res,DFT_COMPLEX_OUTPUT);


idft(res,res,DFT_COMPLEX_OUTPUT,img.rows);

Mat padded;
copyMakeBorder(img, padded, 0, img.rows, 0, img.cols, BORDER_CONSTANT, Scalar::all(0));
Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
split(res, planes);
magnitude(planes[0], planes[1], planes[0]);
Mat mag = planes[0];
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;

normalize(mag, mag, 1, 0, CV_MINMAX);

cv::Mat croped = mag(cv::Rect(cx, cy, img.cols,img.rows));
cv::threshold(croped , croped , 0.56, 1, cv::THRESH_BINARY);

imshow("fftPLUShpf", mag);
imshow("cropedBinary", croped);

指の隆起谷を表示できるようになり、しきい値に関してもより最適化できるようになりました

4

1 に答える 1

3

ここでいくつかの問題が発生しています。

まず、関数mulSpectrumsを使用して2 つの FFT をたたみ込む必要があります。乗算ではありません

第 2 に、createGaussianHighPassFilterは単一チャネルの非複雑なフィルタのみを出力しています。Mat::zeros入力画像に対して行ったように、複雑なチャネルを設定するだけでよいでしょう。

第 3 に、FFT の出力を対数振幅スペクトルに変換しないでください。フィルターと正しく結合されず、逆を実行しても同じ結果が得られません。complexImgしたがって、 DFT が実行された直後に戻るだけです。対数振幅スペクトルは、人間がデータを見るのに役立ちますが、あなたがしようとしていることには役立ちません。

dft最後に、完全複素数出力と複素共役対称 (CCS) パック出力の違いに注意してください。Intel には、このデータがどのようにフォーマットされているかについての良いページがあります。あなたの場合、簡単にするために、すべてを完全な複雑なモードにして、あなたの生活を楽にします。

それが役立つことを願っています!

于 2012-03-12T13:03:23.480 に答える