我试图将代码从Matlab转换为OpenCV, 我在图像上应用FFT \ DFT,乘以幅度(缩放),而不是使用dft将图像恢复。
我使用matlab fft和Opencv DFT收到不同的结果,这是我想在这里解决的问题。
我想在这里解决的是以下内容: 我希望收到与matlab相同的结果,但仍然在opencv命令中使用最佳DFT大小。
在matlab中,我填充图像以进行FFT使用,2 * N + 1。 在opencv中,我用以下函数填充图像:
getOptimalDFTSize
真正困扰我的是,如果我在opencv中丢弃getOptimalDFTSize命令,并使用2 * N + 1,我会收到与Matlab相同的结果。 但是,如果我使用getOptimalDFTSize命令,则结果完全不同。
我坚持使用getOptimalDFTSize,因为它应该使我的代码更快。
matlab代码:
构建过滤器
[m,n] = size(img);
%M = 2*m+1; N = n*2+1;
M = 2*m; N = n*2;
[X, Y] = meshgrid(1:N,1:M);
CentX = ceil(N/2);
CentY = ceil(M/2);
dist = (X-CentX).*(X-CentX)+(Y-CentY).*(Y-CentY);
H = (GammaH-GammaL)*(1-exp(-dist/(2*D0.^2)))+GammaL;
% applying the filter
IMG =fft2(Limg,M,N);
H = fftshift(H);
Iret = real(ifft2(IMG.*H));
Iret = Iret(1:m,1:n);
Iend = exp(Iret)-1;
我的Opencv c ++代码
//--------------------------UserInputStart
double m_GammaL = 0.02;
double m_GammaH = 1.2;
double m_D0 = 30;
//--------------------------UserInputEnd
int imageType = /*CV_64FC1 */CV_32F;
// Convert the input image into float
Mat inputImage32f;
inputImage8uchar->convertTo(inputImage32f,imageType);
// Convert the image from 0 to 1 scale , matlab corespondance : Limg = log(im2double(img)+1);
inputImage32f = inputImage32f / 255;
inputImage32f = inputImage32f + 1;
// Create a log image
Mat logImage;
cv::log(inputImage32f,logImage);
// Apply the filter
// Transform the image into the special domain
Mat paddedLogImage; //expand input image to optimal size
int m = getOptimalDFTSize( logImage.rows );
int n = getOptimalDFTSize( logImage.cols ); // on the border add zero pixels
copyMakeBorder(logImage, paddedLogImage, 0, m - logImage.rows, 0, n - logImage.cols,
BORDER_CONSTANT, Scalar::all(0));
Mat homoFilter(paddedLogImage.rows,paddedLogImage.cols,imageType);
Mat* p_homoFilter = &homoFilter;
// Handle the homomorphic filter
CreateHomomorphFilter(p_homoFilter,paddedLogImage.cols,paddedLogImage.rows,m_GammaL, m_GammaH , m_D0);
// Shift the filter
(*p_homoFilter) = (*p_homoFilter)(Rect(0, 0, (*p_homoFilter).cols & -2, (*p_homoFilter).rows & -2));
int cx = (*p_homoFilter).cols/2;
int cy = (*p_homoFilter).rows/2;
Mat q0((*p_homoFilter), Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrant
Mat q1((*p_homoFilter), Rect(cx, 0, cx, cy)); // Top-Right
Mat q2((*p_homoFilter), Rect(0, cy, cx, cy)); // Bottom-Left
Mat q3((*p_homoFilter), Rect(cx, cy, cx, cy)); // Bottom-Right
// swap quadrants (Top-Left with Bottom-Right)
Mat tmp;
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
// swap quadrant (Top-Right with Bottom-Left)
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
Mat complexI;
Mat planes[] = {Mat_<float>(paddedLogImage), Mat::zeros(paddedLogImage.size(), imageType)};
merge(planes, 2, complexI); // Add to the expanded another plane with zeros
// this way the result may fit in the source matrix
dft(paddedLogImage, complexI,/*cv::DFT_SCALE|*/cv::DFT_COMPLEX_OUTPUT);
split(complexI, planes);
//planes[0] = planes[0].mul((*p_homoFilter));
multiply(planes[0],(*p_homoFilter),planes[0],1,imageType);
multiply(planes[1],(*p_homoFilter),planes[1],1,imageType);
merge(planes, 2, complexI);
// Back to image scope
idft(complexI, complexI,cv::DFT_SCALE|cv::DFT_INVERSE/*|cv::DFT_REAL_OUTPUT*/);
split(complexI, planes);
// Use only the planes[0] which is the real number
complexI = planes[0];
// Crop the relevant image values
Mat outputImage32f(complexI, Rect(0, 0, inputImage8uchar->cols,inputImage8uchar->rows));
我想在这里解决的是以下内容: 问题是
我希望收到与matlab相同的结果,但仍然在opencv命令中使用最佳DFT大小。
任何帮助都会非常合适
关于opencv命令,获取最佳DFT大小
getOptimalDFTSize 返回给定矢量大小的最佳DFT大小。
DFT性能不是矢量大小的单调函数。因此,当您计算两个数组的卷积或执行数组的频谱分析时,通常有意义的是用零填充输入数据以获得比原始数组更快转换的更大的数组。大小为2的幂(2个,4个,8个,16个,32个......)的数组是最快的处理。但是,尺寸为2,3和5的乘积(例如,300 = 5 * 5 * 3 * 2 * 2)的阵列也可以非常有效地处理。
函数getOptimalDFTSize返回大于或等于vecsize的最小数量N,以便可以有效地处理大小为N的向量的DFT。在当前实现中,对于某个整数p,q,r,
,N = 2 p * 3 q * 5 r求助:
我花了一些时间来解决这个问题,最终代码没有差异,但是Matlab和OpenCV之间的采样率存在差异。
如果我在OpenCV中更改采样率,事情就会成功,但是我必须支付更高的运行时间
我猜Opencv支持DFT与Matlab的FFT标准