Попытка выполнить 2D кросс-корреляцию на 2 изображениях без использования Matlab / Numpy / etc - PullRequest
0 голосов
/ 28 апреля 2018

Я пытаюсь выполнить взаимную корреляцию на этих 2 изображениях в C #:
Изображение , Шаблон
Матлаб говорит, что результат должен выглядеть следующим образом: Результат Матлаба
Но это мой результат: Мой результат

Вот моя функция взаимной корреляции:

public static Signal2D CrossCorrelation2D(Signal2D signal, Signal2D pulse) {
    return InverseFFT2D(FFT2D(signal) * FFT2D(pulse).GetConjugate());
}

Вот мой FFT2D:

public static Signal2D FFT2D(Signal2D signal) {
    Signal2D result = new Signal2D(signal.Height, signal.Width);
    for (int i = 0; i < result.Height; i++)
        result[i] = new ComplexNumber[signal[i].Length];
    //rows
    for (int n = 0; n < signal.Height; n++) {
        result[n] = FFT(signal[n]);
    }
    //columns
    for (int i = 0; i < signal[0].Length; i++) {
        ComplexNumber[] col = new ComplexNumber[signal.Height];
        for (int j = 0; j < col.Length; j++) {
            col[j] = result[j][i];
        }
        col = FFT(col);
        for (int j = 0; j < col.Length; j++) {
            result[j][i] = col[j];
        }
    }
    return result;
}

Вот мой БПФ:

public static Signal FFT(Signal signal) {
    int N = signal.Length;
    if (N == 1)
        return signal;
    if ((N & (N - 1)) != 0)
        throw new ArgumentOutOfRangeException("signal length must be a power of 2");
    Signal evenArr = new Signal(N / 2);
    Signal oddArr = new Signal(N / 2);
    for (int i = 0; i < N / 2; i++) {
        evenArr[i] = signal[2 * i];
    }
    evenArr = FFT(evenArr);
    for (int i = 0; i < N / 2; i++) {
        oddArr[i] = signal[2 * i + 1];
    }
    oddArr = FFT(oddArr);
    Signal result = new Signal(N);
    for (int k = 0; k < N / 2; k++) {
        double w = -2.0 * k * Math.PI / N;
        ComplexNumber wk = new ComplexNumber(Math.Cos(w), Math.Sin(w));
        ComplexNumber even = evenArr[k];
        ComplexNumber odd = oddArr[k];
        result[k] = even + (wk * odd);
        result[k + N / 2] = even - (wk * odd);
    }
    return result;
}

Вот мое умножение сигнала (с использованием точечного умножения):

public static Signal2D operator* (Signal2D a, Signal2D b) {
    if (a.Height != b.Height || a.Width != b.Width)
        throw new ArgumentException("Sizes must be equal");
    Signal2D result = new Signal2D(a.Height, a.Width);
    for (int y = 0; y < a.Height; y++) {
        for (int x = 0; x < a.Width; x++) {
            result[y][x] = a[y][x] * b[y][x];
        }
    }
    return result;
}

Любая помощь приветствуется, спасибо.

Редактировать: я оставил изображение matlab с исходным размером 1023 на 1023 и наложил свой результат. Похоже, я уже могу быть в результате, я просто не уверен, как Matlab дополняет изображение. Наложенные результаты (красный - это белая часть моего результата, серый - черная часть моего результата. Черно-белый - из Matlab)

...