示例#1
0
        public void Remove(BinaryMap input)
        {
            BinaryMap sw2ne     = new BinaryMap(input.Size);
            BinaryMap se2nw     = new BinaryMap(input.Size);
            BinaryMap positions = new BinaryMap(input.Size);
            BinaryMap squares   = new BinaryMap(input.Size);

            while (true)
            {
                sw2ne.Copy(input, new RectangleC(0, 0, input.Width - 1, input.Height - 1), new Point());
                sw2ne.And(input, new RectangleC(1, 1, input.Width - 1, input.Height - 1), new Point());
                sw2ne.AndNot(input, new RectangleC(0, 1, input.Width - 1, input.Height - 1), new Point());
                sw2ne.AndNot(input, new RectangleC(1, 0, input.Width - 1, input.Height - 1), new Point());

                se2nw.Copy(input, new RectangleC(0, 1, input.Width - 1, input.Height - 1), new Point());
                se2nw.And(input, new RectangleC(1, 0, input.Width - 1, input.Height - 1), new Point());
                se2nw.AndNot(input, new RectangleC(0, 0, input.Width - 1, input.Height - 1), new Point());
                se2nw.AndNot(input, new RectangleC(1, 1, input.Width - 1, input.Height - 1), new Point());

                positions.Copy(sw2ne);
                positions.Or(se2nw);
                if (positions.IsEmpty())
                {
                    break;
                }

                squares.Copy(positions);
                squares.Or(positions, new RectangleC(0, 0, positions.Width - 1, positions.Height - 1), new Point(1, 0));
                squares.Or(positions, new RectangleC(0, 0, positions.Width - 1, positions.Height - 1), new Point(0, 1));
                squares.Or(positions, new RectangleC(0, 0, positions.Width - 1, positions.Height - 1), new Point(1, 1));

                input.AndNot(squares);
            }
            Logger.Log(input);
        }
示例#2
0
        void UpdateView()
        {
            if (IsVisible && Skeleton != null)
            {
                SourceAFIS.General.Size minSize = new SkeletonShadow().GetSize(Skeleton);
                if (OriginalWidth >= minSize.Width && OriginalHeight >= minSize.Height)
                {
                    BinaryMap shadow = new BinaryMap(OriginalWidth, OriginalHeight);
                    new SkeletonShadow().Draw(Skeleton, shadow);
                    SetValue(ShadowProperty, shadow);
                    BinaryMap blur = new BinaryMap(shadow);
                    blur.Or(shadow, new RectangleC(0, 0, OriginalWidth - 1, OriginalHeight), new APoint(1, 0));
                    blur.Or(shadow, new RectangleC(1, 0, OriginalWidth - 1, OriginalHeight), new APoint(0, 0));
                    blur.Or(shadow, new RectangleC(0, 0, OriginalWidth, OriginalHeight - 1), new APoint(0, 1));
                    blur.Or(shadow, new RectangleC(0, 1, OriginalWidth, OriginalHeight - 1), new APoint(0, 0));
                    SetValue(ShadowBlurProperty, blur);

                    var points = from minutia in Skeleton.Minutiae
                                 where minutia.Valid
                                 select new WPoint(minutia.Position.X - 3, OriginalHeight - 1 - minutia.Position.Y - 3);
                    SetValue(PositionsProperty, points);
                }
                else
                {
                    SetValue(ShadowProperty, null);
                    SetValue(PositionsProperty, null);
                }
            }
            else
            {
                SetValue(ShadowProperty, null);
                SetValue(ShadowBlurProperty, null);
                SetValue(PositionsProperty, null);
            }
        }
