예제 #1
0
        public RectangleArea GetDimensionArea(RegionVO region)
        {
            RectangleArea result = new RectangleArea(short.MaxValue, short.MaxValue, short.MinValue, short.MinValue);

            for (int i = 0; i < region.Pixels.Length; i++)
            {
                int pixelIndex = region.Pixels[i];
                var(x, y) = Get_XY(pixelIndex);

                if (result.X > x)
                {
                    result.X = x;
                }
                if (result.X2 < x)
                {
                    result.X2 = x;
                }
                if (result.Y > y)
                {
                    result.Y = y;
                }
                if (result.Y2 < y)
                {
                    result.Y2 = y;
                }
            }

            return(result);
        }
예제 #2
0
        private static List <RegionVO> Helper_GetMergedNeighbours2(RegionVO destRegion, RegionVO forFuseRegion)
        {
            //List<RegionVO> neighbours = new List<RegionVO>();
            neighbours.Clear();

            //HashSet<RegionVO> neighbours = new HashSet<RegionVO>();
            foreach (var item in destRegion.NeighbourRegions)
            {
                if (item != destRegion && item != forFuseRegion)
                {
                    if (neighbours.IndexOf(item) < 0)
                    {
                        neighbours.Add(item);
                    }
                }
            }

            foreach (var item in forFuseRegion.NeighbourRegions)
            {
                if (item != destRegion && item != forFuseRegion)
                {
                    if (neighbours.IndexOf(item) < 0)
                    {
                        neighbours.Add(item);
                    }
                }
            }


            return(neighbours);
        }
예제 #3
0
        /// <summary>
        /// slouci dva regiony
        /// dest region = k nemu jsou pridany pixely ze slucovaneho
        /// </summary>
        /// <param name="destRegion"></param>
        /// <param name="forFuseRegion"></param>
        private void FuseRegions(RegionVO destRegion, RegionVO forFuseRegion, CanvasPixel canvasPixel)
        {
            Pixel finalColor = new Pixel();

            //finalColor = destRegion.Color;
            //finalColor = Pixel.Average(destRegion.Color, forFuseRegion.Color);
            finalColor = Pixel.Average(destRegion.Color, destRegion.Pixels.Length, forFuseRegion.Color, forFuseRegion.Pixels.Length);



            foreach (var item in destRegion.Pixels)
            {
                canvasPixel.Data[item] = finalColor;
                destRegion.Color       = finalColor;
            }

            List <int> dPixels = destRegion.Pixels.ToList();

            Pixel[] cpData = canvasPixel.Data;

            foreach (var item in forFuseRegion.Pixels)
            {
                dPixels.Add(item);
                // reassign region
                _regionPixelLookup[item] = destRegion;
                // apply color
                cpData[item] = finalColor;// destRegion.Color;
            }

            dPixels.Sort();
            destRegion.Pixels = dPixels.ToArray();
            //destRegion.CreatePixelEdges(_regionPixelLookup);
            //_regionManipulator.CreatePixelEdges(destRegion);
        }
예제 #4
0
        private RegionVO [] Helper_GetMergedNeighbours(RegionVO destRegion, RegionVO forFuseRegion)
        {
            //List<RegionVO> lookup = new List<RegionVO>();

            HashSet <RegionVO> neighbours2 = _pool_Hashset_RegionVO.GetNewOrRecycle();

            neighbours2.Clear();

            //HashSet<RegionVO> neighbours2 = new HashSet<RegionVO>();
            foreach (var item in destRegion.NeighbourRegions)
            {
                if (item != destRegion && item != forFuseRegion)
                {
                    neighbours2.Add(item);
                }
            }

            foreach (var item in forFuseRegion.NeighbourRegions)
            {
                if (item != destRegion && item != forFuseRegion)
                {
                    neighbours2.Add(item);
                }
            }


            RegionVO[] result = neighbours2.ToArray();

            neighbours2.Clear();
            _pool_Hashset_RegionVO.PutForRecycle(neighbours2);

            return(result);
        }
예제 #5
0
        private void ReduceAllRegionUnderCountPixel(CanvasPixel canvasPixel, int minCountPixels)
        {
            List <RegionVO> tmpRegions = new List <RegionVO>();

            for (int i = 0; i < _listRegion.Count; i++)
            {
                if (_listRegion[i].Pixels.Length < minCountPixels)
                {
                    RegionVO region = _listRegion[i]; // _listRegion.FirstOrDefault(x => x.Pixels.Count < minCountPixels);

                    if (region == null)
                    {
                        break;
                    }

                    RegionVO bestForFuse = BestRegionToFuse(region, canvasPixel, 1024);
                    if (bestForFuse == null)
                    {
                        tmpRegions.Add(_listRegion[i]);
                        continue;
                        //throw new NotImplementedException();
                    }

                    FuseRegions(bestForFuse, region, canvasPixel);
                }
                else
                {
                    tmpRegions.Add(_listRegion[i]);
                }
            }

            _listRegion = tmpRegions;
        }
