Автоматическое обнаружение и распознавание текста в натуральных изображениях

В этом примере показано, как обнаружить области в изображении, которые содержат текст. Это обычная задача, выполняемая на неструктурированных сценах. Неструктурированные сцены являются изображениями, которые содержат неопределенные или случайные сценарии. Например, вы можете автоматически обнаруживать и распознавать текст из захваченного видео, чтобы предупредить драйвер о дорожном знаке. Это отличается от структурированных сцен, которые содержат известные сценарии, где положение текста известно заранее.

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

Шаг 1: Обнаружение текстовых областей кандидата с помощью MSER

Детектор функций MSER хорошо работает для нахождения текстовых областей [1]. Он хорошо работает для текста, потому что последовательный цвет и высокая контрастность текста приводят к стабильным профилям интенсивности.

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

colorImage = imread('handicapSign.jpg');
I = im2gray(colorImage);

% Detect MSER regions.
[mserRegions, mserConnComp] = detectMSERFeatures(I, ... 
    'RegionAreaRange',[200 8000],'ThresholdDelta',4);

figure
imshow(I)
hold on
plot(mserRegions, 'showPixelList', true,'showEllipses',false)
title('MSER regions')
hold off

Figure contains an axes. The axes with title MSER regions contains 1120 objects of type image, line.

Шаг 2. Удаление нетекстовых областей на основе основных геометрических свойств

Несмотря на то, что алгоритм MSER выбирает большую часть текста, он также обнаруживает многие другие стабильные области в изображении, которые не являются текстом. Можно использовать подход, основанный на правилах, для удаления нетекстовых областей. Для примера геометрические свойства текста могут использоваться для фильтрации нетекстовых областей с помощью простых порогов. Кроме того, можно использовать подход машинного обучения для обучения классификатора текста и нетекста. Как правило, комбинация двух подходов дает лучшие результаты [4]. Этот пример использует простой подход на основе правил для фильтрации нетекстовых областей на основе геометрических свойств.

Существует несколько геометрических свойств, которые хороши для различения текстовых и нетекстовых областей [2,3], включая:

  • Соотношение сторон

  • Оригинальность

  • Число Эйлера

  • Степень

  • Основательность

Использование regionprops чтобы измерить несколько из этих свойств и затем удалить области на основе значений их свойств.

% Use regionprops to measure MSER properties
mserStats = regionprops(mserConnComp, 'BoundingBox', 'Eccentricity', ...
    'Solidity', 'Extent', 'Euler', 'Image');

% Compute the aspect ratio using bounding box data.
bbox = vertcat(mserStats.BoundingBox);
w = bbox(:,3);
h = bbox(:,4);
aspectRatio = w./h;

% Threshold the data to determine which regions to remove. These thresholds
% may need to be tuned for other images.
filterIdx = aspectRatio' > 3; 
filterIdx = filterIdx | [mserStats.Eccentricity] > .995 ;
filterIdx = filterIdx | [mserStats.Solidity] < .3;
filterIdx = filterIdx | [mserStats.Extent] < 0.2 | [mserStats.Extent] > 0.9;
filterIdx = filterIdx | [mserStats.EulerNumber] < -4;

% Remove regions
mserStats(filterIdx) = [];
mserRegions(filterIdx) = [];

% Show remaining regions
figure
imshow(I)
hold on
plot(mserRegions, 'showPixelList', true,'showEllipses',false)
title('After Removing Non-Text Regions Based On Geometric Properties')
hold off

Figure contains an axes. The axes with title After Removing Non-Text Regions Based On Geometric Properties contains 1042 objects of type image, line.

Шаг 3: Удаление нетекстовых областей на основе вариаций ширины штриха

Другой распространенной метрикой, используемой для различения текста и нетекста, является ширина штриха. Ширина штриха-это мера ширины кривых и линий, образующих символ. Текстовые области, как правило, имеют небольшие вариации ширины штриха, в то время как нетекстовые области, как правило, имеют большие изменения.

Чтобы помочь понять, как ширина штриха может использоваться, чтобы удалить нетекстовые области, оцените ширину штриха одной из обнаруженных областей MSER. Вы можете сделать это с помощью преобразования расстояния и бинарной операции утончения [3].

% Get a binary image of the a region, and pad it to avoid boundary effects
% during the stroke width computation.
regionImage = mserStats(6).Image;
regionImage = padarray(regionImage, [1 1]);

