如何使用ImageMagick检测水平黑线?

时间:2010-04-14 21:02:45

标签: ruby image-processing image-manipulation

所以我有一个本质上是TIFF格式的电子表格。它有一些统一性......例如,所有列宽都相同。我希望通过那些已知列宽度来限制此工作表,并且基本上创建大量的小图形文件,每个单元格一个,并对它们运行OCR并将其存储到数据库中。问题是水平线的高度并不完全相同,所以我需要使用某种图形库命令来检查每个像素是否是相同的颜色(即黑色)。如果是这样,那么我知道我已达到一个单元格的高度分隔符。我该怎么做呢? (我正在使用RMagick)

2 个答案:

答案 0 :(得分:1)

使用image#get_pixelhttp://www.simplesystems.org/RMagick/doc/image2.html#get_pixels 警告:这些文档很旧,因此在较新版本中可能已更改。假设他们有rdocs,请使用$ gem server查看您自己的rdoc。

image#rows为您提供图像的高度,然后您可以执行类似(未经测试)的操作:

def black_line?(pixels)
  pixels.each do |pixel| 
    unless pixel.red == 0 && pixel.green == 0 && pixel.blue == 0
      return false
    end
  end
  true
end 

black_line_heights = []
height = image.rows
width = image.columns
height.times do |y|
  pixels = image.get_pixel(0,y,width,1)
  black_line_heights << y if black_line?(pixels)
end 

请记住,我不确定api。查看较旧的文档,我现在无法测试它。但它看起来像你会采取的一般方法。顺便说一句,它假设行边界是1像素厚。如果没有,请将1更改为实际厚度,这可能足以使其按预期工作。

答案 1 :(得分:0)

Ehsanul几乎是正确的......调用是get_pixels,它接受参数x,y,w,h并返回这些像素的数组。如果尺寸是1厚,你将得到一个漂亮的一维数组。

由于文档中的黑色可能会有所不同,我稍微改变了Ehsanul的方法以检测连续像素是否大致相同。在大约100个像素之后,它可能是一条线:

  def solid_line?(pixels, opt={}, black_val = 10)
    last_pixel = nil
     thresh =  opt[:threshold].blank? ? 4 : opt[:threshold]

     pixels.each do |pix|     
       pixel = [pix.red, pix.green, pix.blue]
       if last_pixel != nil            
         return false if pixel.reject{|p| (p-last_pixel[pixel.index(p)]).abs < thresh && p < black_val}.length > 0
       end
       last_pixel = pixel
     end
     true


    end