Пример #1
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;
 }
Пример #2
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);
        }
Пример #3
0
        void Combine(BinaryMap source, RectangleC area, Point at, CombineFunction function)
        {
            int shift      = (int)((uint)area.X & WordMask) - (int)((uint)at.X & WordMask);
            int vectorSize = (area.Width >> WordShift) + 2;

            Parallel.For(0, area.Height,
                         () => new CombineLocals {
                Vector = new uint[vectorSize], SrcVector = new uint[vectorSize]
            },
                         delegate(int y, ParallelLoopState state, CombineLocals locals)
            {
                LoadLine(locals.Vector, new Point(at.X, at.Y + y), area.Width);
                source.LoadLine(locals.SrcVector, new Point(area.X, area.Y + y), area.Width);
                if (shift >= 0)
                {
                    ShiftLeft(locals.SrcVector, shift);
                }
                else
                {
                    ShiftRight(locals.SrcVector, -shift);
                }
                function(locals.Vector, locals.SrcVector);
                SaveLine(locals.Vector, new Point(at.X, at.Y + y), area.Width);
                return(locals);
            }, locals => { });
        }
Пример #4
0
        float[,] PerformEqualization(BlockMap blocks, byte[,] image, float[, ,] equalization, BinaryMap blockMask)
        {
            float[,] result = new float[blocks.PixelCount.Height, blocks.PixelCount.Width];
            Parallel.ForEach(blocks.AllBlocks, delegate(Point block)
            {
                if (blockMask.GetBit(block))
                {
                    RectangleC area = blocks.BlockAreas[block];
                    for (int y = area.Bottom; y < area.Top; ++y)
                        for (int x = area.Left; x < area.Right; ++x)
                        {
                            byte pixel = image[y, x];

                            float bottomLeft = equalization[block.Y, block.X, pixel];
                            float bottomRight = equalization[block.Y, block.X + 1, pixel];
                            float topLeft = equalization[block.Y + 1, block.X, pixel];
                            float topRight = equalization[block.Y + 1, block.X + 1, pixel];

                            PointF fraction = area.GetFraction(new Point(x, y));
                            result[y, x] = Calc.Interpolate(topLeft, topRight, bottomLeft, bottomRight, fraction);
                        }
                }
            });
            Logger.Log(result);
            return result;
        }
Пример #5
0
        public BinaryMap DetectLowContrast(byte[,] contrast, BlockMap blocks)
        {
            List<byte> sortedContrast = new List<byte>();
            foreach (byte contrastItem in contrast)
                sortedContrast.Add(contrastItem);
            sortedContrast.Sort();
            sortedContrast.Reverse();

            int pixelsPerBlock = Calc.GetArea(blocks.PixelCount) / blocks.AllBlocks.TotalArea;
            int sampleCount = Math.Min(sortedContrast.Count, SampleSize / pixelsPerBlock);
            int consideredBlocks = Math.Max(Convert.ToInt32(sampleCount * SampleFraction), 1);

            int averageContrast = 0;
            for (int i = 0; i < consideredBlocks; ++i)
                averageContrast += sortedContrast[i];
            averageContrast /= consideredBlocks;
            byte limit = Convert.ToByte(averageContrast * RelativeLimit);

            BinaryMap result = new BinaryMap(blocks.BlockCount.Width, blocks.BlockCount.Height);
            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;
        }
Пример #6
0
        public BinaryMap Filter(BinaryMap input)
        {
            RectangleC rect = new RectangleC(new Point(BorderDistance, BorderDistance),
                new Size(input.Width - 2 * BorderDistance, input.Height - 2 * BorderDistance));
            BinaryMap output = new BinaryMap(input.Size);
            Parallel.For(rect.RangeY.Begin, rect.RangeY.End, delegate(int y)
            {
                for (int x = rect.Left; x < rect.Right; ++x)
                {
                    RectangleC neighborhood = new RectangleC(
                        new Point(Math.Max(x - Radius, 0), Math.Max(y - Radius, 0)),
                        new Point(Math.Min(x + Radius + 1, output.Width), Math.Min(y + Radius + 1, output.Height)));

                    int ones = 0;
                    for (int ny = neighborhood.Bottom; ny < neighborhood.Top; ++ny)
                        for (int nx = neighborhood.Left; nx < neighborhood.Right; ++nx)
                            if (input.GetBit(nx, ny))
                                ++ones;

                    double voteWeight = 1.0 / neighborhood.TotalArea;
                    if (ones * voteWeight >= Majority)
                        output.SetBitOne(x, y);
                }
            });
            Logger.Log(output);
            return output;
        }
