Accord.Imaging.CorrelationMatching.computeCorrelationMatrix C# (CSharp) Method

computeCorrelationMatrix() private static method

Constructs the correlation matrix between selected points from two images.
Rows correspond to points from the first image, columns correspond to points in the second.
private static computeCorrelationMatrix ( Bitmap image1, IntPoint points1, Bitmap image2, IntPoint points2, int windowSize, double maxDistance ) : ].double[
image1 System.Drawing.Bitmap
points1 AForge.IntPoint
image2 System.Drawing.Bitmap
points2 AForge.IntPoint
windowSize int
maxDistance double
return ].double[
        private static double[,] computeCorrelationMatrix(
            Bitmap image1, IntPoint[] points1,
            Bitmap image2, IntPoint[] points2,
            int windowSize, double maxDistance)
        {

            // Create the initial correlation matrix
            double[,] matrix = Matrix.Create(points1.Length, points2.Length, Double.NegativeInfinity);

            // Gather some information
            int width1 = image1.Width;
            int width2 = image2.Width;
            int height1 = image1.Height;
            int height2 = image2.Height;

            int r = (windowSize - 1) / 2; //  'radius' of correlation window
            double m = maxDistance * maxDistance; // maximum considered distance
            double[,] w1 = new double[windowSize, windowSize]; // first window
            double[,] w2 = new double[windowSize, windowSize]; // second window

            // Lock the images
            BitmapData bitmapData1 = image1.LockBits(new Rectangle(0, 0, width1, height1),
                ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
            BitmapData bitmapData2 = image2.LockBits(new Rectangle(0, 0, width2, height2),
                ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);

            int stride1 = bitmapData1.Stride;
            int stride2 = bitmapData2.Stride;


            // We will ignore points at the edge
            int[] idx1 = Matrix.Find(points1, p => p.X >= r && p.X < width1 - r &&
                                                   p.Y >= r && p.Y < height1 - r);

            int[] idx2 = Matrix.Find(points2, p => p.X >= r && p.X < width2 - r &&
                                                   p.Y >= r && p.Y < height2 - r);


            // For each index in the first set of points
            foreach (int n1 in idx1)
            {
                // Get the current point
                IntPoint p1 = points1[n1];
                double sum = 0;

                unsafe // Create the first window for the current point
                {
                    byte* src = (byte*)bitmapData1.Scan0 + (p1.X - r) + (p1.Y - r) * stride1;

                    for (int j = 0; j < windowSize; j++)
                    {
                        for (int i = 0; i < windowSize; i++)
                        {
                            double w = (byte)(*(src + i));
                            w1[i, j] = w;
                            sum += w * w;
                        }
                        src += stride1;
                    }
                }

                // Normalize the window
                w1.Divide(System.Math.Sqrt(sum), result: w1);

                // Identify the indices of points in p2 that we need to consider.
                int[] candidates;
                if (maxDistance == 0)
                {
                    // We should consider all points
                    candidates = idx2;
                }
                else
                {
                    // We should consider points that are within
                    //  distance maxDistance apart

                    // Compute distances from the current point
                    //  to all points in the second image.
                    double[] distances = new double[idx2.Length];
                    for (int i = 0; i < idx2.Length; i++)
                    {
                        double dx = p1.X - points2[idx2[i]].X;
                        double dy = p1.Y - points2[idx2[i]].Y;
                        distances[i] = dx * dx + dy * dy;
                    }

                    candidates = idx2.Get(Matrix.Find(distances, d => d < m));
                }


                // Calculate normalized correlation measure
                foreach (int n2 in candidates)
                {
                    IntPoint p2 = points2[n2];

                    unsafe // Generate window in 2nd image
                    {
                        byte* src = (byte*)bitmapData2.Scan0 + (p2.X - r) + (p2.Y - r) * stride2;

                        for (int j = 0; j < windowSize; j++)
                        {
                            for (int i = 0; i < windowSize; i++)
                                w2[i, j] = (byte)(*(src + i));
                            src += stride2;
                        }
                    }

                    double sum1 = 0, sum2 = 0;
                    for (int i = 0; i < windowSize; i++)
                    {
                        for (int j = 0; j < windowSize; j++)
                        {
                            sum1 += w1[i, j] * w2[i, j];
                            sum2 += w2[i, j] * w2[i, j];
                        }
                    }

                    matrix[n1, n2] = sum1 / Math.Sqrt(sum2);
                }
            }

            // Release the images
            image1.UnlockBits(bitmapData1);
            image2.UnlockBits(bitmapData2);

            return matrix;
        }