5

MATLAB で色が正しく表示されないことがあります。これが私の側のプログラミング エラーなのか、それとも MATLAB の実際のバグなのかはわかりません。昨年かそこらで、この動作に一定の規則性があることに気付きました。

今回は、問題のエラーのある Figure のスナップショットを作成することにしました (Windows 7、64 ビットの MATLAB 2011b で取得)。

                                   ここに画像の説明を入力

問題の画像を表示するコードは次のとおりです。

figure;
clf;
cla;
imshow(matrix, []);
colormap(cmap);
set(gca, 'Clim', [0 highest_index]);

どこ:

  • matrixタイプです(ただし、を呼び出す前にuint32明示的にキャストしようとmatrixしましたが)doubleimshow
  • matrix~の範囲0の値900
  • cmap901エントリがあります
  • highest_index900

259の値のRGB エントリは、matrix[1, 0, 0.1]の画像とカラーマップ配列の両方にあります(cmapつまり、カラーマップの最初のエントリはマトリックス値のためであるため、マトリックス値はカラーマップでインデックスを取得するcmap(300, :) = [1, 0, 0.1]ことに注意してください)。2593000

質問:

なぜこれが起こるのですか?エラーですか?私が間違っていることはありますか?

更新 1:

  1. またはに切り替えCDataMappingてみましたが、違いはありませんでした。directscaled
  2. imagescの代わりに も使用してみimshowましたが、違いはありませんでした。
  3. 最初に画像を RGB に変換すると (つまり、indexed imageを画像に変換しtrue colorます。詳細については、こちらを参照してください)、つまり を使用するi_rgb = ind2rgb(i_indexed, cmap)と、エラーがなくなり、画像が正しく表示されます。

    残念ながら、true color画像を表示すると、データ ヒントは各色の元のマトリックスのインデックスを明らかにせず、代わりに RGB ベクトルを表示するだけです (つまり、MATLAB は元のインデックスを認識していないため、これは論理的です)。

更新 2:

サンプルコードは次のとおりです。

h_f = figure(1);
clf;
i_spiral = spiral(40);
h_i = image(i_spiral);

% Synthesize a colormap first in HSV and then transform it to RGB:
max_i_spiral = max(i_spiral(:));
m           = max_i_spiral;
h           = (0:m-1)'/max(m,1);
cmap_spiral = hsv2rgb([h ones(m,2)]);  
colormap(cmap_spiral);

% If I comment out the following two lines or use imshow instead of image, 
% it makes no difference (I still get the same error):
set(gca, 'Clim', [1 max_i_spiral]);
set(h_i, 'CDataMapping', 'direct');

上記のコードの結果は次のとおりです。

            ここに画像の説明を入力

4

3 に答える 3

8

[この回答は以前の回答とはまったく関係がないため、最初の回答は編集していません]

あなたが言及するリンク(http://www.mathworks.com/help/matlab/creating_plots/image-types.html)は次のように述べています。

Windowsプラットフォームでペインターレンダラーを使用する場合、インデックス付き画像を表示するときは256色のみを使用する必要があります。画家のアルゴリズムはWindows256カラーパレットを使用するため、カラーマップが大きくなると予期しない色になる可能性があります。Windows256カラーパレットは、グラフィックスドライバーとグラフィックスハードウェアで異なる方法で処理されることが知られています。この問題を回避するには、必要に応じてZbufferまたはOpenGLレンダラーを使用します。MATLABのグラフィックスレンダラーの詳細については、テクニカルノート1201:グラフィックスレンダリングとトラブルシューティングのテクニカルサポートガイドを参照してください。

したがって、問題は、カラーマップに256を超える値があることのようです。また、インデックス付き画像を使用しない場合に問題が解決する理由についても説明します。注のテクニカルサポートリンクで提案されているように、別のレンダラーを使用してみてください。

set(gcf, 'Renderer', 'opengl')

また

set(gcf, 'Renderer', 'Zbuffer')
于 2011-10-16T17:09:37.313 に答える
3

IMSHOWを使用するより良い方法は次のとおりです。

imshow(img,map)

これはあなたの例を少し書き直したものです:

%# indexed image
I = spiral(40);

%# Synthesize a colormap first in HSV and then transform it to RGB
mx = max(I(:));
cmap = hsv2rgb([(0:mx-1)'./max(mx,1) ones(mx,2)]);         %'

%# show image
imshow(I,cmap)
colorbar
datacursormode on

スクリーンショット


編集:

@ItamarKatzのおかげで、Windows で 256 色を超えるインデックス付き画像を表示する場合、「ペインター」アルゴリズムをレンダラーとして使用してはならないことがわかりました。

IMSHOW (下位レベルの IMAGE 関数を呼び出します) は、そのようなケースを検出し、正しく処理します。

それでも IMAGE/IMAGESC を使用する場合は、インデックス付きの画像データ型に注意する必要があります。

  • double[1 length(cmap)] : イメージには、現在のカラーマップのインデックスとして範囲内の整数が含まれます
  • uint8/uint16 : イメージには、またはの範囲[0 255]の整数が含まれ、現在のカラーマップのインデックスとして解釈されます。uint8[0 65535]uint16

したがって、注意が必要なオフセット (0またはから始まる範囲) があります。1

IMAGE 関数を直接使用した上記と同じ例を次に示します (1 回は double データ型、もう 1 回は uint16 を使用)。

%# indexed image and colormap
I = spiral(40);
cmap = hsv( max(I(:)) );

%# show indexed image (double)
hFig = figure(2);
hImg = image(I);                          %# one-based index into colormap
colormap(cmap), colorbar
axis off image

%# fix bug on Windows with indexed image of more than 256 colors
if ispc && strcmpi(get(hImg,'CDataMapping'),'direct') && size(cmap,1) > 256
    set(hFig, 'Renderer','zbuffer')       %# opengl renderer also works
end

%# show indexed image (uint16)
hFig = figure(3);
hImg = image( uint16(I-1) );              %# zero-based index into colormap
colormap(cmap), colorbar
axis off image

%# fix bug on Windows with indexed image of more than 256 colors
if ispc && strcmpi(get(hImg,'CDataMapping'),'direct') && size(cmap,1) > 256
    set(hFig, 'Renderer','zbuffer')
end
于 2011-10-16T17:31:19.023 に答える
1

100% 確信はありませんが (データなしでは検証できませんでした)、データ ヒント表示関数のコールバックによって行われたマッピング/丸めが間違っていることが原因だと思います。Edit Text Update Function...データ ヒントを右クリックして を選択し、次のように入力して、独自のコールバックを作成できます。

function output_txt = dataCursorCallback(obj,event_obj)
% Display the position of the data cursor, and the RGB data to 6 decimal places.

pos = get(event_obj,'Position');
output_txt = {['X: ',num2str(pos(1),4)],...
    ['Y: ',num2str(pos(2),4)]};

h = get(event_obj,'target');
cdata = get (h, 'CData');
cmap = colormap;
rgb = cmap(cdata(pos(2),pos(1)),:);
output_txt{end+1} = ['RGB: ' num2str(rgb,'%.6f')];

上記のコードは、プロットされた行列のカラーマップの長さとデータ範囲が同じであると想定していることに注意してください-あなたの例のように。コールバックを保存するには、 をクリックsave and closeします。データ ヒントを右クリックして、次の機会に再度選択することができます。Select Text Update Function...

于 2011-10-15T10:50:41.560 に答える