Пример #7
0
 public void And(BinaryMap source, RectangleC area, Point at)
 {
     Combine(source, area, at, delegate(uint[] target, uint[] srcVector)
     {
         for (int i = 0; i < target.Length; ++i)
             target[i] &= srcVector[i];
     });
 }
Пример #8
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);
 }
Пример #9
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;
 }
Пример #10
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);
 }
Пример #11
0
        public BinaryMap Thin(BinaryMap input)
        {
            BinaryMap intermediate = new BinaryMap(input.Size);
            intermediate.Copy(input, new RectangleC(1, 1, input.Width - 2, input.Height - 2), new Point(1, 1));

            BinaryMap border = new BinaryMap(input.Size);
            BinaryMap skeleton = new BinaryMap(input.Size);
            bool removedAnything = true;
            for (int i = 0; i < MaxIterations && removedAnything; ++i)
            {
                removedAnything = false;
                for (int j = 0; j < 4; ++j)
                {
                    border.Copy(intermediate);
                    switch (j)
                    {
                        case 0:
                            border.AndNot(intermediate, new RectangleC(1, 0, border.Width - 1, border.Height), new Point(0, 0));
                            break;
                        case 1:
                            border.AndNot(intermediate, new RectangleC(0, 0, border.Width - 1, border.Height), new Point(1, 0));
                            break;
                        case 2:
                            border.AndNot(intermediate, new RectangleC(0, 1, border.Width, border.Height - 1), new Point(0, 0));
                            break;
                        case 3:
                            border.AndNot(intermediate, new RectangleC(0, 0, border.Width, border.Height - 1), new Point(0, 1));
                            break;
                    }
                    border.AndNot(skeleton);

                    for (int odd = 0; odd < 2; ++odd)
                        Parallel.For(1, input.Height - 1, delegate(int y)
                        {
                            if (y % 2 == odd)
                                for (int xw = 0; xw < input.WordWidth; ++xw)
                                    if (border.IsWordNonZero(xw, y))
                                        for (int x = xw << BinaryMap.WordShift; x < (xw << BinaryMap.WordShift) + BinaryMap.WordSize; ++x)
                                            if (x > 0 && x < input.Width - 1 && border.GetBit(x, y))
                                            {
                                                uint neighbors = intermediate.GetNeighborhood(x, y);
                                                if (IsRemovable[neighbors]
                                                    || IsEnding[neighbors] && IsFalseEnding(intermediate, new Point(x, y)))
                                                {
                                                    removedAnything = true;
                                                    intermediate.SetBitZero(x, y);
                                                }
                                                else
                                                    skeleton.SetBitOne(x, y);
                                            }
                        });
                }
            }

            Logger.Log(skeleton);
            return skeleton;
        }
Пример #12
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;
 }
Пример #13
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);
 }
Пример #14
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;
 }
Пример #15
0
 public BinaryMap(BinaryMap other)
 {
     Width = other.Width;
     Height = other.Height;
     WordWidth = other.WordWidth;
     Map = new uint[other.Map.GetLength(0), other.Map.GetLength(1)];
     for (int y = 0; y < Map.GetLength(0); ++y)
         for (int x = 0; x < Map.GetLength(1); ++x)
             Map[y, x] = other.Map[y, x];
 }
Пример #16
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;
 }
