方法
0から255のグレースケール値をOpenCVのRGB値(疑似カラー)に変換する。色んなやり方があるがその1つ。
cv::Vec3b calcPseudoColor(double phase, double shift = 0.0) { phase = max(min(phase,1.0), 0.0); //0から1に shift += PI+PI/4; //青から赤に return Vec3b ( uchar( 255*(sin(1.5*PI*phase + shift + PI ) + 1)/2.0 ), uchar( 255*(sin(1.5*PI*phase + shift + PI/2 ) + 1)/2.0 ), uchar( 255*(sin(1.5*PI*phase + shift ) + 1)/2.0 ) ); }
使い方
たとえばカラーバーを作ってみる。
int w = 1024; int h = 100; cv::Mat_<cv::Vec3b> bar(h, w); for(int j=0; j<h; j++) { for(int i=0; i<w; i++) { bar(j, i) = calcPseudoColor(double(i)/(w-1)); } }
結果
$1024\times 100$の画像にphase=0から1までを均等に割り当てて描画した。緑に鮮やかさがないが、青から赤まで虹色に変化するグラデーションが表現できている。
補足
この方法が良いという理由は、$sin$関数が使えるのでソースコードが短くなること以外はあまりない。HSV表色系のHueを計算するよりは単純だと思う。緑が鮮やかでなかったのは、以下の理由で説明できる。つまり、この方法は、RGBの3つのチャンネルを足した和、つまり輝度が255などの一定値にはならない。gnuplotで上記3つの関数を表示してみれば一発で確認できる。横軸がphase、縦軸が輝度値である。緑のあたりの合計輝度値$I(x)=r(x)+g(x)+b(x)$が他と比べて高くなっており、純粋なGチャンネルのみのphaseは存在しない。
gnuplotの表示に用いたコードも載せておく。よく使うので。
set xrange [0:1] set yrange [0:600] #set terminal postscript eps enhanced color #set output 'plot.eps' set terminal png color set output 'plot.png' r(x) = 255*(sin(1.5*pi*x+pi+pi/4 + pi) + 1)/2.0 g(x) = 255*(sin(1.5*pi*x+pi+pi/4 + pi/2) + 1)/2.0 b(x) = 255*(sin(1.5*pi*x+pi+pi/4) + 1)/2.0 I(x) = r(x) + g(x) + b(x) plot r(x), g(x), b(x), I(x), 255 set terminal windows set output plot r(x), g(x), b(x), I(x), 255 reset