예제 #1
0
        public void ReadLeftSide(RawOutline pathW, bool topDown)
        {
            //read once
            if (_leftSideChecked)
            {
                throw new System.NotSupportedException();
            }

            _leftSideChecked = true;

            if (topDown)
            {
                int count = _spanList.Count;

                RawOutline.BeginLoadSegmentPoints(pathW);
                for (int i = 0; i < count; ++i)
                {
                    HSpan span = _spanList[i];
                    pathW.AppendPoint(span.startX, span.y);
                }
                RawOutline.EndLoadSegmentPoints(pathW);
            }
            else
            {
                RawOutline.BeginLoadSegmentPoints(pathW);
                for (int i = _spanList.Count - 1; i >= 0; --i)
                {
                    HSpan span = _spanList[i];
                    pathW.AppendPoint(span.startX, span.y);
                }
                RawOutline.EndLoadSegmentPoints(pathW);
            }
        }
예제 #2
0
        HSpan[] SortAndCollectHSpans()
        {
            int spanSort(HSpan sp1, HSpan sp2)
            {
                //NESTED METHOD
                //sort  asc,
                if (sp1.y > sp2.y)
                {
                    return(1);
                }
                else if (sp1.y < sp2.y)
                {
                    return(-1);
                }
                else
                {
                    return(sp1.startX.CompareTo(sp2.startX));
                }
            }

            //1.
            _upperSpans.Sort(spanSort);
            _lowerSpans.Sort(spanSort);

            HSpan[] hspans = new HSpan[_upperSpans.Count + _lowerSpans.Count];
            _upperSpans.CopyTo(hspans);
            _lowerSpans.CopyTo(hspans, _upperSpans.Count);

            //clear
            _upperSpans.Clear();
            _lowerSpans.Clear();

            return(hspans);
        }
예제 #3
0
        HSpanColumn FindTouchColumn(HSpan newspan, ref int colIndex)
        {
            for (int i = colIndex; i < _hSpanColumns.Length; ++i)
            {
                HSpanColumn col = _hSpanColumns[i];
                if (col.BottomSideTouchWith(newspan.y, newspan.startX, newspan.endX))
                {
                    //found
                    colIndex = i;
                    return(col);
                }
            }
            //----

            if (colIndex > 0)
            {
                //we didn't start from the first
                for (int i = 0; i < colIndex; ++i)
                {
                    HSpanColumn col = _hSpanColumns[i];
                    if (col.BottomSideTouchWith(newspan.y, newspan.startX, newspan.endX))
                    {
                        //found
                        colIndex = i;
                        return(col);
                    }
                }
            }

            //not found
            return(null);
        }
예제 #4
0
 public void AddHSpan(HSpan span)
 {
     _spanList.Add(span);
     XLeftBottom  = span.startX;
     XRightBottom = span.endX;
     YBottom      = span.y + 1;
 }
예제 #5
0
 void AddHSpan(HSpan hspan)
 {
     if (hspan.y >= _yCutAt)
     {
         _lowerSpans.Add(hspan);
     }
     else
     {
         _upperSpans.Add(hspan);
     }
 }
예제 #6
0
        public HSpan[] InternalFill(IPixelEvaluator pixelEvalutor, int x, int y, bool collectHSpans)
        {
            _pixelEvalutor = pixelEvalutor;
            _yCutAt        = y;
            //set cut-point
            if (collectHSpans)
            {
                _upperSpans.Clear();
                _lowerSpans.Clear();
            }

            int imgW = pixelEvalutor.OrgBitmapWidth;
            int imgH = pixelEvalutor.OrgBitmapHeight;

            //reset new buffer, clear mem?
            _pixelsChecked = new bool[imgW * imgH];
            //***
            pixelEvalutor.SetStartPos(x, y);
            TryLinearFill(x, y);

            while (_hspanQueue.Count > 0)
            {
                HSpan hspan = _hspanQueue.Dequeue();
                if (collectHSpans)
                {
                    AddHSpan(hspan);
                }
                int downY           = hspan.y - 1;
                int upY             = hspan.y + 1;
                int downPixelOffset = (imgW * (hspan.y - 1)) + hspan.startX;
                int upPixelOffset   = (imgW * (hspan.y + 1)) + hspan.startX;

                for (int rangeX = hspan.startX; rangeX < hspan.endX; rangeX++)
                {
                    if (hspan.y > 0 && !_pixelsChecked[downPixelOffset])
                    {
                        TryLinearFill(rangeX, downY);
                    }
                    if (hspan.y < (imgH - 1) && !_pixelsChecked[upPixelOffset])
                    {
                        TryLinearFill(rangeX, upY);
                    }
                    upPixelOffset++;
                    downPixelOffset++;
                }
            }

            //reset
            _hspanQueue.Clear();
            _pixelEvalutor = null;

            return(collectHSpans ? SortAndCollectHSpans() : null);
        }
