Main Content

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

イメージ内の色数の削減

24 ビット カラー表示のシステムで、トゥルーカラー イメージは最大 16,777,216 色 (224) まで表示可能です。しかし、より低いスクリーン ビット深度をもつシステム上で、トゥルーカラー イメージは、非常にうまく表示できます。これは、必要に応じて、MATLAB® が自動的に色近似とディザリングを行うからです。色近似は、正確に一致する色が見つからない場合に、ソフトウェアが代わりの色を選択する処理です。

しかし、インデックス付きイメージは、多くの色数をもっている場合に問題が起こる可能性があります。一般に、次の理由で、インデックス付きイメージを 256 色までに制限すべきです。

  • 8 ビット表示をもつシステムで、256 色を超えるカラーのインデックス付きイメージは、ディザリングまたはマッピングしなければなりません。そのため、うまく表示できません。

  • 一部のプラットフォームでは、カラーマップに 256 を超えるエントリを登録できません。

  • インデックス付きイメージが 256 色を超える場合、MATLAB は uint8 配列にイメージ データをストアすることはできません。しかし、一般には、代わりに、double クラスの配列を使い、イメージのストレージサイズをより大きくします(各ピクセルは 64 ビットを使用)。

  • 多くの画像ファイル形式は、インデックス付きイメージを 256 色に制限しています。256 色を超える色数を使用するインデックス付きイメージを (imwrite を使用して) 256 色までしかサポートしない形式に書き込むと、エラーが発生します。

イメージの色数を削減する方法には以下があります。

色近似を使用したトゥルーカラー イメージの色数の削減

イメージの色数を削減するには、関数 rgb2ind を使用します。この関数は、トゥルーカラー イメージをインデックス付きイメージに変換し、この処理で色数を削減します。rgb2ind では、元のイメージでの色を近似するために次の方法が提供されます。

結果のイメージの画質は、使用する近似法、入力イメージの色の範囲、およびディザリングの使用の有無に依存します。どの方法がより有効に機能するかはイメージによって異なります。ディザリングとそれを有効または無効にする方法の詳細は、ディザリングを使用した色数の削減を参照してください。

量子化

イメージ内の色数を削減するには、量子化を行います。関数 rgb2ind は、色数低減アルゴリズムの一部として量子化を使用します。rgb2ind は、一様量子化最小分散量子化の 2 つの量子化法をサポートします。

イメージの量子化の説明で重要な用語は、"RGB カラー キューブ" です。RGB カラー キューブは、特別なデータ型に対して、定義されるカラー全体を表す 3 次元配列です。MATLAB の中で RGB イメージは、uint8uint16double のいずれかのタイプで、これらに対して 3 種類の異なるタイプのカラー キューブの定義があります。たとえば、RGB イメージが uint8 クラスの場合、256 個の値は、各色平面 (赤、緑、青) に対して定義され、全体として、224 (16,777,216) の色がカラー キューブで定義されます。このカラーチューブは、実際に使用する色にかかわらず、uint8RGB イメージ全体に対して、同じものになります。

uint8uint16double の 3 つのカラー キューブは、同じ色範囲をもっています。言い換えれば、uint8 RGB イメージの中の明るい赤は、double RGB イメージの中の明るい赤と同じように表示されます。違いは、double RGB カラー キューブは、より多くの赤の階調 (すべての色で多くの階調) をもっていることです。次の図は、uint8 イメージ用のRGB カラー キューブを示しています。

uint8 イメージ用の RGB カラー キューブ

量子化は、RGB カラー キューブをより小さな数のボックスに分け、その後、すべてのカラーを、対応するボックスの中心のカラー値にマッピングする処理です。

一様量子化と最小分散量子化は、RGB カラー キューブを分けるために使用するアプローチに違いがあります。一様量子化では、カラー キューブは、同じサイズのボックス(より小さいキューブ)に切り取られます。最小分散量子化では、種々の異なるサイズのボックス(必ずしも、キューブではない)に切り取られます。ボックスのサイズは、イメージの中に分布する色数に依存します。