Пример #17
0
 public void AndNot(BinaryMap source, RectangleC area, Point at)
 {
     Combine(source, area, at, delegate(uint[] target, uint[] srcVector)
     {
         for (int i = 0; i < target.Length; ++i)
         {
             target[i] &= ~srcVector[i];
         }
     });
 }
Пример #18
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);
     }
 }
Пример #19
0
 public BinaryMap(BinaryMap other)
 {
     Width     = other.Width;
     Height    = other.Height;
     WordWidth = other.WordWidth;
     Map       = new uint[other.Map.GetLength(0), other.Map.GetLength(1)];
     for (int y = 0; y < Map.GetLength(0); ++y)
     {
         for (int x = 0; x < Map.GetLength(1); ++x)
         {
             Map[y, x] = other.Map[y, x];
         }
     }
 }
Пример #20
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();
 }
Пример #21
0
        public BinaryMap FillCornerAreas(BlockMap blocks)
        {
            BinaryMap result = new BinaryMap(blocks.PixelCount);

            Parallel.For(0, blocks.CornerCount.Height, delegate(int cornerY)
            {
                for (int cornerX = 0; cornerX < blocks.CornerCount.Width; ++cornerX)
                {
                    if (GetBit(cornerX, cornerY))
                    {
                        result.Fill(blocks.CornerAreas[cornerY, cornerX]);
                    }
                }
            });
            return(result);
        }
Пример #22
0
        public BinaryMap FillBlocks(BlockMap blocks)
        {
            BinaryMap result = new BinaryMap(blocks.PixelCount);

            Parallel.For(0, blocks.BlockCount.Height, delegate(int blockY)
            {
                for (int blockX = 0; blockX < blocks.BlockCount.Width; ++blockX)
                {
                    if (GetBit(blockX, blockY))
                    {
                        result.Fill(blocks.BlockAreas[blockY, blockX]);
                    }
                }
            });
            return(result);
        }
Пример #23
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;
 }
Пример #24
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;
        }
Пример #25
0
        public BinaryMap GetInverted()
        {
            BinaryMap result = new BinaryMap(Size);

            for (int y = 0; y < Map.GetLength(0); ++y)
            {
                for (int x = 0; x < Map.GetLength(1); ++x)
                {
                    result.Map[y, x] = ~Map[y, x];
                }
            }
            if (((uint)Width & WordMask) != 0u)
            {
                for (int y = 0; y < Map.GetLength(0); ++y)
                {
                    result.Map[y, Map.GetLength(1) - 1] &= ~0u >> (WordSize - (int)((uint)Width & WordMask));
                }
            }
            return(result);
        }
Пример #26
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;
 }
Пример #27
0
        public void Copy(BinaryMap source, RectangleC area, Point at)
        {
            int shift = (int)((uint)area.X & WordMask) - (int)((uint)at.X & WordMask);

            Parallel.For(0, area.Height,
                         () => new uint[(area.Width >> WordShift) + 2],
                         delegate(int y, ParallelLoopState state, uint[] vector)
            {
                source.LoadLine(vector, new Point(area.X, area.Y + y), area.Width);
                if (shift >= 0)
                {
                    ShiftLeft(vector, shift);
                }
                else
                {
                    ShiftRight(vector, -shift);
                }
                SaveLine(vector, new Point(at.X, at.Y + y), area.Width);
                return(vector);
            }, vector => { });
        }
Пример #28
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;
        }
Пример #29
0
 public void OrNot(BinaryMap source)
 {
     OrNot(source, Rect, new Point());
 }
Пример #30
0
 public void Xor(BinaryMap source)
 {
     Xor(source, Rect, new Point());
 }
Пример #31
0
 public void AndNot(BinaryMap source)
 {
     AndNot(source, Rect, new Point());
 }
Пример #32
0
 public void OrNot(BinaryMap source)
 {
     OrNot(source, Rect, new Point());
 }
Пример #33
0
 public void Xor(BinaryMap source)
 {
     Xor(source, Rect, new Point());
 }
Пример #34
0
 public void Copy(BinaryMap source)
 {
     Copy(source, Rect, new Point());
 }
