Перейти к содержимому
Compvision.ru

Борода22

Пользователи
  • Количество публикаций

    21
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные пользователем Борода22


  1. Прописал вот такой код:

    var lines = Cv2.HoughLinesP(thresh_img, 1, Math.PI / 180, 200, 150, 30);
    LineSegmentPoint max_line = new LineSegmentPoint();
    for (int i = 0; i < lines.Length; i++)
    {
       // получаем максимальную длинную прямую
       if (lines[i].Length() > max_line.Length())
       {
          max_line = lines[i];
       }
       Cv2.Line(original_img, lines[i].P1, lines[i].P2, new Scalar(0, 0, 250), 2);
    }
    // выводим линию максимальной длины
    Cv2.Line(original_img, max_line.P1, max_line.P2, new Scalar(255, 0, 0), 3);

    отображает вот в таком виде (синяя линия - это максимально прямая линия)

    Как теперь определить угол поворота по синей линии ? Это необходимо для выравнивания скана документа.

    Как я понял, угол можно получить с помощью HoughLines(), можно ли как-то получит угол по LineSegmentPoint ?

    lines-2.png


  2. В 12.08.2020 at 17:48, Smorodov сказал:

    По поводу морфологических операций, cv::dilate затем cv::erode.

    Да, спасибо, я уже понял методом "тыка" что представляют эти методы

    В 12.08.2020 at 17:48, Smorodov сказал:

    Для детектора линий, нужно белое изображение на черном фоне

    Хорошо, попробую. Просто я линии, которые нашел с помощью HoughLines(), выводил на оригинал изображения. С вашим примером обязательно попробую.


  3. Все-таки видимо нужно идти другим путем. Убрать все прямые вертикальные и горизонтальные линии, т.к. они мешают для утолщения.

    Написал (поправил чужой код) вот такой код для поиска и отображения прямых линий:

    Mat original_img = new Mat(PathToImage);
    Mat gray_img = original_img.CvtColor(ColorConversionCodes.BGR2GRAY);
    Mat thresh_img = gray_img.Threshold(0, 255, ThresholdTypes.Otsu | ThresholdTypes.BinaryInv);
    
    var lines = Cv2.HoughLines(thresh_img, 200, Math.PI/180, 2);
    
    for(int x = 0; x < lines.Count(); x++)
    {
       float rho = lines[x].Rho;
       float theta = lines[x].Theta;
    
       double a = Math.Cos(theta);
       double b = Math.Sin(theta);
       double x0 = a * rho;
       double y0 = b * rho;
    
       LineSegmentPoint point = new LineSegmentPoint();
    
       point.P1.X = (int)Math.Round(x0 + (1000 * (-b)));
       point.P1.Y = (int)Math.Round(y0 + (1000 * (a)));
    
       point.P2.X = (int)Math.Round(x0 - (1000 * (-b)));
       point.P2.Y = (int)Math.Round(y0 - (1000 * (a)));
    
       Cv2.Line(original_img, point.P1, point.P2, new Scalar(0, 200, 20));
    }

    Но линии рисуются вообще не правильно (рисуются диагоналями, под углом), я так понимаю, что накосячил где-то в преобразовании координат ?

    И что это за магические числа в виде 1000 ?

    lines.png


  4. Все-таки рано радовался. На "эталонном" документе все отрабатывает как нужно, т.к. я распознаю заранее фиксированные области Но предстоит работать со сканированными изображениями, причем, сама форма документа может отличаться от "эталонного" в визуальном плане. Поэтому работа с OpenCV, думаю, все-таки предстоит. Нужно как-то определять границы текста, далее его "вырезать" и скармливать tesseract-у. Походу возвращаюсь к сообщению.

    Как корректно распознать области(границы) с текстом ?


  5. Я использую вот такой код:

    var img = Pix.LoadFromFile(pathToImage);
    var page = tessEngine.Process(img);
    string result = page.GetText();
    page.Dispose();

     

    47 минут назад, Smorodov сказал:

    попробуйте увеличить размер изображения

    Для этого нужно использовать метод Scale() ?

    Как я понял, нужно для page segmentation mode установить режим single char. Как это сделать ?

    Установил свойство DefaultPageSegMode = PageSegMode.SingleChar, теперь распознает, но не корректно распознает строки :lol:


  6. И вот столкнулся с проблемой. Не хочет распознавать одиночные символы. Например, вот как на скрине. Что можно попытаться предпринять ? Увеличить изображение ? Причем, если "дописать" цифру слева или справа, то распознает корректно.

    cropped_image.jpg


  7. Разобрался. Все было проще. Устанавливается все из ну-гета, подключается к проекту папка tessdata, в свойствах выставляем - копировать всегда. Теперь склоняюсь ко второму варианту - фиксированные области скармливать tesseract-у. Как по мне - проще и надежнее, чем определять эти области с помощью OpenCV


  8. @Smorodov Спасибо большое. Я уже пробовал использовать tesseract sdk, распознает кириллицу, но как я понял, распознавание идет "потоком". Т.е. распознает все, но в одну строку. Полагаю что разбор такой строки будет еще тот геморрой. Либо я подключал не ту библиотеку, либо что-то не так настроил, но tesseract дает распознать картинку максимальным разрешением в 500 px.

    Как я понимаю, у меня два пути - поиск областей с данными с помощью OpenCVSharp и потом скармливать эти области tesseract-у, либо определиться с координатами фиксированных областей, и потом опять же, скармливать их tesseract-у для распознавания. Кто что может подсказать :) ?


  9. У меня есть такой код на шарпе:

            public void RunTextRecog()
            {
                List<Rect> boundRect = new List<Rect>();
    
                using (Mat img = new Mat(PathToImage))
                using (Mat img_gray = new Mat())
                using (Mat img_sobel = new Mat())
                
                using (Mat img_threshold = new Mat())
                {
                    Cv2.CvtColor(img, img_gray, ColorConversionCodes.BGR2GRAY);
                    Cv2.Sobel(img_gray, img_sobel, MatType.CV_8U, 1, 0, 3, 1, 0, BorderTypes.Default);
                    //Cv2.AdaptiveThreshold(img_sobel, img_threshold, 250, AdaptiveThresholdTypes.GaussianC, ThresholdTypes.Binary, 3, 1);
                    Cv2.Threshold(img_sobel, img_threshold, 0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);
                    using (Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(20, 20)))
                    {
                        Cv2.MorphologyEx(img_threshold, img_threshold, MorphTypes.Close, element);
                        Point[][] edgesArray = img_threshold.Clone().FindContoursAsArray(RetrievalModes.External, ContourApproximationModes.ApproxNone);
                        foreach (Point[] edges in edgesArray)
                        {
                            Point[] normalizedEdges = Cv2.ApproxPolyDP(edges, 17, true);
                            Rect appRect = Cv2.BoundingRect(normalizedEdges);
                            boundRect.Add(appRect);
                        }
                    }
    
                    for (int ind = 0; ind < boundRect.Count; ind++)
                    {
                        Cv2.Rectangle(img,
                            new Point(boundRect[ind].X, boundRect[ind].Y),
                            new Point(boundRect[ind].X + boundRect[ind].Width, boundRect[ind].Y + boundRect[ind].Height),
                            new Scalar(100, 200, 0),
                            3);
                    }
                    Mat resize_img = new Mat();
                    Cv2.ImShow("Результат", img);
                    Cv2.ImShow("Собель", img_sobel);
                    Cv2.ImShow("Threshold", img_threshold);
                    Cv2.ImShow("Grey", img_gray);
                    Cv2.ImWrite("segmented.jpg", img);
                }
            }

    Результаты на скриншотах. Как я понял опытным путем (изменяя параметры), выделение объектов происходит с помощью GetStructuringElement().

    original.png

    sobel.png

    threshold.png

    result.png

    У меня тут еще идея возникла. Тупо вырезать определенные области на сканере, и скармливать их tesseract-у


  10. Приветствую, ребята. Направьте пожалуйста в нужное русло. Задача у меня такая. Распознать реквизиты на платежном документе. Есть скан платежного документа. Т.к. это унифицированная форма документа, то каждый реквизит находится на определенном месте. Подскажите пожалуйста, можно ли как-то извлечь данные по определенным координатам и распознать текст ? Использую OpenCvSharp4. В интернетах находил код (при необходимости могу выложить) и общее описание алгоритма, но совсем не понимаю что, куда и откуда. Буду признателен если кто-то проведет ликбез.

×