Как использовать OpenCV для обработки изображения, чтобы текст стал четким и понятным?
Требуется добиться чего-то вроде этого: http://www.leptonica.com/binarization.html
При поиске решений большинство ответов были общими инструкциями, такими как рекомендации по адаптивному фильтру, гауссовскому размытию, расширению и эрозии, но ни один из них не дает кода примера для начала (так что можно играть со значениями)..
Я знаю, что разные изображения требуют разных методов и значений для достижения оптимальной ясности, но мне нужен только общий фильтр, чтобы изображение было по крайней мере немного более резким и менее шумным по сравнению с оригиналом, прежде чем делать какое-либо OCR на нем.
Это то, что я пробовал до сих пор.
Mat imageMat = new Mat();
Utils.bitmapToMat(photo, imageMat);
Imgproc.cvtColor(imageMat, imageMat, Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur(imageMat, imageMat, new Size(3, 3), 0);
Imgproc.adaptiveThreshold(imageMat, imageMat, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 5, 4);
но будучи обработкой изображений newb, очевидно, я не знаю, что я делаю XD
исходное изображение:
![original image]()
после применения вышеуказанного:
![image after applying filters]()
Как это сделать правильно?
UPDATE: он стал намного ближе благодаря мецбургу, берку и Аврелию
Использование метода medianBlur, поскольку cvSmooth с CV_MEDIAN устарел и заменен на medianBlur:
Imgproc.medianBlur(imageMat, imageMat, 3);
Imgproc.threshold(imageMat, imageMat, 0, 255, Imgproc.THRESH_OTSU);
Результат:
![using medianblur before applying otsu]()
Используя метод GaussianBlur, результат на самом деле немного лучше:
Imgproc.GaussianBlur(imageMat, imageMat, new Size(3, 3), 0);
Imgproc.threshold(imageMat, imageMat, 0, 255, Imgproc.THRESH_OTSU);
Результат:
![using gaussianblur before applying otsu]()
Для этого изображения разница не примечательна, поэтому я попробовал другое изображение, снятое с экрана компьютера. Экран компьютера дает много шумов (волнистые линии), поэтому очень трудно удалить шум.
Пример исходного изображения:
![pcscreen original image]()
Непосредственно применение otsu:
![pcscreen directly apply otsu]()
используя medianBlur перед otsu:
![pcscreen using medianBlur before applying otsu]()
с использованием GaussianBlur перед otsu:
![pcscreen using GaussianBlur before applying otsu]()
Кажется, что gaussian blur немного лучше, но я все еще играю с настройками.
Если кто-нибудь может посоветовать, как улучшить изображение на экране компьютера, пожалуйста, сообщите нам об этом:)
Еще одна вещь.. использование этого метода на изображении внутри верхнего звена дает ужасные результаты: (см. Здесь: http://imgur.com/vOZAaE0
Ответы
Ответ 1
Ну, ты почти там. Просто попробуйте следующие модификации:
Вместо
Imgproc.GaussianBlur(imageMat, imageMat, new Size(3, 3), 0);
попробовать:
cvSmooth(imageMat, imageMat, CV_MEDIAN, new Size(3, 3), 0);
проверить синтаксис, не может точно соответствовать
Введенная вами ссылка использует пороговое значение Otsu, поэтому попробуйте следующее:
Imgproc.threshold(imageMat, imageMat, 0, 255, Imgproc.THRESH_OTSU);
для порогового значения.
Попробуйте настроить параметры здесь и там, вы должны получить что-то очень близкое к вашему желаемому результату.
Ответ 2
Вместо использования Imgproc.THRESH_BINARY_INV
используйте Imgproc.THRESH_BINARY
только как _INV инвертирует ваше изображение после бинаризаций, и в результате приведен результат, показанный выше в вашем примере.
правильный код:
Imgproc.adaptiveThreshold(imageMat, imageMat, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 5, 4);