一様量子化-  一様量子化を実行するには、関数 rgb2ind を呼び出し、許容誤差を指定します。許容誤差は、RGB カラー キューブを分配する立方体のサイズを決定します。許容誤差の設定値は、[0,1] の範囲の値です。たとえば、許容誤差を 0.1 とすると、ボックスのエッジは、RGB カラー キューブの長さの 1/10 になり、ボックスの最大数は、次のようになります。

n = (floor(1/tol)+1)^3

次のコマンドは、許容誤差 0.1 を設定した一様量子化を行います。

RGB = imread('peppers.png');
[x,map] = rgb2ind(RGB, 0.1);

次の図は、uint8 イメージの一様量子化を示します。この図は、わかりやすくするためにカラー キューブの 2 次元スライス (または、色平面) を示しており、red=0、green と blue が 0 から 255 までの範囲に相当します。実際のピクセル値は x の中心で示されています。

RGBカラー キューブのスライス上での一様量子化

カラー キューブを分割した後、すべての空のボックスを切り捨てます。そのため、ボックスの中の 1 つのみを使用して、カラーマップ用の 1 つのカラーを作ります。前に示したように、一様量子化で作成されるカラーマップの最大長は予測できますが、rgb2ind は入力イメージの中に現れない色を除去するので、カラーマップは予測したものより短くなります。

最小分散量子化-  最小分散量子化を実行するには、rgb2ind を呼び出し、出力イメージのカラーマップの中の色数の最大数を指定します。指定した値によって、RGB カラー キューブが分割されるボックスの数が決定します。次のコマンドは、185 カラーをもつインデックス付きイメージを最小分散量子化を使用して作成します。

RGB = imread('peppers.png');
[X,map] = rgb2ind(RGB,185);

最小分散量子化は、ピクセル値間の分散に基づいてピクセルをグループに関連付けることによって行われます。たとえば、青のピクセルの集合は、グループの中心ピクセルからわずかしかズレていないので、すべて同じグループになります。

最小分散量子化で、カラー キューブを分配するボックスのサイズは異なり、カラー キューブを必ずしも満たすものではありません。カラー キューブのある部分で、ピクセルが存在しない場合、これらの部分にはボックスは存在しません。

rgb2ind を使用するときに、ボックス数 n を設定すると、配置はイメージのカラー データを解析するときのアルゴリズムにより決定されます。イメージが、最適に配置された n 個のボックスに分割されると、各ボックスの中のピクセルは、一様量子化と同様にボックスの中心のピクセル値にマッピングされます。

結果のカラーマップは、ユーザーが指定したエントリ数をもっています。これは、各領域は、入力イメージの中で少なくとも 1 つの色を含むようにカラー キューブが分割されるためです。入力イメージは、指定した数より少ない色を使う場合、出力カラーマップは、色数 n より少なくなり、出力イメージは、入力イメージの色のすべてを含んでいます。

次の図は、前の図 (一様量子化) で使用されているカラー キューブと同じ 2 次元スライスを示しています。11 個のボックスが、最小分散量子化を使用して作成されます。

RGB カラー キューブのスライス上での最小分散量子化

色数を与えると、最小分散量子化は、実際のデータを考慮するので一様量子化よりも良い結果を出力します。最小分散量子化は、入力イメージに頻繁に現れる色には、より多くのカラーマップ エントリを割り当てます。あまり頻繁に現れないものは、カラーマップ要素の割り当てが少なくなります。結果として、色の精度は一様量子化よりも高くなります。たとえば、入力イメージには、緑の階調が多く、赤の階調が少ないとすると、出力のカラーマップには、赤よりも緑が増えます。最小分散量子化に必要な計算時間は一様量子化の場合よりも増えます。

カラーマップ マッピング

使用する実際のカラーマップを指定する場合、rgb2ind は、(量子化の代わりに) "カラーマップ マッピング" を使用して、指定したカラーマップの中で、RGB イメージの中の色と最も近い色を探します。この方法は、固定したカラーマップを使用してイメージを作成する場合に役に立ちます。たとえば、8 ビット表示上で複数のインデックス付きイメージを表示する場合、同じカラーマップにこれらすべてをマッピングすることにより、色に関する問題を避けることができます。カラーマップ マッピングは、指定したカラーマップが、RGB イメージの中のカラーマップと同じ色を使う場合に良い近似になります。カラーマップが、RGB イメージのものと異なる場合、この方法による結果は良いものではありません。

