예제 #1
0
        public unsafe int LabelIpp(IntPtr src, int bw, int bh, int stride, bool connectivity_4or8)
        {
            var matSrc = new Mat(bh, bw, MatType.CV_8UC1, src, stride);

            // label 버퍼
            this.Labels = new Mat(bw, bw, MatType.CV_32SC1, Scalar.All(0));


            int numLabels = 0;

            numLabels = IpDll.LabelMarker(src, (IntPtr)Labels.DataPointer, bw, bh, connectivity_4or8);

            // 4. 데이터 추출
            var blobs = this.Blobs;

            blobs.Clear();
            for (int i = 0; i < numLabels; i++)
            {
                int label = i + 1;
                blobs[label] = new MyBlob(label);
            }

            // labels 수정
            for (int y = 0; y < bh; y++)
            {
                int *plabel = (int *)Labels.Ptr(y);
                for (int x = 0; x < bw; x++, plabel++)
                {
                    var label = *plabel;
                    if (label == 0)
                    {
                        continue;
                    }

                    var blob = blobs[label];
                    blob.area++;
                    blob.centroidX += x;
                    blob.centroidY += y;
                    if (x < blob.MinX)
                    {
                        blob.MinX = x;
                    }
                    if (y < blob.MinY)
                    {
                        blob.MinY = y;
                    }
                    if (x > blob.MaxX)
                    {
                        blob.MaxX = x;
                    }
                    if (y > blob.MaxY)
                    {
                        blob.MaxY = y;
                    }
                }
            }

            foreach (var blob in this.Blobs.Values)
            {
                blob.centroidX /= blob.area;
                blob.centroidY /= blob.area;
            }

            return(numLabels);
        }
예제 #2
0
        public int LabelIpp(IntPtr src, int bw, int bh, int stride)
        {
            Glb.TimerStart();
            // prepare
            byte *psrc = (byte *)src.ToPointer();

            // label 버퍼
            this.Labels = new int[bw * bh];
            this.bw     = bw;
            this.bh     = bh;

            Console.WriteLine($"=> 1. Prepare buffer time: {Glb.TimerStop()}ms");

            Glb.TimerStart();
            int numLabels = 0;

            fixed(int *pLabels = Labels)
            {
                numLabels = IpDll.LabelMarker(src, (IntPtr)pLabels, bw, bh);
            }

            Console.WriteLine($"=> 2. IpDll.LabelMarker time: {Glb.TimerStop()}ms");

            // 4. 데이터 추출
            Glb.TimerStart();
            var blobs = this.Blobs;

            blobs.Clear();
            for (int i = 0; i < numLabels; i++)
            {
                int label = i + 1;
                blobs[label] = new MyBlob(label);
            }

            // labels 수정
            for (int y = 0; y < bh; y++)
            {
                for (int x = 0; x < bw; x++)
                {
                    var label = this.Labels[bw * y + x];
                    if (label == 0)
                    {
                        continue;
                    }

                    var blob = blobs[label];
                    blob.area++;
                    blob.centroidX += x;
                    blob.centroidY += y;
                    if (x < blob.MinX)
                    {
                        blob.MinX = x;
                    }
                    if (y < blob.MinY)
                    {
                        blob.MinY = y;
                    }
                    if (x > blob.MaxX)
                    {
                        blob.MaxX = x;
                    }
                    if (y > blob.MaxY)
                    {
                        blob.MaxY = y;
                    }
                }
            }

            foreach (var blob in this.Blobs.Values)
            {
                blob.centroidX /= blob.area;
                blob.centroidY /= blob.area;
            }
            Console.WriteLine($"=> 3. 데이터 추출 time: {Glb.TimerStop()}ms");

            return(numLabels);
        }
