Fourier transformation in frequency domain with opencv
来源:互联网 发布:无线访客网络 编辑:程序博客网 时间:2024/05/21 10:42
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?
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?
- Fourier transformation in frequency domain with opencv
- [cv] convolution in frequency domain
- Displaying Fourier transforms in OpenCV
- Fourier Transform Intro - Oscillation frequency vs Angular frequency Expression
- Heart Rate Variability Analysis with the HRV Toolkit: Basic Time and Frequency Domain Measures/背景
- FFT(Fast Fourier Transformation)快速傅里叶变换
- 数字图像处理实验(9):PROJECT 04-05,Correlation in the Frequency Domain
- opencv学习一: Fourier变换
- Create Gaussian Filter on Frequency Domain
- 【Get深一度】最通俗易懂的 傅里叶变换Fourier Transformation
- WCF 4.0 service consumed in Silverlight 4.0 with cross domain
- Find Foundamental Frequency with Python
- Transformation in IDA
- openCV 傅立叶逆变换 inverse fourier transform
- 基于opencv的一维Fourier变换
- rectify propeties in c++ coding with opencv
- Applying Domain-Driven Design and Patterns: With Examples in C# and .NET
- Applying Domain-Driven Design and Patterns(ADDDP) With examples in C# and .NET
- Protobuf java版本安装步骤
- 倒计时 jquery countdown
- linux curl定时任务
- js下拉列表级联案例
- 会声会影X9无法正常启动0xc000007b
- Fourier transformation in frequency domain with opencv
- 攻破JAVA NIO技术壁垒
- 让MT7620完美支持32M SPI Flash(W25Q256) — 兼谈设备驱动中的shutdown方法
- 7种方法解决移动端Retina屏幕1px边框问题
- Luogu P1970 [NOIp提高组2013]花匠
- 人工智能都要进小学了,你还在等什么?
- 数组toString()方法,数组常用操作
- 网络请求+XListView展示数据
- 类的加载机制与反射学习笔记