예제 #1
0
        /// <summary>
        /// Get borders of meaning part of image
        /// </summary>
        /// <param name="angle">Skew angle of image</param>
        /// <param name="completedWidth">Width to which the image was completed</param>
        /// /// <param name="resultWidth">Width of result (deskewed) image</param>
        /// <param name="resultHeight">Height of result (deskewed) image</param>
        /// <param name="projectedImage">Projected image</param>
        /// <param name="originalWidth">Width of original image</param>
        /// <param name="originalHeight">Height of original image</param>
        /// <returns>Rectangle which bounds meaning part of image</returns>
        private static Rectangle GetImageBordersWithoutWhiteSpaces(double angle, int completedWidth, int resultWidth, int resultHeight, KrecImage projectedImage, int originalWidth, int originalHeight)
        {
            var smallImage  = BitmapProcessor.RotateGrayscaleImage(projectedImage, -angle);            // Для скорости, границы обрезки ищем на уменьшенном изображении
            var smallBinary = BitmapProcessor.BinarizeGrayscaleImage(smallImage);

            var cutBorders = ImagePartitioner.GetImageWithoutBorders(smallBinary);

            var k = (double)originalWidth / completedWidth;
            var preComplementWidth  = (int)(originalWidth / k);
            var preComplementHeight = (int)(originalHeight / k);

            var scaleRect = GetUnprojectedRectangle(cutBorders, projectionSideWidth, projectionSideWidth,
                                                    preComplementWidth, preComplementHeight,
                                                    originalWidth, originalHeight, angle);

            int scaleXError = resultWidth / projectionSideWidth;             //Увеличиваем с учетом погрешности
            int scaleYError = resultHeight / projectionSideWidth;

            scaleRect.X = Math.Max(scaleRect.X - scaleXError, 0);
            scaleRect.Y = Math.Max(scaleRect.Y - scaleYError, 0);

            scaleRect.Width  = Math.Min(scaleRect.Width + scaleXError, resultWidth - scaleRect.X);
            scaleRect.Height = Math.Min(scaleRect.Height + scaleYError, resultHeight - scaleRect.Y);
            return(scaleRect);
        }
예제 #2
0
        /// <summary>
        /// Get angle to right image orientation (Multiples Pi/2, from -Pi/2 to Pi)
        /// </summary>
        /// <param name="image">Deskewed mage which nedd to be oriented</param>
        /// <returns>Angle to right orientation</returns>
        public static double GetAngleToRightOrientation(KrecImage image)
        {
            var binary = BitmapProcessor.BinarizeGrayscaleImage(image);

            var result90 = Get90AngleToRightOrientation(binary, image.HorizontalResolution, image.VerticalResolution);

            bool isCorrect90Oriented = result90.Item1;
            var  lines = result90.Item2.Lines;

            // Not enough information to perform calculations of rotation angle
            // All lines contains less than one char inside
            if (lines.All(line => line.Chars.Length <= 1))
            {
                return(0);
            }

            if (!isCorrect90Oriented)
            {
                binary = RotateMatrixBy90(binary);
            }

            CleanUpBinaryFromNoise(binary, result90.Item2.BadChars);

            var linesSum = GetBluredBoundingRectsSums(lines.Select(line => line.BoundingRect), binary);

            double orientSum = 0;

            for (var i = 0; i < linesSum.Count; ++i)
            {
                orientSum += GetLineOrientation(lines[i].BoundingRect, binary, linesSum[i], result90.Item2.MaxCharHeight);
            }

            double expectation = orientSum / linesSum.Count;

            bool isCorrect180Oriented = (Math.Abs(expectation) < 0.011) || orientSum >= 0;             //при мат. ожидании меньше 0.011 результаты данной оценки недостоверны, а статистически вероятнее всего изображение ориентировано правильно

            if (!isCorrect180Oriented && !isCorrect90Oriented)
            {
                return(-Math.PI / 2);
            }
            if (!isCorrect180Oriented)
            {
                return(Math.PI);
            }
            if (!isCorrect90Oriented)
            {
                return(Math.PI / 2);
            }
            return(0);
        }
 /// <summary>
 /// Initialize processor for grayscale image
 /// </summary>
 /// <param name="image">Grayscale image</param>
 public RectanglesProcessor(KrecImage image)
     : this(BitmapProcessor.BinarizeGrayscaleImage(image), image.VerticalResolution)
 {
 }