グレースケール 2007/08/20


グレースケールです。上記のサイトを参考にさせていただきました。

groovyを使ってピクセル操作しています。
といっても、特にjavaと変わらないコードになってしまっていますが。。。
ちょっとおちついてコードをみなおしていますと、ループの処理に統一がないですね。


1.単純にRGB の平均値を用いる方法

変換後の値 = (R + G + B)/3
で計算します。

下記、groovyコードです。

package fun.g.filter.grayscale;

import fun.g.filter.IFilter;
import com.jhlabs.image.GrayscaleFilter;

public class grayscale implements IFilter{

public int[] filterPixels(int width, int height, int[] pix){

def d = pix;
def dout = new int[width * height];
int p = 0;
(0..<height).each{ y ->
int x = 0;
while(x< width) {
int gray = 0;
int rgb = d[p];
int a = rgb & 0xff000000;
int r = (rgb & 0xff0000) >> 16;
int g = (rgb & 0xff00) >> 8 ;
int b = rgb & 0xff;

rgb = (r + g + b) / 3;
gray = (0xff000000 | rgb << 16 | rgb << 8 | rgb);
dout[p] = gray;
x++;
p++;
}
}

println "ok gray"
return dout;
}

}


2.中間値法 ( middle value )

R、G、B の3つの値は 0 ~ 255 の任意の整数を取るものとし、また値が最大のものを max、最小のものを min とすると、グレースケール変換後の値 Y (値の範囲は 0 ~ 255 の整数とする)は、以下の式で求められます。
Y = ( max + min ) / 2
osakana.factory - グレースケールのひみつ


package fun.g.filter.grayscale;

import fun.g.filter.IFilter;
import com.jhlabs.image.GrayscaleFilter;

public class grayscale implements IFilter{

public int[] filterPixels(int width, int height, int[] pix){

def d = pix;
def dout = new int[width * height];
int p = 0;
(0..<height).each{ y ->
int x = 0;
while(x< width) {
int gray = 0;
int rgb = d[p];
int a = rgb & 0xff000000;
int r = (rgb & 0xff0000) >> 16;
int g = (rgb & 0xff00) >> 8 ;
int b = rgb & 0xff;
int max = (r < g) ? g:r;
max = (max < b) ? b:max;
int min = (r < g) ? r:g;
min = (min < b) ? min:b;
rgb = ( max + min ) / 2;
gray = (0xff000000 | rgb << 16 | rgb << 8 | rgb);
dout[p] = gray;
x++;
p++;
}
}

println "ok gray middle value "
return dout;
}

}


3.NTSC 係数による加重平均法

Y = ( 0.298912 * R + 0.586611 * G + 0.114478 * B )


下記、groovyコード

package fun.g.filter.grayscale;

import fun.g.filter.IFilter;
import com.jhlabs.image.GrayscaleFilter;

public class grayscale implements IFilter{

public int[] filterPixels(int width, int height, int[] pix){

def d = pix;
def dout = new int[width * height];
int p = 0;
(0..<height).each{ y ->
int x = 0;
while(x< width) {
int gray = 0;
int rgb = d[p];
int a = rgb & 0xff000000;
int r = (rgb & 0xff0000) >> 16;
int g = (rgb & 0xff00) >> 8 ;
int b = rgb & 0xff;
rgb = ((r * 0.299) + (g * 0.587) + (b * 0.114 ));
gray = (0xff000000 | rgb << 16 | rgb << 8 | rgb);
dout[p] = gray;
x++;
p++;
}
}

println "ok NTSC Coef. method"
return dout;
}

}



4.HDTV 係数による加重平均と補正

X = 2.2

R = ( R ^ X ) * 0.222015
G = ( G ^ X ) * 0.706655
B = ( B ^ X ) * 0.071330

Y = ( R + G + B ) ^ ( 1 / X )


以下、groovyコード。


package fun.g.filter.grayscale;

import fun.g.filter.IFilter;
import com.jhlabs.image.GrayscaleFilter;

public class grayscale implements IFilter{

public int[] filterPixels(int width, int height, int[] pix){

def d = pix;
def dout = new int[width * height];
int p = 0;
(0..<height).each{ y ->
int x = 0;
while(x< width) {
int gray = 0;
int rgb = d[p];
int a = rgb & 0xff000000;
int r = (rgb & 0xff0000) >> 16;
int g = (rgb & 0xff00) >> 8 ;
int b = rgb & 0xff;

double X = 2.2;
// groovy's pow is **
// r ^ X, g ^ X, b ^ X
r = (r ** X) * 0.222015
g = (g ** X) * 0.706655
b = (b ** X) * 0.071330
rgb = (r + g + b) ** ( 1 / X );

gray = (0xff000000 | rgb << 16 | rgb << 8 | rgb);
dout[p] = gray;
x++;
p++;
}
}

println "ok ITU Coef. method"
return dout;
}

}

: