我使用 Matlab 代码得到了合理的结果,但是当将其转换为 OpenCV 时,我得到了毫无意义的奇怪数字......我已经研究了太久并且没有发现错误,也许你可以吗?
Matlab 实现:
function [ score ] = getSimilarityScore( sig1, sig2, delta )
%%Calculate how much the signals are alike allowing a delta of shift.
%signal is assumed to be normalized such that it's elements sum is 1, sig1 and sig2 have the same number of elements.
sig1fft = fft(sig1);
sig1fft(1) = 0; %zero-out dc
sig2fft = fft(sig2);
sig2fft(1) = 0; %zero-out dc
%Should be the same as multiplying the signal by itself, and subtracting the mean times the number of element. could have just looked at the first element for the max...
norm1 = max(real(ifft(hist1fft.*conj(hist1fft))));
norm2 = max(real(ifft(hist2fft.*conj(hist2fft))));
corrConv = fftshift(real(ifft(hist1fft.*conj(hist2fft))));
corrConv((length(corrConv)/2 - delta):(length(corrConv)/2 + delta))
score = max(corrConv((length(corrConv)/2 - delta):(length(corrConv)/2 + delta)))/sqrt(norm1*norm2);
end
OpenCV(Java 包装器)
public double getMaxCorrelationScoreUsingFFT(Mat sig1, Mat sig2, int allowedDelta)
{
Mat dft1 = new Mat(), dft2 = new Mat(), dftCorr = new Mat();
Core.dft(sig1,dft1,Core.DFT_COMPLEX_OUTPUT,0);
Core.dft(sig2,dft2,Core.DFT_COMPLEX_OUTPUT,0);
float [] zeroFreq = {0,0};
dft1.put(0,0,zeroFreq); //remove dc
dft2.put(0,0,zeroFreq); //remove dc
Core.mulSpectrums(dft1,dft2,dftCorr,0,true);
Core.mulSpectrums(dft1,dft1,dft1,0,true);
Core.mulSpectrums(dft2,dft2,dft2,0,true);
Core.dft(dft1,dft1,Core.DFT_INVERSE + Core.DFT_REAL_OUTPUT,0);
Core.dft(dft2,dft2,Core.DFT_INVERSE + Core.DFT_REAL_OUTPUT,0);
Core.dft(dftCorr,dftCorr,Core.DFT_INVERSE + Core.DFT_REAL_OUTPUT, 0);
double [] norm1, norm2;
norm1 = dft1.get(0,0);
norm2 = dft2.get(0,0);
if (norm1[0] == 0 || norm2[0] == 0)
if (norm1[0] != norm2[0])
return -1;
else
return 1;
//get -delta:delta range:
Mat fftShifted = new Mat(allowedDelta*2 + 1,1,CvType.CV_32F);
dftCorr.rowRange(dftCorr.height()/2 + 1,dftCorr.height()/2 + allowedDelta + 1).copyTo(fftShifted.rowRange(0,allowedDelta));
dftCorr.rowRange(0,allowedDelta+1).copyTo(fftShifted.rowRange(allowedDelta,fftShifted.height()));
Core.MinMaxLocResult minmaxCorr = Core.minMaxLoc(fftShifted);
return minmaxCorr.maxVal / Math.sqrt(norm1[0] * norm2[0]);
}
如果有人能找到这两个实现之间的不同之处,我将不胜感激......
最佳答案
问题出在 fftshift 代码上:
应该是
dftCorr.rowRange(dftCorr.height() -allowedDelta,dftCorr.height()).copyTo(fftShifted.rowRange(0,allowedDelta));
而不是
dftCorr.rowRange(dftCorr.height()/2 + 1,dftCorr.height()/2 + allowedDelta + 1).copyTo(fftShifted.rowRange(0,allowedDelta));
关于java - OpenCV 和 Matlab 使用 DFT 实现信号相关的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34601269/