2010年5月26日水曜日

[Ruby]Gruffを使ってS字トーンカーブを描いてみた

画像処理のプログラミングなどをやっていると数学的な関数を使って値を生成するということがよくあります。

例えば画像のコントラストを変更する処理では、ピクセルの輝度にたいしてどの程度「強い」コントラストを作るか係数を設定して数学的に関数化します。

PhotoshopやGimpなどでコントラストを調整するときに利用するトーンカーブというのはこの関数をグラフ化したものですよね。


傾きが急であれば黒と白が強調されたコントラストが強い画像、ということになります。


このS字トーンカーブを画像で生成するスクリプトを書けば、どういう係数を設定すればどういうカーブを描くか視覚的に判断出来るということで、ちょっと調べてみました。

とりあえずRubyでグラフ画像生成までやってみることに。



コントラストやトーンカーブはこちらの記事が参考になりました。
http://blog.goo.ne.jp/souichi-kikaizikake/e/9c633489d8e5f09c79d70722c6c86635



0~255の輝度値に対して変換する式は下のようになります。 (式の意味はシグモイド関数で検索してみて下さい )
# e => 係数
# i => 輝度値

e = ARGV[0].to_f * 10
256.times do |i|
  v = 255 / (1 + (e ** ((3.5 / 100) * (-i + 127))))
  p v
end
tonecurve.rbという名前で保存して実行してみます。

$ ruby tonecurve.rb 0.5

0.0886149353083345
0.0943479462700696
0.100451712597905
0.10695191619086
...
254.899548287402
254.9056205373
254.911385064692
254.91676982554
数字が256個だーっと生成されます。
これだけだと傾き具合などを把握するのが困難なのでグラフ化します。


幸いrubyには優れたグラフ生成用のgemが用意されているのでそれを活用します。

グラフ生成はGruffを利用することに。
(RMagickのインストールなどがやや面倒だけどオススメです。)


生成された数値を配列に格納して渡すだけでキレイなグラフを作ってくれます。

require 'rubygems'
require 'gruff'

contrast = ARGV[0].to_f

e = 10.0 * contrast
x = 3.5
values = []

256.times do |i|
  values << 255 / (1 + (e ** ((x / 100) * (-i + 127))))
end

g = Gruff::Line.new
g.title = "tonecurve"

g.data("tone (#{e})", values)
g.write('tonecurve.png')

比較のためにグラフを3つ並べてみます。

require 'rubygems'
require 'gruff'

contrast = ARGV[0].to_f

e1 = 10.0 * contrast
e2 = p1 * 0.5
e3 = p1 * 1.5

values1 = []
values2 = []
values3 = []

x = 3.5

256.times do |i|
  values1 << 255 / (1 + (e1 ** ((x / 100) * (-i + 127))))
  values2 << 255 / (1 + (e2 ** ((x / 100) * (-i + 127))))
  values3 << 255 / (1 + (e3 ** ((x / 100) * (-i + 127))))
end


g = Gruff::Line.new
g.title = "tonecurve contrast=#{contrast}"

g.data("tone1 (#{e1})", values1)
g.data("tone2 (#{e2})", values2)
g.data("tone2 (#{e3})", values3)

g.write('tonecurve.png')

視覚化することではっきり傾きが確認できます。
これで係数やゲインの調節がしやすくなりました。

0 件のコメント: