使用ruby-vips的第一步

gin*_*ime 6 ruby image-processing

我正在尝试实现/转换daltonize算法,以便将色盲人员的图像校正为红宝石.

有两个主要的参考实现用javascriptpython + 编写的其他实现在我不熟悉的语言/环境中.

我几乎没有图像处理经验,更不用说VIPS/ruby​​-vips了.我想知道如何迈出第一步.文档似乎主要在C/C++中,而在ruby方面则很少.它也非常详细.我甚至不确定要使用哪些基本操作.看起来这个lin功能是一个很好的起点,但我不确定如何应用它.

任何具有一些VIPS经验的人都可以在几分钟内完成整个算法.我想知道是否有人可以给我一些指示从哪里开始.特别:

  • 如何访问单个(R/G/B)元素?
  • 是否有更好的方法基于daltonize实现?

jcu*_*itt 5

我是ruby-vips的维护者.

这里有相当完整的Ruby文档:http://rubydoc.info/gems/ruby-vips/0.3.0/frames

出于某种原因,文档在当前版本的gem(0.3.5)中大多缺失,但是在0.3.0中存在,我无法弄清楚原因.0.3.0和0.3.5之间的变化大多只是错误修正,所以0.3.0文档可以使用.

与大多数图像处理库一样,您不能使用ruby-vips访问单个像素(或者很少访问).Ruby太慢而不实用.相反,你将ruby-vips提供的向量操作链接在一起.例如:

require 'vips'

if ARGV.length < 2
    raise "usage: #{$PROGRAM_NAME}: input-file output-file"
end

im = Vips::Image.new_from_file ARGV[0], access: :sequential

im *= [1, 2, 1]

mask = Vips::Image.new_from_array [
        [-1, -1, -1],
        [-1, 16, -1],
        [-1, -1, -1]
       ], 8
im = im.conv mask, precision: :integer

im.write_to_file ARGV[1]
Run Code Online (Sandbox Code Playgroud)

该方法Vips采用图像x并应用线性变换.它返回一个新图像,其中每个像素已经乘以Vips然后Vips添加到它,请参阅http://rubydoc.info/gems/ruby-vips/0.3.0/VIPS/Image#lin-instance_method.如果你像这样运行这个程序:

./example.rb x.jpg y.ppm
Run Code Online (Sandbox Code Playgroud)

它将加载图像Vips,将每个像素乘以1.1(即使其亮10%),并将其保存到Vips.

您可以将中心线更改为:

require 'vips'

if ARGV.length < 2
    raise "usage: #{$PROGRAM_NAME}: input-file output-file"
end

im = Vips::Image.new_from_file ARGV[0], access: :sequential

im *= [1, 2, 1]

mask = Vips::Image.new_from_array [
        [-1, -1, -1],
        [-1, 16, -1],
        [-1, -1, -1]
       ], 8
im = im.conv mask, precision: :integer

im.write_to_file ARGV[1]
Run Code Online (Sandbox Code Playgroud)

现在它将执行三个操作:它将线性化图像(假设输入图像的伽玛值为2.4),缩放亮度,然后重新应用伽玛.在内部,vips将一次性计算这三个操作,并将工作分散到可用的处理器上.

(这不是线性化图像的最佳方法,我只是想显示链接)

最后,由于我们正在执行的操作是一个简单的逐像素计算,没有旋转或翻转,我们可以流式传输图像,我们不需要提前加载整个事物.您可以将加载操作更改为:

./example.rb x.jpg y.ppm
Run Code Online (Sandbox Code Playgroud)

现在,ruby-vips将通过您的计算机流式传输图像,而不是将整个图像加载到内存中.这使您可以处理任何大小的图像,而不会达到内存限制.

这是一个完整的Daltonize示例

require 'vips'

if ARGV.length < 2
    raise "usage: #{$PROGRAM_NAME}: input-file output-file"
end

im = Vips::Image.new_from_file ARGV[0], access: :sequential

im *= [1, 2, 1]

mask = Vips::Image.new_from_array [
        [-1, -1, -1],
        [-1, 16, -1],
        [-1, -1, -1]
       ], 8
im = im.conv mask, precision: :integer

im.write_to_file ARGV[1]
Run Code Online (Sandbox Code Playgroud)