https://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93
RGBとHSVの相互変換のプログラム作成については次のサイトが参考になります。
http://hooktail.org/computer/index.php?RGB%A4%AB%A4%E9HSV%A4%D8%A4%CE%CA%D1%B4%B9%A4%C8%C9%FC%B8%B5
上記サイトでは彩度と明度が0~255で表されています。こちらもint型を用いるためにそのようにしたいと思います。(一部doubleキャストしていますが)
ヒートマップフィルターにおいては、HSVのなかでHのみを変化させます。これにより色相の変化した画像となります。ただし、0から360まで変化させてしまうと色がほとんど元に戻ってしまうため、色相は0から240まで変化させます。
まず、HSVとRGBの相互変換プログラムを作成します。Tutorial1Activityクラスと同じ場所にHSVTransクラスを作成します。その後、以下のコードを入力します。
public int[] RGBtoHSV(int rgb){
double red = (rgb >> 16) & 0xff;
double green = (rgb >> 8) & 0xff;
double blue = (rgb) & 0xff;
red=red/255;
green=green/255;
blue=blue/255;
double max;
double min;
int H;
int S;
int V;
int result[]=new int[3];
if(red > green){
if(red > blue){
max=red;
if(green < blue){
min=green;
}else{
min=blue;
}
H=(int) (60*(green-blue)/(max-min));
}else{
max=blue;
min=green;
H=(int) (60*(red-green)/(max-min)) +240 ;
}
}else{
if(green > blue){
max=green;
if(red < blue){
min=red;
}else{
min=blue;
}
H=(int) (60*(blue-red)/(max-min)) +120 ;
}else{
max=blue;
min=red;
H=(int) (60*(red-green)/(max-min)) +240 ;
}
}
if(H < 0){
H+=360;
}
H=H%360;
S=(int)(((max-min)/max)*255);
if(S > 255){
S=255;
}else if(S < 0){
S=0;
}
V=(int)((max)*255);
if(V > 255){
V=255;
}else if(V < 0){
V=0;
}
result[0]=H;
result[1]=S;
result[2]=V;
return result;
}
public int HSVtoRGB(int hsv[]){
//hsv H:0~360, S:0~255, V:0~255;
int H=hsv[0];
int S=hsv[1];
int V=hsv[2];
int red=0;
int green=0;
int blue=0;
if(S==0){
red=V;
green=V;
blue=V;
}else{
int I=(int)(H/60);
double F=((double)H)/60 -I;
int p=V*(255-S) / 255;
int q=(int) (V*(255 - F*((double) S))/255);
int t=(int) (V*(255-1*(1-F)*((double) S))/255);
if(I==0){
red=V;
green=t;
blue=p;
}else
if(I==1){
red=q;
green=V;
blue=p;
}else
if(I==2){
red=p;
green=V;
blue=t;
}else
if(I==3){
red=p;
green=q;
blue=V;
}else
if(I==4){
red=t;
green=p;
blue=V;
}else
if(I==5){
red=V;
green=p;
blue=q;
}
}
int result=255*16777216+red*65536+green*256+blue;
return result;
}
次にHeatMapFilterクラスを作成し、filterメソッドに以下のコードを入力します。
public int[] filter(int[] imageArray, int width, int height) {
int length = width*height;
int[] oimgArray = new int[imageArray.length];
int rgb;
int red,green,blue;
int y_val;
int h;
for(int i =0;i < length;i++){
rgb = imageArray[i];
red = (rgb >> 16) & 0xff;
green = (rgb >> 8) & 0xff;
blue = (rgb) & 0xff;
y_val = ( 2 * red + 4 * green + blue ) / 7;//①
h = 240- y_val*240/255;//②
int hsv[]=new int[]{h,255,255};//③
oimgArray[i]=new HSVTrans().HSVtoRGB(hsv);//④
}
return oimgArray;
}
①では輝度グレイスケールに変換しています。そして、②ではその値をまず0~240の範囲に変換してから、240から引くことによって逆転させています。これは、元画像での白色が赤色に対応するようにするためです。
③ではHSVからRGBに変換するための配列を用意します。HSVの順番ですが、SとVは最大値の255に設定します。
④ではHSVの値をRGB値に変換します。
最後に、 Tutorial1Activityクラスのint imageArray[]=ba2ia(ba);の下に以下の文を記入します。
imageArray=new HeatMapFilter().filter(imageArray, imagewidth, imageheight);
以下に実機での実行結果を示します。

0 件のコメント:
コメントを投稿