Esempio n. 1
0
    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;
    }