public List<RawTexture2D> BlobDetection() { int w = width; int h = height; int s = pixels.Length; bool[] p = new bool[5]; int[] pL = new int[5]; int[,] labels = new int[h, w]; int[] linked = new int[w*h/4]; int label = 1; for (int i = 0; i < s; i++) { int x = i%w; int y = i/w; p [0] = pixels [i].r != 255; pL [0] = labels[y,x]; if(y - 1 < 0 || x - 1 < 0){ p[1] = false; pL[1] = 0; } else { p[1] = pixels [i - w - 1].r != 255; pL[1] = linked[labels[y-1,x-1]]; } if(y - 1 < 0){ p[2] = false; pL[2] = 0; } else { p[2] = pixels [i - w].r != 255; pL[2] = linked[labels[y-1,x]]; } if(y - 1 < 0 || x + 1 > w - 1){ p[3] = false; pL[3] = 0; } else { p[3] = pixels [i - w + 1].r != 255; pL[3] = linked[labels[y-1,x+1]]; } if(x - 1 < 0){ p[4] = false; pL[4] = 0; } else { p[4] = pixels [i - 1].r != 255; pL[4] = linked[labels[y,x-1]]; } if(p[0]){ if(pL[1]==0 && pL[2]==0 && pL[3]==0 && pL[4]==0){ labels[y,x] = label; linked[label] = label; label++; } else { int minLabel = 999; for(int j = 1; j<5; j++){ if(pL[j] != 0 && pL[j] < minLabel) minLabel = pL[j]; } labels[y,x] = minLabel; if(pL[1]!=0){ linked[pL[1]] = minLabel; //labels[y-1,x-1] = minLabel; } if(pL[2]!=0){ linked[pL[2]] = minLabel; //labels[y-1,x] = minLabel; } if(pL[3]!=0){ linked[pL[3]] = minLabel; //labels[y-1,x+1] = minLabel; } if(pL[4]!=0){ linked[pL[4]] = minLabel; //labels[y,x-1] = minLabel; } } } } int k = 1; while (linked[k]!=0) { int j = k; while(linked[j] != j){ j = linked[j]; } linked[k] = j; k++; } k = 1; int maxLabel = linked.Distinct ().Count ()-1; int[] newLabels = new int[maxLabel+1]; int index = 1; while (linked[k]!=0) { bool isFound = false; for (int i = 1; i <= index-1; i++) { if(linked[k] == newLabels[i] && linked[k]!=0){ linked[k] = i; isFound = true; } } if(!isFound) { newLabels[index] = linked[k]; linked[k] = index; index++; } k++; } for (int j = 0; j < h; j++) { for(int i = 0; i < w; i++){ labels[j,i] = linked[labels[j,i]]; } } /* for (int j = 0; j < h; j++) { for(int i = 0; i < w; i++){ if(labels[j,i] != 0){ pixels[j*w+i].r = (byte)((255 * labels[j,i] / maxLabel)%256); pixels[j*w+i].b = (byte)(255-pixels[j*w+i].r); pixels[j*w+i].g = (byte)((pixels[j*w+i].r+pixels[j*w+i].b)/2); } } } */ Rect[] blobRect = new Rect[maxLabel]; for (int i = 0; i < maxLabel; i++) { blobRect[i] = new Rect(w,h,0,0); } for (int j = 0; j < h; j++) { for(int i = 0; i < w; i++){ if(labels[j,i] != 0){ for(int lb = 0; lb < maxLabel; lb++){ if(labels[j,i]-1 == lb){ if(i < blobRect[lb].x) blobRect[lb].x = i; if(i > blobRect[lb].width) blobRect[lb].width = i; if(j < blobRect[lb].y) blobRect[lb].y = j; if(j > blobRect[lb].height) blobRect[lb].height = j; } } } } } List<Tuple<int,int>> order = new List<Tuple<int, int>> (); for (int i = 0; i < blobRect.Length; i++) { order.Add(Tuple.Create(i+1, (int)blobRect[i].x)); } order = order.OrderBy (i => i.Item2).ToList(); blobRect = blobRect.OrderBy(i => i.x).ToArray(); List<RawTexture2D> blobs = new List<RawTexture2D> (); for (int i = 0; i < maxLabel; i++) { int blobX = (int)blobRect[i].x; int blobY = (int)blobRect[i].y; int blobW = (int)(blobRect[i].width - blobRect[i].x + 1); int blobH = (int)(blobRect[i].height - blobRect[i].y + 1); if(blobW*blobH>9){ RawTexture2D rawTexture = new RawTexture2D(blobW, blobH); for(int yy=0; yy < blobH; yy++){ for(int xx=0; xx<blobW; xx++){ rawTexture.pixels[yy*blobW+xx] = labels[blobY+yy, blobX+xx] == order[i].Item1 ? Color.black : Color.white; } } blobs.Add(rawTexture); } } return blobs; }