グレースケール
実行例
ソースコード
TypeScript
解説/アルゴリズム
画像を無彩色な状態にする、つまり灰色の明暗だけで表現した形式にすることをグレースケールと呼ぶ。
灰色の明暗には白や黒も含まれる。
無彩色というのは RGB で考えると、R, G, B それぞれの値が同じで、白(#ffffff), 黒(#000000)、灰色(#232323 や #777777 など) が該当する。
画像の各ピクセルには色情報が入っている。
例えば #123456 という色が入っているとして、それをグレースケールのアルゴリズムで変換すると、#333333 のような無彩色に変わる。
グレースケールのアルゴリズムは色々と存在するが、ここでは 2 つの手法を紹介する。
単純平均
(R + G + B) / 3;
RGB の平均値を RGB それぞれに代入する方法。
グレースケールとしての性能は低いが、計算自体は単純。
ITU-R BT.601
0.299 * R + 0.587 * G + 0.114 * B;
ITU-R BT.601 はテレビ放送用の規格で、グレースケールの変換には上記の定数が使用される。
コード例(GLSL)
attribute vec2 aPosition;
attribute vec2 aTexCoord;
uniform vec2 uResolution;
varying vec2 vTexCoord;
void main() {
vec2 clipSpace = aPosition / uResolution * 2.0 - 1.0;
gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
vTexCoord = aTexCoord;
}
precision mediump float;
uniform sampler2D uImage;
varying vec2 vTexCoord;
void main() {
vec4 color = texture2D(uImage, vTexCoord);
// float gray = (color.r + color.g + color.b) / 3.0;
float gray = 0.299 * color.r + 0.587 * color.g + 0.114 * color.b;
gl_FragColor = vec4(gray, gray, gray, color.a);
}
コード例(p5.js)
import * as p5 from "p5";
new p5((p: p5) => {
let image: p5.Image;
p.preload = () => {
image = p.loadImage("./0.jpg");
};
p.setup = () => {
p.createCanvas(p.windowWidth, p.windowHeight);
image.loadPixels();
// 画像の全ピクセルを走査
for (let y = 0; y < image.height; y++) {
for (let x = 0; x < image.width; x++) {
// 対象のピクセルを取り出す
const color = getPixel(x, y);
const r = p.red(color);
const g = p.green(color);
const b = p.blue(color);
// const gray = (r + g + b) / 3; // 単純平均
const gray = 0.299 * r + 0.587 * g + 0.114 * b; // ITU-R BT.601
// 計算した明るさをRGBとしてセットする。
setPixel(x, y, [gray, gray, gray]);
}
}
image.updatePixels();
p.image(image, 0, 0);
};
function getPixel(x: number, y: number): number[] {
const i = (y * image.width + x) * 4;
return [
image.pixels[i],
image.pixels[i + 1],
image.pixels[i + 2],
image.pixels[i + 3],
];
}
function setPixel(x: number, y: number, color: number[]): void {
const i = (y * image.width + x) * 4;
image.pixels[i + 0] = color[0];
image.pixels[i + 1] = color[1];
image.pixels[i + 2] = color[2];
}
});