1週間ぶりの更新です。
自分でも何をやっていたのか忘れましたがどうやら今回は表色系について説明して、こんなフィルタを作ることになるらしいです。

虹色ファインダー


wikipediaで検索してみると「表色系とは心理的概念あるいは心理物理的概念に従い、色を定量的に表す体系である。通常は3つの方向性を具える空間で表現され、色空間を構成する。」
ということだそうです、ありがとうございました、これだけではさっぱり意味が分かりません。

分かっているところから説明していきます。
コンピュータ業界で一番定番な表色系は光の三原色であるRGB表色系でデジタル画像も基本はこの表色系で表されています。
RGBはそれぞれ下のRedGreenBlueを表しており、この3色を混ぜ合わせることで様々な色を生み出してます。
rgb

なぜRGB表色系が一番定番かというと、単純に情報を表示するディスプレイがライトの光を利用して色を作ってるからです。
例えば黄色をディスプレイに表示させたければRedGreenのライトを照らせば人間の目には黄色に映ります。
じゃあRGB表色系だけでいいじゃないかと思いますがそうもいかず、このRGB表色系での色の作り方は光に限った話で、プリンタで色を再現する時はRGB表色系が通用しません。
ためしにプリンタでRedGreenを混ぜるとどどめ色になるそうです。

じゃあプリンタはどうしてるかっていうと下の図のとおり皆さんが買ってくるインクジェットのC(シアン)M(マゼンダ)Y(イエロー)を混ぜることで様々な色を再現してます。
つまりプリンタはCMY表色系ですね。
cmy

まあ実際のプリンタはそれにK(ブラック)を混ぜたCMYK表色系ですが。

今あげたRGB表色系やCMY表色系はインクの混ざり方のルールを解明した、いわば物理法則に合わせた表色系でした。
これでは例えば下の画像みたいに「画面全体たくさんのやかな色埋め尽くしたい」とか思った時にRGB表色系やCMY表色系で考えると難しい!

niji

そんなわけでRGB表色系のように「物理法則に合わせた表色系」ではなく「人の色彩感覚に合わせた表色系」がコンピュータの世界でも使われるようになりました。
そのひとつが下の図のHSV表色系で、HHue(色相)、SSaturation(彩度)、VValue(明度)を意味してます。

HSV

色相
が外周の円を意味し、色相環とか言われたりもします。
ようするに色を角度で表し、一番上を0度とすると、Hの90度といえば右の赤っぽい色を意味するということです。
そして円内の三角形がSとVを意味しており、S彩度は読んで字のごとくHで指定している(上の図なら90度の赤)の鮮やかさを変え、V明度はHで指定している色の明るさを変えます。
彩度を落とすとくすんだ灰色に近づき、明るさを落とすと暗くなっていることが分かると思います。
で、このHSV表色系で何が嬉しいかというと!
彩度と明度を一定のままで色相をぐるっと一周させまーすとかやると下みたいな綺麗な虹色が再現できます。

niji

これを利用して綺麗な写真フィルタが作られます。
ではようやく最後にこれを応用したOpenCVjsを使った虹色フィルタのプログラムが以下です。
※OpenCVjsの色相は0~255で色相が一周します。

function Rainbow(imgId, iplImage){

//虹色の画面の領域を作成
var layer1 = cvCreateImage(iplImage.width, iplImage.height);
var max = layer1.width*layer1.width + layer1.height*layer1.height;
//色相を画像の左上から右下にかけて変更していく
for(i = 0 ; i < layer1.height ; i++){
for(j = 0 ; j < layer1.width ; j++){
var v = j*j + i*i;
                        //色相
layer1.RGBA[(j + i * layer1.width) * CHANNELS] = 255*v/max;
//彩度
                        layer1.RGBA[1 + (j + i * layer1.width) * CHANNELS] = 255;
//明度
                        layer1.RGBA[2 + (j + i * layer1.width) * CHANNELS] = 255;
//アルファ値
                        layer1.RGBA[3 + (j + i * layer1.width) * CHANNELS] = 255;
}
}
//HSV表色系からRGB表色系に変換
cvCvtColor(layer1, layer1, CV_CODE.HSV2RGB);
var newIplImage = cvCloneImage(iplImage);
var bg = cvCloneImage(iplImage);
//画像をぼやけた雰囲気を出すためにスムージングして原画増と合成
cvSmooth(bg, bg, CV_SMOOTH_TYPE.GAUSSIAN, 7);
cvBlendImage(bg, newIplImage, newIplImage, CV_BLEND_MODE.SCREEN);
//虹色を前面にして合成
cvBlendImage(newIplImage, layer1, newIplImage, CV_BLEND_MODE.SOFT_LIGHT);
//imgタグに転送
cvShowImage(imgId, newIplImage);
}

よく見たらcvSmoothやらcvBlendImageやらも使ってましたw
次回はこの辺の説明します。
では最後にでかく虹色美人を。
虹色ファインダー