使用DFT实现信号相关的OpenCV和Matlab之间的差异

时间:2016-01-04 22:46:42

标签: java matlab opencv image-processing convolution

我使用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]);
}

如果有人能找到两种实现之间的不同之处,我将不胜感激......

1 个答案:

答案 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));