Коэффициент корреляции Пирсона

Я написал следующий код C #, чтобы найти коэффициент корреляции Пирсона между двумя изображениями. Полный исходный код находится здесь, в DotNetFiddle.

Исходный код корреляции:

public sealed class PearsonCorrelation 
{
    public static double GetSimilarityScore(double[,] p, double[,] q)
    {
        int Width = p.GetLength(0);
        int Height = p.GetLength(1);

        if (Width != q.GetLength(0) || Height != q.GetLength(1))
        {
            throw new ArgumentException("Input vectors must be of the same dimension.");
        }

        double pSum = 0, qSum = 0, pSumSq = 0, qSumSq = 0, productSum = 0;
        double pValue, qValue;

        for (int y = 0; y < Height; y++)
        {
            for (int x = 0; x < Width; x++)
            {
                pValue = p[y, x];
                qValue = q[y, x];

                pSum += pValue;
                qSum += qValue;
                pSumSq += pValue * pValue;
                qSumSq += qValue * qValue;
                productSum += pValue * qValue;
            }
        }

        double numerator = productSum - ((pSum * qSum) / (double)Height);
        double denominator = Math.Sqrt((pSumSq - (pSum * pSum) / (double)Height) * (qSumSq - (qSum * qSum) / (double)Height));

        return (denominator == 0) ? 0 : numerator / denominator;
    }
}

Результат:

введите описание изображения здесь

Одно и то же изображение загружается в два окна с изображениями.

Значение их коэффициента корреляции стало -1.

Это правильный результат?

Если нет, что мне делать, чтобы это исправить?


person user366312    schedule 17.08.2016    source источник
comment
Насколько я могу судить, в окончательной формуле для numerator и denominator вы должны разделить на n - количество очков, которое равно Height * Width, а не просто Height.   -  person Dmitry Bychenko    schedule 17.08.2016
comment
Было бы очень полезно, если бы вы могли дать нам ссылку на формулу, которую вы используете. Однако я считаю, что результат должен быть 1, поскольку два изображения одинаковы. Более того, поскольку знаменатель всегда положительный, с числителем должно быть что-то не так.   -  person Mahdi    schedule 17.08.2016
comment
@Mahdi, github.com/cureos/aforge/blob / master / Sources / Math / Metrics /   -  person user366312    schedule 17.08.2016


Ответы (1)


Корреляция одинаковых последовательностей должна быть 1.

Кажется, что у вас проблема в самом конце распорядка; вместо того

 double numerator = productSum - ((pSum * qSum) / (double)Height);
 double denominator = Math.Sqrt((pSumSq - (pSum * pSum) / (double)Height) * (qSumSq - (qSum * qSum) / (double)Height));

ты должен положить

 double n = ((double) Width) * Height;

 double numerator = productSum - ((pSum * qSum) / n);
 double denominator = 
   Math.Sqrt((pSumSq - (pSum * pSum) / n) * (qSumSq - (qSum * qSum) / n));

видеть

https://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient

person Dmitry Bychenko    schedule 17.08.2016
comment
Вы проверяли мой код Fiddle на предмет других проблем? - person user366312; 17.08.2016
comment
@anonymous: Мне не удалось его запустить: using System.Windows.Forms;, похоже, мешает его запуску - person Dmitry Bychenko; 17.08.2016
comment
Fiddle не имеет механизма для выполнения кодов WinForms и unsafe. - person user366312; 17.08.2016
comment
@anonymous: да, понятно; но в вашем коде используется WinForms; более того, он получает тестовые данные (массивы) путем button1_Click загрузки их из @"E:\Lenagr.png". Было бы намного лучше, если бы вы составили аннотацию процедуры, которую можно было бы выполнять и отлаживать. - person Dmitry Bychenko; 17.08.2016
comment
Вы можете просто скопировать и вставить код в решение VS2013 Windows Forms. И используйте любое из этих изображений: google.com/ - person user366312; 17.08.2016