Example #1
0
        public void ClassifySegments()
        {
            //label some segments as noise

            //label the color group with the largest segment as a background element
            //label all segments in the color group as a background (?), unless it is noise
            //001-noise, 010-background, 100-foreground
            double largestSize = 0;
            int    segIdx      = -1;

            for (int i = 0; i < segments.Count(); i++)
            {
                double size = segments[i].points.Count();
                if (segments[i].assignmentId >= 0 && largestSize < size)
                {
                    largestSize = size;
                    segIdx      = i;
                }
            }

            int groupId = segments[segIdx].groupId;

            NamedFeature bg = new NamedFeature("Label");

            bg.values = new List <Double> {
                0, 1, 0
            };
            foreach (int idx in groups[groupId].members)
            {
                if (segments[idx].assignmentId >= 0)
                {
                    segments[idx].features.Add(bg);
                }
            }

            NamedFeature noise = new NamedFeature("Label");

            noise.values = new List <Double> {
                0, 0, 1
            };

            NamedFeature fg = new NamedFeature("Label");

            fg.values = new List <Double> {
                1, 0, 0
            };

            foreach (Segment s in segments)
            {
                if (s.assignmentId < 0)
                {
                    s.features.Add(noise);
                }
                else if (s.groupId != groupId)
                {
                    s.features.Add(fg);
                }
            }
        }
Example #2
0
        public void ComputeFeatures(SegmentGroup g)
        {
            double imarea = (double)(imageWidth * imageHeight);

            // Amount of the image this group takes up
            NamedFeature sizef = new NamedFeature("RelativeSize");
            int          size  = 0;

            foreach (int i in g.members)
            {
                Segment s = segments[i];
                size += s.points.Count();
            }
            sizef.values.Add(size / imarea);
            g.features.Add(sizef);

            // (Normalized) number of segments in the group
            NamedFeature numsegf = new NamedFeature("NormalizedNumSegs");

            numsegf.values.Add(g.members.Count() / (double)(segments.Count()));
            g.features.Add(numsegf);

            // min, max, mean, stddev segment size
            int minsegsize, maxsegsize, segsizesum;

            minsegsize = Int32.MaxValue;
            maxsegsize = 0;
            segsizesum = 0;
            foreach (int i in g.members)
            {
                int s = segments[i].points.Count;
                minsegsize  = Math.Min(s, minsegsize);
                maxsegsize  = Math.Max(s, maxsegsize);
                segsizesum += s;
            }
            double meansegsize   = ((double)segsizesum) / g.members.Count;
            double stddevsegsize = 0;

            foreach (int i in g.members)
            {
                int    s    = segments[i].points.Count;
                double diff = (s - meansegsize);
                stddevsegsize += (diff * diff);
            }
            stddevsegsize /= g.members.Count;
            NamedFeature segsizestatsf = new NamedFeature("SegmentSizeStatistics");

            segsizestatsf.values.Add(minsegsize / imarea);
            segsizestatsf.values.Add(maxsegsize / imarea);
            segsizestatsf.values.Add(meansegsize / imarea);
            segsizestatsf.values.Add(stddevsegsize / imarea);
            g.features.Add(segsizestatsf);

            // "spread" - covariance of segment centroids
            PointF meanc = new PointF(0, 0);

            foreach (int i in g.members)
            {
                PointF c = NormalizedCentroid(segments[i]);
                meanc.X += c.X;
                meanc.Y += c.Y;
            }
            meanc.X        /= g.members.Count;
            meanc.Y        /= g.members.Count;
            double[,] covar = new double[, ] {
                { 0, 0 }, { 0, 0 }
            };
            foreach (int i in g.members)
            {
                PointF c = NormalizedCentroid(segments[i]);
                float  x = c.X - meanc.X;
                float  y = c.Y - meanc.Y;
                covar[0, 0] += x * x;
                covar[0, 1] += x * y;
                covar[1, 0] += x * y;
                covar[1, 1] += y * y;
            }
            covar[0, 0] /= g.members.Count;
            covar[0, 1] /= g.members.Count;
            covar[1, 0] /= g.members.Count;
            covar[1, 1] /= g.members.Count;
            NamedFeature spreadf = new NamedFeature("SegmentSpread",
                                                    new List <double> {
                covar[0, 0], covar[0, 1], covar[1, 0], covar[1, 1]
            });

            g.features.Add(spreadf);
        }
