2008年12月21日

以前、ハロウィン前に公開して一部の方から好評をいただいた「かぼちゃミク」(初音ミクの髪などの青色をかぼちゃ色にしたもの)。冬至が近いということで、そのときのプログラムをRuby+RMagickに移植したものを公開してみる。

RMagickのインストールは若干面倒なので、多分このあたりを参照すればよいでしょう(私は試していませんが)。

肝心のコードはこちら。<gist.githubでコードを入手>

require "rubygems"
require "RMagick"

module Magick
  class Pixel
    def get_hsv
      r = red; g = green; b = blue
      
      if r > g
        max = ((b > r) ? b : r); min = ((g > b) ? b : g)
      else
        max = ((b > g) ? b : g); min = ((r > b) ? b : r)
      end

      # Hue 色相(0-360)
      if max == min
        # 未定義
        h = 0
      else
        if max == r
          h = 60 * (g - b) / (max - min)
        elsif max == g
          h = 60 * (b - r) / (max - min) + 120
        else
          h = 60 * (r - g) / (max - min) + 240
        end
      end
      h += 360 if h < 0

      # Saturation 彩度(0.0-1.0)
      s = ((max == 0) ? 0 : ((max - min)*QuantumRange.to_f/max)/QuantumRange)
      # max == 0 のときは未定義
      
      # Value 明度(0.0-1.0) : max/(RGBそれぞれの最大値)に等しい
      [h, s, max.to_f/QuantumRange]
    end
    
    def Pixel.from_hsv(h, s, v)
      range = (h / 60).to_i
      diff_h = h - 60 * range
      
      p = (v * (1.0 - s)) * QuantumRange
      q = (v * (60 - s * diff_h) / 60) * QuantumRange
      t = (v * (60 - s * (60 - diff_h)) / 60) * QuantumRange
      v *= QuantumRange
      
      case range
      when 0; Pixel.new(v, t, p)
      when 1; Pixel.new(q, v, p)
      when 2; Pixel.new(p, v, t)
      when 3; Pixel.new(p, q, v)
      when 4; Pixel.new(t, p, v)
      else;   Pixel.new(v, p, q)
      end
    end
  end
end

include Magick
img = ImageList.new("kabochamiku-src.png")

for y in 0...img.rows
  for x in 0...img.columns
    h, s, v = img.pixel_color(x, y).get_hsv
    
    if h > 120 && h < 240 && v >= 0.3
      h -= 180
      h += 360 if h < 0
      img.pixel_color(x, y, Pixel.from_hsv(h, s, v))
    end
  end
end

img.write("kabochamiku-out.png")

ミソなのは、髪の色かどうかの判断を、色をHSVに変換して表現していることである。HSVのメリットは、色を三原色の強さでなく「色の種類」「鮮やかさ」「明るさ」といった要素で表現しているので、例えば光の強さの変化などに影響されにくい形で条件式を書けることである。

RMagickには、HSVに似たHLSという形式での色表現が事前に組み込まれているのだが、これの挙動がどうもおかしいため、上記コードでは改めてHSVでの色の値を取得するメソッドを定義している。

変換元の画像"kabochamiku-src.png"として、以下の画像を使うとする。

変換元の画像(ミクフィギュア)

このプログラムを実行した結果出力される画像"kabochamiku-out.png"は以下のようになった。かぼちゃっぽくなった。

変換後の画像(かぼちゃミク)


※2009.3.14追記

ふと思い立って、gist.githubに貼り付けておきました。



maraigue at 03:43コメント(0)トラックバック(0)プログラミング | コンピュータ全般 

トラックバックURL

コメントする

名前
 
  絵文字
 
 
livedoor プロフィール

H. Hiro

  • ライブドアブログ