如何检测盒的图像中并拉出来作为单独的文件?(How can I detect boxes in an

2019-07-28 21:08发布

我需要服用扫描图像编程的方式(假设PNG或任何其他方便的图像格式),并分解成许多较小的图像。 扫描的图像的网格,以及网格的框将始终是相同的尺寸,并在相同的相对位置。 由于图像被扫描时,他们不一定在同一绝对位置。 在每个盒子是一个字符,最好我想字符保存为自己的图像文件,没有任何包装盒边框。

我更喜欢PHP和ImageMagick的,我认为这将是工具的正确组合。 不过,我很灵活,如果有一个更好的方法来做到这一点。

Answer 1:

这里是一个算法解决问题的方法的开始......

我使用这个形象我出于测试目的,称为创造box.jpg ,具有352x232像素尺寸:

我们的目标是找出红色框,并提取了“戴夫”的画面。

我的算法方法是如下:

  1. 缩放图像的一个具有原始宽度,但是只有1个像素的高度; 在同一时间转换为灰度和提高对比度; 使用ImageMagick的可发射的每个像素的属性的文本描述。 这样,你应该能够找到这两个景点在垂直红线像素积累了极致色彩值。 (垂直红线与灰色字母像素一起像素将具有更常见的颜色值。)

  2. 做同样在其他方向:缩放图片以一个有原来的高度,但只有1个像素的宽度(转换为灰度,增加对比度,使用文字说明... yadda,yadda)。 你会找到两个点,它的水平红线像素积累了极致色彩值。 (带灰色字母象素垂直红线相结合,将有更多的“平均”颜色值。)

  3. 识别每个在每两个结果的颜色值峰值的位置:这会给你的子图像的几何形状从原来的提取。

  4. 提取从原来的子图像。 根据需要裁剪每一侧上。

我就不细说了详细完整的算法,但这里是我使用的步骤1和2的命令。

命令第1步

convert                   \
    -type grayscale       \
    -depth 8              \
     box.jpg              \
    -scale x1\!           \
    -contrast-stretch 6x6 \
     columns.txt

结果第1步

这是内容columns.txt

 # ImageMagick pixel enumeration: 352,1,255,gray
 0,0: (  0,  0,  0)  \#000000  black                 <-- left outer image border 
 1,0: (253,253,253)  #FDFDFD  gray(253,253,253)
 2,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 3,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 [...]
 20,0: (255,255,255)  #FFFFFF  white
 21,0: (255,255,255)  #FFFFFF  white
 [...]
 46,0: (255,255,255)  #FFFFFF  white
 47,0: (255,255,255)  #FFFFFF  white
 48,0: (243,243,243)  #F3F3F3  gray(243,243,243)
 49,0: (  0,  0,  0)  #000000  black                 <-- left box border (ex-red)
 50,0: (  0,  0,  0)  #000000  gray(0,0,0)           <-- left box border (ex-red)
 51,0: (  0,  0,  0)  #000000  black                 <-- left box border (ex-red)
 52,0: (  0,  0,  0)  #000000  black                 <-- left box border (ex-red)
 53,0: (221,221,221)  #DDDDDD  gray(221,221,221)
 54,0: (231,231,231)  #E7E7E7  gray(231,231,231)
 55,0: (236,236,236)  #ECECEC  gray(236,236,236)
 [...]
 247,0: (236,236,236)  #ECECEC  gray(236,236,236)
 248,0: (216,216,216)  #D8D8D8  gray(216,216,216)
 249,0: (  0,  0,  0)  #000000  black                <-- right box border (ex-red)
 250,0: (  1,  1,  1)  #010101  gray(1,1,1)          <-- right box border (ex-red)
 251,0: (  0,  0,  0)  #000000  black                <-- right box border (ex-red)
 252,0: (  1,  1,  1)  #010101  gray(1,1,1)          <-- right box border (ex-red)
 253,0: (226,226,226)  #E2E2E2  gray(226,226,226)
 254,0: (244,244,244)  #F4F4F4  gray(244,244,244)
 255,0: (244,244,244)  #F4F4F4  gray(244,244,244)
 [...]
 303,0: (255,255,255)  #FFFFFF  white
 304,0: (255,255,255)  #FFFFFF  white
 305,0: (255,255,255)  #FFFFFF  white
 [...]
 342,0: (255,255,255)  #FFFFFF  white
 343,0: (255,255,255)  #FFFFFF  white
 344,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 345,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 346,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 347,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 348,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 349,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 350,0: (253,253,253)  #FDFDFD  gray(253,253,253)
 351,0: (  0,  0,  0)  #000000  black                <-- right outer image border

:这似乎是一个有点混乱的是ImageMagick的要求的颜色值#FFFFFF有时white ,有时gray(255,255,255) -以及调用的颜色值#000000 somtimes black ,somtimes gray(0,0,0) ..也许一个错误?无论如何,在这里不阻止我们... ...)

命令第2步

convert                   \
    -type grayscale       \
    -depth 8              \
     box.jpg              \
    -scale 1x\!           \
    -contrast-stretch 6x6 \
     rows.txt

结果第2步

这是内容rows.txt (这时候我放弃了混乱的颜色名称):

 # ImageMagick pixel enumeration: 1,232,255,gray 
 0,0: (  0,  0,  0)  #000000                 <-- top outer image border
 0,1: (255,255,255)  #FFFFFF  
 0,2: (255,255,255)  #FFFFFF  
 0,3: (255,255,255)  #FFFFFF       
 0,4: (255,255,255)  #FFFFFF       
 0,5: (255,255,255)  #FFFFFF       
 0,6: (255,255,255)  #FFFFFF       
 0,7: (255,255,255)  #FFFFFF       
 0,8: (255,255,255)  #FFFFFF       
 0,9: (255,255,255)  #FFFFFF       
 0,10: (255,255,255)  #FFFFFF       
 [...]
 0,46: (255,255,255)  #FFFFFF       
 0,47: (255,255,255)  #FFFFFF       
 0,48: (240,240,240)  #F0F0F0       
 0,49: (  0,  0,  0)  #000000                <-- top box border (ex-red)
 0,50: (  0,  0,  0)  #000000                <-- top box border (ex-red)
 0,51: (  0,  0,  0)  #000000                <-- top box border (ex-red)
 0,52: (  0,  0,  0)  #000000                <-- top box border (ex-red)
 0,53: (225,225,225)  #E1E1E1       
 0,54: (234,234,234)  #EAEAEA       
 [...]
 0,207: (244,244,244)  #F4F4F4       
 0,208: (230,230,230)  #E6E6E6       
 0,209: (  0,  0,  0)  #000000               <-- bottom box border (ex-red) 
 0,210: (  0,  0,  0)  #000000               <-- bottom box border (ex-red)
 0,211: (  0,  0,  0)  #000000               <-- bottom box border (ex-red)
 0,212: (  0,  0,  0)  #000000               <-- bottom box border (ex-red)
 0,213: (234,234,234)  #EAEAEA       
 0,214: (245,245,245)  #F5F5F5       
 [...]
 0,229: (255,255,255)  #FFFFFF       
 0,230: (255,255,255)  #FFFFFF       
 0,231: (  0,  0,  0)  #000000               <-- bottom outer image border

从这两个结果,我们可以得出结论可靠:

  1. 左垂直红框边界线是在像素列49-52。
  2. 右侧垂直红框边界线是在像素列249-252。
  3. 顶部水平红框边界线是在像素行49-52。
  4. 底部水平红框边界线是在像素行209-222。
  5. 从1和2就可以计算197(249减去52)将红色框的“内部宽度”。 让我们用196所提取的子图像的宽度即可。
  6. 从3和4,你可以计算的157(209减52)红框中的“内部高度”。 让我们用156所提取的子图像的高度即可。
  7. 水平的作物的偏移必须是52个像素。 我们选择53。
  8. 垂直的作物需要偏移是52个像素。 我们选择53。

因此,我们的命令切断从原来的一个子图像可以是:

convert  -crop 196x156+53+53  box3.jpg  sub-box.jpg

或者,以使图像尺寸与该网页的白色背景更好的区分:

convert  -crop 196x156+53+53  box3.jpg  -colorize 20,0,20  sub-box.jpg

得到的图像:

现在,您可以在图像上应用OCR:

tesseract sub-box.jpg OCR-subbox 1>/dev/null && cat OCR-subbox.txt

  Dave


文章来源: How can I detect boxes in an image and pull them out as individual files?