为 OCR 对齐文本
Align text for OCR
我正在根据历史记录创建一个数据库,这些记录是我从书中拍摄的页面(+100K 页)。在对每个页面进行 OCR 之前,我编写了一些 python 代码来进行一些图像处理。由于这些书中的数据没有以格式良好的表格形式出现,我需要将每一页分成行和列,然后分别对每一部分进行 OCR。
其中一个关键步骤是对齐图像中的文本。
例如,这是一个需要对齐的典型页面:
我找到的一个解决方案是水平涂抹文本(我正在使用 skimage.ndimage.morphology.binary_dilation)并找到使水平方向的白色像素总和最大化的旋转。
这工作正常,但每页大约需要 8 秒,考虑到我正在处理的页面量,这太多了。
您知道更好、更快的对齐文本的方法吗?
更新:
我使用 scikit-image 实现图像处理功能,scipy 最大化水平轴上的白色像素数。
这是我以前处理此问题的 Jupyter notebook 的 link 到 html 视图。该代码使用了我为该项目编写的模块中的一些函数,因此它不能单独 运行。
Link 到笔记本(投递箱):https://db.tt/Mls9Tk8s
更新 2:
这是原始原始图像(dropbox)的link:https://db.tt/1t9kAt0z
这不是一个完整的解决方案,但不仅仅是评论的想法。
您的图片左右、上下都有边距。如果你删除它,甚至在此过程中切入文本,你仍然会有足够的信息来对齐图像。因此,如果您将顶部、底部、左侧和右侧切掉,比如说 15%,那么您的图像区域就已经减少了 50%——这将加快处理速度。
现在把剩下的中心区域分成 10 个高度相同但宽度与页面相同的条带。现在计算这些条带的平均亮度,并取 1-4 个最暗的条带,因为它们包含最多(黑色)的字母。现在并行地处理每一个,或者只是最黑暗的。您现在只处理页面最有趣的 5-20%。
这是在 ImageMagick 中执行此操作的命令 - 它只是我的首选武器,您也可以在 Python.
中执行此操作
convert scan.jpg -crop 300x433+64+92 -crop x10@ -format "%[fx:mean]\n" info:
0.899779
0.894842
0.967889
0.919405
0.912941
0.89933
0.883133 <--- choose 4th last because it is darkest
0.889992
0.88894
0.888865
如果我用这 10 个条纹制作单独的图像,我会得到这个
convert scan.jpg -crop 300x433+64+92 -crop x10@ m-.jpg
实际上,我对倒数第四张图片而不是整张图片进行对齐。
也许不科学,但非常有效并且很容易尝试。
另一个想法,一旦你整理好你的 procedure/script 来拉直单个图像,不要忘记你通常可以通过使用 GNU Parallel
来骚扰你所有的 CPU 来获得巨大的加速同时拥有可爱、昂贵的内核。这里我指定8个进程并行运行...
#!/bin/bash
for ((i=0;i<100000;i++)); do
ProcessPage $i
done | parallel --eta -j 8
前言:我没有用python做过太多图像处理。我可以给你一个图像处理建议,但你必须自己在 Python 中实现它。您只需要一个 FFT 和一个极坐标变换(我认为 OpenCV 有一个 in-built function for that),所以这应该很简单。
您只发布了一张示例图片,所以我不知道这是否适用于其他图片,但对于这张图片,傅立叶变换可能非常有用:只需将图片填充到一个不错的幂两个(例如 2048x2048),你会得到这样的傅立叶频谱:
我发布了傅立叶变换的直观解释 here,但简而言之:您的图像可以表示为一系列 sin/cosine 波,其中大部分 "waves" 与文档方向平行或垂直。这就是为什么您会在大约 0°、90°、180° 和 270° 看到强烈的频率响应。要测量准确的角度,您可以对傅里叶光谱进行极坐标变换:
并简单地取列均值:
该图中的峰值位置在 90.835°,如果我将图像旋转 -90.835 模 90,方向看起来不错:
就像我说的,我没有更多的测试图像,但它适用于图像的旋转版本。至少它应该缩小搜索范围 space 以获得更昂贵的搜索方法。
注1:FFT速度很快,但对于较大的图像显然需要更多时间。遗憾的是,获得更好角度分辨率的最佳方法是使用更大的输入图像(即源图像周围有更多的白色填充。)
注2:FFT实际上returns一幅图像,其中"DC"(上面频谱图像的中心)位于原点0/0。但是旋转属性如果你把它移到中心会更清楚,而且它使极坐标变换更容易,所以我只展示了移位的版本。
"align the text in the image" 我想是指对图像进行校正以使文本行具有相同的基线。
我非常喜欢阅读对这个设计过度的任务的科学答案。答案很好,但是真的有必要花这么多时间(非常宝贵的资源)来实现这个吗?有大量工具可用于此功能,而无需编写一行代码(除非 OP 是 CS 学生并且想实践科学,但显然 OP 这样做是出于处理所有图像的必要)。这些方法让我回到了大学时代,但今天我会使用不同的工具快速高效地处理这批产品,这是我每天都在做的事情。我在一家大批量文档转换和数据提取服务机构和 OCR 咨询公司工作。
这是 ABBYY FineReader 商业桌面 OCR 包中基本打开和校正步骤的结果。去偏移对于进一步的 OCR 处理来说绰绰有余。
而且我不需要为了 post 这个答案而重新创建和编程我自己的浏览器。
我正在根据历史记录创建一个数据库,这些记录是我从书中拍摄的页面(+100K 页)。在对每个页面进行 OCR 之前,我编写了一些 python 代码来进行一些图像处理。由于这些书中的数据没有以格式良好的表格形式出现,我需要将每一页分成行和列,然后分别对每一部分进行 OCR。
其中一个关键步骤是对齐图像中的文本。
例如,这是一个需要对齐的典型页面:
我找到的一个解决方案是水平涂抹文本(我正在使用 skimage.ndimage.morphology.binary_dilation)并找到使水平方向的白色像素总和最大化的旋转。
这工作正常,但每页大约需要 8 秒,考虑到我正在处理的页面量,这太多了。
您知道更好、更快的对齐文本的方法吗?
更新:
我使用 scikit-image 实现图像处理功能,scipy 最大化水平轴上的白色像素数。
这是我以前处理此问题的 Jupyter notebook 的 link 到 html 视图。该代码使用了我为该项目编写的模块中的一些函数,因此它不能单独 运行。
Link 到笔记本(投递箱):https://db.tt/Mls9Tk8s
更新 2:
这是原始原始图像(dropbox)的link:https://db.tt/1t9kAt0z
这不是一个完整的解决方案,但不仅仅是评论的想法。
您的图片左右、上下都有边距。如果你删除它,甚至在此过程中切入文本,你仍然会有足够的信息来对齐图像。因此,如果您将顶部、底部、左侧和右侧切掉,比如说 15%,那么您的图像区域就已经减少了 50%——这将加快处理速度。
现在把剩下的中心区域分成 10 个高度相同但宽度与页面相同的条带。现在计算这些条带的平均亮度,并取 1-4 个最暗的条带,因为它们包含最多(黑色)的字母。现在并行地处理每一个,或者只是最黑暗的。您现在只处理页面最有趣的 5-20%。
这是在 ImageMagick 中执行此操作的命令 - 它只是我的首选武器,您也可以在 Python.
中执行此操作convert scan.jpg -crop 300x433+64+92 -crop x10@ -format "%[fx:mean]\n" info:
0.899779
0.894842
0.967889
0.919405
0.912941
0.89933
0.883133 <--- choose 4th last because it is darkest
0.889992
0.88894
0.888865
如果我用这 10 个条纹制作单独的图像,我会得到这个
convert scan.jpg -crop 300x433+64+92 -crop x10@ m-.jpg
实际上,我对倒数第四张图片而不是整张图片进行对齐。
也许不科学,但非常有效并且很容易尝试。
另一个想法,一旦你整理好你的 procedure/script 来拉直单个图像,不要忘记你通常可以通过使用 GNU Parallel
来骚扰你所有的 CPU 来获得巨大的加速同时拥有可爱、昂贵的内核。这里我指定8个进程并行运行...
#!/bin/bash
for ((i=0;i<100000;i++)); do
ProcessPage $i
done | parallel --eta -j 8
前言:我没有用python做过太多图像处理。我可以给你一个图像处理建议,但你必须自己在 Python 中实现它。您只需要一个 FFT 和一个极坐标变换(我认为 OpenCV 有一个 in-built function for that),所以这应该很简单。
您只发布了一张示例图片,所以我不知道这是否适用于其他图片,但对于这张图片,傅立叶变换可能非常有用:只需将图片填充到一个不错的幂两个(例如 2048x2048),你会得到这样的傅立叶频谱:
我发布了傅立叶变换的直观解释 here,但简而言之:您的图像可以表示为一系列 sin/cosine 波,其中大部分 "waves" 与文档方向平行或垂直。这就是为什么您会在大约 0°、90°、180° 和 270° 看到强烈的频率响应。要测量准确的角度,您可以对傅里叶光谱进行极坐标变换:
并简单地取列均值:
该图中的峰值位置在 90.835°,如果我将图像旋转 -90.835 模 90,方向看起来不错:
就像我说的,我没有更多的测试图像,但它适用于图像的旋转版本。至少它应该缩小搜索范围 space 以获得更昂贵的搜索方法。
注1:FFT速度很快,但对于较大的图像显然需要更多时间。遗憾的是,获得更好角度分辨率的最佳方法是使用更大的输入图像(即源图像周围有更多的白色填充。)
注2:FFT实际上returns一幅图像,其中"DC"(上面频谱图像的中心)位于原点0/0。但是旋转属性如果你把它移到中心会更清楚,而且它使极坐标变换更容易,所以我只展示了移位的版本。
"align the text in the image" 我想是指对图像进行校正以使文本行具有相同的基线。
我非常喜欢阅读对这个设计过度的任务的科学答案。答案很好,但是真的有必要花这么多时间(非常宝贵的资源)来实现这个吗?有大量工具可用于此功能,而无需编写一行代码(除非 OP 是 CS 学生并且想实践科学,但显然 OP 这样做是出于处理所有图像的必要)。这些方法让我回到了大学时代,但今天我会使用不同的工具快速高效地处理这批产品,这是我每天都在做的事情。我在一家大批量文档转换和数据提取服务机构和 OCR 咨询公司工作。
这是 ABBYY FineReader 商业桌面 OCR 包中基本打开和校正步骤的结果。去偏移对于进一步的 OCR 处理来说绰绰有余。
而且我不需要为了 post 这个答案而重新创建和编程我自己的浏览器。