예제 #7
0
        /// <summary>
        /// check if the bottom side of this group touch with specific range
        /// </summary>
        /// <param name="lowerGroupTopLeft"></param>
        /// <param name="lowerGroupTopRight"></param>
        /// <returns></returns>
        public bool BottomSideTouchWith(int lowerGroupTop, int lowerGroupTopLeft, int lowerGroupTopRight)
        {
            //[     THIS group    ]
            //---------------------
            //[ other (lower)group]


            return((lowerGroupTop != this.YBottom) ?
                   false :
                   HSpan.HorizontalTouchWith(
                       XLeftBottom, XRightBottom,
                       lowerGroupTopLeft, lowerGroupTopRight));
        }
예제 #8
0
        public void Separate(HSpan[] hspans)
        {
            int count = hspans.Length;

            if (count == 0)
            {
                return;
            }

            int startCollectIndex = 0;
            int colCount          = 0;

            _lastestLine = hspans[0].y;

            for (int i = 0; i < count; ++i)
            {
                HSpan sp       = hspans[i];
                int   lineDiff = sp.y - _lastestLine;
                switch (lineDiff)
                {
                case 1:
                {
                    //go next lower line
                    //flush current collected columns
                    FlushCollectedColumns(hspans, startCollectIndex, colCount);
                    //
                    startCollectIndex = i;
                    colCount          = 1;
                    _lastestLine      = sp.y;
                }
                break;

                case 0:
                {
                    //sameline
                    colCount++;
                }
                break;

                default:
                    throw new System.NotSupportedException();
                }
            }

            if (startCollectIndex < count - 1)
            {
                //flush remaining
                FlushCollectedColumns(hspans, startCollectIndex, colCount);
            }
        }
예제 #9
0
        /// <summary>
        /// check if the top side of this group touch with specific range)
        /// </summary>
        /// <param name="upperBottomLeft"></param>
        /// <param name="upperBottomRight"></param>
        /// <returns></returns>
        public bool TopSideTouchWith(int upperBottom, int upperBottomLeft, int upperBottomRight)
        {
            //[ other (lower)group]
            //---------------------
            //[     THIS group    ]

            //find the first column that its top side touch with
            //another uppper group

            return((upperBottom != this.YTop) ?
                   false :
                   HSpan.HorizontalTouchWith(
                       XLeftTop, XRightTop,
                       upperBottomLeft, upperBottomRight));
        }
예제 #10
0
        PixelFarm.Drawing.Rectangle FindTotalRectBoundsFromHSpans()
        {
            HSpan[] hspans = HSpans;
            if (hspans == null)
            {
                throw new System.NotSupportedException();
            }


            int left   = int.MaxValue;
            int right  = int.MinValue;
            int top    = int.MaxValue;
            int bottom = int.MinValue;

            for (int i = 0; i < hspans.Length; ++i)
            {
                HSpan span      = hspans[i];
                int   sp_bottom = span.y + 1;

                if (sp_bottom > bottom)
                {
                    bottom = sp_bottom;
                }

                if (span.y < top)
                {
                    top = span.y;
                }
                //

                if (span.startX < left)
                {
                    left = span.startX;
                }

                if (span.endX > right)
                {
                    right = span.endX;
                }
            }

            return(new Drawing.Rectangle(left, top, right - left, bottom - top));
        }
