4-3離散傅立葉轉換

4-3離散傅立葉轉換

程式說明:


範例程式:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp<

int main(int argc, char** argv)
{
    cv::Mat img = cv::imread("lena.bmp");
    if (img.empty())
    {        std::cout << "無法讀取檔案" << std::endl;
       return -1;
    }
    cv::Mat imgGray;
    cv::cvtColor(img, img, CV_RGB2GRAY);
    //得到圖像的長和寬
    int M = cv::getOptimalDFTSize(img.rows);
    int N = cv::getOptimalDFTSize(img.cols);
    //擴充邊界
    cv::Mat padded;
    cv::copyMakeBorder(img, padded, 0, M - img.rows, 0, N - img.cols, cv::BORDER_CONSTANT, cv::Scalar::all(0));
    cv::Mat planes[] = { cv::Mat_(padded), cv::Mat::zeros(padded.size(), CV_32F) };
    cv::Mat complexImg;
    cv::merge(planes, 2, complexImg);

    //離散傅立葉轉換
    cv::dft(complexImg, complexImg);
    // 計算 log(1 + sqrt(Re(DFT(img))**2 + Im(DFT(img))**2))
    split(complexImg, planes);
    magnitude(planes[0], planes[1], planes[0]);
    cv::Mat mag = planes[0];
    mag += cv::Scalar::all(1);
    log(mag, mag);
    // 將算完的頻譜複製出來
    mag = mag(cv::Rect(0, 0, mag.cols & -2, mag.rows & -2));
    int cx = mag.cols / 2;
    int cy = mag.rows / 2;
    // 重新安排斯個傅立葉影像並複製
    // 原點為圖的中心點
    cv::Mat tmp;
    cv::Mat q0(mag, cv::Rect(0, 0, cx, cy));
    cv::Mat q1(mag, cv::Rect(cx, 0, cx, cy));
    cv::Mat q2(mag, cv::Rect(0, cy, cx, cy));
    cv::Mat q3(mag, cv::Rect(cx, cy, cx, cy));
    q0.copyTo(tmp);
    q3.copyTo(q0);
    tmp.copyTo(q3);
    q1.copyTo(tmp);
    q2.copyTo(q1);
    tmp.copyTo(q2);
    normalize(mag, mag, 0, 1, cv::NORM_MINMAX);
    imshow("spectrum magnitude", mag);
    cv::waitKey(0);
    return 0;
}