示例#3
0
        public BinaryMap Binarize(float[,] input, float[,] baseline, BinaryMap mask, BlockMap blocks)
        {
            BinaryMap binarized = new BinaryMap(input.GetLength(1), input.GetLength(0));

            Parallel.For(0, blocks.AllBlocks.Height, delegate(int blockY)
            {
                for (int blockX = 0; blockX < blocks.AllBlocks.Width; ++blockX)
                {
                    if (mask.GetBit(blockX, blockY))
                    {
                        RectangleC rect = blocks.BlockAreas[blockY, blockX];
                        for (int y = rect.Bottom; y < rect.Top; ++y)
                        {
                            for (int x = rect.Left; x < rect.Right; ++x)
                            {
                                if (input[y, x] - baseline[y, x] > 0)
                                {
                                    binarized.SetBitOne(x, y);
                                }
                            }
                        }
                    }
                }
            });
            Logger.Log(binarized);
            return(binarized);
        }
示例#4
0
 public float[,] Smooth(float[,] input, byte[,] orientation, BinaryMap mask, BlockMap blocks)
 {
     Point[][] lines = Lines.Construct();
     float[,] output = new float[input.GetLength(0), input.GetLength(1)];
     Parallel.ForEach(blocks.AllBlocks, delegate(Point block)
     {
         if (mask.GetBit(block))
         {
             Point[] line = lines[Angle.Quantize(Angle.Add(orientation[block.Y, block.X], AngleOffset), lines.Length)];
             foreach (Point linePoint in line)
             {
                 RectangleC target = blocks.BlockAreas[block];
                 RectangleC source = target.GetShifted(linePoint);
                 source.Clip(new RectangleC(blocks.PixelCount));
                 target = source.GetShifted(Calc.Negate(linePoint));
                 for (int y = target.Bottom; y < target.Top; ++y)
                     for (int x = target.Left; x < target.Right; ++x)
                         output[y, x] += input[y + linePoint.Y, x + linePoint.X];
             }
             RectangleC blockArea = blocks.BlockAreas[block];
             for (int y = blockArea.Bottom; y < blockArea.Top; ++y)
                 for (int x = blockArea.Left; x < blockArea.Right; ++x)
                     output[y, x] *= 1f / line.Length;
         }
     });
     Logger.Log(output);
     return output;
 }
示例#5
0
        BinaryMap Subtract(BinaryMap outer, BinaryMap inner)
        {
            BinaryMap buffer = new BinaryMap(outer);

            buffer.AndNot(inner);
            return(buffer);
        }
示例#6
0
        Range GetMaskLineRange(BinaryMap mask, int y)
        {
            int first = -1;
            int last  = -1;

            for (int x = 0; x < mask.Width; ++x)
            {
                if (mask.GetBit(x, y))
                {
                    last = x;
                    if (first < 0)
                    {
                        first = x;
                    }
                }
            }
            if (first >= 0)
            {
                return(new Range(first, last + 1));
            }
            else
            {
                return(new Range());
            }
        }
示例#7
0
        public BinaryMap Draw(SkeletonBuilder skeleton)
        {
            BinaryMap binary = new BinaryMap(GetSize(skeleton));

            Draw(skeleton, binary);
            return(binary);
        }
示例#8
0
        public BinaryMap Compute(BinaryMap outer)
        {
            BinaryMap inner = new BinaryMap(outer.Size);

            inner.Copy(outer, new RectangleC(1, 1, outer.Width - 2, outer.Height - 2), new Point(1, 1));
            BinaryMap temporary = new BinaryMap(outer.Size);

            if (MinBorderDistance >= 1)
            {
                ShrinkBy(temporary, inner, 1);
            }
            int total = 1;

            for (int step = 1; total + step <= MinBorderDistance; step *= 2)
            {
                ShrinkBy(temporary, inner, step);
                total += step;
            }
            if (total < MinBorderDistance)
            {
                ShrinkBy(temporary, inner, MinBorderDistance - total);
            }
            Logger.Log(inner);
            return(inner);
        }
示例#9
0
 PointF[,] Smooth(PointF[,] orientation, BinaryMap mask)
 {
     PointF[,] smoothed = new PointF[mask.Height, mask.Width];
     Parallel.For(0, mask.Height, delegate(int y)
     {
         for (int x = 0; x < mask.Width; ++x)
         {
             if (mask.GetBit(x, y))
             {
                 RectangleC neighbors = new RectangleC(
                     new Point(Math.Max(0, x - SmoothingRadius), Math.Max(0, y - SmoothingRadius)),
                     new Point(Math.Min(mask.Width, x + SmoothingRadius + 1), Math.Min(mask.Height, y + SmoothingRadius + 1)));
                 PointF sum = new PointF();
                 for (int ny = neighbors.Bottom; ny < neighbors.Top; ++ny)
                 {
                     for (int nx = neighbors.Left; nx < neighbors.Right; ++nx)
                     {
                         if (mask.GetBit(nx, ny))
                         {
                             sum = Calc.Add(sum, orientation[ny, nx]);
                         }
                     }
                 }
                 smoothed[y, x] = sum;
             }
         }
     });
     return(smoothed);
 }
示例#10
0
 public byte[,] Detect(float[,] image, BinaryMap mask, BlockMap blocks)
 {
     PointF[,] accumulated = AccumulateOrientations(image, mask, blocks);
     PointF[,] byBlock     = SumBlocks(accumulated, blocks, mask);
     PointF[,] smooth      = Smooth(byBlock, mask);
     byte[,] angles        = ToAngles(smooth, mask);
     Logger.Log(angles);
     return(angles);
 }
示例#11
0
 public void Filter(TemplateBuilder template, BinaryMap mask)
 {
     template.Minutiae.RemoveAll(minutia =>
     {
         var arrow = Calc.Round(-DirectedExtension * Angle.ToVector(minutia.Direction));
         return(!mask.GetBitSafe((Point)minutia.Position + new Size(arrow), false));
     });
     Logger.Log(template);
 }
示例#12
0
 void ShrinkBy(BinaryMap temporary, BinaryMap inner, int amount)
 {
     temporary.Clear();
     temporary.Copy(inner, new RectangleC(amount, 0, inner.Width - amount, inner.Height), new Point(0, 0));
     temporary.And(inner, new RectangleC(0, 0, inner.Width - amount, inner.Height), new Point(amount, 0));
     temporary.And(inner, new RectangleC(0, amount, inner.Width, inner.Height - amount), new Point(0, 0));
     temporary.And(inner, new RectangleC(0, 0, inner.Width, inner.Height - amount), new Point(0, amount));
     inner.Copy(temporary);
 }
示例#13
0
        public void Trace(BinaryMap binary, SkeletonBuilder skeleton)
        {
            List <Point> minutiaPoints = FindMinutiae(binary);
            Dictionary <Point, List <Point> >           linking    = LinkNeighboringMinutiae(minutiaPoints);
            Dictionary <Point, SkeletonBuilder.Minutia> minutiaMap = ComputeMinutiaCenters(linking, skeleton);

            TraceRidges(binary, minutiaMap);
            FixLinkingGaps(skeleton);
            Logger.Log(skeleton);
        }
示例#14
0
        public TemplateBuilder Extract(byte[,] invertedImage, int dpi)
        {
            TemplateBuilder template = null;

            DpiAdjuster.Adjust(this, dpi, delegate()
            {
                byte[,] image = ImageInverter.GetInverted(invertedImage);

                BlockMap blocks = new BlockMap(new Size(image.GetLength(1), image.GetLength(0)), BlockSize);
                Logger.Log("BlockMap", blocks);

                short[, ,] histogram       = Histogram.Analyze(blocks, image);
                short[, ,] smoothHistogram = Histogram.SmoothAroundCorners(blocks, histogram);
                BinaryMap mask             = Mask.ComputeMask(blocks, histogram);
                float[,] equalized         = Equalizer.Equalize(blocks, image, smoothHistogram, mask);

                byte[,] orientation = Orientation.Detect(equalized, mask, blocks);
                float[,] smoothed   = RidgeSmoother.Smooth(equalized, orientation, mask, blocks);
                float[,] orthogonal = OrthogonalSmoother.Smooth(smoothed, orientation, mask, blocks);

                BinaryMap binary = Binarizer.Binarize(smoothed, orthogonal, mask, blocks);
                binary.AndNot(BinarySmoother.Filter(binary.GetInverted()));
                binary.Or(BinarySmoother.Filter(binary));
                Logger.Log("ResultadoSmoothingBinario", binary);
                CrossRemover.Remove(binary);

                BinaryMap pixelMask = mask.FillBlocks(blocks);
                BinaryMap innerMask = InnerMask.Compute(pixelMask);

                BinaryMap inverted = binary.GetInverted();
                inverted.And(pixelMask);

                SkeletonBuilder ridges  = null;
                SkeletonBuilder valleys = null;
                Parallel.Invoke(
                    () => { ridges = ProcessSkeleton("Ridges", binary); },
                    () => { valleys = ProcessSkeleton("Valleys", inverted); });

                template                = new TemplateBuilder();
                template.OriginalDpi    = dpi;
                template.OriginalWidth  = invertedImage.GetLength(1);
                template.OriginalHeight = invertedImage.GetLength(0);

                MinutiaCollector.Collect(ridges, TemplateBuilder.MinutiaType.Extremidade, template);
                MinutiaCollector.Collect(valleys, TemplateBuilder.MinutiaType.Bifurcação, template);
                MinutiaMask.Filter(template, innerMask);
                StandardDpiScaling.Scale(template);
                MinutiaCloudRemover.Filter(template);
                UniqueMinutiaSorter.Filter(template);
                MinutiaSorter.Shuffle(template);
                Logger.Log("FinalTemplate", template);
            });
            return(template);
        }
示例#15
0
 bool IsOverlapping(Point[] line, BinaryMap shadow)
 {
     for (int i = ToleratedOverlapLength; i < line.Length - ToleratedOverlapLength; ++i)
     {
         if (shadow.GetBit(line[i]))
         {
             return(true);
         }
     }
     return(false);
 }
示例#16
0
 void UpdateBorder()
 {
     if (IsVisible && Mask != null)
     {
         BinaryMap mask = Inverted ? Mask.GetInverted() : Mask;
         SetValue(BorderProperty, Subtract(Expand(Expand(mask)), mask));
     }
     else
     {
         SetValue(BorderProperty, null);
     }
 }
示例#17
0
 static bool IsFalseEnding(BinaryMap binary, Point ending)
 {
     foreach (Point relativeNeighbor in Neighborhood.CornerNeighbors)
     {
         Point neighbor = Calc.Add(ending, relativeNeighbor);
         if (binary.GetBit(neighbor))
         {
             return(Calc.CountBits(binary.GetNeighborhood(neighbor)) > 2);
         }
     }
     return(false);
 }
示例#18
0
 void AddRidge(SkeletonBuilder skeleton, BinaryMap shadow, Gap gap, Point[] line)
 {
     SkeletonBuilder.Ridge ridge = new SkeletonBuilder.Ridge();
     foreach (Point point in line)
     {
         ridge.Points.Add(point);
     }
     ridge.Start = gap.End1;
     ridge.End   = gap.End2;
     foreach (Point point in line)
     {
         shadow.SetBitOne(point);
     }
 }
示例#19
0
        float[, ,] ComputeEqualization(BlockMap blocks, short[, ,] histogram, BinaryMap blockMask)
        {
            float widthMax = RangeSize / 256f * MaxScaling;
            float widthMin = RangeSize / 256f * MinScaling;

            float[] limitedMin = new float[256];
            float[] limitedMax = new float[256];
            for (int i = 0; i < 256; ++i)
            {
                limitedMin[i] = Math.Max(i * widthMin + RangeMin, RangeMax - (255 - i) * widthMax);
                limitedMax[i] = Math.Min(i * widthMax + RangeMin, RangeMax - (255 - i) * widthMin);
            }

            float[, ,] equalization = new float[blocks.CornerCount.Height, blocks.CornerCount.Width, 256];
            Parallel.ForEach(blocks.AllCorners, delegate(Point corner)
            {
                if (blockMask.GetBitSafe(corner.X, corner.Y, false) ||
                    blockMask.GetBitSafe(corner.X - 1, corner.Y, false) ||
                    blockMask.GetBitSafe(corner.X, corner.Y - 1, false) ||
                    blockMask.GetBitSafe(corner.X - 1, corner.Y - 1, false))
                {
                    int area = 0;
                    for (int i = 0; i < 256; ++i)
                    {
                        area += histogram[corner.Y, corner.X, i];
                    }
                    float widthWeigth = RangeSize / area;

                    float top = RangeMin;
                    for (int i = 0; i < 256; ++i)
                    {
                        float width     = histogram[corner.Y, corner.X, i] * widthWeigth;
                        float equalized = top + ToFloatTable[i] * width;
                        top            += width;

                        float limited = equalized;
                        if (limited < limitedMin[i])
                        {
                            limited = limitedMin[i];
                        }
                        if (limited > limitedMax[i])
                        {
                            limited = limitedMax[i];
                        }
                        equalization[corner.Y, corner.X, i] = limited;
                    }
                }
            });
            return(equalization);
        }
示例#20
0
        BinaryMap Expand(BinaryMap map)
        {
            BinaryMap buffer = new BinaryMap(map);

            buffer.Or(map, new RectangleC(0, 0, map.Width - 1, map.Height), new APoint(1, 0));
            buffer.Or(map, new RectangleC(1, 0, map.Width - 1, map.Height), new APoint(0, 0));
            buffer.Or(map, new RectangleC(0, 0, map.Width, map.Height - 1), new APoint(0, 1));
            buffer.Or(map, new RectangleC(0, 1, map.Width, map.Height - 1), new APoint(0, 0));
            buffer.Or(map, new RectangleC(0, 0, map.Width - 1, map.Height - 1), new APoint(1, 1));
            buffer.Or(map, new RectangleC(1, 1, map.Width - 1, map.Height - 1), new APoint(0, 0));
            buffer.Or(map, new RectangleC(0, 1, map.Width - 1, map.Height - 1), new APoint(1, 0));
            buffer.Or(map, new RectangleC(1, 0, map.Width - 1, map.Height - 1), new APoint(0, 1));
            return(buffer);
        }
示例#21
0
 byte[,] ToAngles(PointF[,] vectors, BinaryMap mask)
 {
     byte[,] angles = new byte[mask.Height, mask.Width];
     Parallel.For(0, mask.Height, delegate(int y)
     {
         for (int x = 0; x < mask.Width; ++x)
         {
             if (mask.GetBit(x, y))
             {
                 angles[y, x] = Angle.ToByte(Angle.Atan(vectors[y, x]));
             }
         }
     });
     return(angles);
 }
示例#22
0
        List <Point> FindMinutiae(BinaryMap binary)
        {
            List <Point> result = new List <Point>();

            for (int y = 0; y < binary.Height; ++y)
            {
                for (int x = 0; x < binary.Width; ++x)
                {
                    if (binary.GetBit(x, y) && IsMinutia[binary.GetNeighborhood(x, y)])
                    {
                        result.Add(new Point(x, y));
                    }
                }
            }
            return(result);
        }
示例#23
0
        public BinaryMap DetectLowContrast(byte[,] contrast)
        {
            BinaryMap result = new BinaryMap(contrast.GetLength(1), contrast.GetLength(0));

            for (int y = 0; y < result.Height; ++y)
            {
                for (int x = 0; x < result.Width; ++x)
                {
                    if (contrast[y, x] < Limit)
                    {
                        result.SetBitOne(x, y);
                    }
                }
            }
            Logger.Log(result);
            return(result);
        }