예제 #3
0
        public int Label(IntPtr src, int bw, int bh, int stride, bool connectivity_4or8)
        {
            var matSrc = new Mat(bh, bw, MatType.CV_8UC1, src, stride);

            // label 버퍼
            this.Labels = new Mat(bw, bw, MatType.CV_32SC1, Scalar.All(0));

            // link 테이블
            int[] links     = new int[bw * bh];
            int   linkCount = 1;

            // 1st stage
            // labeling with scan
            int[] nbrs = new int[4];
            for (int y = 0; y < bh; y++)
            {
                byte *ps     = (byte *)matSrc.Ptr(y);
                int * plabel = (int *)Labels.Ptr(y);
                for (int x = 0; x < bw; x++, ps++, plabel++)
                {
                    // 배경이면 skip
                    if (*ps == 0)
                    {
                        continue;
                    }

                    // 주변 4개의 label버퍼 조사 (l, tl, t, tr)
                    int nbrCount = 0;
                    int checkLabel;
                    if (x != 0)
                    {
                        // check left
                        checkLabel = plabel[-1];
                        if (checkLabel != 0)
                        {
                            nbrs[nbrCount++] = checkLabel;
                        }
                    }
                    if (y != 0)
                    {
                        // check top
                        checkLabel = plabel[-bw];
                        if (checkLabel != 0)
                        {
                            nbrs[nbrCount++] = checkLabel;
                        }
                        if (connectivity_4or8 == false)
                        {
                            if (x != 0)
                            {
                                // check lt
                                checkLabel = plabel[-bw - 1];
                                if (checkLabel != 0)
                                {
                                    nbrs[nbrCount++] = checkLabel;
                                }
                            }
                            if (x != bw - 1)
                            {
                                // check rt
                                checkLabel = plabel[-bw + 1];
                                if (checkLabel != 0)
                                {
                                    nbrs[nbrCount++] = checkLabel;
                                }
                            }
                        }
                    }

                    if (nbrCount == 0)
                    {
                        // 주변에 없다면 새번호 생성하고 라벨링
                        int newLabel = linkCount;
                        *   plabel   = newLabel;
                        // link 테이블에 새 루트 라벨 추가
                        links[linkCount] = 0;
                        linkCount++;
                    }
                    else
                    {
                        // 주변에 있다면 주변 라벨들의 루트중 최소라벨
                        int minLabel = nbrs[0];
                        while (links[minLabel] != 0)
                        {
                            minLabel = links[minLabel];
                        }
                        for (int i = 0; i < nbrCount; i++)
                        {
                            var label = nbrs[i];
                            while (links[label] != 0)
                            {
                                label = links[label];
                            }
                            if (label < minLabel)
                            {
                                minLabel = label;
                            }
                        }
                        *plabel = minLabel;
                        // link 테이블에서 주변 라벨의 parent 수정
                        for (int i = 0; i < nbrCount; i++)
                        {
                            int label = nbrs[i];
                            // 라벨이 min라벨이 아니라면 라벨의 link를 minlabel로 바꿈
                            // 이전 link가 0이 아니라면 이전 link의 link도 minlabel로 바꿈
                            while (label != minLabel)
                            {
                                var oldLink = links[label];
                                links[label] = minLabel;
                                if (oldLink == 0)
                                {
                                    break;
                                }
                                label = oldLink;
                            }
                        }
                    }
                }
            }

            // 2nd stage
            // links 수정
            for (int i = 0; i < linkCount; i++)
            {
                if (links[i] == 0)
                {
                    continue;
                }

                int label = links[i];
                while (links[label] != 0)
                {
                    label = links[label];
                }
                links[i] = label;
            }

            // labels 수정
            for (int y = 0; y < bh; y++)
            {
                int *plabel = (int *)Labels.Ptr(y);
                for (int x = 0; x < bw; x++, plabel++)
                {
                    int label = *plabel;
                    if (label == 0)
                    {
                        continue;
                    }
                    var link = links[label];
                    if (link == 0)
                    {
                        continue;
                    }
                    *plabel = link;
                }
            }


            // 3. 후처리
            // link index 수정
            Dictionary <int, int> relabelTable = new Dictionary <int, int>();
            int newIndex = 1;

            for (int i = 1; i < linkCount; i++)
            {
                var link = links[i];
                if (link == 0)
                {
                    relabelTable.Add(i, newIndex++);
                }
            }

            // 4. 데이터 추출
            var blobs = this.Blobs;

            blobs.Clear();
            foreach (var newLable in relabelTable.Values)
            {
                blobs[newLable] = new MyBlob(newLable);
            }

            // labels 수정
            for (int y = 0; y < bh; y++)
            {
                int *plabel = (int *)Labels.Ptr(y);
                for (int x = 0; x < bw; x++, plabel++)
                {
                    var label = *plabel;
                    if (label == 0)
                    {
                        continue;
                    }

                    int newLabel = relabelTable[label];
                    *   plabel   = newLabel;

                    var blob = blobs[newLabel];
                    blob.area++;
                    blob.centroidX += x;
                    blob.centroidY += y;
                    if (x < blob.MinX)
                    {
                        blob.MinX = x;
                    }
                    if (y < blob.MinY)
                    {
                        blob.MinY = y;
                    }
                    if (x > blob.MaxX)
                    {
                        blob.MaxX = x;
                    }
                    if (y > blob.MaxY)
                    {
                        blob.MaxY = y;
                    }
                }
            }

            foreach (var blob in this.Blobs.Values)
            {
                blob.centroidX /= blob.area;
                blob.centroidY /= blob.area;
            }

            return(Blobs.Count);
        }
