2012-12-10 21 views
6

我試圖實現/轉換daltonize算法,用於將色盲人士的圖像改正爲ruby。使用ruby-vips的第一步

在我不熟悉的語言/環境中,有javascriptpython +其他實現編寫了兩個主要參考實現。

我幾乎沒有圖像處理的經驗,更不用說使用VIPS/ruby​​-vips了。我想知道如何做出第一步。文檔看起來主要用C/C++編寫,而且在ruby方面很少。它也非常詳細。我甚至不確定要使用哪些基本的操作。看起來像lin函數是一個很好的起點,但我不確定如何應用它。

任何具有一定的VIPS經驗的人都可能在幾分鐘內完成整個算法。我想知道有沒有人可以給我一些指導從哪裏開始。具體如下:

  • 如何訪問單個(R/G/B)元素?
  • 基於daltonize實現有更好的方法嗎?

回答

6

我是ruby-vips維護者。

有相當完整的Ruby文檔在這裏:http://rubydoc.info/gems/ruby-vips/0.3.0/frames

出於某種原因,該文檔在創業板(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) 

現在紅寶石貴賓將通過您的電腦流中的圖像和整個圖像不加載到內存中。這使您可以處理任何大小的圖像而不會觸及內存限制。

下面是一個完整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

哇。非常感謝。它讓我覺得很花時間試圖轉換js/python算法。我知道有這方面經驗的人只需要幾分鐘就可以解決這個問題。我會試着看看我能否弄清楚它是如何工作的,以便我可以在這個過程中學習一些東西。我希望我能+1000這個。謝謝! – gingerlime

+0

@YoavAner,也看到這個:http://stackoverflow.com/questions/10709995/ruby-vips-image-processing-library-are-there-any-good-examples-of-usage –

+0

謝謝@Stanislaw - 我沒有已經看到你的問題了,但仍然對如何在達爾頓轉換中取得進展感到非常失落。我還沒有嘗試過建議的實施,但希望能很快再次深入研究。 – gingerlime

1

對於新人:紅寶石貴賓有維基:https://github.com/jcupitt/ruby-vips/wiki與「例子」,並在它的基本概念「的網頁。他們展示了ruby-vips使用的基礎知識。

此外,隨時添加您自己的用例,如@YoavAner(Daltonize示例)。