예제 #6
0
        private void ReduceAllRegionUnderColorTolerance(CanvasPixel canvasPixel, int maxColorDiff)
        {
            int origRegionCount = 0;

            do
            {
                HashSet <RegionVO> usedInFuseLookup = new HashSet <RegionVO>();

                List <RegionVO> tmpRegions = new List <RegionVO>(_listRegion.Count);
                //tmpRegions.Clear();
                //tmpRegions.AddRange(_listRegion);

                _listRegion = _listRegion.OrderBy(x => x.Pixels.Length).ToList();

                origRegionCount = _listRegion.Count();
                for (int i = 0; i < _listRegion.Count; i++)
                {
                    RegionVO region = _listRegion[i]; // _listRegion.FirstOrDefault(x => x.Pixels.Count < minCountPixels);

                    if (region == null)
                    {
                        break;
                    }
                    if (usedInFuseLookup.Contains(region))
                    {
                        tmpRegions.Add(_listRegion[i]);
                        continue;
                    }

                    RegionVO bestForFuse = BestRegionToFuse(region, canvasPixel, maxColorDiff, usedInFuseLookup);
                    if (bestForFuse == null)
                    {
                        usedInFuseLookup.Add(region);
                        tmpRegions.Add(region);
                        continue;
                        //throw new NotImplementedException();
                    }

                    //if (bestForFuse.Pixels.Count >= region.Pixels.Count())
                    {
                        usedInFuseLookup.Add(bestForFuse);
                        usedInFuseLookup.Add(region);

                        FuseRegions(bestForFuse, region, canvasPixel);
                    }
                    //else
                    {
                        //  tmpRegions.Add(region);
                        //  continue;
                    }
                    //else
                    //{
                    //    FuseRegions(region,bestForFuse , canvasPixel);
                    //}
                }
                //tmpRegions.CopyTo(_listRegion);

                _listRegion = tmpRegions;
            } while (origRegionCount > _listRegion.Count);
        }
예제 #7
0
        private void BestRegionToFuse_DetectRegionFromPixel(int indexPixel, RegionVO regionSource, Dictionary <RegionVO, int> regionsArround, HashSet <RegionVO> fuseIgnore)
        {
            RegionVO region = _regionPixelLookup[indexPixel];

            if (region != null && region != regionSource //&& !fuseIgnore.Contains(region)
                )
            {
                int outInt;
                if (regionsArround.TryGetValue(region, out outInt))
                {
                    regionsArround[region] = outInt + 1;
                }
                else
                {
                    regionsArround.Add(region, 1);
                }
                //if (regionsArround.Keys.Contains(region))
                //{
                //    regionsArround[region]++;
                //}
                //else
                //{
                //    regionsArround.Add(region, 1);
                //}
            }
        }
예제 #8
0
        private void BestRegionToFuse_DetectRegionFromPixel(int indexPixel, RegionVO regionSource, List <KeyValuePair <RegionVO, int> > regionsArround, HashSet <RegionVO> fuseIgnore)
        {
            RegionVO region = _regionPixelLookup[indexPixel];

            if (region != null && region != regionSource //&& !fuseIgnore.Contains(region)
                )
            {
                int regionIndex = -1;
                for (int i = 0; i < regionsArround.Count; i++)
                {
                    if (regionsArround[i].Key == region)
                    {
                        regionIndex = i;
                        break;
                    }
                }

                if (regionIndex < 0)
                {
                    regionsArround.Add(new KeyValuePair <RegionVO, int>(region, 1));
                }
                //else
                //{
                //    var tmp = regionsArround[regionIndex];
                //    regionsArround[regionIndex] = new KeyValuePair<RegionVO, int>( tmp.Key,tmp.Value+1);
                //}
            }
        }
예제 #9
0
        private int [] CreatePixelNeighbourEdge_p(RegionVO region, RegionVO[] regionPixelLookup)
        {
            //HashSet<int> pixelEdgesLookup = new HashSet<int>();
            List <int> pixelsNeighbours = new List <int>();

            for (int i = 0; i < region.Pixels.Length; i++)
            {
                int item         = region.Pixels[i];
                int WidthPixels  = this._widthPixels;
                int HeightPixels = this._heightPixels;
                {
                    if ((item) % WidthPixels != 0)
                    {
                        if (regionPixelLookup[item - 1] != region)
                        {
                            // if (pixelEdgesLookup.Add(item - 1))
                            {
                                pixelsNeighbours.Add(item - 1);
                            }
                        }
                    }

                    if ((item) % WidthPixels != WidthPixels - 1)
                    {
                        if (regionPixelLookup[item + 1] != region)
                        {
                            // if (pixelEdgesLookup.Add(item + 1))
                            {
                                pixelsNeighbours.Add(item + 1);
                            }
                        }
                    }

                    if (item - WidthPixels >= 0)
                    {
                        if (regionPixelLookup[item - WidthPixels] != region)
                        {
                            // if (pixelEdgesLookup.Add(item - WidthPixels))
                            {
                                pixelsNeighbours.Add(item - WidthPixels);
                            }
                        }
                    }

                    if (item + WidthPixels < WidthPixels * HeightPixels)
                    {
                        if (regionPixelLookup[item + WidthPixels] != region)
                        {
                            //  if (pixelEdgesLookup.Add(item + WidthPixels))
                            {
                                pixelsNeighbours.Add(item + WidthPixels);
                            }
                        }
                    }
                }
            }

            return(pixelsNeighbours.ToArray());
        }
예제 #10
0
        private void ReduceAllRegionUnderCountPixel(CanvasPixel canvasPixel, int maxCountPixel, CanvasPixel canvasPixelOriginal)
        {
            int origRegionCount = 0;

            do
            {
                origRegionCount = _listRegion.Count;
                for (int i = 0; i < _listRegion.Count; i++)
                {
                    RegionVO region = _listRegion[i];

                    if (region == null)
                    {
                        break;
                    }
                    if (region.NotValid)
                    {
                        continue;
                    }

                    if (region.Pixels.Length <= maxCountPixel)
                    {
                        RegionVO bestForFuse = BestRegionToFuse2(region, canvasPixel, int.MaxValue, true);
                        if (bestForFuse == null)
                        {
                            continue;
                        }

                        if (bestForFuse != region)
                        {
                            //// swap for faster merge
                            if (region.Pixels.Length > bestForFuse.Pixels.Length)
                            {
                                RegionVO tmp = region;
                                region      = bestForFuse;
                                bestForFuse = tmp;
                            }

                            FuseRegions(bestForFuse, region, canvasPixel, canvasPixelOriginal);

                            region.NotValid = true;
                            region.Clear();
                        }
                    }
                }

                List <RegionVO> kk = new List <RegionVO>(_listRegion.Count);
                for (int i = 0; i < _listRegion.Count; i++)
                {
                    if (!_listRegion[i].NotValid)
                    {
                        kk.Add(_listRegion[i]);
                    }
                }

                _listRegion = kk;
            } while (origRegionCount > _listRegion.Count);
        }
예제 #11
0
        /// <summary>
        /// slouci dva regiony
        /// dest region = k nemu jsou pridany pixely ze slucovaneho
        /// </summary>
        /// <param name="destRegion"></param>
        /// <param name="forFuseRegion"></param>
        private void FuseRegions(RegionVO destRegion, RegionVO forFuseRegion, CanvasPixel canvasPixel, CanvasPixel canvasPixelOriginal)
        {
            if (destRegion == forFuseRegion)
            {
                throw new Exception();
            }



            for (int i = 0; i < forFuseRegion.Pixels.Length; i++)
            {
                int item = forFuseRegion.Pixels[i];
                // reassign region
                _regionPixelLookup[item] = destRegion;
            }

            destRegion.Pixels = MergeOrderedPixel(destRegion.Pixels, forFuseRegion.Pixels);

            //destRegion.Pixels.Sort();
            //destRegion.CreatePixelEdges(_regionPixelLookup);
            //destRegion.CreatePixelEdges();
            //_regionManipulator.CreatePixelNeighbourEdge(destRegion,_regionPixelLookup);

            // _regionManipulator.MergePixelNeighbourEdge(destRegion,forFuseRegion, _regionPixelLookup);


            //if (destRegion.Pixels.Length > 100)
            //{
            //    destRegion.SetColor_AsNearToAverageToAll(canvasPixelOriginal, canvasPixel);
            //}
            //else
            //{
            //    destRegion.SetColorAsMedinToAll(canvasPixelOriginal, canvasPixel);
            //}

            //destRegion.SetColor_AsNearToAverageToAll(canvasPixelOriginal, canvasPixel);


            //destRegion.SetColorAsFixToAll(canvasPixelOriginal, canvasPixel);
            destRegion.SetColor_AsAverageToAll(canvasPixelOriginal, canvasPixel);
            //destRegion.SetColorHSLAsAverageToAll(canvasPixelOriginal, canvasPixel);

            //List<RegionVO> neighbours = Helper_GetMergedNeighbours2(destRegion, forFuseRegion);
            //destRegion.NeighbourRegions = neighbours.ToArray();
            RegionVO[] neighbours = Helper_GetMergedNeighbours(destRegion, forFuseRegion);
            destRegion.NeighbourRegions = neighbours;

            foreach (RegionVO item in neighbours)
            {
                item.Add_NeightbourRegion(destRegion);
                item.Remove_NeightbourRegion(forFuseRegion);

                //item.Create_NeighbourRegions(_regionPixelLookup);
            }
        }
