LoginSignup
39
34

More than 5 years have passed since last update.

色差アルゴリズムの違いをビジュアル化してみた

Last updated at Posted at 2017-02-14

2つの色の知覚的な差を定量化するアルゴリズムがいつくか公開されていて、このアルゴリズムを使って計算すると色の違いを数量化することができます。値が小さければ小さいほど似て(又は同じ色)に見え、大きければ大きいほど異なって見えるということらしいです。

以前Color difference(Wikipedia)で公開されていた色差を求める計算式をJavaScriptで作ってみたことがあったので、それぞれの結果の違いをビジュアル化してみました。

色差計算およびカラーサンプル作成に使ったHSVからRGBに変換するスクリプトはページの最後にリンク先を載せていますので、間違っている等、お気づきのところがあったら教えてくれると助かります。

どうやってビジュアル化する?

以下のようなHSVカラーサンプルを作って、それを変換することで確認してみたいと思います。
colorsample.png

変換先の色として私でもイメージできそうな以下の13色(赤、橙、黄、黄緑、緑、青、紫、桃、白、黒、灰、茶、水)を用意しました。
tocolor3.png

それをJavaScriptで定義するとこんな感じ。

色の指定
let colorNames = [
    {name:"", reading:"あか", hex:"#e60033"},
    {name:"", reading:"だいだい", hex:"#ee7800"},
    {name:"", reading:"きい", hex:"#ffd900"},
    {name:"黄緑", reading:"きみどり", hex:"#b8d200"},
    {name:"", reading:"みどり", hex:"#3eb370"},
    {name:"", reading:"あお", hex:"#0095d9"},
    {name:"", reading:"むらさき", hex:"#884898"},
    {name:"", reading:"もも", hex:"#f09199"},
    {name:"", reading:"しろ", hex:"#ffffff"},
    {name:"", reading:"くろ", hex:"#2b2b2b"},
    {name:"", reading:"はい", hex:"#7d7d7d"},
    {name:"", reading:"ちゃ", hex:"#965042"},
    {name:"", reading:"みず", hex:"#bce2e8"}
]

プログラムとしては用意した13色の中で最も近い(差が小さい)色を探し、その色に置き換えていくという感じです。以下はそのサンプルです。サンプルなのでrgbからLabへの変換や色差を求めるプログラムは含めていませんので、このままでは動きません。それらの情報はページの最後に載せているリンクを参考にしてください。またテキストからPNGへの変換については「ImageMagickで画像を座標+RGB値のテキストに変換する、またその逆」を参考にしてください。

変換(サンプル)
//rgbとlabを計算
for (let o of colorNames) {
    o.rgb = [
            parseInt(o.hex.substring(1,3), 16),
            parseInt(o.hex.substring(3,5), 16),
            parseInt(o.hex.substring(5,7), 16)
    ];
    o.lab = rgbToLab(...o.rgb);
}

//カラーサンプルを作成
let colorSample = [];
for(let s=1;s<=100;s++) {
    for(let h=0; h<360; h++){
        let o = {x:h, y:s-1, rgb:hsvToRgb(h, s/100, 1)};
        o.lab = rgbToLab(...o.rgb);
        colorSample.push(o);
    }
}

//最も近い色で変換
for (let o of colorSample) {
    o.euclidean = colorNames.map(p=>[p, euclidean(...p.rgb, ...o.rgb)]).reduce((a,b)=>a[1]<b[1]?a:b)[0];
    o.cie76 = colorNames.map(p=>[p, cie76(...p.lab, ...o.lab)]).reduce((a, b)=>a[1]<b[1]?a:b)[0];
    o.cie94 = colorNames.map(p=>[p, cie94(...p.lab, ...o.lab)]).reduce((a, b)=>a[1]<b[1]?a:b)[0];
    o.ciede2000 = colorNames.map(p=>[p, ciede2000(...p.lab, ...o.lab)]).reduce((a, b)=>a[1]<b[1]?a:b)[0];
}

//保存
let fs = require('fs');
let imageText = []
imageText.push("# ImageMagick pixel enumeration: 360,500,255,srgb");

for (let o of colorSample) {
    imageText.push(`${o.x},${o.y      }: (${o.rgb.join(",")})`);
    imageText.push(`${o.x},${o.y + 100}: (${o.euclidean.rgb.join(",")})`);
    imageText.push(`${o.x},${o.y + 200}: (${o.cie76.rgb.join(",")})`);
    imageText.push(`${o.x},${o.y + 300}: (${o.cie94.rgb.join(",")})`);
    imageText.push(`${o.x},${o.y + 400}: (${o.ciede2000.rgb.join(",")})`);
}

fs.writeFileSync('diff.txt', imageText.join("\n"));

//実行後 convert diff.txt diff.png でPNG形式に変換。

それではGO!

Euclidean(ユークリッド)

もっとも単純そうな計算式です。3次元での距離を求める計算式と似ています。

Euclidean
(「Color difference」(5 Feb 2017, at 02:30. UTC)『ウィキペディア』より引用)

euc.png

CIE76

計算式は以下のようになっています。

CIE76
(「Color difference」(5 Feb 2017, at 02:30. UTC)『ウィキペディア』より引用)

式はユークリッドとほとんど同じにみえるのですがRGBではなくLabが使われています。Lab色空間はLab color space - Wikipediaに情報があるのですが、XYZ色空間からの変換方法しか書かれていません。そしてsRGB - WikipediaにはRGBからXYZ色空間への変換方法が書かれています。つまりRGB→XYZ→Labという計算を行わないと計算が行えないことになります。で計算した結果が以下のとおりです。
cie76.png

CIE94

以下のような計算式なのですが「graphic arts」と「textiles」があったり、比較する色のどちらをL1a1b1にするかによって結果が変わります。

CIE94
(「Color difference」(5 Feb 2017, at 02:30. UTC)『ウィキペディア』より引用)

以下の結果は「graphic arts」の場合です。
cie94.png

「textiles」の場合は以下のような感じです。
cie94t.png

「graphic arts」の場合でL1a1b1とL2a2b2の値を入れ替えると以下のようになります。今回の場合は前者の方が近いようです。
cie94r.png

CIEDE2000

きっと最も新しいと思うんですが、計算式もかなり複雑です。

CIE2000
(「Color difference」(5 Feb 2017, at 02:30. UTC)『ウィキペディア』より引用)

cie2000.png

まとめて比較してみる

名称 結果
元画像 colorsample.png
Euclidean euc.png
CIE76 cie76.png
CIE94 graphic cie94.png
CIE94 textiles cie94t.png
CIEDE2000 cie2000.png

使用したスクリプト

今回使用した色差を求めるスクリプトは以下で公開しています。

39
34
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
34