Jump to content
Compvision.ru

Борода22

Пользователи
  • Content count

    21
  • Joined

  • Last visited

Everything posted by Борода22

  1. Премного благодарен, уважаемый, получилось выровнить изображение.
  2. Приветствую, ребята. Направьте пожалуйста в нужное русло. Задача у меня такая. Распознать реквизиты на платежном документе. Есть скан платежного документа. Т.к. это унифицированная форма документа, то каждый реквизит находится на определенном месте. Подскажите пожалуйста, можно ли как-то извлечь данные по определенным координатам и распознать текст ? Использую OpenCvSharp4. В интернетах находил код (при необходимости могу выложить) и общее описание алгоритма, но совсем не понимаю что, куда и откуда. Буду признателен если кто-то проведет ликбез.
  3. @Smorodov, премного благодарен. Как я понял, параметры dy, dx - разность координат точек отрезка (линии) ?
  4. Прописал вот такой код: 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 ?
  5. Да, спасибо, я уже понял методом "тыка" что представляют эти методы Хорошо, попробую. Просто я линии, которые нашел с помощью HoughLines(), выводил на оригинал изображения. С вашим примером обязательно попробую.
  6. Все-таки видимо нужно идти другим путем. Убрать все прямые вертикальные и горизонтальные линии, т.к. они мешают для утолщения. Написал (поправил чужой код) вот такой код для поиска и отображения прямых линий: 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 ?
  7. @Smorodov, Приветствую, уважаемый! А можно пример в виде используемых функций ? Простите уж за такое наглое пожелание
  8. Вот я обработал контуры, с помощью чего можно их объединить?
  9. Это просто жуть, тут не то что бутылка нужна, нужно заново родиться, и впитывать это с молоком матери
  10. За что отвечает функция GetStructuringElement() и что за параметры используются ?
  11. Все-таки рано радовался. На "эталонном" документе все отрабатывает как нужно, т.к. я распознаю заранее фиксированные области Но предстоит работать со сканированными изображениями, причем, сама форма документа может отличаться от "эталонного" в визуальном плане. Поэтому работа с OpenCV, думаю, все-таки предстоит. Нужно как-то определять границы текста, далее его "вырезать" и скармливать tesseract-у. Походу возвращаюсь к сообщению. Как корректно распознать области(границы) с текстом ?
  12. Да, кажется все нормально, спасибо большое!
  13. Выставил в SingleBlock и все корректно распозналось
  14. Я использую вот такой код: var img = Pix.LoadFromFile(pathToImage); var page = tessEngine.Process(img); string result = page.GetText(); page.Dispose(); Для этого нужно использовать метод Scale() ? Как я понял, нужно для page segmentation mode установить режим single char. Как это сделать ? Установил свойство DefaultPageSegMode = PageSegMode.SingleChar, теперь распознает, но не корректно распознает строки
  15. И вот столкнулся с проблемой. Не хочет распознавать одиночные символы. Например, вот как на скрине. Что можно попытаться предпринять ? Увеличить изображение ? Причем, если "дописать" цифру слева или справа, то распознает корректно.
  16. Использовал tesseract, результаты вполне пригодны.
  17. @Smorodov Спасибо большое за ссылочку, хорошее чтиво.
  18. Разобрался. Все было проще. Устанавливается все из ну-гета, подключается к проекту папка tessdata, в свойствах выставляем - копировать всегда. Теперь склоняюсь ко второму варианту - фиксированные области скармливать tesseract-у. Как по мне - проще и надежнее, чем определять эти области с помощью OpenCV
  19. Установил из Nu-get`а библиотеку Tesseract 4.1. А дальше что ? Как я понял, в проект еще необходимо добавить какие-то библиотеки ?
  20. @Smorodov Спасибо большое. Я уже пробовал использовать tesseract sdk, распознает кириллицу, но как я понял, распознавание идет "потоком". Т.е. распознает все, но в одну строку. Полагаю что разбор такой строки будет еще тот геморрой. Либо я подключал не ту библиотеку, либо что-то не так настроил, но tesseract дает распознать картинку максимальным разрешением в 500 px. Как я понимаю, у меня два пути - поиск областей с данными с помощью OpenCVSharp и потом скармливать эти области tesseract-у, либо определиться с координатами фиксированных областей, и потом опять же, скармливать их tesseract-у для распознавания. Кто что может подсказать ?
  21. У меня есть такой код на шарпе: 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(). У меня тут еще идея возникла. Тупо вырезать определенные области на сканере, и скармливать их tesseract-у
×