예제 #12
0
        public Point[] ToPolygon(RegionVO region)
        {
            List <Point> result = new List <Point>();

            List <int> edgePixelInOrder = new RegionEdgeCrawler(region, this._regionManipulator).GetInOrderEdgePixels();

            edgePixelInOrder = ReduceSameSequence(edgePixelInOrder);

            result.AddRange(edgePixelInOrder.Select(x => _regionManipulator.Get_PointFromIndex(x)));

            //result = ReduceToEdgePoints_WhenChangeDirection(result);
            return(result.ToArray());
        }
예제 #13
0
        public Point [] ToPolygonOld(RegionVO region)
        {
            var points = this._regionManipulator.Get_RegionEdgePeaks(region);


            List <Point> result = new List <Point>();

            for (int i = 0; i < points.Length; i++)
            {
                result.Add(_regionManipulator.Get_PointFromIndex(points[i]));
            }

            return(result.ToArray());
        }
예제 #14
0
        private int Helper_GetCountNeighbour(RegionVO region)
        {
            int lenght = this.NeighbourRegions.Length;

            int count = 0;

            for (int i = 0; i < lenght; i++)
            {
                if (this.NeighbourRegions[i] == region)
                {
                    count++;
                }
            }

            return(count);
        }
예제 #15
0
        private void BestRegionToFuse_DetectRegionFromPixel(int indexPixel, RegionVO regionSource, Dictionary <RegionVO, int> regionsArround, HashSet <RegionVO> fuseIgnore)
        {
            RegionVO region = _regionPixelLookup[indexPixel];

            if (region != null && region != regionSource && !fuseIgnore.Contains(region))
            {
                if (regionsArround.Keys.Contains(region))
                {
                    regionsArround[region]++;
                }
                else
                {
                    regionsArround.Add(region, 1);
                }
            }
        }
예제 #16
0
        public void Add_NeightbourRegion(RegionVO region)
        {
            int countRegions = Helper_GetCountNeighbour(region);

            if (countRegions == 0)
            {
                int lenght = this.NeighbourRegions.Length;

                RegionVO[] newNeighbours = new RegionVO[lenght + 1];

                Array.Copy(this.NeighbourRegions, 0, newNeighbours, 0, lenght);

                newNeighbours[lenght] = region;

                this.NeighbourRegions = newNeighbours;
            }
        }
예제 #17
0
        public int[] Get_RegionEdgePeaks(RegionVO region)
        {
            HashSet <int> lookup = new HashSet <int>(region.Pixels);

            List <int> result = new List <int>();

            for (int i = 0; i < region.Pixels.Length; i++)
            {
                int item       = region.Pixels[i];
                int itemLeft   = Helper_GetPixelIndex_Left(item);
                int itemRight  = Helper_GetPixelIndex_Right(item);
                int itemTop    = Helper_GetPixelIndex_Top(item);
                int itemBottom = Helper_GetPixelIndex_Bottom(item);

                int itemLeftTop     = (itemLeft >= 0 && itemTop >= 0) ? itemTop - 1 : -1;
                int itemRightTop    = (itemRight >= 0 && itemTop >= 0) ? itemTop + 1 : -1;
                int itemLeftBottom  = (itemLeft >= 0 && itemBottom >= 0) ? itemBottom - 1 : -1;
                int itemRightBottom = (itemRight >= 0 && itemBottom >= 0) ? itemBottom + 1 : -1;


                bool leftPixelValid   = itemLeft >= 0 && lookup.Contains(itemLeft);
                bool rightPixelValid  = itemRight >= 0 && lookup.Contains(itemRight);
                bool topPixelValid    = itemTop >= 0 && lookup.Contains(itemTop);
                bool bottomPixelValid = itemBottom >= 0 && lookup.Contains(itemBottom);

                bool leftTopValid     = itemLeftTop >= 0 && lookup.Contains(itemLeftTop);
                bool rightTopValid    = itemRightTop >= 0 && lookup.Contains(itemRightTop);
                bool leftBottomValid  = itemLeftBottom >= 0 && lookup.Contains(itemLeftBottom);
                bool rightBottomValid = itemRightBottom >= 0 && lookup.Contains(itemRightBottom);

                if ((!leftPixelValid && !topPixelValid) ||
                    (!rightPixelValid && !topPixelValid) ||
                    (!leftPixelValid && !bottomPixelValid) ||
                    (!leftPixelValid && !bottomPixelValid) ||
                    !leftBottomValid || !leftTopValid || !rightBottomValid || !rightTopValid)
                {
                    result.Add(item);
                }
            }

            return(result.ToArray());
        }