示例#24
0
 public void Draw(SkeletonBuilder skeleton, BinaryMap binary)
 {
     foreach (SkeletonBuilder.Minutia minutia in skeleton.Minutiae)
     {
         binary.SetBitOne(minutia.Position);
         foreach (SkeletonBuilder.Ridge ridge in minutia.Ridges)
         {
             if (ridge.Start.Position.Y <= ridge.End.Position.Y)
             {
                 foreach (Point point in ridge.Points)
                 {
                     binary.SetBitOne(point);
                 }
             }
         }
     }
 }
示例#25
0
        public BinaryMap ComputeMask(BlockMap blocks, short[, ,] histogram)
        {
            byte[,] contrast = Contrast.Compute(blocks, histogram);

            BinaryMap mask = new BinaryMap(AbsoluteContrast.DetectLowContrast(contrast));

            mask.Or(RelativeContrast.DetectLowContrast(contrast, blocks));
            mask.Or(LowContrastMajority.Filter(mask));

            mask.Or(BlockErrorFilter.Filter(mask));
            mask.Invert();
            mask.Or(BlockErrorFilter.Filter(mask));
            mask.Or(BlockErrorFilter.Filter(mask));
            mask.Or(InnerMaskFilter.Filter(mask));

            Logger.Log(mask);
            return(mask);
        }
示例#26
0
        SkeletonBuilder ProcessSkeleton(string name, BinaryMap binary)
        {
            SkeletonBuilder skeleton = null;

            DetailLogger.RunInContext(name, delegate()
            {
                Logger.Log("Binarized", binary);
                BinaryMap thinned = Thinner.Thin(binary);
                skeleton          = new SkeletonBuilder();
                RidgeTracer.Trace(thinned, skeleton);
                DotRemover.Filter(skeleton);
                PoreRemover.Filter(skeleton);
                GapRemover.Filter(skeleton);
                TailRemover.Filter(skeleton);
                FragmentRemover.Filter(skeleton);
                BranchMinutiaRemover.Filter(skeleton);
            });
            return(skeleton);
        }
示例#27
0
        void TraceRidges(BinaryMap binary, Dictionary <Point, SkeletonBuilder.Minutia> minutiaePoints)
        {
            Dictionary <Point, SkeletonBuilder.Ridge> leads = new Dictionary <Point, SkeletonBuilder.Ridge>();

            foreach (Point minutiaPoint in minutiaePoints.Keys)
            {
                foreach (Point startRelative in Neighborhood.CornerNeighbors)
                {
                    Point start = Calc.Add(minutiaPoint, startRelative);
                    if (binary.GetBitSafe(start, false) && !minutiaePoints.ContainsKey(start) && !leads.ContainsKey(start))
                    {
                        SkeletonBuilder.Ridge ridge = new SkeletonBuilder.Ridge();
                        ridge.Points.Add(minutiaPoint);
                        ridge.Points.Add(start);
                        Point previous = minutiaPoint;
                        Point current  = start;
                        do
                        {
                            Point next = new Point();
                            foreach (Point nextRelative in Neighborhood.CornerNeighbors)
                            {
                                next = Calc.Add(current, nextRelative);
                                if (binary.GetBitSafe(next, false) && next != previous)
                                {
                                    break;
                                }
                            }
                            AssertException.Check(next != new Point());
                            previous = current;
                            current  = next;
                            ridge.Points.Add(current);
                        } while (!minutiaePoints.ContainsKey(current));
                        Point end = current;

                        ridge.Start                     = minutiaePoints[minutiaPoint];
                        ridge.End                       = minutiaePoints[end];
                        leads[ridge.Points[1]]          = ridge;
                        leads[ridge.Reversed.Points[1]] = ridge;
                    }
                }
            }
        }
