Jump to content
Compvision.ru
Борода22

Распознавание реквизитов платежного документа

Recommended Posts

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

Share this post


Link to post
Share on other sites

Предлагаю начать либо с голого tesseract-ocr, либо с примеров из opencv_text. А потом по результатам.

  • Like 1

Share this post


Link to post
Share on other sites

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

        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-у

Share this post


Link to post
Share on other sites

Прислушайтесь к тому, что советует Nuzhny, начните с tesseract-ocr, есть даже бинды под шарп https://github.com/charlesw/tesseract например. 

Пример применения : https://github.com/charlesw/tesseract-samples

Но если есть много энергии и желание повозиться, пишите, посоветуем по шагам, но это длинный путь )

 

  • Like 1

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

Установил из Nu-get`а библиотеку Tesseract 4.1. А дальше что ? Как я понял, в проект еще необходимо добавить какие-то библиотеки ?

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

В OpenCv ecть встроенные детекторы текста, гляньте здесь: https://www.pyimagesearch.com/2018/08/20/opencv-text-detection-east-text-detector/

 

  • Like 1

Share this post


Link to post
Share on other sites

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

cropped_image.jpg

Share this post


Link to post
Share on other sites

Может там фильтр по минимальной площади текста стоит, попробуйте увеличить размер изображения, или посмотрите параметры тессеракта, помнится таи их огромная куча была.

Вот, кстати:

https://www.sk-spell.sk.cx/tesseract-ocr-parameters-in-302-version

  • Like 1

Share this post


Link to post
Share on other sites

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

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:

Share this post


Link to post
Share on other sites

На CPP это cv::resize , на шарпе не знаю.

Ну если все получилось, поздравляю!  ))  

Share this post


Link to post
Share on other sites
15 часов назад, Smorodov сказал:

Ну если все получилось, поздравляю!  ))  

Да, кажется все нормально, спасибо большое!

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

На английском конечно, но по теме ) : https://www.pyimagesearch.com/2014/09/01/build-kick-ass-mobile-document-scanner-just-5-minutes/

GetStructuringElement создает структурный элемент для морфологических операций (эрозия, дилатация, открытие, закрытие .... ) элемент представляет собой маленький шаблончик в виде прямоугольника заполненного единицами, реже используется эллипс, крест, и т.д. Посмотрите про морфологические операции и все станет ясно. 

https://ru.wikipedia.org/wiki/Математическая_морфология

 

Share this post


Link to post
Share on other sites
12 часа назад, Smorodov сказал:

На английском конечно, но по теме )

Это просто жуть, тут не то что бутылка нужна, нужно заново родиться, и впитывать это с молоком матери:lol:

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.

×