2012-12-10 16 views
6

私は色覚障害者の画像をルビーに修正するアルゴリズムを実装/変換しようとしています。ruby​​-vipsを使った最初のステップ

javascriptpythonで書かれている2つの主なリファレンス実装と、私が慣れていない言語/環境での他の実装があります。

私は、VIPS/ruby​​-vipsはもちろん、画像処理に関する経験はほとんどありません。私は最初のステップを作る方法が不思議です。ドキュメンテーションは主にC/C++で、ルビー側ではほとんど見えません。それはまた非常に詳細です。私はどの基本的な操作を使用することもよく分からない。 linのような機能は良い出発点ですが、私はそれをどのように適用するかは正確には分かりません。

何人かのVIPS経験をお持ちの方は、おそらく数分でアルゴリズム全体を実行できます。誰かが私にどこから始めるべきかの指針を与えることができるのだろうかと思う。具体的には

  • どのように1つの(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はこれほど実用的ではありません。代わりに、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を取り、線形変換を適用x.lin(a, b)方法。各ピクセルにaを掛けた後、bを追加した新しいイメージを返します。http://rubydoc.info/gems/ruby-vips/0.3.0/VIPS/Image#lin-instance_methodを参照してください。あなたはこのようにこのプログラムを実行する場合:

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

それは1.1ですべてのピクセルを掛け、画像k2.jpgをロードし、x.jpgに保存し(すなわち、それは10%明るくします。)。

あなたがする中心線を変更することができます:それは3つの操作を行います

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

:それは(入力画像のガンマが2.4であると仮定して)画像を線形化よ、スケールの明るさを、そして再適用ガンマ内部的には、vipsはこれらの3つのオペレーションを一度に計算し、使用可能なプロセッサに分散します。

(これは画像を線形化するための最良の方法はありませんが、私はちょうどチェーンを表示しようとしている)最後に

、我々が行っている操作が無回転でシンプルなピクセル単位で計算されるので、私たちはイメージをストリームすることができます、私たちは事前にすべてをロードする必要はありません。あなたはするロード操作を変更することができます。

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

そして今、ルビー-VIPは、コンピュータを介して画像をストリーミングし、メモリに画像全体をロードしません。これにより、メモリの制限を受けることなく、任意のサイズの画像を処理できます。新参者のために

ここ

が完了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 - 私はしましたあなたの質問は既に見ていますが、daltonize変換をどのように進めるかについてはまだ失われています。私はまだ提案された実装を試していないが、うまくいけばすぐにもう一度それを掘り下げていくだろう。 – gingerlime

1

:「例」と、その中に「基本概念」ページでhttps://github.com/jcupitt/ruby-vips/wiki:ルビーのVIPのwikiを持っています。彼らは、ルビの使用法の基本を示しています。

また、@ YoavAnerのように独自のユースケースを自由に追加できます(Daltonizeの例)。

関連する問題