В этом примере показано, как обнаружить области изображения, содержащие текст. Это обычная задача, выполняемая на неструктурированных сценах. Неструктурированные сцены - это изображения, содержащие неопределенные или случайные сценарии. Например, можно автоматически обнаружить и распознать текст из снятого видео, чтобы предупредить водителя о дорожном знаке. Это отличается от структурированных сцен, которые содержат известные сценарии, где положение текста известно заранее.
Сегментирование текста из неструктурированной сцены значительно помогает с дополнительными задачами, такими как оптическое распознавание символов (OCR). Алгоритм автоматического обнаружения текста в этом примере обнаруживает большое количество кандидатов в текстовую область и постепенно удаляет те, которые с меньшей вероятностью содержат текст.
Детектор функций 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

Хотя алгоритм 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

Другой общей метрикой, используемой для различения текста и нетекста, является ширина обводки. Ширина обводки - это мера ширины кривых и линий, составляющих символ. Текстовые области имеют тенденцию к незначительному изменению ширины обводки, в то время как нетекстовые области имеют тенденцию к большему изменению.
Чтобы понять, как можно использовать ширину обводки для удаления нетекстовых областей, оцените ширину обводки одной из обнаруженных областей 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')

На изображениях, показанных выше, обратите внимание, что изображение ширины обводки имеет очень небольшое изменение по большей части области. Это указывает на то, что область с большей вероятностью будет текстовой областью, поскольку линии и кривые, составляющие область, имеют одинаковую ширину, что является общей характеристикой читаемого человеком текста.
Чтобы использовать изменение ширины обводки для удаления нетекстовых областей с использованием порогового значения, изменение по всей области должно быть количественно определено в одну метрику следующим образом:
% 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. В следующем примере для-цикла обрабатываются все области, а затем показаны результаты удаления нетекстовых областей с помощью изменения ширины обводки.
% 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

На этом этапе все результаты обнаружения состоят из отдельных текстовых символов. Чтобы использовать эти результаты для задач распознавания, таких как 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')

Теперь перекрывающиеся ограничивающие рамки могут быть объединены вместе, чтобы образовать одну ограничивающую рамку вокруг отдельных слов или текстовых строк. Для этого вычислите коэффициент перекрытия между всеми парами ограничивающих рамок. Это количественно определяет расстояние между всеми парами текстовых областей, так что можно найти группы соседних текстовых областей путем поиска ненулевых коэффициентов перекрытия. После вычисления парных коэффициентов перекрытия используйте 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')

После обнаружения текстовых областей используйте 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] Чен, Хойчжун, и др. «Надежное обнаружение текста в естественных изображениях с расширенными краями и максимально стабильными экстремальными областями». Обработка изображений (ICIP), 2011 18-я Международная конференция IEEE по. IEEE, 2011.
[2] Гонсалес, Альваро и др. «Расположение текста в сложных изображениях». Распознавание образов (ICPR), 2012 21-я Международная конференция по. IEEE, 2012.
[3] Ли, Яо и Хучуань Лу. «Обнаружение текста сцены по ширине обводки». Распознавание образов (ICPR), 2012 21-я Международная конференция по. IEEE, 2012.
[4] Нойман, Лукас и Иржи Матас. «Локализация и распознавание текста сцены в реальном времени». Компьютерное зрение и распознавание образов (CVPR), 2012 Конференция IEEE on. IEEE, 2012.