Пример #1
0
 private unsafe void DoMagicWand(BitmapData pdata, Point startPoint, byte tolerance, bool isContinued,
                                 Action <int, int, int> segmentAction, Action regionAction)
 {
     CheckArgBandFillFields(pdata, tolerance, startPoint);
     _visitedPixels = new StatusRecorder(_width * pdata.Height);
     if (isContinued)
     {
         _seeds.Enqueue(startPoint.Y * _width + startPoint.X);
         FloodFill(segmentAction);
         if (regionAction != null)
         {
             regionAction();
         }
     }
     else
     {
         int   count = _width * _height;
         byte *ptr;
         for (int i = 0; i < count; i++)
         {
             if (_visitedPixels.IsTrue(i))
             {
                 continue;
             }
             ptr = (byte *)_scan0 + (i / _width) * _stride + (i % _width) * _pixelWidth;
             if (ColorIsMatched(ptr))
             {
                 _seeds.Enqueue(i);
                 FloodFill(segmentAction);
                 if (regionAction != null)
                 {
                     regionAction();
                 }
             }
             else
             {
                 _visitedPixels.SetStatus(i, true);
             }
         }
     }
 }
Пример #2
0
        public static int[] Reversal(int[] aoi, Size size)
        {
            int            count    = size.Width * size.Height;
            StatusRecorder status   = new StatusRecorder(count);
            int            aoiCount = aoi.Length;

            for (int i = 0; i < aoiCount; i++)
            {
                status.SetStatus(aoi[i], true);
            }
            List <int> retAOI = new List <int>(count - aoiCount);

            for (int i = 0; i < count; i++)
            {
                if (!status.IsTrue(i))
                {
                    retAOI.Add(i);
                }
            }
            return(retAOI.Count > 0 ? retAOI.ToArray() : null);
        }
Пример #3
0
        private unsafe void FloodFill(Action <int, int, int> segmentAction)
        {
            int   oRow = 0;
            int   oCol = 0;
            byte *ptr0 = (byte *)_scan0;
            byte *oPtr = ptr0;
            byte *ptr;
            int   bCol = 0, eCol = 0;
            int   seedIdx = 0;

            while (_seeds.Count > 0)
            {
                int oSeedIdx = _seeds.Dequeue();
                if (_visitedPixels.IsTrue(oSeedIdx))
                {
                    continue;
                }
                oRow = oSeedIdx / _width;
                oCol = oSeedIdx % _width;
                oPtr = ptr0 + oRow * _stride + oCol * _pixelWidth;
                //临界像元标记
                bool isCriticalPixel = true;
                bool isEnd           = false;
                //—> left
                bCol = oCol;
                if (oCol > 0)
                {
                    ptr     = oPtr;
                    seedIdx = oSeedIdx;
                    Dec(ref bCol, ref ptr, ref seedIdx);
                    isEnd = IsToLeftBorder(ptr, bCol);
                    while (!isEnd)
                    {
                        HitPixel(seedIdx, ptr);
                        Dec(ref bCol, ref ptr, ref seedIdx);
                        isEnd           = IsToLeftBorder(ptr, bCol);
                        isCriticalPixel = false;
                    }
                    Inc(ref bCol, ref ptr, ref seedIdx);
                    if (isCriticalPixel)
                    {
                        HitPixel(seedIdx, ptr);
                    }
                    //for debug
                    //if (bCol > 0)
                    //    HitColorGreen(ptr - _pixelWidth);
                }
                //—> right
                eCol = oCol;
                if (oCol < _width - 1)
                {
                    isCriticalPixel = true;
                    ptr             = oPtr;
                    seedIdx         = oSeedIdx;
                    Inc(ref eCol, ref ptr, ref seedIdx);
                    isEnd = IsToRightBorder(ptr, eCol);
                    while (!isEnd)
                    {
                        HitPixel(seedIdx, ptr);
                        Inc(ref eCol, ref ptr, ref seedIdx);
                        isEnd           = IsToRightBorder(ptr, eCol);
                        isCriticalPixel = false;
                    }
                    Dec(ref eCol, ref ptr, ref seedIdx);
                    if (isCriticalPixel)
                    {
                        HitPixel(seedIdx, ptr);
                    }
                    //for debug
                    //if (eCol < _width - 1)
                    //    HitColorGreen(ptr + _pixelWidth);
                }
                //
                HitPixel(oSeedIdx, oPtr);
                //
                if (segmentAction != null)
                {
                    segmentAction(oRow, bCol, eCol);
                }
                //—> up
                if (oRow > 0)
                {
                    UpDownMoveRow(bCol, eCol, oRow, -1, ptr0);
                }
                //—> down
                if (oRow < _height - 1)
                {
                    UpDownMoveRow(bCol, eCol, oRow, 1, ptr0);
                }
                //
                if (!_visitedPixels.IsTrue(oSeedIdx))
                {
                    _visitedPixels.SetStatus(oSeedIdx, true);
                }
            }
        }