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

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

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

Шаг 1: обнаружьте текстовые области кандидата Используя MSER

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

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

colorImage = imread('handicapSign.jpg');
I = rgb2gray(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

Шаг 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

Шаг 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')

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

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

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

% 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

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

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

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

Шаг 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] Чен, Хойчжун, и др. "Устойчивое текстовое Обнаружение в Естественных Изображениях с Улучшенными Ребром Максимально Стабильными Экстремальными областями". Обработка изображений (ICIP), 2 011 18-х Международных конференций IEEE по вопросам. IEEE, 2011.

[2] Гонсалес, Альваро, и др. "Текстовое местоположение в комплексных изображениях". Распознавание образов (ICPR), 2 012 21-х Международных конференций по вопросам. IEEE, 2012.

[3] Литий, Яо и Хучуэн Лу. "Текстовое обнаружение сцены через штриховую ширину". Распознавание образов (ICPR), 2 012 21-х Международных конференций по вопросам. IEEE, 2012.

[4] Нейман, Лукаш и Иржи Матас. "Текстовая локализация сцены в реальном времени и распознавание". Компьютерное зрение и Распознавание образов (CVPR), 2 012 Конференций по IEEE по. IEEE, 2012.