使用ruby-vips的第一步

时间:2012-12-10 12:35:46

标签: ruby image-processing

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

javascriptpython中编写了两个主要参考实现,以及我不熟悉的语言/环境中的其他实现。

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

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

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

2 个答案:

答案 0 :(得分:6)

我是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提供的向量操作链接在一起。例如:

#!/usr/bin/ruby

require 'rubygems'
require 'vips'

a = VIPS::Image.jpeg(ARGV[0])

b = a.lin(1.1, 0)

b.write(ARGV[1])

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

$ ./try.rb k2.jpg x.jpg 

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

您可以将中心线更改为:

b = a.pow(1 / 2.4).lin(1.1, 0).pow(2.4)

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

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

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

a = VIPS::Image.jpeg(ARGV[0], :sequential => true)

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

这是一个完整的Daltonize示例

#!/usr/bin/ruby

# daltonize an image with ruby-vips
# based on
# http://scien.stanford.edu/pages/labsite/2005/psych221/projects/05/ofidaner/colorblindness_project.htm

require 'rubygems'
require 'vips'

im = VIPS::Image.new(ARGV[0])

# remove any alpha channel before processing
alpha = nil
if im.bands == 4
    alpha = im.extract_band(3)
    im = im.extract_band(0, 3)
end

begin
    # import to CIELAB with lcms
    # if there's no profile there, we'll fall back to the thing below
    lab = im.icc_import_embedded(:relative)
    xyz = lab.lab_to_xyz()
rescue VIPS::Error
    # nope .. use the built-in converter instead
    xyz = im.srgb_to_xyz()
end

# and now to bradford cone space (a variant of LMS)
brad = xyz.recomb([[0.8951,  0.2664, -0.1614],
                   [-0.7502,  1.7135,  0.0367],
                   [0.0389, -0.0685,  1.0296]])

# through the Deuteranope matrix
# we need rows to sum to 1 in Bradford space --- the matrix in the original
# Python code sums to 1.742
deut = brad.recomb([[1, 0, 0],
                    [0.7, 0, 0.3],
                    [0, 0, 1]])

# back to xyz (this is the inverse of the brad matrix above)
xyz = deut.recomb([[0.987, -0.147, 0.16],
                   [0.432, 0.5184, 0.0493],
                   [-0.0085, 0.04, 0.968]])

# .. and back to sRGB 
rgb = xyz.xyz_to_srgb()

# so this is the colour error 
err = im - rgb

# add the error back to other channels to make a compensated image
im = im + err.recomb([[0, 0, 0],
                      [0.7, 1, 0],
                      [0.7, 0, 1]])

# reattach any alpha we saved above
if alpha
    im = im.bandjoin(alpha.clip2fmt(im.band_fmt))
end

im.write(ARGV[1])

答案 1 :(得分:1)

对于新手:ruby-vips有wiki:https://github.com/jcupitt/ruby-vips/wiki,其中包含'Examples'和'Basic concepts'页面。它们展示了ruby-vips使用的基础知识。

此外,您可以随意添加自己的用例,例如@YoavAner(Daltonize示例)。