java - OpenCV 和 Matlab 使用 DFT 实现信号相关的区别

标签 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 包装器)

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/

相关文章:

java - 部署 Web 服务的好习惯是什么?

java - 如何阻止 Spring 重定向 url 被编码

matlab - matlab中的阿拉伯语短信

python - 具有间隙的信号的功率谱密度?

c++ - 使用 Hough OpenCV 时出错

c++ - 调试错误-R6025 纯虚函数调用(No virtual called)

java - 如何将缺少的 Maven 库添加到 Jetty

java - 如何以编程方式在 android 中授予 "draw over other apps"权限?

matlab - 如何将目录转换为包?

ios - OpenCV VideoCapture 无法打开文件 ios