示例#28
0
        SkeletonBuilder ProcessSkeleton(string name, BinaryMap binary)
        {
            SkeletonBuilder skeleton = null;

            DetailLogger.RunInContext(name, delegate()
            {
                Logger.Log("Binarized", binary);
                BinaryMap thinned = Thinner.Thin(binary);
                skeleton          = new SkeletonBuilder();
                RidgeTracer.Trace(thinned, skeleton);

                ////Testing Start
                //var outFileDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "outputSkeletonRidgeTracer-" + name + DateTime.UtcNow.Millisecond + ".bin");
                //var file = new FileStream(outFileDir, FileMode.CreateNew);
                //var binWrite = new BinaryWriter(file);
                //binWrite.Write(skeleton.Minutiae.Count());
                //Console.WriteLine(skeleton.Minutiae.Count());
                //foreach (var minutia in skeleton.Minutiae)
                //{
                //    binWrite.Write(minutia.Valid);
                //    Console.WriteLine(minutia.Valid);
                //    binWrite.Write(minutia.Position.X);
                //    Console.WriteLine(minutia.Position.X);
                //    binWrite.Write(minutia.Position.Y);
                //    Console.WriteLine(minutia.Position.Y);
                //    binWrite.Write(minutia.Ridges.Count);
                //    Console.WriteLine(minutia.Ridges.Count);
                //}
                //binWrite.Close();
                //file.Close();
                ////Testing Finish

                DotRemover.Filter(skeleton);
                PoreRemover.Filter(skeleton);
                GapRemover.Filter(skeleton);
                TailRemover.Filter(skeleton);
                FragmentRemover.Filter(skeleton);
                BranchMinutiaRemover.Filter(skeleton);
            });
            Count++;
            return(skeleton);
        }
示例#29
0
 PointF[,] SumBlocks(PointF[,] orientation, BlockMap blocks, BinaryMap mask)
 {
     PointF[,] sums = new PointF[blocks.BlockCount.Height, blocks.BlockCount.Width];
     Parallel.ForEach(blocks.AllBlocks, delegate(Point block)
     {
         if (mask.GetBit(block))
         {
             PointF sum      = new PointF();
             RectangleC area = blocks.BlockAreas[block];
             for (int y = area.Bottom; y < area.Top; ++y)
             {
                 for (int x = area.Left; x < area.Right; ++x)
                 {
                     sum = Calc.Add(sum, orientation[y, x]);
                 }
             }
             sums[block.Y, block.X] = sum;
         }
     });
     return(sums);
 }
示例#30
0
        PointF[,] AccumulateOrientations(float[,] input, BinaryMap mask, BlockMap blocks)
        {
            List <List <NeighborInfo> > neighbors = PrepareNeighbors();

            PointF[,] orientation = new PointF[input.GetLength(0), input.GetLength(1)];
            Parallel.For(0, mask.Height, delegate(int blockY)
            {
                Range validMaskRange = GetMaskLineRange(mask, blockY);
                if (validMaskRange.Length > 0)
                {
                    Range validXRange = new Range(blocks.BlockAreas[blockY, validMaskRange.Begin].Left,
                                                  blocks.BlockAreas[blockY, validMaskRange.End - 1].Right);
                    for (int y = blocks.BlockAreas[blockY, 0].Bottom; y < blocks.BlockAreas[blockY, 0].Top; ++y)
                    {
                        foreach (NeighborInfo neighbor in neighbors[y % neighbors.Count])
                        {
                            int radius = Math.Max(Math.Abs(neighbor.Position.X), Math.Abs(neighbor.Position.Y));
                            if (y - radius >= 0 && y + radius < input.GetLength(0))
                            {
                                Range xRange = new Range(Math.Max(radius, validXRange.Begin),
                                                         Math.Min(input.GetLength(1) - radius, validXRange.End));
                                for (int x = xRange.Begin; x < xRange.End; ++x)
                                {
                                    float before   = input[y - neighbor.Position.Y, x - neighbor.Position.X];
                                    float at       = input[y, x];
                                    float after    = input[y + neighbor.Position.Y, x + neighbor.Position.X];
                                    float strength = at - Math.Max(before, after);
                                    if (strength > 0)
                                    {
                                        orientation[y, x] = Calc.Add(orientation[y, x], Calc.Multiply(strength, neighbor.Orientation));
                                    }
                                }
                            }
                        }
                    }
                }
            });
            Logger.Log("Raw", orientation);
            return(orientation);
        }