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); } } }
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 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); } }