1

私は OpenCV の使い方を学んでいて、DFT の使用に問題があります。MatLab を使用した信号処理クラスを行ったので、そのクラスで行った演習のいくつかを実行しようとしています。画像の FT を取得して表示しようとしているので、一部の周波数をマスクできます。FT を表示できるようにしたいので、マスクの大きさはわかっていますが、試してみると、
代替テキスト
これらの
代替テキスト http://www.ceremade. dauphine.fr/~peyre/numerical-tour/tours/graphics_synthesis_fourier/index_03.png
どこかでステップを忘れていませんか? 画像をロードし、その型を CV_32FC1 に変換し、その行列を取得し、DFT を取得してから、結果の行列を画像に戻しています。コードを掲載します。
または、誰かが FT を表示する例へのリンクを持っている場合は? 畳み込みに使用したものしか見つかりませんでした。

編集:画像のフェーズを取得しましたか?

4

1 に答える 1

2

OpenCVに関して画像上の2DDFTの大きさを視覚化しようとすると、同様の問題が発生しました。私はついに実用的な実装を作り上げました。私はそれが素晴らしいコードだとは思わないでしょう、そしてそれは256 x 256の8ビット(グレースケール)シングルチャンネル画像でのみテストされました--lenna.png(他の画像のために適切にパディングするために微調整する必要があるかもしれません寸法)。入力画像と再構成画像の間の平均二乗誤差はゼロであるため、正常に機能しています。OpenCVv2.1が必要です。

ファイル:mstrInclude.h

    #ifndef _MASTER_INCLUDE_
    #define _MASTER_INCLUDE_

    // Standard
    #include <stdio.h>
    #include <string>
    #include <sstream>
    #include <iostream>
    #include <cmath>
    using namespace std;

    // OpenCV2.1
    #include "cv.h"
    #include "highgui.h"
    using namespace cv;

    #define LOAD_IMAGE "lenna.png"

    #endif // _MASTER_INCLUDE_

ファイル:main.cpp

    #include "mstrInclude.h"
    void translateImg(Mat& imgIn, Mat& imgOut)
    {
        int i, j;

        for (i = 0; i < imgIn.rows; i++)
            for (j = 0; j < imgIn.cols; j++)
                imgOut.at<double>(i,j) = imgIn.at<double>(i,j) * pow(-1.0, i+j);
    }
    void scaleImg(Mat& imgIn, Mat& imgOut, float scaleFactor)
    {
        int i, j;

        for (i = 0; i < imgIn.rows; i++)
            for (j = 0; j < imgIn.cols; j++)
                imgOut.at<double>(i,j) = (double)scaleFactor * log(1.0 + imgIn.at<double>(i,j));
    }

    void consoleOut(cv::Mat outMat, int rows = 5, int cols = 5)
    {
        rows = ((rows == -1 || rows >= outMat.rows) ? outMat.rows : rows);
        cols = ((cols == -1 || cols >= outMat.cols) ? outMat.cols : cols);

        for(int i = 0; i < rows; i++)
        {
            for(int j = 0; j < cols; j++)
            {
                cout << outMat.at<double>(i, j);
                cout << " ";
            }
            cout << endl;
        }
    }

    double calcMSE(Mat& imgOrig, Mat& imgReconst)
    {
        int valOrig = 0, valReconst = 0;
        double MSE = 0.0;

        for(int i = 0; i < imgOrig.rows; i++)
        {
            for (int j = 0; j < imgOrig.cols; j++)
            {
                valOrig = imgOrig.at<unsigned char>(i, j);
                valReconst = imgReconst.at<unsigned char>(i, j);

                MSE += pow( (double)(valOrig - valReconst), 2.0 );
            }
        }
        return (MSE / (imgOrig.rows * imgOrig.cols));
    }

    string convertInt(int number) // converts integer to string
    {
       stringstream ss;
       ss << number;
       return ss.str();
    }

    int main(unsigned int argc, char* const argv[])
    {
        int dftH, dftW;
        cv::Mat imgIn;

        imgIn = cv::imread(LOAD_IMAGE, 0); //grayscale
        cv::imshow("Original Image", imgIn);
        waitKey();

        dftH = cv::getOptimalDFTSize(imgIn.rows);
        dftW = cv::getOptimalDFTSize(imgIn.cols);

        Mat imgMod;
        Mat imgPrecFFT(dftH, dftW, CV_64FC1, Scalar::all(0));
        imgIn.convertTo(imgMod, CV_64FC1);
        imgPrecFFT = imgMod(cv::Range::all(), cv::Range::all()).clone();

        // translate image
        std::vector<Mat> imgsTrans;
        imgsTrans.push_back(Mat_<double>(imgIn.size(), CV_64FC1));
        imgsTrans.push_back(Mat_<double>(imgIn.size(), CV_64FC1));
        imgsTrans[1].setTo(Scalar::all(0), Mat());
        translateImg(imgPrecFFT, imgsTrans[0]);

        Mat imgPrecTransFFT(imgIn.size(), CV_64FC2, Scalar::all(0));
        cv::merge(imgsTrans, imgPrecTransFFT);

        // dft
        cv::Mat imgFFT;
        dft(imgPrecTransFFT, imgFFT, DFT_COMPLEX_OUTPUT);
        cv::Mat imgDispFFT;

        // calculate magnitude
        Mat imgMagnitude(imgIn.size(), CV_64FC1);
        std::vector<Mat> chans;
        cv::split(imgFFT, chans);
        cv::magnitude(chans[0], chans[1], imgMagnitude);

        // scale magnitude image
        Mat imgMagnitudeScaled(imgIn.size(), CV_64FC1);
        scaleImg(imgMagnitude, imgMagnitudeScaled, 10.0);

        // display magnitude image
        cv::Mat imgDisp;
        cv::convertScaleAbs(imgMagnitudeScaled, imgDisp);
        imshow("Magnitude Output", imgDisp);
        waitKey();

        // inverse dft
        cv::split(imgFFT, chans);
        chans[1].zeros(imgIn.size(), CV_64FC1);
        cv::merge(chans, imgFFT);
        cv::Mat invFFT;
        cv::idft(imgFFT, invFFT, DFT_REAL_OUTPUT + DFT_SCALE);

        // translate image back to original location
        cv::split(invFFT, imgsTrans);
        Mat imgAfterTrans(imgIn.size(), CV_64FC1);
        translateImg(imgsTrans[0], imgAfterTrans);
        imgAfterTrans.convertTo(imgDisp, CV_8UC1);

        imshow("After Inverse Output", imgDisp);
        waitKey();

        // calculate and output mean-squared error between input/output images
        double MSE = calcMSE(imgIn, imgDisp);
        cout<<endl<<"MSE: "<<MSE<<endl;
        waitKey();

        return 0;
    }
于 2010-12-24T10:02:57.327 に答える