public Blob(Blob source) { id = source.id; rect = source.rect; cog = source.cog; area = source.area; fullness = source.fullness; colorMean = source.colorMean; colorStdDev = source.colorStdDev; }
// Collect objects' rectangles private void CollectObjectsInfo(PixelRegion sourcePixelRegion) { int i = 0, label; // create object coordinates arrays int[] x1 = new int[objectsCount + 1]; int[] y1 = new int[objectsCount + 1]; int[] x2 = new int[objectsCount + 1]; int[] y2 = new int[objectsCount + 1]; int[] area = new int[objectsCount + 1]; long[] xc = new long[objectsCount + 1]; long[] yc = new long[objectsCount + 1]; long[] meanR = new long[objectsCount + 1]; long[] meanG = new long[objectsCount + 1]; long[] meanB = new long[objectsCount + 1]; long[] stdDevR = new long[objectsCount + 1]; long[] stdDevG = new long[objectsCount + 1]; long[] stdDevB = new long[objectsCount + 1]; for (int j = 1; j <= objectsCount; j++) { x1[j] = imageWidth; y1[j] = imageHeight; } // color images byte r, g, b; // RGB value // walk through labels array for (int y = 0; y < imageHeight; y++) { for (int x = 0; x < imageWidth; x++, i++) { // get current label label = objectLabels[i]; // skip unlabeled pixels if (label == 0) continue; // check and update all coordinates if (x < x1[label]) { x1[label] = x; } if (x > x2[label]) { x2[label] = x; } if (y < y1[label]) { y1[label] = y; } if (y > y2[label]) { y2[label] = y; } area[label]++; xc[label] += x; yc[label] += y; Color c = ToColor(sourcePixelRegion.ImagePixels[y * imageWidth + x]); r = c.R; g = c.G; b = c.B; meanR[label] += r; meanG[label] += g; meanB[label] += b; stdDevR[label] += r * r; stdDevG[label] += g * g; stdDevB[label] += b * b; } } // create blobs blobs.Clear(); for (int j = 1; j <= objectsCount; j++) { int blobArea = area[j]; Blob blob = new Blob(j, new Rect(x1[j], y1[j], x2[j] - x1[j] + 1, y2[j] - y1[j] + 1)); blob.Area = blobArea; blob.Fullness = (double)blobArea / ((x2[j] - x1[j] + 1) * (y2[j] - y1[j] + 1)); blob.CenterOfGravity = new Point((float)xc[j] / blobArea, (float)yc[j] / blobArea); blob.ColorMean = Color.FromArgb(255, (byte)(meanR[j] / blobArea), (byte)(meanG[j] / blobArea), (byte)(meanB[j] / blobArea)); blob.ColorStdDev = Color.FromArgb( 255, (byte)(Math.Sqrt(stdDevR[j] / blobArea - blob.ColorMean.R * blob.ColorMean.R)), (byte)(Math.Sqrt(stdDevG[j] / blobArea - blob.ColorMean.G * blob.ColorMean.G)), (byte)(Math.Sqrt(stdDevB[j] / blobArea - blob.ColorMean.B * blob.ColorMean.B))); blobs.Add(blob); } }
public Blob[] GetObjectsInformation() { // check if objects map was collected if (objectLabels == null) throw new ApplicationException("Image should be processed before to collect objects map."); Blob[] blobsToReturn = new Blob[objectsCount]; // create each blob for (int k = 0; k < objectsCount; k++) { blobsToReturn[k] = new Blob(blobs[k]); } return blobsToReturn; }
public void GetBlobsTopAndBottomEdges(Blob blob, out List<Point> topEdge, out List<Point> bottomEdge) { // check if objects map was collected if (objectLabels == null) throw new ApplicationException("Image should be processed before to collect objects map."); topEdge = new List<Point>(); bottomEdge = new List<Point>(); int xmin = (int)blob.Rectangle.Left; int xmax = (int)(xmin + blob.Rectangle.Width - 1); int ymin = (int)blob.Rectangle.Top; int ymax = (int)(ymin + blob.Rectangle.Height - 1); int label = blob.ID; // for each column for (int x = xmin; x <= xmax; x++) { // scan from top to bottom int p = ymin * imageWidth + x; for (int y = ymin; y <= ymax; y++, p += imageWidth) { if (objectLabels[p] == label) { topEdge.Add(new Point(x, y)); break; } } // scan from bottom to top p = ymax * imageWidth + x; for (int y = ymax; y >= ymin; y--, p -= imageWidth) { if (objectLabels[p] == label) { bottomEdge.Add(new Point(x, y)); break; } } } }
public void GetBlobsLeftAndRightEdges(Blob blob, out List<Point> leftEdge, out List<Point> rightEdge) { // check if objects map was collected if (objectLabels == null) throw new Exception("Image should be processed before to collect objects map."); leftEdge = new List<Point>(); rightEdge = new List<Point>(); int xmin = (int)blob.Rectangle.Left; int xmax = (int)(xmin + blob.Rectangle.Width - 1); int ymin = (int)blob.Rectangle.Top; int ymax = (int)(ymin + blob.Rectangle.Height - 1); int label = blob.ID; // for each line for (int y = ymin; y <= ymax; y++) { // scan from left to right int p = y * imageWidth + xmin; for (int x = xmin; x <= xmax; x++, p++) { if (objectLabels[p] == label) { leftEdge.Add(new Point(x, y)); break; } } // scan from right to left p = y * imageWidth + xmax; for (int x = xmax; x >= xmin; x--, p--) { if (objectLabels[p] == label) { rightEdge.Add(new Point(x, y)); break; } } } }
public List<Point> GetBlobsEdgePoints(Blob blob) { // check if objects map was collected if (objectLabels == null) throw new ApplicationException("Image should be processed before to collect objects map."); List<Point> edgePoints = new List<Point>(); int xmin = (int)blob.Rectangle.Left; int xmax = (int)(xmin + blob.Rectangle.Width - 1); int ymin = (int)blob.Rectangle.Top; int ymax = (int)(ymin + blob.Rectangle.Height - 1); int label = blob.ID; // array of already processed points on left/right edges // (index in these arrays represent Y coordinate, but value - X coordinate) int[] leftProcessedPoints = new int[(int)blob.Rectangle.Height]; int[] rightProcessedPoints = new int[(int)blob.Rectangle.Height]; // for each line for (int y = ymin; y <= ymax; y++) { // scan from left to right int p = y * imageWidth + xmin; for (int x = xmin; x <= xmax; x++, p++) { if (objectLabels[p] == label) { edgePoints.Add(new Point(x, y)); leftProcessedPoints[y - ymin] = x; break; } } // scan from right to left p = y * imageWidth + xmax; for (int x = xmax; x >= xmin; x--, p--) { if (objectLabels[p] == label) { // avoid adding the point we already have if (leftProcessedPoints[y - ymin] != x) { edgePoints.Add(new Point(x, y)); } rightProcessedPoints[y - ymin] = x; break; } } } // for each column for (int x = xmin; x <= xmax; x++) { // scan from top to bottom int p = ymin * imageWidth + x; for (int y = ymin, y0 = 0; y <= ymax; y++, y0++, p += imageWidth) { if (objectLabels[p] == label) { // avoid adding the point we already have if ((leftProcessedPoints[y0] != x) && (rightProcessedPoints[y0] != x)) { edgePoints.Add(new Point(x, y)); } break; } } // scan from bottom to top p = ymax * imageWidth + x; for (int y = ymax, y0 = ymax - ymin; y >= ymin; y--, y0--, p -= imageWidth) { if (objectLabels[p] == label) { // avoid adding the point we already have if ((leftProcessedPoints[y0] != x) && (rightProcessedPoints[y0] != x)) { edgePoints.Add(new Point(x, y)); } break; } } } return edgePoints; }