% Compute the stroke width image.
distanceImage = bwdist(~regionImage); 
skeletonImage = bwmorph(regionImage, 'thin', inf);

strokeWidthImage = distanceImage;
strokeWidthImage(~skeletonImage) = 0;

% Show the region image alongside the stroke width image. 
figure
subplot(1,2,1)
imagesc(regionImage)
title('Region Image')

subplot(1,2,2)
imagesc(strokeWidthImage)
title('Stroke Width Image')

Figure contains 2 axes. Axes 1 with title Region Image contains an object of type image. Axes 2 with title Stroke Width Image contains an object of type image.

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

В порядок использования вариаций ширины штриха для удаления нетекстовых областей с помощью порога значения изменение по всей области должно быть количественно определено в одну метрику следующим образом:

% Compute the stroke width variation metric 
strokeWidthValues = distanceImage(skeletonImage);   
strokeWidthMetric = std(strokeWidthValues)/mean(strokeWidthValues);

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

% Threshold the stroke width variation metric
strokeWidthThreshold = 0.4;
strokeWidthFilterIdx = strokeWidthMetric > strokeWidthThreshold;

Процедура, показанная выше, должна применяться отдельно к каждой обнаруженной области MSER. В следующем цикле for-loop обрабатываются все области, а затем показываются результаты удаления нетекстовых областей с помощью вариаций ширины штриха.

% Process the remaining regions
for j = 1:numel(mserStats)
    
    regionImage = mserStats(j).Image;
    regionImage = padarray(regionImage, [1 1], 0);
    
    distanceImage = bwdist(~regionImage);
    skeletonImage = bwmorph(regionImage, 'thin', inf);
    
    strokeWidthValues = distanceImage(skeletonImage);
    
    strokeWidthMetric = std(strokeWidthValues)/mean(strokeWidthValues);
    
    strokeWidthFilterIdx(j) = strokeWidthMetric > strokeWidthThreshold;
    
end

% Remove regions based on the stroke width variation
mserRegions(strokeWidthFilterIdx) = [];
mserStats(strokeWidthFilterIdx) = [];

% Show remaining regions
figure
imshow(I)
hold on
plot(mserRegions, 'showPixelList', true,'showEllipses',false)
title('After Removing Non-Text Regions Based On Stroke Width Variation')
hold off

Figure contains an axes. The axes with title After Removing Non-Text Regions Based On Stroke Width Variation contains 1032 objects of type image, line.

Шаг 4: Объедините текстовые области для окончательного результата обнаружения

На данной точке все результаты обнаружения состоят из отдельных текстовых символов. Чтобы использовать эти результаты для задач распознавания, таких как OCR, отдельные текстовые символы должны быть объединены в текстовые строки или слова. Это позволяет распознавать фактические слова в изображении, которые несут более значимую информацию, чем только отдельные символы. Например, распознавание строки 'EXIT' по сравнению с набором отдельных символов {'X', 'E', 'T', 'I'}, где значение слова теряется без правильного упорядоченного расположения.

Один из подходов для объединения отдельных текстовых областей в слова или текстовые строки состоит в том, чтобы сначала найти соседние текстовые области, а затем сформировать ограничивающий прямоугольник вокруг этих областей. Чтобы найти соседние области, разверните ограничительные рамки, вычисленные ранее с помощью regionprops. Это заставляет ограничивающие рамки соседних текстовых областей перекрываться так, что текстовые области, которые являются частью одного и того же слова или текстовой строки, образуют цепь перекрывающихся ограничивающих рамок.

% Get bounding boxes for all the regions
bboxes = vertcat(mserStats.BoundingBox);

% Convert from the [x y width height] bounding box format to the [xmin ymin
% xmax ymax] format for convenience.
xmin = bboxes(:,1);
ymin = bboxes(:,2);
xmax = xmin + bboxes(:,3) - 1;
ymax = ymin + bboxes(:,4) - 1;

% Expand the bounding boxes by a small amount.
expansionAmount = 0.02;
xmin = (1-expansionAmount) * xmin;
ymin = (1-expansionAmount) * ymin;
xmax = (1+expansionAmount) * xmax;
ymax = (1+expansionAmount) * ymax;

% Clip the bounding boxes to be within the image bounds
xmin = max(xmin, 1);
ymin = max(ymin, 1);
xmax = min(xmax, size(I,2));
ymax = min(ymax, size(I,1));

