イメージ内の色数の削減
トゥルーカラー イメージの色数を削減するには、関数 rgb2ind
を使用します。この関数は、トゥルーカラー イメージをインデックス付きイメージに変換し、この処理で色数を削減します。rgb2ind
では、元のイメージでの色を近似するために次の方法が提供されます。
インデックス付きイメージの色数を削減するには、関数 imapprox
を使用します。詳細については、imapprox を使用したインデックス付きイメージの色数の削減を参照してください。
結果のイメージの画質は、使用する近似法、入力イメージの色の範囲、および "ディザリング" の使用の有無に依存します。ディザリングとそれを有効または無効にする方法の詳細については、ディザリングを使用した色数の削減を参照してください。どの近似方法がより有効に機能するかはイメージによって異なります。
量子化を使用したトゥルーカラー イメージの色数の削減
関数 rgb2ind
は、色数削減アルゴリズムの一部として量子化を使用します。量子化は、"RGB カラー キューブ" をより小さな数のボックスに分け、その後、すべてのカラーを、対応するボックスの中心のカラー値にマッピングする処理です。RGB カラー キューブは、特別なデータ型に対して、定義されるカラー全体を表す 3 次元配列です。
uint8
、uint16
、double
のイメージのカラー キューブはすべて同じ色範囲をもちます。言い換えれば、uint8
RGB イメージの中の明るい赤は、double
RGB イメージの中の明るい赤と同じように表示されます。違いは、double
RGB カラー キューブは、より多くの赤の階調 (すべての色で多くの階調) をもっていることです。次の図は、uint8
イメージ用のRGB カラー キューブを示しています。
uint8 イメージ用の RGB カラー キューブ
rgb2ind
は 2 つの量子化方法をサポートしています。
"一様量子化" では、カラー キューブが、同じサイズのボックス (より小さいキューブ) に分割されます。
"最小分散量子化" では、カラー キューブが、さまざまなサイズのボックス (必ずしもキューブではない) に分割されます。ボックスのサイズは、イメージ内で色がどのように分布しているかによって異なります。
一様量子化
一様量子化を実行するには、関数 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);
次の図は、許容誤差が 0.25 の 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 カラーマップを作成する関数 colorcube
を使用して、即時に作成されます。(colorcube
は、与えられた色数に対して常に同じカラーマップを作成します。)このカラーマップは RGB カラー キューブに含まれるすべての色を含んでいるため、出力イメージは入力イメージにかなり近くなります。
RGB1 = imread("autumn.tif"); RGB2 = imread("peppers.png"); X1 = rgb2ind(RGB1,colorcube(128)); X2 = rgb2ind(RGB2,colorcube(128));
imapprox
を使用したインデックス付きイメージの色数の削減
インデックス付きイメージで色数を削減しなければならない場合は、imapprox
を使用します。imapprox
は rgb2ind
に基づいて処理され、同じ近似法を使用します。本質的に、imapprox
は、最初に ind2rgb
を呼び出して、イメージを RGB 形式に変換し、次に rgb2ind
を呼び出して、色数を減らした新しいインデックス付きイメージを返します。
たとえば、元のイメージは 128 色ですが、次のコマンドを使用して、64 色の trees
イメージを作成します。
load trees
[Y,newcmap] = imapprox(X,map,64);
imshow(Y,newcmap)
インデックス付きイメージは、多くの色数をもっている場合に問題が起こる可能性があります。一般に、次の理由で、インデックス付きイメージを 256 色までに制限すべきです。
8 ビット表示をもつシステムで、256 色を超えるカラーのインデックス付きイメージは、ディザリングまたはマッピングしなければなりません。そのため、うまく表示できません。
一部のプラットフォームでは、カラーマップに 256 個を超えるエントリを登録できません。
インデックス付きイメージに 256 色を超える色がある場合、MATLAB® はイメージ データを
uint8
配列に保存できません。代わりに、MATLAB は通常、データ型double
の配列を使用します。これにより、各ピクセルが 64 ビットを使用するため、イメージのストレージ サイズが大幅に大きくなります。多くのイメージ ファイル形式は、インデックス付きイメージを 256 色に制限しています。256 色を超える色数を使用するインデックス付きイメージを (
imwrite
を使用して) 256 色までしかサポートしない形式に書き込むと、エラーが発生します。
ディザリングを使用した色数の削減
イメージの色数を減らすために rgb2ind
または imapprox
を使うと、一部の色が失われるために、最終的なイメージは元のイメージより劣化して見える可能性があります。rgb2ind
と imapprox
はどちらも "ディザリング" を行って出力イメージの見かけの色の数を増やします。"ディザリング" は、ある近傍の中でピクセルの色数を変化させ、各ピクセルの周りの平均色が元の 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)