Пример #35
0
 public float[,] Equalize(BlockMap blocks, byte[,] image, short[, ,] histogram, BinaryMap blockMask)
 {
     float[, ,] equalization = ComputeEqualization(blocks, histogram, blockMask);
     return PerformEqualization(blocks, image, equalization, blockMask);
 }
Пример #36
0
 public void AndNot(BinaryMap source)
 {
     AndNot(source, Rect, new Point());
 }
Пример #37
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;
 }
Пример #38
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;
 }
Пример #39
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;
 }
Пример #40
0
 void Combine(BinaryMap source, RectangleC area, Point at, CombineFunction function)
 {
     int shift = (int)((uint)area.X & WordMask) - (int)((uint)at.X & WordMask);
     int vectorSize = (area.Width >> WordShift) + 2;
     Parallel.For(0, area.Height,
         () => new CombineLocals { Vector = new uint[vectorSize], SrcVector = new uint[vectorSize] },
         delegate(int y, ParallelLoopState state, CombineLocals locals)
         {
             LoadLine(locals.Vector, new Point(at.X, at.Y + y), area.Width);
             source.LoadLine(locals.SrcVector, new Point(area.X, area.Y + y), area.Width);
             if (shift >= 0)
                 ShiftLeft(locals.SrcVector, shift);
             else
                 ShiftRight(locals.SrcVector, -shift);
             function(locals.Vector, locals.SrcVector);
             SaveLine(locals.Vector, new Point(at.X, at.Y + y), area.Width);
             return locals;
         }, locals => { });
 }
Пример #41
0
        public BinaryMap Filter(BinaryMap input)
        {
            ////Testing Start
            //Count++;
            //var inFileDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "inputBinary" + Count + ".bin");
            //var outFileDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "outputBinary" + Count + ".bin");
            //var file = new FileStream(inFileDir, FileMode.CreateNew);
            //var binWrite = new BinaryWriter(file);
            //binWrite.Write(input.WordWidth);
            //Console.WriteLine(input.WordWidth);
            //binWrite.Write(input.Width);
            //Console.WriteLine(input.Width);
            //binWrite.Write(input.Height);
            //Console.WriteLine(input.Height);
            //foreach (var i in input.Map)
            //{
            //    binWrite.Write(i);
            //    Console.WriteLine(i);
            //}
            //binWrite.Close();
            //file.Close();
            ////Testing Finish

            RectangleC rect = new RectangleC(new Point(BorderDistance, BorderDistance),
                new Size(input.Width - 2 * BorderDistance, input.Height - 2 * BorderDistance));
            BinaryMap output = new BinaryMap(input.Size);
            Parallel.For(rect.RangeY.Begin, rect.RangeY.End, delegate (int y)
            {
                for (int x = rect.Left; x < rect.Right; ++x)
                {
                    RectangleC neighborhood = new RectangleC(
                        new Point(Math.Max(x - Radius, 0), Math.Max(y - Radius, 0)),
                        new Point(Math.Min(x + Radius + 1, output.Width), Math.Min(y + Radius + 1, output.Height)));

                    int ones = 0;
                    for (int ny = neighborhood.Bottom; ny < neighborhood.Top; ++ny)
                        for (int nx = neighborhood.Left; nx < neighborhood.Right; ++nx)
                            if (input.GetBit(nx, ny))
                                ++ones;

                    double voteWeight = 1.0 / neighborhood.TotalArea;
                    if (ones * voteWeight >= Majority)
                        output.SetBitOne(x, y);
                }
            });
            Logger.Log(output);

            ////Testing
            //file = new FileStream(outFileDir, FileMode.CreateNew);
            //binWrite = new BinaryWriter(file);
            //binWrite.Write(output.WordWidth);
            //binWrite.Write(output.Width);
            //binWrite.Write(output.Height);
            //foreach (var i in output.Map)
            //{
            //    binWrite.Write(i);
            //}
            //binWrite.Close();
            //file.Close();
            ////Testing End

            return output;
        }