예제 #18
0
        public void AreasToSVG(CanvasPixel original, List <RegionVO> regions, RegionManipulator regMan)
        {
            Write_StartHeader(original.Width, original.Height);

            RegionVO[] regionsOrdered = regMan.GetOrderedForRendering(regions.ToArray());

            RegionToPolygonBO regionToPolygon = new RegionToPolygonBO(regMan);

            for (int i = 0; i < regionsOrdered.Length; i++)
            {
                RegionVO region = regionsOrdered[i];

                Point[] points = regionToPolygon.ToPolygon(region);

                _output.WriteLine(Helper_CreateSVGPolyLine(points, region.Color));
                // _output.WriteLine(Helper_CreateSVGPolyGone(points, region.Color));
            }


            Write_EndHeader();
        }
예제 #19
0
        private bool Check_ValidRegionData(RegionVO[] regionPixelLookup, List <RegionVO> listRegions)
        {
            HashSet <RegionVO> listRegionLookup = new HashSet <RegionVO>(listRegions);

            for (int i = 0; i < regionPixelLookup.Length; i++)
            {
                RegionVO tmpRegion = regionPixelLookup[i];
                // specialni pripad, nepatri zadnemu regionu
                if (tmpRegion == null)
                {
                    continue;
                }

                if (!listRegionLookup.Contains(tmpRegion))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #20
0
        /// <summary>
        /// vraci region ktery je nejlepsi k slouceni s timto
        /// </summary>
        /// <param name="region"></param>
        /// <returns></returns>
        private RegionVO BestRegionToFuse2(RegionVO region, CanvasPixel canvasPixel, int maxColorDiff, bool ignoreColorCategory = false)
        {
            int isRegionColorCategory = Helper_GetPixelColorCategory(region.Color);

            RegionVO result      = null;
            int      resultDiff  = int.MaxValue;
            int      resultCount = -1;

            foreach (var item in region.NeighbourRegions)
            {
                // int diff = BasicHelpers.FastAbs(item.Key.Color.IntClearAlpha() - region.Color.IntClearAlpha());

                //int maxDiff = Pixel.MaxDiff(item.Key.Color, region.Color);
                //if (maxDiff > (maxColorDiff / 2) + 1) continue;

                bool colorRegionEqual = true;

                if (!ignoreColorCategory)
                {
                    int isItemColorCategory = Helper_GetPixelColorCategory(item.Color);
                    colorRegionEqual = isRegionColorCategory == isItemColorCategory;
                }


                int diff = Pixel.SumAbsDiff(item.Color, region.Color);

                if (diff <= maxColorDiff && colorRegionEqual)
                {
                    if (diff < resultDiff
                        )
                    {
                        resultDiff = diff;
                        result     = item;
                    }
                }
            }

            return(result);
        }
예제 #21
0
        //private static HashSet<RegionVO> tmpLookup = new HashSet<RegionVO>();

        public void Create_NeighbourRegions(RegionVO region, RegionVO[] regionPixelLookup)
        {
            int[] pixelsEdgeNeighbour = CreatePixelNeighbourEdge_p(region, regionPixelLookup);

            HashSet <RegionVO> tmpLookup = _pool_Hashset_RegionVO.GetNewOrRecycle();

            tmpLookup.Clear();


            List <RegionVO> newNeightbours = _pool_List_RegionVO.GetNewOrRecycle();

            newNeightbours.Clear();

            for (int i = 0; i < pixelsEdgeNeighbour.Length; i++)
            {
                int index = pixelsEdgeNeighbour[i];

                RegionVO regionForTest = regionPixelLookup[index];

                if (regionForTest != null)
                {
                    if (tmpLookup.Add(regionForTest))
                    {
                        newNeightbours.Add(regionForTest);
                    }
                }
            }

            if (newNeightbours.Count > 0)
            {
                newNeightbours.AddRange(region.NeighbourRegions);
                region.NeighbourRegions = newNeightbours.ToArray();
            }

            _pool_List_RegionVO.PutForRecycle(newNeightbours);
            tmpLookup.Clear();
            _pool_Hashset_RegionVO.PutForRecycle(tmpLookup);
        }
예제 #22
0
        public void Remove_NeightbourRegion(RegionVO region)
        {
            int countForRemove = Helper_GetCountNeighbour(region);

            if (countForRemove > 0)
            {
                int lenght = this.NeighbourRegions.Length;

                System.Buffers.ArrayPool <RegionVO> pool = System.Buffers.ArrayPool <RegionVO> .Shared;

                RegionVO[] newNeighbours = new RegionVO[this.NeighbourRegions.Length - countForRemove];
                int        newNIndex     = 0;
                for (int i = 0; i < lenght; i++)
                {
                    if (this.NeighbourRegions[i] != region)
                    {
                        newNeighbours[newNIndex] = this.NeighbourRegions[i];
                        newNIndex++;
                    }
                }

                this.NeighbourRegions = newNeighbours;
            }
        }
예제 #23
0
        //static Dictionary<RegionVO, int> regionsAround = new Dictionary<RegionVO, int>();


        private RegionVO BestRegionToFuse(RegionVO region, CanvasPixel canvasPixel, int maxColorDiff)
        {
            return(BestRegionToFuse(region, canvasPixel, maxColorDiff, new HashSet <RegionVO>()));
        }
예제 #24
0
        /// <summary>
        /// vraci region ktery je nejlepsi k slouceni s timto
        /// </summary>
        /// <param name="region"></param>
        /// <returns></returns>
        private RegionVO BestRegionToFuse(RegionVO region, CanvasPixel canvasPixel, int maxColorDiff, HashSet <RegionVO> fuseIgnore)
        {
            //regionsAround.Clear();
            Dictionary <RegionVO, int> regionsAround = new Dictionary <RegionVO, int>();

            foreach (int pixelIndex in region.Pixels)
            {
                int pixelIndexborder = pixelIndex - 1;

                BestRegionToFuse_DetectRegionFromPixel(pixelIndexborder, region, regionsAround, fuseIgnore);
                pixelIndexborder = pixelIndex + 1;
                BestRegionToFuse_DetectRegionFromPixel(pixelIndexborder, region, regionsAround, fuseIgnore);
                pixelIndexborder = pixelIndex - canvasPixel.Width;
                BestRegionToFuse_DetectRegionFromPixel(pixelIndexborder, region, regionsAround, fuseIgnore);
                pixelIndexborder = pixelIndex + canvasPixel.Width;
                BestRegionToFuse_DetectRegionFromPixel(pixelIndexborder, region, regionsAround, fuseIgnore);
            }

            //RegionVO result = null;
            //int resultCount = int.MaxValue;
            //foreach (var item in regionsAround)
            //{
            //    if (item.Value < resultCount)
            //    {
            //        resultCount = item.Value;
            //        result = item.Key;
            //    }
            //}

            RegionVO result      = null;
            int      resultDiff  = int.MaxValue;
            int      resultCount = -1;
            Pixel    re          = region.Color;

            re.ConvertRGBToHSL();
            foreach (var item in regionsAround)
            {
                // int diff = BasicHelpers.FastAbs(item.Key.Color.IntClearAlpha() - region.Color.IntClearAlpha());

                //int maxDiff = Pixel.MaxDiff(item.Key.Color, region.Color);
                //if (maxDiff > (maxColorDiff / 2) + 1) continue;
                Pixel it = item.Key.Color;
                it.ConvertRGBToHSL();

                int diff = Pixel.SumAbsDiff(item.Key.Color, region.Color);

                int diff2_min = BasicHelpers.Min(re.CH, it.CH);

                int  diff2     = BasicHelpers.FastAbs(re.CH - it.CH);
                bool firstLess = re.CH < it.CH;

                int diff2absl = BasicHelpers.FastAbs(re.CL - it.CL);

                Pixel p = new Pixel();
                p.CR = 255;
                p.CG = 255;
                p.CB = 255;

                p.ConvertRGBToHSL();

                if (diff <= maxColorDiff)
                {
                    if (!((re.CL < 50 && it.CL < 50) ||
                          (re.CL > 205 && it.CL > 205)))
                    {
                        if (diff2absl > 160)
                        {
                            continue;
                        }

                        if (!(((diff2_min + diff2 + 1) * item.Key.Pixels.Length <= (diff2_min + 1) * region.Pixels.Length && firstLess) ||
                              ((diff2 + 1) * item.Key.Pixels.Length <= (diff2_min + diff2_min + 1) * region.Pixels.Length && !firstLess)
                              ))
                        {
                            continue;
                        }
                    }

                    if (
                        //       ((diff2+1)*item.Key.Pixels.Count) < resultDiff
                        diff < resultDiff
                        //item.Value > resultCount
                        )
                    {
                        resultDiff =
                            diff;
                        //((diff2 + 1) * item.Key.Pixels.Count);
                        result      = item.Key;
                        resultCount = item.Value;
                    }
                }
            }

            return(result);
        }
예제 #25
0
        public int [] Get_CreatePixelNeighbourEdge(RegionVO region)
        {
            HashSet <int> lookup = new HashSet <int>(region.Pixels);

            HashSet <int> pixelEdgesLookup = new HashSet <int>();
            List <int>    pixelsNeighbours = new List <int>();


            for (int i = 0; i < region.Pixels.Length; i++)
            {
                int item = region.Pixels[i];
                {
                    int itemLeft = Helper_GetPixelIndex_Left(item);
                    if (itemLeft >= 0)
                    {
                        if (!lookup.Contains(itemLeft))
                        {
                            if (pixelEdgesLookup.Add(itemLeft))
                            {
                                pixelsNeighbours.Add(itemLeft);
                            }
                        }
                    }

                    if (item + this._widthPixels < this._widthPixels * this._heightPixels)
                    {
                        if (!lookup.Contains(item + this._widthPixels))
                        {
                            if (pixelEdgesLookup.Add(item + this._widthPixels))
                            {
                                pixelsNeighbours.Add(item + this._widthPixels);
                            }
                        }
                    }

                    if ((item) % this._widthPixels != 0)
                    {
                        if (!lookup.Contains(item - 1))
                        {
                            if (pixelEdgesLookup.Add(item - 1))
                            {
                                pixelsNeighbours.Add(item - 1);
                            }
                        }
                    }

                    if ((item + 1) % this._widthPixels != this._widthPixels - 1)
                    {
                        if (!lookup.Contains(item + 1))
                        {
                            if (pixelEdgesLookup.Add(item + 1))
                            {
                                pixelsNeighbours.Add(item + 1);
                            }
                        }
                    }
                }
            }

            return(pixelsNeighbours.ToArray());
        }
예제 #26
0
 public RegionEdgeCrawler(RegionVO region, RegionManipulator rm)
 {
     this._regionManipulator = rm;
     this._pixels            = new HashSet <int>(region.Pixels);
 }
예제 #27
0
        private void CreateRegionFromStartPixel(int x, int y, List <int> listSinglePoints, CanvasPixel canvasPixel, int tolerance)
        {
            CanvasPixel cp = canvasPixel;

            Pixel[] data = cp.Data;

            int tmpRow = (y) * cp.Width;

            int rowindex1 = tmpRow - cp.Width + x;
            int rowindex2 = tmpRow + x;
            int rowindex3 = tmpRow + cp.Width + x;


            if (_regionPixelLookup[rowindex2] != null)
            {
                return;
            }

            int middleColor = data[rowindex2].Get_ColorClearAlpha_Int();

            int v2 = int.MaxValue;
            int v4 = int.MaxValue;
            int v6 = int.MaxValue;
            int v8 = int.MaxValue;

            //int v2 = Helpers.BasicHelpers.FastAbs(middleColor - data[rowindex1].IntClearAlpha());
            //int v4 = Helpers.BasicHelpers.FastAbs(middleColor - data[rowindex2 - 1].IntClearAlpha());
            //int v6 = Helpers.BasicHelpers.FastAbs(middleColor - data[rowindex2 + 1].IntClearAlpha());
            //int v8 = Helpers.BasicHelpers.FastAbs(middleColor - data[rowindex3].IntClearAlpha());

            if (y > 1)
            {
                v2 = Pixel.SumAbsDiff(data[rowindex2], data[rowindex1]);
            }
            if (x > 1)
            {
                v4 = Pixel.SumAbsDiff(data[rowindex2], data[rowindex2 - 1]);
            }
            if (x < (cp.Width - 1 - 1))
            {
                v6 = Pixel.SumAbsDiff(data[rowindex2], data[rowindex2 + 1]);
            }
            if (y < (cp.Height - 1 - 1))
            {
                v8 = Pixel.SumAbsDiff(data[rowindex2], data[rowindex3]);
            }


            bool b2 = v2 <= tolerance;
            bool b4 = v4 <= tolerance;
            bool b6 = v6 <= tolerance;
            bool b8 = v8 <= tolerance;

            if (b2 || b4 || b6 || b8)
            {
                RegionVO region = null;

                {
                    // detekce uz existujiciho regionu v okoli
                    if (b2 && _regionPixelLookup[rowindex1] != null)
                    {
                        region = _regionPixelLookup[rowindex1];
                    }
                    else if (b4 && _regionPixelLookup[rowindex2 - 1] != null)
                    {
                        region = _regionPixelLookup[rowindex2 - 1];
                    }
                    else if (b6 && _regionPixelLookup[rowindex2 + 1] != null)
                    {
                        region = _regionPixelLookup[rowindex2 + 1];
                    }
                    else if (b8 && _regionPixelLookup[rowindex3] != null)
                    {
                        region = _regionPixelLookup[rowindex3];
                    }
                }

                if (region != null)
                {
                    region.Add_Pixel(rowindex2);
                    _regionPixelLookup[rowindex2] = region;
                    data[rowindex2] = region.Color;
                    //this._regionManipulator.CreatePixelNeighbourEdge(region);
                }
                else
                {
                    Pixel      tmpMiddleColor = data[rowindex2];
                    RegionVO   newRegion      = new RegionVO(tmpMiddleColor);
                    List <int> tmpPixels      = new List <int>(4);
                    tmpPixels.Add(rowindex2);
                    _regionPixelLookup[rowindex2] = newRegion;

                    if (b2 && y > 1)
                    {
                        tmpPixels.Add(rowindex1);
                        _regionPixelLookup[rowindex1] = newRegion;
                        data[rowindex1] = tmpMiddleColor;
                    }

                    if (b4 && x > 1)
                    {
                        tmpPixels.Add(rowindex2 - 1);
                        _regionPixelLookup[rowindex2 - 1] = newRegion;
                        data[rowindex2 - 1] = tmpMiddleColor;
                    }

                    if (b6 && x < (cp.Width - 1 - 1))
                    {
                        tmpPixels.Add(rowindex2 + 1);
                        _regionPixelLookup[rowindex2 + 1] = newRegion;
                        data[rowindex2 + 1] = tmpMiddleColor;
                    }

                    if (b8 && y < (cp.Height - 1 - 1))
                    {
                        tmpPixels.Add(rowindex3);
                        _regionPixelLookup[rowindex3] = newRegion;
                        data[rowindex3] = tmpMiddleColor;
                    }

                    newRegion.Add_Pixels(tmpPixels.ToArray());
                    _listRegion.Add(newRegion);
                    // newRegion.CreatePixelEdges();
                    //this._regionManipulator.CreatePixelNeighbourEdge(newRegion);
                }
            }
            else
            {
                Pixel    tmpMiddleColor = data[rowindex2];
                RegionVO newRegion      = new RegionVO(tmpMiddleColor);
                newRegion.Add_Pixel(rowindex2);
                _regionPixelLookup[rowindex2] = newRegion;
                _listRegion.Add(newRegion);
            }
        }
예제 #28
0
        private void ReduceAllRegionUnderColorTolerance(CanvasPixel canvasPixel, int maxColorDiff, CanvasPixel canvasPixelOriginal)
        {
            int origRegionCount = 0;

            //List<RegionVO> tmpRegions = new List<RegionVO>(_listRegion.Count);

            //HashSet<RegionVO> tmpRegions = new HashSet<RegionVO>();

            do
            {
                //  tmpRegions.Clear();

                //if (!Check_ValidRegionData(_regionPixelLookup, _listRegion))
                //{
                //    System.Diagnostics.Trace.WriteLine($"Start Invalid region data {_listRegion.Count}");
                //}



                origRegionCount = _listRegion.Count;
                for (int i = 0; i < _listRegion.Count; i++)
                {
                    RegionVO region = _listRegion[i];

                    if (region == null)
                    {
                        break;
                    }
                    if (region.NotValid)
                    {
                        continue;
                    }


                    RegionVO bestForFuse = BestRegionToFuse2(region, canvasPixel, maxColorDiff);
                    if (bestForFuse == null)
                    {
                        continue;
                    }


                    if (bestForFuse != region)
                    {
                        //// swap for faster merge
                        if (region.Pixels.Length > bestForFuse.Pixels.Length)
                        {
                            RegionVO tmp = region;
                            region      = bestForFuse;
                            bestForFuse = tmp;
                        }

                        FuseRegions(bestForFuse, region, canvasPixel, canvasPixelOriginal);

                        region.NotValid = true;
                        region.Clear();
                    }



                    //if (!Check_ValidRegionData(_regionPixelLookup, _listRegion))
                    //{
                    //    throw new Exception();
                    //}
                }

                //   _listRegion = _listRegion.Where(x => !x.NotValid ).ToList();
                List <RegionVO> kk = new List <RegionVO>(_listRegion.Count);
                for (int i = 0; i < _listRegion.Count; i++)
                {
                    if (!_listRegion[i].NotValid)
                    {
                        kk.Add(_listRegion[i]);
                    }
                }

                _listRegion = kk;
                //if (!Check_ValidRegionData(_regionPixelLookup, _listRegion))
                //{
                //    System.Diagnostics.Trace.WriteLine($"End Invalid region data {_listRegion.Count}");
                //}

                //if (tmpRegions.Count == 0)
                //{
                //    throw new Exception();
                //}
            } while (origRegionCount > _listRegion.Count);
        }
예제 #29
0
 private RegionVO BestRegionToFuse(RegionVO region, CanvasPixel canvasPixel, int maxColorDiff, bool ignoreColorCategory = false)
 {
     return(BestRegionToFuse2(region, canvasPixel, maxColorDiff, ignoreColorCategory));
 }