我使用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 wraper)
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]);
}
如果有人能找到两种实现之间的不同之处,我将不胜感激......
答案 0 :(得分:1)
问题在于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));