自动检测和识别自然图像中的文本

这个例子展示了如何检测图像中包含文本的区域。这是在非结构化场景上执行的常见任务。非结构化场景是指包含不确定或随机场景的图像。例如,您可以从捕获的视频中自动检测和识别文本,以提醒司机有路标。这与结构化场景不同,结构化场景包含预先知道文本位置的已知场景。

从非结构化场景分割文本极大地帮助完成其他任务,如光学字符识别(OCR)。本例中的自动文本检测算法检测大量文本区域候选,并逐步删除不太可能包含文本的区域。

步骤1:使用MSER检测候选文本区域

MSER特征检测器可以很好地查找文本区域[1]。它适用于文本,因为文本的一致颜色和高对比度导致稳定的强度配置文件。

使用detectMSERFeatures函数查找图像中的所有区域并绘制这些结果。请注意,在文本旁边检测到许多非文本区域。

colorImage = imread (“handicapSign.jpg”);I = rgb2gray (colorImage);%检测MSER区域。[mserRegions,mserConnComp]=检测特征(I,...“RegionAreaRange”,[200 8000],“ThresholdDelta”4);图imshow(我)在…上情节(mserRegions“显示像素列表”符合事实的“showEllipses”、假)标题(“女士地区”)持有

步骤2:删除基于基本几何属性的非文本区域

虽然MSER算法挑选出了大部分的文本,但它也检测出了图像中许多其他稳定的非文本区域。您可以使用基于规则的方法来删除非文本区域。例如,可以使用文本的几何属性来使用简单的阈值过滤掉非文本区域。或者,您可以使用机器学习方法来训练文本分类器和非文本分类器。通常,两种方法的结合会产生更好的结果[4]。这个例子使用了一个简单的基于规则的方法来基于几何属性过滤非文本区域。

有几个几何属性可以很好地区分文本和非文本区域[2,3],包括:

  • 纵横比

  • 古怪

  • 欧拉数

  • 程度

  • 可靠性

使用区域道具测量其中一些属性,然后根据它们的属性值删除区域。

%使用regionprops度量MSER属性mserStats=regionprops(mserConnComp,的边界框(“大小)“怪癖”...“稳健”“程度”“欧拉”“图像”);%使用边界框数据计算宽高比。bbox=vertcat(mserStats.BoundingBox);w=bbox(:,3);h=bbox(:,4);aspectRatio=w./h;%设置数据阈值以确定要删除的区域。这些阈值%可能需要针对其他图像进行调整。filterIdx=aspectRatio>3;filterIdx=filterIdx|[mserStats.偏心率]>0.995;filterIdx=filterIdx|[mserStats.坚固性]<.3;filterIdx=filterIdx|[mserStats.范围]<0.2 |[mserStats.范围]>0.9;filterIdx=filterIdx=filterIdx|[mserStats.EulerNumber]<-4;%去除区域mserStats(filterIdx)=[];mserRegions(filterIdx)=[];显示剩余区域图imshow(我)在…上情节(mserRegions“显示像素列表”符合事实的“showEllipses”、假)标题('基于几何属性删除非文本区域后')持有

步骤3:根据笔划宽度变化删除非文本区域

另一个用来区分文本和非文本的常用指标是笔画宽度。笔划宽度是对构成一个字符的曲线和线条宽度的量度。文本区域的描边宽度变化较小,而非文本区域的描边宽度变化较大。

为了帮助理解如何使用笔画宽度来删除非文本区域,请估计一个检测到的MSER区域的笔画宽度。您可以通过使用距离变换和二进制细化操作[3]来实现这一点。

