예제 #1
0
        public static BlobAnalysisResult Analyze(this BlobContainer blob,
                                                 int?frameXOffset = null, int?frameYOffset = null,
                                                 int?frameXLength = null, int?frameYLength = null)
        {
            var mass       = 0D;
            var xAggregate = 0D;
            var yAggregate = 0D;

            foreach (var c in blob.Points)
            {
                mass       += c.Color.TotalBrightness();
                xAggregate += c.Location.X;
                yAggregate += c.Location.Y;
            }

            if (mass == 0)
            {
                return(null);
            }

            var response = new BlobAnalysisResult
            {
                Mass         = mass,
                CentroidX    = xAggregate / mass,
                CentroidY    = yAggregate / mass,
                OriginalBlob = blob
            };

            var radiusComponents  = new List <double>();
            var paddingComponents = new List <double>();

            var xOffset = frameXOffset ?? blob.Points.Min(a => a.Location.X);
            var yOffset = frameYOffset ?? blob.Points.Min(a => a.Location.Y);
            var xLength = frameXLength ?? (blob.Points.Max(a => a.Location.X) - xOffset);
            var yLength = frameYLength ?? (blob.Points.Max(a => a.Location.Y) - yOffset);

            foreach (var c in blob.Points)
            {
                var radius   = Math.Sqrt(Math.Pow(c.Location.X - response.CentroidX, 2) + Math.Pow(c.Location.Y - response.CentroidY, 2));
                var weighted = radius * c.Color.TotalBrightness();
                radiusComponents.Add(weighted);

                paddingComponents.Add(Util.AbsMin(c.Location.X - xOffset, c.Location.X - (xOffset + xLength),
                                                  c.Location.Y - yOffset, c.Location.Y - (yOffset + yLength)));
            }

            response.MeanRadius    = radiusComponents.Average();
            response.MedianRadius  = radiusComponents.Median();
            response.MeanPadding   = paddingComponents.Average();
            response.MedianPadding = paddingComponents.Median();

            return(response);
        }
예제 #2
0
        public static ICollection <BlobContainer> SplitToBlobs(this Bitmap bitmap, int?minimumBlobMass = 3)
        {
            var nonEmptyPixels = bitmap.ParseBitmap()
                                 .Where(a => a.Color.TotalBrightness() > 0.5);

            var blobs   = new List <BlobContainer>();
            var blobMap = new Dictionary <Point, BlobContainer>();

            foreach (var locus in nonEmptyPixels)
            {
                Console.WriteLine("Parsing ({0}, {1})", locus.Location.X, locus.Location.Y);

                var adjacentPoints = new List <Point>();
                if (locus.Location.X > 0)
                {
                    adjacentPoints.Add(new Point(locus.Location.X - 1, locus.Location.Y));
                }
                if (locus.Location.Y > 0)
                {
                    adjacentPoints.Add(new Point(locus.Location.X, locus.Location.Y - 1));
                }
                if (locus.Location.X < bitmap.Width - 1)
                {
                    adjacentPoints.Add(new Point(locus.Location.X + 1, locus.Location.Y));
                }
                if (locus.Location.Y < bitmap.Height - 1)
                {
                    adjacentPoints.Add(new Point(locus.Location.X, locus.Location.Y + 1));
                }

                var matchingBlobs = adjacentPoints
                                    .Where(blobMap.ContainsKey)
                                    .Select(a => blobMap[a])
                                    .Distinct();

                BlobContainer targetBlob = null;
                foreach (var m in matchingBlobs)
                {
                    if (targetBlob == null)
                    {
                        targetBlob = m;
                    }
                    else
                    {
                        foreach (var l in m.Points)
                        {
                            targetBlob.Points.Add(l);
                            blobMap[l.Location] = targetBlob;
                            blobs.Remove(m);
                        }
                    }
                }
                if (targetBlob == null)
                {
                    targetBlob = new BlobContainer
                    {
                        Points = new List <ColorPoint>()
                    };
                    blobs.Add(targetBlob);
                }
                targetBlob.Points.Add(locus);
                blobMap[locus.Location] = targetBlob;
            }

            if (minimumBlobMass.HasValue)
            {
                blobs.RemoveAll(a => a.Points.Count < minimumBlobMass.Value);
            }
            return(blobs);
        }