シングルプレーンの取り出しとマージ

OpenCV 2.4.11(VS10), ActiveScriptRuby 2.2(32bit), ruby-opencv-0.0.14

RGB画像から、Gプレーンのみ取り出し、RとBをゼロで埋めた画像を作成したいのだけど、感覚的に書いたコードだとエラーが出る。

b,g,r = img.split
b2 = IplImage.merge(b)
g2 = IplImage.merge(nil, g)
r2 = IplImage.merge(nil, nil, r)
で動いて欲しいのだけど、うまく動かない。

まず、merge(b)だと「array.cpp:1238: error: (-5) Array should be CvMat or IplImage in function cvGetSize」となる。
merge(b.to_CvMat)だとエラーが出ないが、RGB全てのプレーンが、B画像で埋まってしまう。
merge(b.to_CvMat, nil, nil)とすると、意図した通りに動く。(Bプレーンのみ取り出され、R/Gプレーンはゼロで埋まった画像)

同様に merge(nil, g.to_CvMat, nil)としたら Gプレーン だけ取り出されて R/Bがゼロで埋まった画像ができそうな気がするのだけど、うまく行かない。
あらかじめ全てがゼロで埋まったB画像を作成して、 merge(b0.to_CvMat, g.to_CvMat, nil) とすると意図通りに動く。

結局、以下の様にすると、RGB画像からRプレーンのみ画像/Gプレーンのみ画像/Bプレーンのみ画像を作成できる。

require 'opencv'
include OpenCV
W,H = 340,200
win = GUI::Window.new("win")
rwin = GUI::Window.new("rwin")
gwin = GUI::Window.new("gwin")
bwin = GUI::Window.new("bwin")

img = IplImage.new(W, H, CV_8U, 3).fill(CvColor::White) # 真白なキャンバスを作成 #
blk = IplImage.new(W, H, CV_8U, 3).fill(CvColor::Black)

# 赤線を引いたり、四角形を描画したり、文字を描画したりする #
img.line!(CvPoint.new(10,140),CvPoint.new(330,190),
          {:color=>CvColor::Red,:thickness=>6})
img.rectangle!(CvPoint.new(200,40),CvPoint.new(280,180),
               {:color=>CvColor::Green,:thickness=>9})
9.times do |i| # 塗り潰し(-1)を指定して、青色の円を描く #
  img.circle!(CvPoint.new(i*40,i*20), 2+i*2, {:color=>CvColor::Blue,:thickness=>-1})
end
font = CvFont.new(:plain, :hscale => 5.0, :vscale => 4.5,
                  :shear => 1.0, :thickness => 3, :line_type => 5, :italic => true)
img.put_text!('Ruby', CvPoint.new(2, 60), font, CvColor::Black)
img.put_text!('OpenCV', CvPoint.new(2, 120), font, CvColor::Black)
win.show img

b,g,r = img.split
b0,g0,r0 = blk.split # 全てがゼロで埋まった R画像/G画像/B画像を作成する #
b2 = IplImage.merge(b.to_CvMat, nil, nil)
g2 = IplImage.merge(b0.to_CvMat, g.to_CvMat, nil)
r2 = IplImage.merge(b0.to_CvMat, g0.to_CvMat, r.to_CvMat)
rwin.show r2
gwin.show g2
bwin.show b2
GUI::wait_key(0)

多分、俺の理解が浅い為だと思うのだけど、時間のある時にマジメに調査することにしよう。