% Show the expanded bounding boxes
expandedBBoxes = [xmin ymin xmax-xmin+1 ymax-ymin+1];
IExpandedBBoxes = insertShape(colorImage,'Rectangle',expandedBBoxes,'LineWidth',3);

figure
imshow(IExpandedBBoxes)
title('Expanded Bounding Boxes Text')

Figure contains an axes. The axes with title Expanded Bounding Boxes Text contains an object of type image.

Теперь перекрывающиеся ограничительные рамки могут быть объединены вместе, чтобы сформировать один ограничивающий прямоугольник вокруг отдельных слов или текстовых строк. Для этого вычислите коэффициент перекрытия между всеми ограничивающими прямоугольными парами. Это количественно определяет расстояние между всеми парами текстовых областей, так что можно найти группы соседних текстовых областей, ища ненулевые коэффициенты перекрытия. После вычисления парных коэффициентов перекрытия используйте graph чтобы найти все текстовые области, «связанные» ненулевым коэффициентом перекрытия.

Используйте bboxOverlapRatio функция для вычисления парных коэффициентов перекрытия для всех развернутых ограничивающих рамок, затем используйте graph для поиска всех связанных областей.

% Compute the overlap ratio
overlapRatio = bboxOverlapRatio(expandedBBoxes, expandedBBoxes);

% Set the overlap ratio between a bounding box and itself to zero to
% simplify the graph representation.
n = size(overlapRatio,1); 
overlapRatio(1:n+1:n^2) = 0;

% Create the graph
g = graph(overlapRatio);

% Find the connected text regions within the graph
componentIndices = conncomp(g);

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

% Merge the boxes based on the minimum and maximum dimensions.
xmin = accumarray(componentIndices', xmin, [], @min);
ymin = accumarray(componentIndices', ymin, [], @min);
xmax = accumarray(componentIndices', xmax, [], @max);
ymax = accumarray(componentIndices', ymax, [], @max);

% Compose the merged bounding boxes using the [x y width height] format.
textBBoxes = [xmin ymin xmax-xmin+1 ymax-ymin+1];

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

% Remove bounding boxes that only contain one text region
numRegionsInGroup = histcounts(componentIndices);
textBBoxes(numRegionsInGroup == 1, :) = [];

% Show the final text detection result.
ITextRegion = insertShape(colorImage, 'Rectangle', textBBoxes,'LineWidth',3);

figure
imshow(ITextRegion)
title('Detected Text')

Figure contains an axes. The axes with title Detected Text contains an object of type image.

Шаг 5: Распознавание обнаруженного текста с помощью OCR

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

ocrtxt = ocr(I, textBBoxes);
[ocrtxt.Text]
ans = 
    'HANDICIXPPED
     PARKING
     SPECIAL PLATE
     REQUIRED
     UNAUTHORIZED
     VEHICLES
     MAY BE TOWED
     AT OWNERS
     EXPENSE
     
     '

В этом примере показано, как обнаружить текст в изображении с помощью детектора функций MSER, чтобы сначала найти текстовые области-кандидаты, а затем оно описало, как использовать геометрические измерения для удаления всех нетекстовых областей. Этот пример кода является хорошей начальной точкой для разработки более устойчивых алгоритмов обнаружения текста. Обратите внимание, что без дополнительных улучшений этот пример может привести к разумным результатам для множества других изображений, например, posters.jpg или licensePlates.jpg.

Ссылки

[1] Chen, Huizhong, et al. «Надежное обнаружение текста в естественных изображениях с максимально стабильнейшие экстремальнейшие области с улучшенными кромками». Обработка изображений (ICIP), 2011 18-я Международная конференция IEEE по. IEEE, 2011.

[2] Gonsalez, Alvaro, et al. «Расположение текста в сложных изображениях». Pattern Recognition (ICPR), 2012 21-я Международная конференция. IEEE, 2012.

[3] Ли, Яо и Хучуань Лу. «Обнаружение текста сцены по ширине штриха». Pattern Recognition (ICPR), 2012 21-я Международная конференция. IEEE, 2012.

[4] Нейман, Лукас и Иржи Матас. «Локализация и распознавание текста сцены в реальном времени». Компьютерное зрение and Pattern Recognition (CVPR), 2012 IEEE Conference on. IEEE, 2012.