public static void FindTextOfTextBlocks(GrayImage grayImage, List <TextBlock> textBlocks, bool isHorizontalTextLayout)
        {
            blocks           = textBlocks;
            image            = grayImage;
            isHorizontalText = isHorizontalTextLayout;
            ProcessFirstBlock();

            int i;

            for (i = 1; i < blocks.Count - 1; i++)
            {
                if (blocks[i].IsNeedOCRProcess)
                {
                    ProcessPotentialMergeBlock(ref i);
                }
                else
                {
                    ClassifyTextBlock(blocks[i]);
                    isPreviousMerge = false;
                }
            }

            if (i < blocks.Count)
            {
                ProcessFinalBlock();
            }

            PostProcess.Start(blocks, isHorizontalText);
        }
Exemple #2
0
        public static void LinearNormalization(GrayImage img, TextBlock block)
        {
            FindAspectRatioAdaptiveNormalization(block.Height, block.Width, FeatureExtaction.SHAPE_NORM_TARGET_LENGTH);
            float width          = (float)block.Width / NormWidth;
            float height         = (float)block.Height / NormHeigth;
            int   maxColumnIndex = block.Right;
            int   maxRowIndex    = block.Bottom;
            int   shiftLeft      = block.Left;
            int   shiftTop       = block.Top;
            int   imgWidth       = img.Width;
            int   length         = NormWidth * NormHeigth;

            Parallel.For(0, length, (index) =>
            {
                int j  = index % NormWidth;
                int i  = index / NormWidth;
                int x0 = (int)Math.Floor(width * j) + shiftLeft;
                int y0 = (int)Math.Floor(height * i) + shiftTop;

                int imgIndex = imgWidth * y0 + x0;
                if (imgIndex < img.Pixels.Length)
                {
                    Pixels[index] = img.Pixels[imgIndex];
                }
                else
                {
                    Pixels[index] = 0;
                }
            });
        }
Exemple #3
0
        private static void CorrectBlockWidth(GrayImage image, TextBlock block)
        {
            int right       = 0;
            int left        = HorizontalTextProjection.MAX_INT;
            int width       = image.Width;
            int topIndex    = block.Top;
            int bottomIndex = block.Bottom + 1;
            int startIndex  = block.Left;
            int stopIndex   = block.Right + 1;

            for (int rowIndx = topIndex; rowIndx < bottomIndex; rowIndx++)
            {
                int index = rowIndx * width + startIndex;
                for (int j = startIndex; j < stopIndex; j++)
                {
                    if (image.Pixels[index] > 0)
                    {
                        if (j < left)
                        {
                            left = j;
                        }
                        if (j > right)
                        {
                            right = j;
                        }
                    }
                    index++;
                }
            }

            block.Width = right - left + 1;
            block.Left  = left;
            block.Right = right;
        }
