如何自动化Linux中的图像切片过程?

时间:2017-07-04 15:10:53

标签: opencv image-processing imagemagick tesseract gimp

输入图片 enter image description here

我需要如下,

output explanation 输出方案

需要执行以下步骤。

  1. 处理输入图像
  2. 根据水平文本行之间的间隙将图像分割为更多图像。
  3. 然后将该图像存储在连续编号中。
  4. 再次处理每个图像,并根据每个单词之间的空格分割成更多图像。
  5. 然后将其存储在每张图片中。
  6. 如果可能,我需要输入图像中的单个字符图像,我不需要文本提取。由于所有泰米尔语OCR都没有正确解密。

1 个答案:

答案 0 :(得分:0)

这是一种方法 - 它可能并不完美但如果您有更多图像可供测试,您可以调整它。

基本的想法是增加单个字母,使它们相互接触,但希望不会跨越相邻的单词。然后执行“连接组件分析”,找到原始文本的单个单词作为blob。

这是第一步 - 用 ImageMagick

增加字母的增长效果
convert text.png -threshold 50% -morphology erode diamond:4 step1.png

enter image description here

我正在使用上面的形态学技术,但你可以尝试模糊和阈值技术。

现在找到“blob”:

convert step1.png \
    -define connected-components:verbose=true        \
    -define connected-components:area-threshold=100  \
    -connected-components 8 -auto-level output.png

示例输出

Objects (id: bounding-box centroid area mean-color):
  0: 1086x188+0+0 556.4,83.0 155156 gray(255)
  7: 364x65+128+118 281.8,142.6 9206 gray(0)
  6: 212x34+817+115 919.3,131.1 4691 gray(0)
  4: 231x33+73+76 184.4,92.3 4645 gray(0)
  2: 181x42+494+8 578.4,27.7 4399 gray(0)
  9: 209x31+608+118 713.1,132.9 3892 gray(0)
  17: 148x34+826+148 903.0,165.1 2932 gray(0)
  22: 132x34+20+153 84.1,169.1 2453 gray(0)
  20: 126x27+384+151 443.4,165.9 2404 gray(0)
  1: 91x42+396+8 440.3,29.0 2390 gray(0)
  18: 117x34+708+149 764.2,165.5 2350 gray(0)
  21: 104x33+509+151 560.3,167.6 2245 gray(0)
  23: 112x27+271+158 325.8,169.3 2159 gray(0)
  8: 100x33+507+118 558.2,134.6 1982 gray(0)
  19: 91x33+615+150 659.4,166.2 1888 gray(0)
  10: 55x25+73+121 100.0,134.4 920 gray(0)
  3: 28x29+361+12 373.8,27.5 456 gray(0)

上面的每一行对应一个blob,或者希望是原始文本中的一个单词。第一行是标题行,它告诉您字段是什么。每个后续行上的第二个字段是一个blob的WIDTH X HEIGHT和X Y OFFSET(从图像的左上角开始),后跟其质心及其区域,最后一个字段是平均颜色。

你不需要下一步,因为我想描述每个单词的文字行是你需要的,但是通过插图的方式,我可以在原始图像的方框中画画:

convert "text.png" -stroke red -fill none -strokewidth 1 \
   -draw "rectangle 128,118 492,183"  \
   -draw "rectangle 817,115 1029,149" \
   -draw "rectangle 73,76 304,109"    \
   -draw "rectangle 494,8 675,50"     \
   -draw "rectangle 608,118 817,149"  \
   -draw "rectangle 826,148 974,182"  \
   -draw "rectangle 20,153 152,187"   \
   -draw "rectangle 384,151 510,178"  \
   -draw "rectangle 396,8 487,50"     \
   -draw "rectangle 708,149 825,183"  \
   -draw "rectangle 509,151 613,184"  \
   -draw "rectangle 271,158 383,185"  \
   -draw "rectangle 507,118 607,151"  \
   -draw "rectangle 615,150 706,183"  \
   -draw "rectangle 73,121 128,146"   \
   -draw "rectangle 361,12 389,41" result.png

enter image description here

你实际上并不需要像我上面那样创建中间图像,你可以一次完成所有操作,但我想解释一下我的技术:

convert text.png -threshold 50% -morphology erode diamond:4 \
    -define connected-components:verbose=true               \
    -define connected-components:area-threshold=100         \
    -connected-components 8 -auto-level output.png

输出图像(output.png)实际上是“标记为”,我的意思是每个识别出的斑点的所有像素都以连续较浅的白色阴影着色。

enter image description here

请注意,还有其他结构元素的形状和大小可以为您的图像带来更好的效果,例如:

convert text.png -threshold 50% -morphology erode disk:3 result.png

enter image description here

见Anthony Thyssen对形态学here的精彩介绍。

关于将图像分割成其组成部分的进一步问题,每个部分都包含一个单词,您可以执行以下操作...

将上一个convert命令的输出导入awk以查找包含单词gray的所有行,并在字段2中打印出该框的几何图形。

convert ... as above ... | awk '/gray/{print $2}'

示例输出

1086x188+0+0
364x65+128+118
212x34+817+115
231x33+73+76
181x42+494+8
209x31+608+118
148x34+826+148
132x34+20+153
126x27+384+151
91x42+396+8
117x34+708+149
104x33+509+151
112x27+271+158
100x33+507+118
91x33+615+150
55x25+73+121
28x29+361+12

现在将其分成加号以分隔X和Y:

convert ... | awk '/gray/{split($2,a,"+");print a[1],a[2],a[3]}'

示例输出

1086x188 0 0
364x65 128 118
212x34 817 115
231x33 73 76
181x42 494 8
209x31 608 118
148x34 826 148
132x34 20 153
126x27 384 151
91x42 396 8
117x34 708 149
104x33 509 151
112x27 271 158
100x33 507 118
91x33 615 150
55x25 73 121
28x29 361 12

现在按Y然后按X排序,使单词按行顺序排列(Y从顶部向下计数)然后单词顺序(X从左侧开始计数):

convert ... | awk '/gray/{split($2,a,"+");print a[1],a[2],a[3]}' | 
    sort -n -k3 -k2 

示例输出

1086x188,0,0
91x42,396,8
181x42,494,8
28x29,361,12
231x33,73,76
212x34,817,115
364x65,128,118
100x33,507,118
209x31,608,118
55x25,73,121
148x34,826,148
117x34,708,149
91x33,615,150
126x27,384,151
104x33,509,151
132x34,20,153
112x27,271,158

现在,将几何图形传递给循环并将其读入bash个变量,然后裁剪原始图像并使用简单索引(i)命名单个单词。

convert ... | awk '/gray/{ split($2,a,"+");print a[1],a[2],a[3] }' |
   sort -n -k3 -k2 | 
 { i=0; 
   while read g x y; do 
          convert text.png -crop ${g}+${x}+${y} word-${i}.png
          ((i+=1))
   done }

请注意,如果您的文字甚至略微旋转,比如说逆时针1度,则任何给定线条右端的单词将比左侧的单词具有更小的Y坐标,因此可能会出现在它们之前在排序时的图像顺序。因此,您可能需要将Y坐标舍入为awk中最接近的10或20或40,以便如果一个单词距离顶部168个像素而另一个单词距离顶部169个像素,则它们都会被排序就好像他们从顶部说170像素,然后出现在同一行。