예제 #11
0
        public bool AddHSpans(HSpan[] hspans, int startIndex, int count)
        {
            int index = startIndex;

            //we must ...
            //1. touch one by one
            //and 2. no overlaped column
            for (int i = 0; i < _hSpanColumns.Length; ++i)
            {
                HSpanColumn col   = _hSpanColumns[i];
                HSpan       hspan = hspans[index];
                if (!col.BottomSideTouchWith(hspan.y, hspan.startX, hspan.endX))
                {
                    //found some 'untouch column'
                    //break all
                    //need another vertical group
                    return(false);
                }
                else if (i > 0 && _hSpanColumns[i - 1].BottomSideTouchWith(hspan.y, hspan.startX, hspan.endX))
                {
                    //see Test/Data/lion_1_v3_2.png for example
                    //check if current hspan dose not touch with prev column
                    //in this case => start a new column
                    return(false);
                }
                index++;
            }
            //---
            //pass all
            index = startIndex; //reset
            for (int i = 0; i < _hSpanColumns.Length; ++i)
            {
                HSpanColumn col = _hSpanColumns[i];
                col.AddHSpan(hspans[index]);
                index++;
            }
            return(true);
        }
예제 #12
0
        public void EvaluateCorners()
        {
#if DEBUG
            dbugEvalCorners = true;
#endif
            //the column may not be rectangle shape ***
            if (_spanList.Count == 0)
            {
                //??
                throw new System.NotSupportedException();
            }
            //..

            HSpan hspan = _spanList[0];
            XLeftTop  = hspan.startX;
            XRightTop = hspan.endX;
            YTop      = hspan.y;

            hspan        = _spanList[_spanList.Count - 1];
            XLeftBottom  = hspan.startX;
            XRightBottom = hspan.endX;
            YBottom      = hspan.y + 1;//***
        }
예제 #13
0
        public static CpuBlit.MemBitmap CreateMaskBitmap(this ReconstructedRegionData rgnData,
                                                         Drawing.Color solidPartColor,
                                                         Drawing.Color holeColor,
                                                         bool useFitBounds = true)
        {
            //1. find size of membitmap
            Drawing.Rectangle fitBounds = rgnData.GetBounds();
            //2. fit bounds or not
            int bmpW, bmpH, offsetX, offsetY;

            if (useFitBounds)
            {
                bmpW    = fitBounds.Width;
                bmpH    = fitBounds.Height;
                offsetX = -fitBounds.X;
                offsetY = -fitBounds.Y;
            }
            else
            {
                bmpW    = fitBounds.Left + fitBounds.Right;
                bmpH    = fitBounds.Top + fitBounds.Height;
                offsetX = 0;
                offsetY = 0;
            }

            //3. create mask bmp
            MemBitmap maskBmp = new MemBitmap(bmpW, bmpH);

            //4. fill mask data
            maskBmp.Clear(solidPartColor);

            int holdColorInt32 =
                (holeColor.A << CO.A_SHIFT) |
                (holeColor.B << CO.B_SHIFT) |
                (holeColor.G << CO.G_SHIFT) |
                (holeColor.R << CO.R_SHIFT);

            var memPtr = MemBitmap.GetBufferPtr(maskBmp);

            unsafe
            {
                int *buffer = (int *)memPtr.Ptr;
                //fill
                HSpan[] hspans = rgnData.HSpans;
                if (useFitBounds)
                {
                    int totalBufferLen = bmpW * bmpH;

                    for (int i = 0; i < hspans.Length; ++i)
                    {
                        HSpan span = hspans[i];
                        int   len  = span.endX - span.startX;

#if DEBUG
                        int offset = ((span.y + offsetY) * bmpW + (span.startX + offsetX));
                        if (offset >= totalBufferLen || offset + len > totalBufferLen)
                        {
                            throw new System.Exception("out-of-range");
                            break;
                        }
                        else if (offset < 0 || offset + len < 0)
                        {
                        }
#endif

                        int *pixAddr = buffer + ((span.y + offsetY) * bmpW + (span.startX + offsetX)); //with offsetX,offsetY

                        for (int n = len - 1; n >= 0; --n)
                        {
                            *pixAddr = holdColorInt32;
                            pixAddr++;
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < hspans.Length; ++i)
                    {
                        HSpan span = hspans[i];
                        int   len  = span.endX - span.startX;

                        int *pixAddr = buffer + ((span.y) * bmpW + (span.startX)); //no offsetX,offsetY

                        for (int n = len - 1; n >= 0; --n)
                        {
                            *pixAddr = holdColorInt32;
                            pixAddr++;
                        }
                    }
                }
            }

            //return null;
            return(maskBmp);
        }