Exemple #4
0
        private static bool SplitMultiBlock(List <TextBlock> blocks, uint[] density, GrayImage image, int i)
        {
            int splitIndex = GetSplitIndexOfBlock(blocks[i], density);

            if (splitIndex < blocks[i].Top + 2 || splitIndex > blocks[i].Bottom - 2)
            {
                return(false);
            }

            TextBlock bottomHalf = new TextBlock()
            {
                Left   = blocks[i].Left,
                Right  = blocks[i].Right,
                Top    = splitIndex,
                Bottom = blocks[i].Bottom,
                Height = blocks[i].Bottom - splitIndex + 1,
                Type   = TextBlockType.Multi
            };

            CorrectBlockWidth(image, bottomHalf);
            blocks.Insert(i + 1, bottomHalf);

            blocks[i].Bottom = splitIndex;
            blocks[i].Height = blocks[i].Bottom - blocks[i].Top + 1;
            CorrectBlockWidth(image, blocks[i]);
            return(true);
        }
        public static bool IsWhiteOnBlack(GrayImage image, int threshold)
        {
            int width  = image.Width;
            int height = image.Height;

            int temp    = 0;
            int lastRow = (height - 1) * width;

            for (int j = 0; j < width; j++)
            {
                temp += image.Pixels[j];
                temp += image.Pixels[lastRow + j];
            }

            int lastCol = width - 1;

            for (int i = 0; i < height; i++)
            {
                temp += image.Pixels[i * width];
                temp += image.Pixels[i * width + lastCol];
            }

            double avgDen = (double)(temp) / ((width + height) * 2);

            if (avgDen < threshold)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
        public static void StartBinarized(GrayImage image)
        {
            var  otsu           = GetOtsuBinarizedParams(image);
            bool isWhiteOnBlack = IsWhiteOnBlack(image, otsu.Threshold);

            OtsuBinarizedImage(image, otsu, isWhiteOnBlack);
        }
        private static void DebugTextExtract(GrayImage image, List <TextBlock> textBlocks, ShowImageHandle showImageFunction)
        {
            var displayImage = image.Clone();

            Helper.DrawTextBlockBox(displayImage, textBlocks);
            showImageFunction(displayImage);
        }
Exemple #8
0
        private static long GetRawMoment00(GrayImage img, TextBlock block)
        {
            int  shiftTop        = block.Top;
            int  shiftLeft       = block.Left;
            int  width           = img.Width;
            long moment          = 0;
            int  start           = shiftTop * width + shiftLeft;
            int  textBlockWidth  = block.Width;
            int  textBlockHeight = block.Height;
            int  skipWidth       = width - textBlockWidth;

            for (int i = 0; i < textBlockHeight; i++)
            {
                for (int j = 0; j < textBlockWidth; j++)
                {
                    if (img.Pixels[start] > 0)
                    {
                        moment++;
                    }

                    start++;
                }
                start += skipWidth;
            }
            return(moment);
        }
Exemple #9
0
        public static void DrawTextBlockBox(GrayImage image, List <TextBlock> blocks)
        {
            foreach (var block in blocks)
            {
                int start = block.Top * image.Width + block.Left;
                for (int i = start; i < start + block.Width; i++)
                {
                    image.Pixels[i] = 255;
                }

                start = block.Bottom * image.Width + block.Left;
                for (int i = start; i < start + block.Width; i++)
                {
                    image.Pixels[i] = 255;
                }

                for (int i = block.Top * image.Width + block.Left; i < block.Bottom * image.Width; i += image.Width)
                {
                    image.Pixels[i] = 255;
                }

                for (int i = block.Top * image.Width + block.Right; i < block.Bottom * image.Width; i += image.Width)
                {
                    image.Pixels[i] = 255;
                }
            }
        }
        public GrayImage Clone()
        {
            GrayImage cloneImg = new GrayImage(Width, Height);

            cloneImg.Pixels = new byte[Pixels.Length];
            Pixels.CopyTo(cloneImg.Pixels, 0);
            return(cloneImg);
        }
 private static int[] GetImageHistogram(GrayImage image)
 {
     int[] hist = new int[NUMBER_OF_GRAY_LEVELS];
     for (int i = 0; i < image.Pixels.Length; i++)
     {
         hist[image.Pixels[i]] = hist[image.Pixels[i]] + 1;
     }
     return(hist);
 }
 private static void DebugShapNormilization(GrayImage image, List <TextBlock> textBlocks, ShowImageHandle showImageFunction)
 {
     foreach (var b in textBlocks)
     {
         ShapeNormalization.LinearNormalization(image, b);
         GrayImage bImag = new GrayImage(ShapeNormalization.NormWidth, ShapeNormalization.NormHeigth);
         bImag.Pixels = ShapeNormalization.Pixels;
         showImageFunction(bImag);
     }
 }
        public static List <TextBlock> RecognizeOneWord(GrayImage image)
        {
            ColorConverter.StartBinarized(image);
            var textBlock = Classifier.ClassifyOneText(image);
            var blocks    = new List <TextBlock>(1);

            blocks.Add(textBlock);

            return(blocks);
        }
        public static List <TextBlock> RecognizeSentences(GrayImage image)
        {
            ColorConverter.StartBinarized(image);
            var textBlocks = TextExtraction.FindTextBlocks(image);

            if (textBlocks.Count > 0)
            {
                Classifier.FindTextOfTextBlocks(image, textBlocks, TextExtraction.IsHorizontalText);
            }

            return(textBlocks);
        }
        private static List <TextBlock> ProcessHorizontalLines(GrayImage image, uint[] vertical)
        {
            List <TextBlock>            textBlocks = new List <TextBlock>();
            List <SplitMultiLines.Line> textLines  = SplitMultiLines.SplitProjectDensity(vertical);

            for (int i = 0; i < textLines.Count; i++)
            {
                var density = Projection.ProjectSubImageOnHorizontalLine(image, textLines[i]);
                textBlocks.AddRange(HorizontalTextProjection.FindAllTextBlock(image, density, textLines[i], i));
            }

            return(textBlocks);
        }
        private static List <TextBlock> ProcessVerticalLines(GrayImage image, uint[] horizontal)
        {
            List <TextBlock>            textBlocks = new List <TextBlock>();
            List <SplitMultiLines.Line> textLines  = SplitMultiLines.SplitProjectDensity(horizontal);

            textLines.Reverse(); //Japanese column is going from right to left
            for (int i = 0; i < textLines.Count; i++)
            {
                var density = Projection.ProjectSubImageOnVerticalLine(image, textLines[i]);
                textBlocks.AddRange(VerticalTextProjection.FindAllTextBlock(image, density, textLines[i], i));
            }

            return(textBlocks);
        }
        public static TextBlock ClassifyOneText(GrayImage grayImage)
        {
            isHorizontalText = true;
            image            = grayImage;
            TextBlock block = InitOneTextBlock();

            block.Type             = TextBlockType.Single;
            block.IsNeedOCRProcess = false;
            block.Ratio            = 1;
            block.HeighRatio       = 1;

            ClassifyTextBlock(block);
            return(block);
        }
        /// <summary>
        /// Get sub images from the results returned by SplitProjectDensity()
        /// </summary>
        /// <param name="image">Image that has been analyzed and split by Split(uint[] density)</param>
        /// <param name="space">A split block</param>
        /// <param name="isHorizontal">True if text layout is horizontal</param>
        /// <returns></returns>
        public static GrayImage GetSubImage(GrayImage image, Line block, bool isHorizontal)
        {
            GrayImage subImage;

            if (isHorizontal)
            {
                subImage = GetHorizontalSplitImage(image, block);
            }
            else
            {
                subImage = GetVerticalSplitImage(image, block);
            }
            return(subImage);
        }
 private static List <TextBlock> ExtractTextBlocks(GrayImage image, bool isHorizontalText)
 {
     IsHorizontalText = isHorizontalText;
     if (isHorizontalText)
     {
         var vertical = Projection.ProjectOnVerticalLine(image);
         return(ProcessHorizontalLines(image, vertical));
     }
     else
     {
         var horizontal = Projection.ProjectOnHorizontalLine(image);
         return(ProcessVerticalLines(image, horizontal));
     }
 }
        /// <summary>
        /// This function is for debugging purposes only
        /// </summary>
        /// <param name="image"></param>
        /// <param name="showImageFunction"></param>
        /// <returns></returns>
        public static List <TextBlock> Start(GrayImage image, ShowImageHandle showImageFunction)
        {
            ColorConverter.StartBinarized(image);
            var textBlocks = TextExtraction.FindTextBlocks(image);

            DebugTextExtract(image, textBlocks, showImageFunction);
            //DebugShapNormilization(image, textBlocks, showImageFunction);

            if (textBlocks.Count > 0)
            {
                Classifier.FindTextOfTextBlocks(image, textBlocks, TextExtraction.IsHorizontalText);
            }

            return(textBlocks);
        }
Exemple #21
0
        public static GrayImage ConvertFloatToByteImage(float[] img, int height, int width)
        {
            GrayImage imageOut = new GrayImage(width, height);

            imageOut.Pixels = new byte[width * height];

            float max = float.MinValue;
            float min = float.MaxValue;

            for (int i = 0; i < img.Length; i++)
            {
                if (img[i] > max)
                {
                    max = img[i];
                }

                if (img[i] < min)
                {
                    min = img[i];
                }
            }

            for (int i = 0; i < img.Length; i++)
            {
                img[i] += -min;
            }

            float maxRange = max - min;
            float scale    = 255 / maxRange;
            float value;

            for (int i = 0; i < img.Length; i++)
            {
                value = img[i] * scale;
                if (value > 255)
                {
                    value = 255;
                }
                else if (value < 0)
                {
                    value = 0;
                }

                imageOut.Pixels[i] = (byte)value;
            }

            return(imageOut);
        }
Exemple #22
0
        public static void MomentNormalization(GrayImage img, TextBlock block)
        {
            var M10 = GetRawMoment10(img, block);
            var M01 = GetRawMoment01(img, block);
            var M00 = GetRawMoment00(img, block);

            if (M00 == 0)
            {
                LinearNormalization(img, block);
            }

            var cX  = M10 / M00;
            var cY  = M01 / M00;
            var u20 = GetRawMoment20(img, block) - cX * M10;
            var u02 = GetRawMoment02(img, block) - cY * M01;

            if (u20 <= 0 || u02 <= 0)
            {
                LinearNormalization(img, block);
            }

            double deltaX2 = u20 * 16.0;
            double deltaY2 = u02 * 16.0;
            double deltaX  = Math.Sqrt(deltaX2);
            double deltaY  = Math.Sqrt(deltaY2);

            FindAspectRatioAdaptiveNormalization(deltaY, deltaX, FeatureExtaction.SHAPE_NORM_TARGET_LENGTH);
            double halfWidth  = NormWidth / 2;
            double halfHeight = NormHeigth / 2;
            int    shiftTop   = block.Top;
            int    shiftLeft  = block.Left;
            int    imgWidth   = img.Width;
            int    textWidth  = block.Width;
            int    textHeight = block.Height;
            int    length     = NormWidth * NormHeigth;

            Parallel.For(0, length, (index) =>
            {
                int i             = index / NormWidth;
                int j             = index % NormWidth;
                double xs         = deltaX * (j - halfWidth) / NormWidth + cX;
                double ys         = deltaY * (i - halfHeight) / NormHeigth + cY;
                int x0            = GetOriginalPixelCoordinate(xs, cX, deltaX, deltaX2, textWidth);
                int y0            = GetOriginalPixelCoordinate(ys, cY, deltaY, deltaY2, textHeight);
                int originalIndex = (y0 + shiftTop) * imgWidth + x0 + shiftLeft;
                Pixels[index]     = img.Pixels[originalIndex];
            });
        }
        private static List <TextBlock> ExtractTextBlocks(GrayImage image)
        {
            var vertical   = Projection.ProjectAndFindVarianceOnVerticalLine(image);
            var horizontal = Projection.ProjectAndFindVarianceOnHorizontalLine(image);

            IsHorizontalText = Projection.IsHorizontalTextLayout(vertical.Vtheta, horizontal.Vtheta);

            if (IsHorizontalText)
            {
                return(ProcessHorizontalLines(image, vertical.Density));
            }
            else
            {
                return(ProcessVerticalLines(image, horizontal.Density));
            }
        }
        public static List <TextBlock> FindTextBlocks(GrayImage image, bool?isHorizontal = null)
        {
            List <TextBlock> textBlocks;

            if (isHorizontal == null)
            {
                textBlocks = ExtractTextBlocks(image);
            }
            else
            {
                textBlocks = ExtractTextBlocks(image, (bool)isHorizontal);
            }

            RemoveNoiseTextBlocks(textBlocks);
            return(textBlocks);
        }
 public static void OtsuBinarizedImage(GrayImage image, Otsu otsu, bool isWhiteOnBlack)
 {
     if (isWhiteOnBlack)
     {
         Parallel.For(0, image.Pixels.Length, (i) =>
         {
             image.Pixels[i] = image.Pixels[i] > otsu.Threshold ? image.Pixels[i] : MIN_BINARY;
         });
     }
     else
     {
         Parallel.For(0, image.Pixels.Length, (i) =>
         {
             image.Pixels[i] = image.Pixels[i] > otsu.Threshold ? MIN_BINARY : (byte)(MAX_BINARY - image.Pixels[i]);
         });
     }
 }
Exemple #26
0
        private static List <TextBlock> InitTextBlocks(GrayImage image, uint[] density, int lineIndex)
        {
            sumBlockWidth  = 0;
            sumBlockHeight = 0;

            List <TextBlock> blocks       = new List <TextBlock>();
            bool             isStartBlock = false;
            TextBlock        block;
            int top = 0;

            for (int j = 1; j < density.Length; j++)
            {
                if (density[j] > 0)
                {
                    if (!isStartBlock)
                    {
                        isStartBlock = true;
                        top          = j;
                    }
                }
                else
                {
                    if (isStartBlock)
                    {
                        block           = GetBlock(image, top, j);
                        block.LineIndex = lineIndex;
                        blocks.Add(block);
                        sumBlockHeight += block.Height;
                        sumBlockWidth  += block.Width;
                    }
                    isStartBlock = false;
                }
            }

            if (isStartBlock)
            {
                block           = GetBlock(image, top, image.Height);
                block.LineIndex = lineIndex;
                blocks.Add(block);
                sumBlockHeight += block.Height;
                sumBlockWidth  += block.Width;
            }
            return(blocks);
        }
 private static void GetOutLinePixelsPosition(GrayImage image, ref int left, ref int right, ref int top, ref int bottom)
 {
     if (left > 0)
     {
         left--;
     }
     if (right < image.Width - 1)
     {
         right++;
     }
     if (top > 0)
     {
         top--;
     }
     if (bottom < image.Height - 1)
     {
         bottom++;
     }
 }
        public static uint[] ProjectOnHorizontalLine(GrayImage image)
        {
            int width   = image.Width;
            var density = new uint[width];

            Parallel.For(0, density.Length, (j) =>
            {
                uint lineProject = 0;
                for (int index = j; index < image.Pixels.Length; index += width)
                {
                    if (image.Pixels[index] > 0)
                    {
                        lineProject++;
                    }
                }
                density[j] = lineProject;
            });
            return(density);
        }
        public static uint[] ProjectOnVerticalLine(GrayImage image)
        {
            int width   = image.Width;
            var density = new uint[image.Height];

            Parallel.For(0, density.Length, (i) =>
            {
                int index        = i * width;
                uint lineProject = 0;
                for (int j = 0; j < width; j++)
                {
                    if (image.Pixels[index] > 0)
                    {
                        lineProject++;
                    }
                    index++;
                }
                density[i] = lineProject;
            });
            return(density);
        }
        public static uint[] ProjectSubImageOnHorizontalLine(GrayImage image, SplitMultiLines.Line line)
        {
            int width   = image.Width;
            var density = new uint[width];
            int stop    = line.StartSpace * width;

            Parallel.For(0, width, (j) =>
            {
                int start        = width * line.StartText + j;
                uint lineProject = 0;
                for (int index = start; index < stop; index += width)
                {
                    if (image.Pixels[index] > 0)
                    {
                        lineProject++;
                    }
                }
                density[j] = lineProject;
            });
            return(density);
        }