private Location GetBlobEdgeLocation(Point point)
        {
            bool isBlob = CanRead(point) && Read(point) == 1;

            if (!isBlob)
            {
                return(default(Location));
            }

            Location location = new Location {
                Top    = point.X,
                Left   = point.Y,
                Bottom = point.X,
                Right  = point.Y
            };

            Location upBlobLocation = GetBlobEdgeLocation(new Point(point.X - 1, point.Y));

            BlobDetectionResult.Merge(ref location, ref upBlobLocation);

            Location rightBlobLocation = GetBlobEdgeLocation(new Point(point.X, point.Y + 1));

            BlobDetectionResult.Merge(ref location, ref rightBlobLocation);

            Location downBlobLocation = GetBlobEdgeLocation(new Point(point.X + 1, point.Y));

            BlobDetectionResult.Merge(ref location, ref downBlobLocation);

            Location leftBlobLocation = GetBlobEdgeLocation(new Point(point.X, point.Y - 1));

            BlobDetectionResult.Merge(ref location, ref leftBlobLocation);

            return(location);
        }
        private Location TraceContour(Point currentPosition, int previousContourPoint)
        {
            Location location = new Location {
                Top    = currentPosition.X,
                Left   = currentPosition.Y,
                Bottom = currentPosition.X,
                Right  = currentPosition.Y
            };

            int startContourPoint = (previousContourPoint + 2) % MaxNeighboringPoints;

            int currentContourPoint = startContourPoint;

            for (int i = 0; i < 8; i++)
            {
                currentContourPoint = (startContourPoint + i) % MaxNeighboringPoints;

                Point nextPosition = CalculateNextPosition(currentPosition, currentContourPoint);

                if (!CanRead(nextPosition))
                {
                    continue;
                }

                if (ContourClosed(currentPosition, nextPosition))
                {
                    break;
                }

                if (Read(nextPosition) == 1)
                {
                    int      relativeContourPoint = (currentContourPoint + (MaxNeighboringPoints / 2)) % MaxNeighboringPoints;
                    Location nextBlobLocation     = TraceContour(
                        nextPosition,
                        previousContourPoint: relativeContourPoint
                        );
                    BlobDetectionResult.Merge(ref location, ref nextBlobLocation);

                    break;
                }
            }

            return(location);
        }