Example #3
0
        public void ComputeFeatures(Segment s)
        {
            //Add the relative size
            NamedFeature f = new NamedFeature("RelativeSize");

            f.values.Add(s.points.Count() / (double)(imageWidth * imageHeight));
            s.features.Add(f);

            // Relative centroid
            PointF c = NormalizedCentroid(s);

            s.features.Add(new NamedFeature("RelativeCentroid", new List <double> {
                c.X, c.Y
            }));

            // One interior point
            PointF np = RandomNormalizedInteriorPoint(s);

            s.features.Add(new NamedFeature("OneInteriorPoint", new List <double> {
                np.X, np.Y
            }));

            //Radial distance
            s.features.Add(new NamedFeature("RadialDistance", new List <double> {
                Math.Sqrt(c.X * c.X + c.Y * c.Y)
            }));


            //Normalized Discrete Compactness http://www.m-hikari.com/imf-password2009/25-28-2009/bribiescaIMF25-28-2009.pdf
            //Find the segment id
            Point sp   = s.points.First();
            int   sidx = assignments[sp.X, sp.Y];

            //count number of perimeter edges
            int perimeter = 0;

            foreach (Point p in s.points)
            {
                for (int i = -1; i <= 1; i++)
                {
                    for (int j = -1; j <= 1; j++)
                    {
                        if (Math.Abs(i) == Math.Abs(j))
                        {
                            continue;
                        }
                        if (Util.InBounds(p.X + i, p.Y + j, imageWidth, imageHeight) && assignments[p.X + i, p.Y + j] != sidx)
                        {
                            perimeter++;
                        }
                        else if (!Util.InBounds(p.X + i, p.Y + j, imageWidth, imageHeight)) //edge pixels should be considered perimeter too
                        {
                            perimeter++;
                        }
                    }
                }
            }
            int    n     = s.points.Count();
            double CD    = (4.0 * n - perimeter) / 2;
            double CDmin = n - 1;
            double CDmax = (4 * n - 4 * Math.Sqrt(n)) / 2;
            double CDN   = (CD - CDmin) / Math.Max(1, (CDmax - CDmin));

            s.features.Add(new NamedFeature("NormalizedDiscreteCompactness", new List <double> {
                CDN
            }));


            //Add elongation (width/length normalized between 0-square to 1-long http://hal.archives-ouvertes.fr/docs/00/44/60/37/PDF/ARS-Journal-SurveyPatternRecognition.pdf
            PointF[] points = s.points.Select <Point, PointF>(p => new PointF(p.X, p.Y)).ToArray <PointF>();
            Emgu.CV.Structure.MCvBox2D box = Emgu.CV.PointCollection.MinAreaRect(points);

            PointF[] vertices   = box.GetVertices();
            double   elongation = 1 - Math.Min(box.size.Width + 1, box.size.Height + 1) / Math.Max(box.size.Width + 1, box.size.Height + 1);

            s.features.Add(new NamedFeature("Elongation", new List <double> {
                elongation
            }));


            //Add Hu shape moments, invariant to translation, scale, and rotation (not sure what each measure refers to intuitively though, or if there is an intuitive analog)
            //They may also do badly on noisy data however. See: http://hal.archives-ouvertes.fr/docs/00/44/60/37/PDF/ARS-Journal-SurveyPatternRecognition.pdf (called Invariant Moments)

            Bitmap   regionBitmap = new Bitmap(imageWidth, imageHeight);
            Graphics g            = Graphics.FromImage(regionBitmap);

            g.FillRectangle(new SolidBrush(Color.Black), 0, 0, imageWidth, imageHeight);
            foreach (Point p in s.points)
            {
                regionBitmap.SetPixel(p.X, p.Y, Color.White);
            }

            Emgu.CV.Image <Gray, byte> region = new Emgu.CV.Image <Gray, byte>(regionBitmap);

            MCvMoments   moment = region.GetMoments(true);
            MCvHuMoments hu     = moment.GetHuMoment();

            s.features.Add(new NamedFeature("HuMoments", new List <double> {
                hu.hu1, hu.hu2, hu.hu3, hu.hu4, hu.hu5, hu.hu6, hu.hu7
            }));
            region.Dispose();
            regionBitmap.Dispose();
        }
        public void ComputeFeatures(SegmentGroup g)
        {
            double imarea = (double)(imageWidth * imageHeight);

            // Amount of the image this group takes up
            NamedFeature sizef = new NamedFeature("RelativeSize");
            int size = 0;
            foreach (int i in g.members)
            {
                Segment s = segments[i];
                size += s.points.Count();
            }
            sizef.values.Add(size / imarea);
            g.features.Add(sizef);

            // (Normalized) number of segments in the group
            NamedFeature numsegf = new NamedFeature("NormalizedNumSegs");
            numsegf.values.Add(g.members.Count() / (double)(segments.Count()));
            g.features.Add(numsegf);

            // min, max, mean, stddev segment size
            int minsegsize, maxsegsize, segsizesum;
            minsegsize = Int32.MaxValue;
            maxsegsize = 0;
            segsizesum = 0;
            foreach (int i in g.members)
            {
                int s = segments[i].points.Count;
                minsegsize = Math.Min(s, minsegsize);
                maxsegsize = Math.Max(s, maxsegsize);
                segsizesum += s;
            }
            double meansegsize = ((double)segsizesum) / g.members.Count;
            double stddevsegsize = 0;
            foreach (int i in g.members)
            {
                int s = segments[i].points.Count;
                double diff = (s - meansegsize);
                stddevsegsize += (diff * diff);
            }
            stddevsegsize /= g.members.Count;
            NamedFeature segsizestatsf = new NamedFeature("SegmentSizeStatistics");
            segsizestatsf.values.Add(minsegsize / imarea);
            segsizestatsf.values.Add(maxsegsize / imarea);
            segsizestatsf.values.Add(meansegsize / imarea);
            segsizestatsf.values.Add(stddevsegsize / imarea);
            g.features.Add(segsizestatsf);

            // "spread" - covariance of segment centroids
            PointF meanc = new PointF(0, 0);
            foreach (int i in g.members)
            {
                PointF c = NormalizedCentroid(segments[i]);
                meanc.X += c.X;
                meanc.Y += c.Y;
            }
            meanc.X /= g.members.Count;
            meanc.Y /= g.members.Count;
            double[,] covar = new double[,] { { 0, 0 }, { 0, 0 } };
            foreach (int i in g.members)
            {
                PointF c = NormalizedCentroid(segments[i]);
                float x = c.X - meanc.X;
                float y = c.Y - meanc.Y;
                covar[0, 0] += x * x;
                covar[0, 1] += x * y;
                covar[1, 0] += x * y;
                covar[1, 1] += y * y;
            }
            covar[0, 0] /= g.members.Count;
            covar[0, 1] /= g.members.Count;
            covar[1, 0] /= g.members.Count;
            covar[1, 1] /= g.members.Count;
            NamedFeature spreadf = new NamedFeature("SegmentSpread",
                new List<double>{covar[0,0], covar[0,1], covar[1,0], covar[1,1]});
            g.features.Add(spreadf);
        }
        public void ComputeFeatures(Segment s)
        {
            //Add the relative size
            NamedFeature f = new NamedFeature("RelativeSize");
            f.values.Add(s.points.Count() / (double)(imageWidth * imageHeight));
            s.features.Add(f);

            // Relative centroid
            PointF c = NormalizedCentroid(s);
            s.features.Add(new NamedFeature("RelativeCentroid", new List<double>{c.X, c.Y}));

            // One interior point
            PointF np = RandomNormalizedInteriorPoint(s);
            s.features.Add(new NamedFeature("OneInteriorPoint", new List<double> { np.X, np.Y }));

            //Radial distance
            s.features.Add(new NamedFeature("RadialDistance", new List<double>{Math.Sqrt(c.X*c.X+c.Y*c.Y)}));

            //Normalized Discrete Compactness http://www.m-hikari.com/imf-password2009/25-28-2009/bribiescaIMF25-28-2009.pdf
            //Find the segment id
            Point sp = s.points.First();
            int sidx = assignments[sp.X, sp.Y];

            //count number of perimeter edges
            int perimeter = 0;
            foreach (Point p in s.points)
            {
                for (int i = -1; i <= 1; i++)
                {
                    for (int j = -1; j <= 1; j++)
                    {
                        if (Math.Abs(i) == Math.Abs(j))
                            continue;
                        if (Util.InBounds(p.X + i, p.Y + j, imageWidth, imageHeight) && assignments[p.X + i, p.Y + j] != sidx)
                            perimeter++;
                        else if (!Util.InBounds(p.X + i, p.Y + j, imageWidth, imageHeight)) //edge pixels should be considered perimeter too
                            perimeter++;
                    }
                }
            }
            int n = s.points.Count();
            double CD = (4.0 * n - perimeter) / 2;
            double CDmin = n - 1;
            double CDmax = (4 * n - 4 * Math.Sqrt(n)) / 2;
            double CDN = (CD - CDmin) / Math.Max(1,(CDmax - CDmin));
            s.features.Add(new NamedFeature("NormalizedDiscreteCompactness", new List<double> { CDN }));

            //Add elongation (width/length normalized between 0-square to 1-long http://hal.archives-ouvertes.fr/docs/00/44/60/37/PDF/ARS-Journal-SurveyPatternRecognition.pdf
            PointF[] points = s.points.Select<Point, PointF>(p => new PointF(p.X, p.Y)).ToArray<PointF>();
            Emgu.CV.Structure.MCvBox2D box = Emgu.CV.PointCollection.MinAreaRect(points);

            PointF[] vertices = box.GetVertices();
            double elongation = 1 - Math.Min(box.size.Width + 1, box.size.Height + 1) / Math.Max(box.size.Width + 1, box.size.Height + 1);
            s.features.Add(new NamedFeature("Elongation", new List<double>{elongation}));

            //Add Hu shape moments, invariant to translation, scale, and rotation (not sure what each measure refers to intuitively though, or if there is an intuitive analog)
            //They may also do badly on noisy data however. See: http://hal.archives-ouvertes.fr/docs/00/44/60/37/PDF/ARS-Journal-SurveyPatternRecognition.pdf (called Invariant Moments)

            Bitmap regionBitmap = new Bitmap(imageWidth, imageHeight);
            Graphics g = Graphics.FromImage(regionBitmap);
            g.FillRectangle(new SolidBrush(Color.Black), 0, 0, imageWidth, imageHeight);
            foreach (Point p in s.points)
            {
                regionBitmap.SetPixel(p.X, p.Y, Color.White);
            }

            Emgu.CV.Image<Gray, byte> region = new Emgu.CV.Image<Gray, byte>(regionBitmap);

            MCvMoments moment = region.GetMoments(true);
            MCvHuMoments hu = moment.GetHuMoment();
            s.features.Add(new NamedFeature("HuMoments", new List<double> {hu.hu1, hu.hu2, hu.hu3,hu.hu4,hu.hu5, hu.hu6, hu.hu7 }));
            region.Dispose();
            regionBitmap.Dispose();
        }
        public void ClassifySegments()
        {
            //label some segments as noise

            //label the color group with the largest segment as a background element
            //label all segments in the color group as a background (?), unless it is noise
            //001-noise, 010-background, 100-foreground
            double largestSize = 0;
            int segIdx = -1;

            for (int i = 0; i < segments.Count(); i++)
            {
                double size = segments[i].points.Count();
                if (segments[i].assignmentId >= 0 && largestSize < size)
                {
                    largestSize = size;
                    segIdx = i;
                }
            }

            int groupId = segments[segIdx].groupId;

            NamedFeature bg = new NamedFeature("Label");
            bg.values = new List<Double>{0, 1, 0};
            foreach (int idx in groups[groupId].members)
            {
                if (segments[idx].assignmentId >=0)
                    segments[idx].features.Add(bg);
            }

            NamedFeature noise = new NamedFeature("Label");
            noise.values = new List<Double>{0, 0, 1};

            NamedFeature fg = new NamedFeature("Label");
            fg.values = new List<Double> { 1, 0, 0 };

            foreach (Segment s in segments)
            {
                if (s.assignmentId < 0)
                    s.features.Add(noise);
                else if (s.groupId != groupId)
                    s.features.Add(fg);
            }
        }