Exemple #1
0
        /// <summary>
        /// Classical Multidimensional Scaling
        /// </summary>
        public void Run()
        {
            // creates distance matrix
            int size = CityDistance.GetLength(0);
            Mat t    = new Mat(size, size, MatType.CV_64FC1, CityDistance);
            // adds Torgerson's additive constant to t
            double torgarson = Torgerson(t);

            t += torgarson;
            // squares all elements of t
            t = t.Mul(t);

            // centering matrix G
            Mat g = CenteringMatrix(size);
            // calculates inner product matrix B
            Mat b = g * t * g.T() * -0.5;
            // calculates eigenvalues and eigenvectors of B
            Mat values  = new Mat();
            Mat vectors = new Mat();

            Cv2.Eigen(b, values, vectors);
            for (int r = 0; r < values.Rows; r++)
            {
                if (values.Get <double>(r) < 0)
                {
                    values.Set <double>(r, 0);
                }
            }

            //Console.WriteLine(values.Dump());

            // multiplies sqrt(eigenvalue) by eigenvector
            Mat result = vectors.RowRange(0, 2);

            {
                var at = result.GetGenericIndexer <double>();
                for (int r = 0; r < result.Rows; r++)
                {
                    for (int c = 0; c < result.Cols; c++)
                    {
                        at[r, c] *= Math.Sqrt(values.Get <double>(r));
                    }
                }
            }

            // scaling
            Cv2.Normalize(result, result, 0, 800, NormTypes.MinMax);

            // opens a window
            using (Mat img = Mat.Zeros(600, 800, MatType.CV_8UC3))
                using (Window window = new Window("City Location Estimation"))
                {
                    var at = result.GetGenericIndexer <double>();
                    for (int c = 0; c < size; c++)
                    {
                        double x = at[0, c];
                        double y = at[1, c];
                        x = x * 0.7 + img.Width * 0.1;
                        y = y * 0.7 + img.Height * 0.1;
                        img.Circle((int)x, (int)y, 5, Scalar.Red, -1);
                        Point textPos = new Point(x + 5, y + 10);
                        img.PutText(CityNames[c], textPos, HersheyFonts.HersheySimplex, 0.5, Scalar.White);
                    }
                    window.Image = img;
                    Cv2.WaitKey();
                }
        }