この例は、2 つのイメージを同じカラーマップにマッピングしたものを示しています。2 つのイメージに対して使用されるカラーマップは、指定の色数を含む RGB カラーマップを作成する MATLAB 関数 colorcube を使用して実行中に作成されます (colorcube は与えられた色数に対して、常に同じカラーマップを作成します)。カラーマップは、RGB カラー キューブに含まれるすべての色を含んでいるので、出力イメージは、入力イメージの良い近似になります。

RGB1 = imread('autumn.tif');
RGB2 = imread('peppers.png');
X1 = rgb2ind(RGB1,colorcube(128));
X2 = rgb2ind(RGB2,colorcube(128));

メモ:

関数 imshow は、複数のインデックス付きイメージを表現するために有効なものです。詳細は、同じ Figure ウィンドウ内に個別にイメージを表示または関数 imshow のリファレンス ページを参照してください。

imapprox を使用したインデックス付きイメージの色数の削減

インデックス付きイメージで色数を削減しなければならない場合は、imapprox を使用します。imapproxrgb2ind に基づいて処理され、同じ近似法を使用します。本質的に、imapprox は、最初に ind2rgb を呼び出して、イメージを RGB 形式に変換し、次に rgb2ind を呼び出して、色数を減らした新しいインデックス付きイメージを戻します。

たとえば、元のイメージは 128 色ですが、次のコマンドを使用して、64 色の trees イメージを作成します。

load trees
[Y,newmap] = imapprox(X,map,64);
imshow(Y, newmap);

結果のイメージの画質は、使用する近似法、入力イメージの色の範囲、およびディザリングの使用の有無に依存します。どの方法がより有効に機能するかはイメージによって異なります。ディザリングとそれを有効または無効にする方法の詳細は、ディザリングを使用した色数の削減を参照してください。

ディザリングを使用した色数の削減

イメージの色数を減らすために rgb2ind または imapprox を使うと、一部の色が失われるために、最終的なイメージは元のイメージより劣化して見える可能性があります。rgb2indimapprox はどちらも "ディザリング" を行って出力イメージの見かけの色の数を増やします。"ディザリング" は、ある近傍の中でピクセルの色数を変化させ、各ピクセルの周りの平均色が元の RGB カラーを近似するものです。

ディザリングがどのように機能するかの例として、カラーマップに厳密な意味で一致しない、暗いオレンジのピクセルを含むイメージを考えます。オレンジのこの階調を作成するために、ディザリングはカラーマップから色の組み合わせを選択し、6 個のピクセルをひとまとめにして、希望するオレンジの階調に近似します。遠目には、ピクセルは正しい階調で見えますが、近くでイメージを見ると、他の階調が混ざっているように見えます。ディザリングを説明するために、次の例では 24 ビットのトゥルーカラー イメージを読み取り、rgb2ind を使用して わずか 8 色だけでインデックス付きイメージを作成します。最初の例はディザリングが使用されていません。2 番目の例はディザリングが使用されています。

イメージを読み取り、それを表示します。

rgb = imread('onion.png'); 
imshow(rgb)

インデックス付きイメージを 8 色で、ディザリングなしで作成します。

[X_no_dither,map] = rgb2ind(rgb,8,'nodither');
imshow(X_no_dither,map)

ディザリングで、8 色のインデックス付きイメージを作成します。ディザリングされたイメージは、見かけの色の数を非常に大きくしますが、若干あいまいに見えることに注意してください。ディザリングされていないイメージは、見かけの色数が少なく見えますが、ディザリングされたイメージと比べ、空間分解能が高くなっています。ディザリングなしで色数を減らすことによるリスクの 1 つに、新しいイメージに偽の等高線を生じる可能性があります。

[X_dither,map] = rgb2ind(rgb,8,'dither');
imshow(X_dither,map)