得到一个区域的二值图像,并填充它以避免边界影响%在描边宽度计算期间。.Image regionImage = mserStats (6);regionImage = padarray(regionImage, [1 1]);计算描边宽度图像。distanceImage = bwdist (~ regionImage);skeletonImage = bwmorph (regionImage,“瘦”、正);strokeWidthImage = distanceImage;strokeWidthImage (~ skeletonImage) = 0;%在笔划宽度图像旁边显示区域图像。图子地块(1,2,1)图像C(区域图像)标题(地区形象的)子批次(1,2,2)图像SC(strokeWidthImage)标题(“笔划宽度的形象”

在上面显示的图像中,注意到描边宽度图像在大部分区域中变化很小。这表明该区域更有可能是文本区域,因为组成该区域的线和曲线都有相似的宽度,这是人类可读文本的共同特征。

为了使用笔画宽度变化来使用阈值删除非文本区域,整个区域的变化必须量化为一个单一的指标,如下所示:

%计算笔划宽度变化度量strokeWidthValues=距离图像(骨架图像);strokeWidthMetric=标准(strokeWidthValues)/平均值(strokeWidthValues);

然后,可以应用一个阈值来删除非文本区域。注意,这个阈值可能需要对具有不同字体样式的图像进行调优。

笔画宽度变化的阈值strokeWidthThreshold = 0.4;strokeWidthFilterIdx = strokeWidthMetric > strokeWidthThreshold;

上述程序必须分别应用于每个检测到的MSER区域。下面的for循环处理所有区域,然后显示使用描边宽度变化删除非文本区域的结果。

%处理剩余区域j = 1:numel(mserStats) regionImage = mserStats(j).Image;regionImage = padarray(regionImage, [1 1], 0);distanceImage = bwdist (~ regionImage);skeletonImage = bwmorph (regionImage,“瘦”strokeWidthValues=距离图像(骨架图像);strokeWidthMetric=标准(strokeWidthValues)/平均值(strokeWidthValues);strokeWidthFilterIdx(j)=strokeWidthMetric>strokeWidthThreshold;结束%根据描边宽度的变化删除区域mserregion(strokeWidthFilterIdx)=[];mserStats(strokeWidthFilterIdx)=[];显示剩余区域图imshow(我)在…上情节(mserRegions“显示像素列表”符合事实的“showEllipses”、假)标题(“基于描边宽度变化删除非文本区域后”)持有

步骤4:合并文本区域以获得最终检测结果

此时,所有检测结果都由单个文本字符组成。为了将这些结果用于识别任务,如OCR,单个文本字符必须合并成单词或文本行。这使得在图像中识别实际的单词,它携带比单个字符更有意义的信息。例如,识别字符串'EXIT' vs.单个字符集{'X','E','T','I'},如果没有正确的顺序,单词的含义就会丢失。

将单个文本区域合并为单词或文本行的一种方法是,首先找到相邻的文本区域,然后在这些区域周围形成一个边界框。要找到相邻区域,请展开前面计算的边界框区域道具。这会使相邻文本区域的边界框重叠,从而使属于同一单词或文本行的文本区域形成重叠边界框链。

%获取所有区域的边界框bboxes = vertcat (mserStats.BoundingBox);%从[x y宽高]边框格式转换为[xmin ymin]%xmax ymax]格式以方便使用。xmin = bboxes (: 1);ymin = bboxes (:, 2);Xmax = xmin + bboxes(:,3) - 1;Ymax = ymin + bboxes(:,4) - 1;%稍微展开边界框。expansionAmount=0.02;xmin=(1-expansionAmount)*xmin;ymin=(1-expansionAmount)*ymin;xmax=(1+expansionAmount)*xmax;ymax=(1+expansionAmount)*ymax;%将边界框剪裁到图像边界内Xmin = max(Xmin, 1);Ymin = max(Ymin, 1);xmax = min(xmax, size(I,2));ymax = min(ymax, size(I,1));显示扩展的边界框扩展dbboxes = [xmin ymin xmax-xmin+1 ymax-ymin+1];IExpandedBBoxes = insertShape (colorImage,“矩形”,展开的B盒,“线宽”,3);图imshow(IExpandedbox)标题(“扩展边框文本”

现在,可以将重叠的边界框合并在一起,以在单个单词或文本行周围形成一个边界框。要做到这一点,计算所有包围盒对之间的重叠比率。这量化了所有文本区域对之间的距离,这样就可以通过寻找非零重叠比率来找到相邻文本区域组。一旦计算出成对重叠比率,使用a查找所有以非零重叠率“连接”的文本区域。

使用bboxOverlapRatio函数计算所有展开的边界框的成对重叠比率,然后使用找到所有连通区域。

%计算重叠率overlapRatio = bboxOverlapRatio(扩展dbboxes,扩展dbboxes);%将边界框与其自身之间的重叠率设置为零到零%简化图形表示。n=大小(重叠比率,1);重叠比率(1:n+1:n^2)=0;%创建图形g=图形(重叠率);%在图形中查找连接的文本区域组件=连接组件(g);

的输出康康普是每个边界框所属的连接文本区域的索引。通过计算组成每个连接组件的单个边界盒的最小值和最大值,使用这些索引将多个相邻边界盒合并为单个边界盒。

%根据最小和最大尺寸合并框。xmin = accumarray(componentIndices', xmin, [], @min);ymin = accumarray(componentIndices', ymin, [], @min);xmax =伏数组(componentIndices', xmax, [], @max);ymax = accumarray(componentIndices', ymax, [], @max); / /组件索引%使用[x y width height]格式合成合并的边界框。textboxes=[xmin-ymin-xmax-xmin+1 ymax-ymin+1];

最后,在显示最终的检测结果之前,通过删除仅由一个文本区域组成的边界框来抑制虚假文本检测。这就消除了不太可能是实际文本的孤立区域,因为文本通常以组(单词和句子)的形式出现。

%删除仅包含一个文本区域的边界框numRegionsInGroup=histcounts(组件索引);textboxes(numRegionsInGroup==1,:)=[];%显示最终的文本检测结果。ITextRegion = insertShape (colorImage,“矩形”,文本框,“线宽”,3);图imshow(ITextRegion)标题(“检测到的文本”

步骤5:使用OCR识别检测到的文本

检测到文本区域后,使用光学字符识别函数来识别每个边界框内的文本。注意,如果不首先查找文本区域,则光学字符识别这个函数的噪音会大得多。

ocrtxt=ocr(I,textboxes);[ocrtxt.Text]
ans=‘所需的手插式停车专用牌照未经授权的车辆可能会被拖走,费用由车主承担’

此示例演示了如何使用MSER特征检测器检测图像中的文本,首先查找候选文本区域,然后描述如何使用几何测量删除所有非文本区域。此示例代码是开发更健壮的文本检测算法的良好起点。请注意,无需进一步增强nts此示例可以为各种其他图像生成合理的结果,例如,posters.jpg或licensePlates.jpg。

参考文献

陈惠忠,等。基于边缘增强最大稳定极值区域的自然图像的鲁棒文本检测图像处理(ICIP), 2011第18届IEEE国际会议。IEEE 2011。

Gonzalez, Alvaro等。“复杂图像中的文本位置。”模式识别(ICPR), 2012第21届国际会议。IEEE 2012。

李,姚,陆虎川。“通过描边宽度检测场景文本。”模式识别(ICPR), 2012第21届国际会议。IEEE 2012。

[4] 实时场景文本定位和识别〉,计算机视觉和模式识别(CVPR),2012年IEEE会议,IEEE,2012年。