Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将文本图像分离为组件字符图像_Python_Image Processing_Python Imaging Library - Fatal编程技术网

Python 将文本图像分离为组件字符图像

Python 将文本图像分离为组件字符图像,python,image-processing,python-imaging-library,Python,Image Processing,Python Imaging Library,我想把一个文本图像分割成它的组成字符,也作为图像。例如,使用下面的示例,我将得到14幅图像 我只在一行上使用文本,所以y高度不重要-我需要找到每个字母的开头和结尾,并裁剪到这些坐标。这样我也可以避免“I”和“j”等的问题 我是图像处理新手,不知道该怎么做。某种形式的边缘检测?有没有办法确定纯色的连续区域?任何帮助都很好 试图提高我的Python技能并熟悉许多可用库中的一些,所以我使用了,但我也看过OpenCV 示例图像: 这不是一项容易的任务,尤其是在背景不均匀的情况下。如果您拥有的是一个像示

我想把一个文本图像分割成它的组成字符,也作为图像。例如,使用下面的示例,我将得到14幅图像

我只在一行上使用文本,所以y高度不重要-我需要找到每个字母的开头和结尾,并裁剪到这些坐标。这样我也可以避免“I”和“j”等的问题

我是图像处理新手,不知道该怎么做。某种形式的边缘检测?有没有办法确定纯色的连续区域?任何帮助都很好

试图提高我的Python技能并熟悉许多可用库中的一些,所以我使用了,但我也看过OpenCV


示例图像:


这不是一项容易的任务,尤其是在背景不均匀的情况下。如果您拥有的是一个像示例中那样的已经是二进制的图像,那么它会稍微简单一些

如果图像不是二值图像,则可以开始应用阈值算法(大津自适应阈值效果良好)

之后,您可以使用标签算法来识别形成形状的每个像素“岛”(本例中的每个字符)

当你有噪音时,问题就出现了。已标记但您不感兴趣的形状。在这种情况下,您可以使用一些启发式方法来确定形状何时为字符(如果文本位于定义良好的位置,则可以使用规范化区域、对象位置等)。如果这还不够,您将需要处理更复杂的工作人员,如形状特征提取算法和某种模式识别算法,如多层感知器

要完成,这似乎是一项简单的任务,但取决于图像的质量,它可能会变得更加困难。这里引用的算法可以很容易地在互联网上找到,也可以在一些库(如OpenCv)中实现


还有什么需要帮忙的,尽管问,如果我能帮忙的话当然可以;)

我最近一直在玩一个开源的文本分析和ocr预处理工具。作为其工作流程的一部分,它还可以创建所需的图像。也许这会对你有所帮助,尽管不涉及python魔法。

你提出的问题真的很难解决,一些世界上最好的图像处理研究人员花了相当长的时间才解决。该解决方案是图像压缩和显示工具集的主要部分:压缩文档的第一步是识别前景并将其拆分为字符。然后,他们使用这些信息来帮助压缩,因为一个小写字母“e”的图像与另一个小写字母“e”的图像非常相似。压缩文档只需要包含这些差异。你可以在网站上找到一堆技术论文的链接;一个好的开始是


Djvu套件中的许多工具都是在这个标题下开源的;不幸的是,我还没有弄清楚如何使用现有的命令行工具拉出前景(或单个字符)。我非常有兴趣看到这一点。

您可以从一个简单的连接组件分析(CCA)算法开始,它可以通过扫描线算法非常有效地实现(您只需跟踪合并的区域并在最后重新标记)。这将为每个连续区域提供单独编号的“blob”,这适用于大多数(但不是所有)字母。然后,您可以简单地获取每个连接blob的边界框,这将为您提供每个连接blob的轮廓。为了提高效率,您甚至可以在应用CCA时维护边界框

因此,在您的示例中,CCA后面左边的第一个单词会导致如下结果:

1111111  2         3
   1     2
   1     2 4444    5  666
   1     22    4   5 6
   1     2     4   5  666
   1     2     4   5     6
   1     2     4   5  666
等价类为4=2

然后,每个blob的边界框为您提供了字母周围的区域。你会遇到像i和j这样的字母的问题,但它们可以是特殊情况。您可以寻找一个小于某个大小的区域,该区域位于另一个具有某个宽度的区域之上(作为一个粗略的启发)


OpenCV中的库应该可以为您完成大部分工作。

嗯,对于您提供的示例来说,这实际上非常简单:

start at left edge
  go right 1 column at a time until the current column contains black (a letter)
  this is the start of the character
  go right again till no black at all in current column
  end of character
repeat till end of image
(顺便提一下,这也适用于将段落拆分成行。)
如果字母重叠或共享列,则会变得更加困难和有趣

编辑: @安德烈斯,不,它适用于“U”,你必须查看每一列的所有内容

 U   U
 U   U
 U   U
 U   U
  UUU
 01234

0,4:everything but bottom row
1-3:only bottom row

我知道我晚了几年:-)但是现在你可以很容易地用ImageMagick做这类事情,直接在命令行上进行,而无需编译任何东西,因为它连接了内置的组件分析:

这里有一个这样做的方法:

#!/bin/bash
image="$1"
draw=$(convert $image                              \
   -threshold 50%                                  \
   -define connected-components:verbose=true       \
   -define connected-components:area-threshold=10  \
   -connected-components 8                         \
   -auto-level objects.png | \
   awk 'BEGIN{command=""}
        /\+0\+0/||/id:/{next}
        {
          geom=$2
          gsub(/x/," ",geom)
          gsub(/+/," ",geom)
          split(geom,a," ")
          d=sprintf("-draw \x27rectangle %d,%d %d,%d\x27 ",a[3],a[4],a[3]+a[1],a[4]+a[2])
          command = command d
          #printf "%d,%d %d,%d\n",a[3],a[4],a[3]+a[1],a[4]+a[2]
        }
        END{print command}')

eval convert "$image" -fill none -strokewidth 2 -stroke red $draw result.png
结果如下所示:

Objects (id: bounding-box centroid area mean-color):
  0: 539x53+0+0 263.7,24.3 20030 srgba(255,255,255,1)
  11: 51x38+308+14 333.1,30.2 869 srgba(0,0,0,1)
  13: 35x39+445+14 461.7,32.8 670 srgba(0,0,0,1)
  12: 35x39+365+14 381.7,32.8 670 srgba(0,0,0,1)
  2: 30x52+48+0 60.4,27.0 634 srgba(0,0,0,1)
  1: 41x52+1+0 20.9,16.6 600 srgba(0,0,0,1)
  8: 30x39+174+14 188.3,33.1 595 srgba(0,0,0,1)
  7: 30x39+102+14 116.3,33.1 595 srgba(0,0,0,1)
  9: 30x39+230+14 244.3,33.1 595 srgba(0,0,0,1)
  10: 35x39+265+14 282.2,33.0 594 srgba(0,0,0,1)
  16: 33x37+484+15 500.2,33.0 520 srgba(0,0,0,1)
  17: 22x28+272+19 282.3,32.8 503 srgba(255,255,255,1)
  5: 18x51+424+2 432.5,27.9 389 srgba(0,0,0,1)
  6: 18x51+520+2 528.5,27.9 389 srgba(0,0,0,1)
  15: 6x37+160+15 162.5,33.0 222 srgba(0,0,0,1)
  14: 6x37+88+15 90.5,33.0 222 srgba(0,0,0,1)
  18: 22x11+372+19 382.6,24.9 187 srgba(255,255,255,1)
  19: 22x11+452+19 462.6,24.9 187 srgba(255,255,255,1)
  3: 6x8+88+0 90.5,3.5 48 srgba(0,0,0,1)
  4: 6x8+160+0 162.5,3.5 48 srgba(0,0,0,1)

首先,我将你的图像设置为50%的阈值,这样图像中只有纯黑色和白色,没有色调渐变。然后我告诉
ImageMagick
输出它找到的边界框的细节,我对总面积小于10像素的对象不感兴趣。然后,我允许像素8-连接,即到它们的对角邻居(NE、SE、NW、SW)以及它们的左右和上下邻居。最后,我用
awk
解析边界框输出,在边界框周围画红线

我用
awk
解析的初始命令的输出如下所示:

Objects (id: bounding-box centroid area mean-color):
  0: 539x53+0+0 263.7,24.3 20030 srgba(255,255,255,1)
  11: 51x38+308+14 333.1,30.2 869 srgba(0,0,0,1)
  13: 35x39+445+14 461.7,32.8 670 srgba(0,0,0,1)
  12: 35x39+365+14 381.7,32.8 670 srgba(0,0,0,1)
  2: 30x52+48+0 60.4,27.0 634 srgba(0,0,0,1)
  1: 41x52+1+0 20.9,16.6 600 srgba(0,0,0,1)
  8: 30x39+174+14 188.3,33.1 595 srgba(0,0,0,1)
  7: 30x39+102+14 116.3,33.1 595 srgba(0,0,0,1)
  9: 30x39+230+14 244.3,33.1 595 srgba(0,0,0,1)
  10: 35x39+265+14 282.2,33.0 594 srgba(0,0,0,1)
  16: 33x37+484+15 500.2,33.0 520 srgba(0,0,0,1)
  17: 22x28+272+19 282.3,32.8 503 srgba(255,255,255,1)
  5: 18x51+424+2 432.5,27.9 389 srgba(0,0,0,1)
  6: 18x51+520+2 528.5,27.9 389 srgba(0,0,0,1)
  15: 6x37+160+15 162.5,33.0 222 srgba(0,0,0,1)
  14: 6x37+88+15 90.5,33.0 222 srgba(0,0,0,1)
  18: 22x11+372+19 382.6,24.9 187 srgba(255,255,255,1)
  19: 22x11+452+19 462.6,24.9 187 srgba(255,255,255,1)
  3: 6x8+88+0 90.5,3.5 48 srgba(0,0,0,1)
  4: 6x8+160+0 162.5,3.5 48 srgba(0,0,0,1)
awk
将其转化为

convert http://imgur.com/AVW7A.png -fill none -strokewidth 2 -stroke red \
-draw 'rectangle 308,14 359,52'        \
-draw 'rectangle 445,14 480,53'        \
-draw 'rectangle 365,14 400,53'        \
-draw 'rectangle 48,0 78,52'           \
-draw 'rectangle 1,0 42,52'            \
-draw 'rectangle 174,14 204,53'        \
-draw 'rectangle 102,14 132,53'        \
-draw 'rectangle 230,14 260,53'        \
-draw 'rectangle 265,14 300,53'        \
-draw 'rectangle 484,15 517,52'        \
-draw 'rectangle 272,19 294,47'        \
-draw 'rectangle 424,2 442,53'         \
-draw 'rectangle 520,2 538,53'         \
-draw 'rectangle 160,15 166,52'        \
-draw 'rectangle 88,15 94,52'          \
-draw 'rectangle 372,19 394,30'        \
-draw 'rectangle 452,19 474,30'        \
-draw 'rectangle 88,0 94,8'            \
-draw 'rectangle 160,0 166,8' result.png

谢谢你的回复!在这一点上,我只对处理简单的图像感兴趣,比如我提供的示例,黑白文本。我以后可能会考虑其他因素,所以谢谢你的提示。那么,标签算法呢?谷歌很快从OpenCV库中找到了cvBlobsLib,这似乎可以完成查找形状的工作。我不知道接下来该如何拯救他们,但我会试试看。这种方法有问题。“再次向右走,直到没有黑色,字符结束”的步骤不正确。如果y