예제 #1
0
        private static DataRectangle <double> Normalise(DataRectangle <double> values)
        {
            var max = values.Enumerate().Max(pointAndValue => pointAndValue.Item2);

            return((max == 0)
                ? values
                : values.Transform(value => (value / max)));
        }
예제 #2
0
        private static IEnumerable <IEnumerable <Point> > GetDistinctObjects(DataRectangle <bool> mask)
        {
            // Flood fill areas in the looks-like-bar-code mask to create distinct areas
            var allPoints = new HashSet <Point>(
                mask.Enumerate(optionalFilter: (point, isMasked) => isMasked).Select(point => point.Item1)
                );

            while (allPoints.Any())
            {
                var currentPoint   = allPoints.First();
                var pointsInObject = GetPointsInObject(currentPoint).ToArray();
                foreach (var point in pointsInObject)
                {
                    allPoints.Remove(point);
                }
                yield return(pointsInObject);
            }

            // Inspired by code at
            // https://simpledevcode.wordpress.com/2015/12/29/flood-fill-algorithm-using-c-net/
            IEnumerable <Point> GetPointsInObject(Point startAt)
            {
                var pixels = new Stack <Point>();

                pixels.Push(startAt);

                var valueAtOriginPoint = mask[startAt.X, startAt.Y];
                var filledPixels       = new HashSet <Point>();

                while (pixels.Count > 0)
                {
                    var currentPoint = pixels.Pop();
                    if ((currentPoint.X < 0) || (currentPoint.X >= mask.Width) ||
                        (currentPoint.Y < 0) || (currentPoint.Y >= mask.Height))
                    {
                        continue;
                    }

                    if ((mask[currentPoint.X, currentPoint.Y] == valueAtOriginPoint) &&
                        !filledPixels.Contains(currentPoint))
                    {
                        filledPixels.Add(new Point(currentPoint.X, currentPoint.Y));
                        pixels.Push(new Point(currentPoint.X - 1, currentPoint.Y));
                        pixels.Push(new Point(currentPoint.X + 1, currentPoint.Y));
                        pixels.Push(new Point(currentPoint.X, currentPoint.Y - 1));
                        pixels.Push(new Point(currentPoint.X, currentPoint.Y + 1));
                    }
                }
                return(filledPixels);
            }
        }