您的位置:首页 > 产品设计 > UI/UE

Fourier transformation in frequency domain with opencv

2017-09-08 13:42 316 查看

I'm new to openCV and I'm trying to filter an image using a gaussian filter in frequency domain. But there is a run time error "assertion failed (type == srcB.type() && srcA.size() == srcB.size()) in cv::mulSpectrum" I know it is caused by the return type
of my filter, the type doesn't match and I don't know how to make it right

here is the filter function (my guess is the return value from this function is wrong):

cv::Mat createGaussianHighPassFilter(cv::Size size, double cutoffInPixels){

Mat ghpf(size, CV_64F);

cv::Point center(size.width / 2, size.height / 2);

for(int u = 0; u < ghpf.rows; u++)

{

for(int v = 0; v < ghpf.cols; v++)

{

ghpf.at<double>(u, v) = gaussianCoeff(u - center.x, v - center.y, cutoffInPixels); //kernel utk gaussian filter yg 128x128

}

}

return ghpf;

}

and this is the main function:

Mat mask = createGaussianHighPassFilter(complexI.size(),16);

shift(mask);

Mat AX[] = {Mat::zeros(complexI.size(), CV_32F), Mat::zeros(complexI.size(), CV_32F)};

Mat kernel_spec;

AX[0] = mask; // real

AX[1] = mask; // imaginar

merge(AX, 2, kernel_spec);

cout<<complexI.type()<<endl<<kernel_spec.type(); //the result is 13 and 14, the type doesn't match

mulSpectrums(complexI, kernel_spec, complexI, DFT_ROWS); // only DFT_ROWS accepted

updateMag(complexI); // show spectrum

updateResult(complexI); // do inverse transform

c++ opencv fft

shareimprove this question

Well of course they don't match. You are initializing kernel_spec as CV_32 but complexI is CV_64. Do a Mat::convertTo() and it should work.

HTH

OpenCV - Create Gaussian Filter on Frequency Domain

Ask Question

up vote

0

down vote

favorite

I've done anything that i got, I just want to create a Gaussian Filter from DFT code that I've done. Here is the code :

//#include <stdafx.h>

#include "opencv2/core/core.hpp"

#include "opencv2/imgproc/imgproc.hpp"

#include "opencv2/highgui/highgui.hpp"

#include <stdio.h>

#include <iostream>

using namespace cv;

using namespace std;

double pixelDistance(double u, double v)

{

return cv::sqrt(u*u + v*v);

}

double gaussianCoeff(double u, double v, double d0)

{

double d = pixelDistance(u, v);

return cv::exp((-d*d) / (2 * d0*d0));

}

cv::Mat createGaussianHighPassFilter(cv::Size size, double cutoffInPixels)

{

Mat ghpf(size, CV_64F);

cv::Point center(size.width / 2, size.height / 2);

for (int u = 0; u < ghpf.rows; u++)

{

for (int v = 0; v < ghpf.cols; v++)

{

ghpf.at<double>(u, v) = gaussianCoeff(u - center.y, v - center.x, cutoffInPixels);

}

}

return ghpf;

}

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("fri.pgm", 0); //grayscale

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;

// gaussian filter

Mat ghpf = createGaussianHighPassFilter(Size(128, 128), 16.0);

imshow("Gaussian Filter", ghpf);

mulSpectrums(imgFFT, ghpf, imgFFT, 0, 0);

waitKey();

// 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 i
ad94
nvFFT;

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;

}

I've try mulspectrum but it said it's error, then how can I merge the Gaussian Filter with the DFT one?

I'm new to openCV and I'm trying to filter an image using a gaussian filter in frequency domain. But there is a run time error "assertion failed (type == srcB.type() && srcA.size() == srcB.size()) in cv::mulSpectrum" I know it is caused by the return type of
my filter, the type doesn't match and I don't know how to make it right

here is the filter function (my guess is the return value from this function is wrong):

cv::Mat createGaussianHighPassFilter(cv::Size size, double cutoffInPixels){

Mat ghpf(size, CV_64F);

cv::Point center(size.width / 2, size.height / 2);

for(int u = 0; u < ghpf.rows; u++)

{

    for(int v = 0; v < ghpf.cols; v++)

    {

        ghpf.at<double>(u, v) = gaussianCoeff(u - center.x, v - center.y, cutoffInPixels); //kernel utk gaussian filter yg 128x128

    }

}

return ghpf;

}

and this is the main function:

Mat mask = createGaussianHighPassFilter(complexI.size(),16);

shift(mask);

Mat AX[] = {Mat::zeros(complexI.size(), CV_32F), Mat::zeros(complexI.size(), CV_32F)};

Mat kernel_spec;

AX[0] = mask; // real

AX[1] = mask; // imaginar

  merge(AX, 2, kernel_spec);

cout<<complexI.type()<<endl<<kernel_spec.type(); //the result is 13 and 14, the type doesn't match

mulSpectrums(complexI, kernel_spec, complexI, DFT_ROWS); // only DFT_ROWS accepted

updateMag(complexI);        // show spectrum

updateResult(complexI);     // do inverse transform

c++ opencv fft

shareimprove this question

Well of course they don't match. You are initializing kernel_spec as CV_32 but complexI is CV_64. Do a Mat::convertTo() and it should work.

HTH

OpenCV - Create Gaussian Filter on Frequency Domain

Ask Question

 

 

up vote

0

down vote

favorite

 

I've done anything that i got, I just want to create a Gaussian Filter from DFT code that I've done. Here is the code :

//#include <stdafx.h>

#include "opencv2/core/core.hpp"

#include "opencv2/imgproc/imgproc.hpp"

#include "opencv2/highgui/highgui.hpp"

#include <stdio.h>

#include <iostream>

using namespace cv;

using namespace std;

double pixelDistance(double u, double v)

{

    return cv::sqrt(u*u + v*v);

}

double gaussianCoeff(double u, double v, double d0)

{

    double d = pixelDistance(u, v);

    return cv::exp((-d*d) / (2 * d0*d0));

}

cv::Mat createGaussianHighPassFilter(cv::Size size, double cutoffInPixels)

{

    Mat ghpf(size, CV_64F);

    cv::Point center(size.width / 2, size.height / 2);

    for (int u = 0; u < ghpf.rows; u++)

    {

        for (int v = 0; v < ghpf.cols; v++)

        {

            ghpf.at<double>(u, v) = gaussianCoeff(u - center.y, v - center.x, cutoffInPixels);

        }

    }

    return ghpf;

}

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("fri.pgm", 0); //grayscale

    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;

    // gaussian filter

    Mat ghpf = createGaussianHighPassFilter(Size(128, 128), 16.0);

    imshow("Gaussian Filter", ghpf);

    mulSpectrums(imgFFT, ghpf, imgFFT, 0, 0);

    waitKey();

    // 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;

}

I've try mulspectrum but it said it's error, then how can I merge the Gaussian Filter with the DFT one?

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