예제 #1
0
        /// <summary>
        ///   Finds local extremum points in the contour.
        /// </summary>
        /// <param name="contour">A list of <see cref="IntPoint">
        /// integer points</see> defining the contour.</param>
        ///
        public List <IntPoint> FindPeaks(List <IntPoint> contour)
        {
            double[] map = new double[contour.Count];

            for (int i = 0; i < contour.Count; i++)
            {
                IntPoint a, b, c;

                int ai = Accord.Math.Tools.Mod(i + K, contour.Count);
                int ci = Accord.Math.Tools.Mod(i - K, contour.Count);

                a = contour[ai];
                b = contour[i];
                c = contour[ci];


                // http://stackoverflow.com/questions/3486172/angle-between-3-points/3487062#3487062
                //double angle = AForge.Math.Geometry.GeometryTools.GetAngleBetweenVectors(b, a, c);

                DoublePoint ab = new DoublePoint(b.X - a.X, b.Y - a.Y);
                DoublePoint cb = new DoublePoint(b.X - c.X, b.Y - c.Y);

                double angba = System.Math.Atan2(ab.Y, ab.X);
                double angbc = System.Math.Atan2(cb.Y, cb.X);
                double rslt  = angba - angbc;

                if (rslt < 0)
                {
                    rslt = 2 * Math.PI + rslt;
                }

                double rs = (rslt * 180) / Math.PI;



                if (Theta.IsInside(rs))
                {
                    map[i] = rs;
                }
            }

            // Non-Minima Suppression
            int             r     = Suppression;
            List <IntPoint> peaks = new List <IntPoint>();

            for (int i = 0; i < map.Length; i++)
            {
                double current = map[i];
                if (current == 0)
                {
                    continue;
                }

                bool isMinimum = true;

                for (int j = -r; j < r && isMinimum; j++)
                {
                    int index = Accord.Math.Tools.Mod(i + j, map.Length);

                    double candidate = map[index];

                    if (candidate == 0)
                    {
                        continue;
                    }

                    if (candidate < current)
                    {
                        isMinimum = false;
                    }
                    else
                    {
                        map[index] = 0;
                    }
                }

                if (isMinimum)
                {
                    peaks.Add(contour[i]);
                }
            }

            return(peaks);
        }