Accord.Math.Geometry.KCurvature.FindPeaks C# (CSharp) Method

FindPeaks() public method

Finds local extremum points in the contour.
public FindPeaks ( List contour ) : List
contour List A list of /// integer points defining the contour.
return List
        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;
        }

Usage Example

Example #1
0
        public void FindPeaksTest()
        {
            Bitmap hand = Properties.Resources.rhand;

            GaussianBlur median = new GaussianBlur(1.1);
            median.ApplyInPlace(hand);

            // Extract contour
            BorderFollowing bf = new BorderFollowing(1);
            List<IntPoint> contour = bf.FindContour(hand);

            hand = hand.Clone(new Rectangle(0, 0, hand.Width, hand.Height), PixelFormat.Format24bppRgb);

            // Find peaks
            KCurvature kcurv = new KCurvature(30, new DoubleRange(0, 45));
            // kcurv.Suppression = 30;
            var peaks = kcurv.FindPeaks(contour);

            List<IntPoint> supports = new List<IntPoint>();
            for (int i = 0; i < peaks.Count; i++)
            {
                int j = contour.IndexOf(peaks[i]);
                supports.Add(contour[(j + kcurv.K) % contour.Count]);
                supports.Add(contour[Accord.Math.Tools.Mod(j - kcurv.K, contour.Count)]);
            }

            // show(hand, contour, peaks, supports);

            Assert.AreEqual(2, peaks.Count);
            Assert.AreEqual(46, peaks[0].X);
            Assert.AreEqual(0, peaks[0].Y);
            Assert.AreEqual(2, peaks[1].X);
            Assert.AreEqual(11, peaks[1].Y);
        }