0

CCL アルゴリズムの 2 番目のパスを高速化する方法についてアドバイスが必要です。最初のパスには数ミリ秒しかかかりませんが、2 番目のパスには数秒かかります。同値テーブルを最適化するか、ポインターを使用するために何度か試みましたが、2 回目のパスは常に非常に低速です。アドバイスをありがとう

       Bitmap bmp = null;

        unsafe
        {
            int stride = _alg.MIplImage.widthStep;
            byte* ptr = (byte*)_alg.MIplImage.imageData;
            byte[] prevRow = new byte[_alg.Cols];

            //First pass
            for (int i = 1; i < _alg.Rows; i++)
            {
                for (int j = 1; j < _alg.Cols; j++)
                {
                    //White pixels only
                    if ((byte)ptr[j] == 255)
                    {
                        //8-connected
                        byte[] array = new byte[4] { ptr[j - 1], prevRow[j - 1], prevRow[j], prevRow[j + 1] };
                        //New Label
                        if (array.All(x => x == 0))
                        {
                            ptr[j] = _color;
                            prevRow[j] = ptr[j];
                            _color++;
                            continue;
                        }

                        byte max = array.Max();
                        byte min = array.Where(f => f > 0).Min();

                        //color dispute
                        if (max != min)
                        {
                            ptr[j] = min;

                            if (_prevMax != max)
                            {   
                                _fromToD.Add(max, min);   //Add to equvalence table
                                _prevMax = max;
                            }

                        }
                        else if (max == min)   //Same color
                        {
                            ptr[j] = min;
                        }
                    }

                    prevRow[j] = ptr[j];   //Aktualize previous row

                }

                ptr += stride;
            }

            //To this section, about 16 ms
            //second pass

            //byte* p = (byte*)(void*)bmData.Scan0.ToPointer();
            //int stopAddress = (int)p + bmData.Stride * bmData.Height;

            //while ((int)p != stopAddress)
            //{
            //    foreach (KeyValuePair<byte, byte> pair in _fromToD)
            //    {
            //        if (p[0] == pair.Key)
            //        {
            //            p[0] = pair.Value;
            //        }
            //    }
            //    p++;
            //}

            //bmp.UnlockBits(bmData);
            //About 3 sec
4

1 に答える 1