Пример #1
0
        public IEnumerable<Segment> Process(ISimpleBitmap input)
        {
            if (Histogram == null)
            {
                throw new InvalidOperationException("The histogram must be provided");
            }

            int[] hx = Histogram.X;
            int[] hy = Histogram.Y;
            Vector histUpperThreshold = Histogram.Max*0.5f;

            // Find seeds for the segmentation:
            // All the x and y histogram indices where the value is above the half maximum and have a min distance
            const int step = 10;
            // x
            List<int> ix = GetIndicesAboveThreshold(Histogram.MaxIndex.X, -step, hx, histUpperThreshold.X);
            ix.AddRange(GetIndicesAboveThreshold(Histogram.MaxIndex.X + step, step, hx, histUpperThreshold.X));
            // y
            List<int> iy = GetIndicesAboveThreshold(Histogram.MaxIndex.Y, -step, hy, histUpperThreshold.Y);
            iy.AddRange(GetIndicesAboveThreshold(Histogram.MaxIndex.Y + step, step, hy, histUpperThreshold.Y));

            // Find the boundaries for the segments defined by the seeds
            var segments = new List<Segment>();
            foreach (int y0 in iy)
            {
                foreach (int x0 in ix)
                {
                    var segment = new Segment(0, 0, 0, 0);
                    segment.Min.X = GetIndexBelowThreshold(x0, -1, hx, ThresholdLuminance.X);
                    segment.Max.X = GetIndexBelowThreshold(x0, 1, hx, ThresholdLuminance.X);
                    segment.Min.Y = GetIndexBelowThreshold(y0, -1, hy, ThresholdLuminance.Y);
                    segment.Max.Y = GetIndexBelowThreshold(y0, 1, hy, ThresholdLuminance.Y);
                    segments.Add(segment);
                }
            }

            if (segments.Count > 0)
            {
                // Sort (only pick the largest for now)
                Segment foundSegment = segments.OrderByDescending(s => s.DiagonalSq).FirstOrDefault();

                // Prevent jittering:
                // If the position doesn't change too much over a certain timespan, the last segment is always returned.

                // Check for jittering position.
                bool isJittering = true;
                if ((lastSegment.Min - foundSegment.Min).LengthSq < jitteringAmountThresholdSq)
                {
                    // Check for jittering size
                    if (System.Math.Abs(foundSegment.DiagonalSq - lastSegment.DiagonalSq) < jitteringAmountThresholdSq)
                    {
                        jitteringCount++;
                        isJittering = false;
                    }
                }

                // Freeze or not
                if (isJittering)
                {
                    jitteringCount = 0;
                }
                if (jitteringCount < JitteringCountThreshold)
                {
                    lastSegment = foundSegment;
                }
            }

            return new List<Segment> {lastSegment};
        }
Пример #2
0
 public void Reset()
 {
     jitteringCount = 0;
     lastSegment = new Segment(-100, -100, -200, -200);
 }