goo*_*dev 6 ocr opencv image-processing computer-vision image-segmentation
我有一个像这样的 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();
}
}
Run Code Online (Sandbox Code Playgroud)
提前致谢,任何帮助将不胜感激。
补充说明:
正如您在上图中所看到的,文本区域不是矩形,但这些区域可以描述为一堆不同大小的矩形的集合,一个叠一个。
请注意,当两个矩形属于同一个文本时,不要将一个矩形与另一个矩形相邻排列,而只能将一个矩形放在另一个矩形之上。
我想要实现的是这些矩形的集合,并知道每个矩形属于哪个文本。
答案可以是任何编程语言,尤其是在C++ Python和C#
我相信这项任务可以主要使用形态学操作来完成。
在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
Run Code Online (Sandbox Code Playgroud)
首先,我们想使用图像膨胀来创建一个掩码,其中同一部分中的所有单词都相互连接:
d1 = imdilate(img < 0.5, ones(gap));
Run Code Online (Sandbox Code Playgroud)
(如果不是因为打印机在每个部分的底部添加了下一页的烦人的话,我们就已经完成了......)
有一些大的空白没有被扩张填补,我们可以用floodfill它们来完成:
f = imfill(d1, 'holes');
Run Code Online (Sandbox Code Playgroud)
使用腐蚀在不同部分之间进行切割:
e = imerode(f, ones(1, 5*gap)); % erosion only horizontally
Run Code Online (Sandbox Code Playgroud)
向后扩张
d2 = imdilate(e, ones(1, 5*gap));
Run Code Online (Sandbox Code Playgroud)
您现在可以简单地查看此二进制掩码的连接组件:

我希望这对我来说算作“Daf Yomi”...
更新:
下一步 - 从线段到矩形多边形需要一些几何运算,我将在此处概述该方法并将实现细节留给您。
最终,我们需要每个线段的边界多边形,基本多边形是线段的矩形边界框。你必须实现这个“多边形”类。这个类的一个重要方法是“多边形减法” -即poly_result = poly_a - poly_b创建一个新的多边形poly_result是poly_a零下之间的交叉poly_a和poly_b。
这是算法:
你应该得到这样的东西: