问题描述
我有一个像这样的Talmud页面:
我想用opencv
查找文本区域以得到这样的结果,即每个文本都将像这样:
在所附图像中,每个区域用不同的颜色标记,并且文本具有数字,重要的是识别属于每个文本的区域,并将其与另一个文本的区域(数字顺序)区分开没关系。
根据文本之间传递的白色条纹,用眼睛做起来真的很容易,但是我尝试用opencv
做,但是我做不到。
在下面的代码中,我尝试捕获所有字母并将它们变成黑色矩形, 然后放大每个矩形,使其与相邻的矩形相交, 这样,整个文本区域将是黑色的,并且在文本之间将出现清晰的白色条纹。
public List<Rectangle> getRects(Mat grayImg)
{
BlobCounter blobCounter = new BlobCounter();
blobCounter.ObjectsOrder = ObjectsOrder.None;
blobCounter.ProcessImage(grayImg);
IEnumerable<Blob> blobs = blobCounter.Getobjectsinformation();
var blackBlobs = grayImg.Clone;
foreach (var b in blobs)
blackBlobs.Rectangle(b.Rectangle.ToCvRect,Scalar.Black,-1);
var widths = blobs.Select(X => X.Rectangle.Width).ToList;
widths.sort();
var median = widths(widths.Count / (double)2);
Mat erodet = new Mat();
Cv2.Erode(grayImg,erodet,null,iterations: median);
using (Window win = new Window())
{
win.ShowImage(erodet);
win.WaitKey();
}
}
在此先感谢您的帮助。
其他说明:
如上图所示,文本区域不是矩形, 但是,这些区域可以描述为不同大小的矩形的集合,这些矩形排列成一堆,一个堆在另一个堆上。
请注意,当两个矩形属于同一文本时,请勿将一个矩形排列在另一个矩形的旁边,而只能将一个矩形排列在另一个矩形的上方。
我想要实现的是这些矩形的集合,并知道其所属的每个矩形。
答案可以使用任何编程语言,尤其是C++
Python
和C#
解决方法
我相信可以使用morphological operations来完成此任务。
在matlab中显示概念比较容易,但是opencv具有等效的操作。
我们首先粗略估计页面不同部分之间的间隙大小。以您的示例为例,该间隙约为页面高度的1%。
img = im2single(rgb2gray(imread('https://i.stack.imgur.com/LoV5x.jpg'))); % read the image into 1ch gray scale image in range [0,1]
gap = ceil(size(img,1) * 0.01); % gap estimation
首先,我们想使用图像dilation创建一个掩码,其中同一节中的所有单词都相互连接:
d1 = imdilate(img < 0.5,ones(gap));
(如果不是下一页中令人讨厌的单词,打印机将在每个部分的底部添加...)
膨胀没有填补一些大的空白,我们可以使用floodfill
来完成它们:
f = imfill(d1,'holes');
使用erosion在不同部分之间切换:
e = imerode(f,ones(1,5*gap)); % erosion only horizontally
向后扩张
d2 = imdilate(e,5*gap));
您现在可以简单地查看此二进制掩码的connected components:
我希望这对我来说算是“达夫·尤米” ...
更新:
下一步-从线段到矩形多边形需要进行一些几何运算,我将在此处概述该方法,并将实现细节留给您。
最终,我们希望每个分段都具有边界polygon,基本多边形是分段的矩形边界框。您必须实现此“多边形”类。此类的一种关键方法是“多边形减法”-poly_result = poly_a - poly_b
创建一个新的多边形poly_result
,该多边形poly_a
减去poly_a
和poly_b
之间的交点
这是算法:
- 对于每个分段计算,它都是边界框,边界框的面积以及分段中的实际像素数。
将每个线段的多边形初始化为其边界框。 - 根据像素数与边框区域的比率按降序对片段进行排序。
- 对于每个段,按降序排列:
从该线段中减去所有先前的多边形。
您应该得到这样的东西:
,根据我的观察,您首先尝试进行布局分析以提取感兴趣的区域。这是一个研究领域,不是很广为人知,但是对于该问题有一些很好的结果。如果不确定使用opencv
解决此问题,建议您研究光学布局识别(OLR)。 LAREX开源工具是一个很好的起点。