예제 #4
0
        public int Label(IntPtr src, int bw, int bh, int stride)
        {
            Glb.TimerStart();
            // prepare
            byte *psrc = (byte *)src.ToPointer();

            // label 버퍼
            this.Labels = new int[bw * bh];
            this.bw     = bw;
            this.bh     = bh;

            // link 테이블
            int[] links     = new int[bw * bh];
            int   linkCount = 1;

            Console.WriteLine($"=> 1. Prepare buffer time: {Glb.TimerStop()}ms");

            Glb.TimerStart();
            // 1st stage
            // labeling with scan
            int[] nbrs = new int[4];
            for (int y = 0; y < bh; y++)
            {
                for (int x = 0; x < bw; x++)
                {
                    // 배경이면 skip
                    if (psrc[stride * y + x] == 0)
                    {
                        continue;
                    }

                    // 주변 4개의 label버퍼 조사 (l, tl, t, tr)
                    int nbrCount = 0;
                    int checkLabel;
                    if (x != 0)
                    {
                        // check left
                        checkLabel = Labels[bw * y + x - 1];
                        if (checkLabel != 0)
                        {
                            nbrs[nbrCount++] = checkLabel;
                        }
                    }
                    if (y != 0)
                    {
                        // check top
                        checkLabel = Labels[bw * (y - 1) + x];
                        if (checkLabel != 0)
                        {
                            nbrs[nbrCount++] = checkLabel;
                        }
                        if (x != 0)
                        {
                            // check lt
                            checkLabel = Labels[bw * (y - 1) + x - 1];
                            if (checkLabel != 0)
                            {
                                nbrs[nbrCount++] = checkLabel;
                            }
                        }
                        if (x != bw - 1)
                        {
                            // check rt
                            checkLabel = Labels[bw * (y - 1) + x + 1];
                            if (checkLabel != 0)
                            {
                                nbrs[nbrCount++] = checkLabel;
                            }
                        }
                    }

                    if (nbrCount == 0)
                    {
                        // 주변에 없다면 새번호 생성하고 라벨링
                        int newLabel = linkCount;
                        Labels[bw * y + x] = newLabel;
                        // link 테이블에 새 루트 라벨 추가
                        links[linkCount] = 0;
                        linkCount++;
                    }
                    else
                    {
                        // 주변에 있다면 주변 라벨들의 루트중 최소라벨
                        int minLabel = nbrs[0];
                        while (links[minLabel] != 0)
                        {
                            minLabel = links[minLabel];
                        }
                        for (int i = 0; i < nbrCount; i++)
                        {
                            var label = nbrs[i];
                            while (links[label] != 0)
                            {
                                label = links[label];
                            }
                            if (label < minLabel)
                            {
                                minLabel = label;
                            }
                        }
                        Labels[bw * y + x] = minLabel;
                        // link 테이블에서 주변 라벨의 parent 수정
                        for (int i = 0; i < nbrCount; i++)
                        {
                            int label = nbrs[i];
                            // 라벨이 min라벨이 아니라면 라벨의 link를 minlabel로 바꿈
                            // 이전 link가 0이 아니라면 이전 link의 link도 minlabel로 바꿈
                            while (label != minLabel)
                            {
                                var oldLink = links[label];
                                links[label] = minLabel;
                                if (oldLink == 0)
                                {
                                    break;
                                }
                                label = oldLink;
                            }
                        }
                    }
                }
            }
            Console.WriteLine($"=> 2. 1st labelling time: {Glb.TimerStop()}ms");

            // 2nd stage
            // links 수정
            Glb.TimerStart();
            for (int i = 0; i < linkCount; i++)
            {
                if (links[i] == 0)
                {
                    continue;
                }

                int label = links[i];
                while (links[label] != 0)
                {
                    label = links[label];
                }
                links[i] = label;
            }
            Console.WriteLine($"=> 3. link 수정 time: {Glb.TimerStop()}ms");

            // labels 수정
            Glb.TimerStart();
            for (int y = 0; y < bh; y++)
            {
                for (int x = 0; x < bw; x++)
                {
                    int label = Labels[bw * y + x];
                    if (label == 0)
                    {
                        continue;
                    }
                    var link = links[label];
                    if (link == 0)
                    {
                        continue;
                    }
                    Labels[bw * y + x] = link;
                }
            }
            Console.WriteLine($"=> 4. labels 수정 time: {Glb.TimerStop()}ms");


            // 3. 후처리
            // link index 수정
            Glb.TimerStart();
            Dictionary <int, int> relabelTable = new Dictionary <int, int>();
            int newIndex = 1;

            for (int i = 1; i < linkCount; i++)
            {
                var link = links[i];
                if (link == 0)
                {
                    relabelTable.Add(i, newIndex++);
                }
            }
            Console.WriteLine($"=> 5. link index 수정 time: {Glb.TimerStop()}ms");

            // 4. 데이터 추출
            Glb.TimerStart();
            var blobs = this.Blobs;

            blobs.Clear();
            foreach (var newLable in relabelTable.Values)
            {
                blobs[newLable] = new MyBlob(newLable);
            }
            int labeledCount = 0;

            // labels 수정
            for (int y = 0; y < bh; y++)
            {
                for (int x = 0; x < bw; x++)
                {
                    var label = Labels[bw * y + x];
                    if (label == 0)
                    {
                        continue;
                    }

                    labeledCount++;

                    int newLabel = relabelTable[label];
                    Labels[bw * y + x] = newLabel;

                    var blob = blobs[newLabel];
                    blob.area++;
                    blob.centroidX += x;
                    blob.centroidY += y;
                    if (x < blob.MinX)
                    {
                        blob.MinX = x;
                    }
                    if (y < blob.MinY)
                    {
                        blob.MinY = y;
                    }
                    if (x > blob.MaxX)
                    {
                        blob.MaxX = x;
                    }
                    if (y > blob.MaxY)
                    {
                        blob.MaxY = y;
                    }
                }
            }

            foreach (var blob in this.Blobs.Values)
            {
                blob.centroidX /= blob.area;
                blob.centroidY /= blob.area;
            }
            Console.WriteLine($"=> 6. 데이터 추출 time: {Glb.TimerStop()}ms");

            return(labeledCount);
        }