2013-05-15 4 views
2

Я хочу превратить отсканированные изображения в черно-белые изображения, цель состоит в том, чтобы уменьшить размер файла до того, как изображения будут переданы через Интернет для OCR.Бинаризация изображения для OCR

Обычные бинаризационные/черно-белые изображения, созданные сканерами/общим программным обеспечением для редактирования изображений, создают нежелательные результаты.

Множество случайных черных пикселей оставлено позади, которые действительно являются просто шумом от бинаризации, это приводит к тому, что OCR пытается распознать символы там, где их нет, или вставить полные стопы, двоеточия и т. Д. После символов.

Что я могу использовать в OpenCV, чтобы разбить изображение, сохранить линии, символы & темные области сплошного и уменьшить шум пикселей в белых областях?

Я играл с cvThreshold и cvAdaptiveThreshold, но результаты пока невелики.

В качестве примера ознакомьтесь с этим original image и desired result.

+0

Ваш пример, кажется, триниальный, я вижу по крайней мере один оттенок серого в дополнение к черно-белым. –

+0

@MarkRansom Когда я вернулся и посмотрел изображения в IrfanView, я думал, что вы правы, и я должен был сэкономить изображение B & W неправильно. Однако при просмотре изображений в Gimp пиксели - это только черно-белые. Что вы используете для просмотра изображения? В моем случае я доверяю gimp над IrfanView. – Michael

+0

Я смотрел на него в Chrome. Сегодня в Firefox это выглядит хорошо, не знаю, что произошло. –

ответ

2

Вы можете попробовать это, однако вам по-прежнему необходимо настроить некоторые параметры.

#define ALPHA_SCALE 2 
#define THRESHOLD_VAL 40 
#define MAX_VAL_FOR_THRESHOLD 250 
#define PIXEL_MISMATCH_COUNT 10 //9, 7 
Mat current_frame_t2;   

    IplImage *img = cvLoadImage("Original.tiff", CV_LOAD_IMAGE_UNCHANGED); 
    cvNamedWindow("My_Win", CV_WINDOW_AUTOSIZE); 
    // namedWindow("My_Win", 1); 
    cvShowImage("My_Win", img); 
     cvWaitKey(10); 
    Mat current_frame_t1(img); 
    cvtColor(current_frame_t1, current_frame_t2, CV_RGB2GRAY); 
    current_frame_t1.release(); 
    imshow("My_Win", current_frame_t2); 
    cvWaitKey(10); 
    equalizeHist(current_frame_t2, current_frame_t1); 
    current_frame_t2.release(); 
    convertScaleAbs(current_frame_t1, current_frame_t2,ALPHA_SCALE); 

    threshold(current_frame_t2, current_frame_t1, THRESHOLD_VAL, MAX_VAL_FOR_THRESHOLD, CV_THRESH_BINARY); 
    medianBlur(current_frame_t1,current_frame_t2,1); 
    imshow("My_Win", current_frame_t2); 
    imwrite("outimg.tiff", current_frame_t2), 
    cvWaitKey(0); 
1

Вы можете использовать алгоритм connected-components labeling и удалить компоненты, не заполняющие достаточное количество пикселей на изображении.

Один очень простой способ ее реализации в OpenCV использует контуры:

1. Do the preliminary bizariztion of the OCR, that will give you a very noise output. 
2. Find all contours on that noise image. 
3. For each found contour: 
    3.1. Fill the contour with a color different of the two options in the binarized image. 
    3.2. Count the ammount of pixels filled with that color. 
    3.3. If the ammount of pixels are smaller than a given treshold, fill the contour with the void collor of the binary image. 

Для справки: cv::findContours и cv::drawContours.

Можно оптимизировать цикл, классифицирующий более одного контура на 3.1. и подсчет пикселей за один проход для всех этих цветов в 3.2. , Я не прокомментировал оптимизированную версию, потому что возможно, что у вас более 253 разных групп (255 цветов - 2 цвета по умолчанию двоичного изображения), и это не так прямо, чтобы взять это на счет.

+0

Как компьютерное зрение и новичок OpenCV, мне пришлось бы потратить немало времени на изучение вашего ответа, чтобы придумать мою собственную реализацию. Сможете ли вы предоставить небольшой фрагмент кода? – Michael

Смежные вопросы