我正在尝试实现/转换daltonize算法,以便将色盲人员的图像校正为红宝石。
在javascript和python中编写了两个主要参考实现,以及我不熟悉的语言/环境中的其他实现。
我几乎没有图像处理经验,更不用说VIPS / ruby-vips了。我想知道如何迈出第一步。文档似乎主要在C / C ++中,而在ruby方面则很少。它也非常详细。我甚至不确定使用哪种基本操作。看起来lin
函数是一个很好的起点,但我不确定如何应用它。
任何具有一些VIPS经验的人都可以在几分钟内完成整个算法。我想知道是否有人可以给我一些指示从哪里开始。具体做法是:
答案 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示例)。