5

我注意到 MATLAB 有时会错误地显示我的颜色。我不确定这是我这边的编程错误,还是 MATLAB 中的实际错误。在过去一年左右的时间里,我经常注意到这种行为。

这一次,我决定拍一张有问题的图的快照(在 Windows 7 64 位的 MATLAB 2011b 上拍摄):

                                   在此处输入图像描述

显示相关图像的代码如下:

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

在哪里:

  • matrix是类型uint32(尽管我也尝试过matrixdouble调用之前显式转换imshow
  • matrix介于0和之间的值900
  • cmap901条目
  • highest_index900

259inmatrix值的 RGB 条目[1, 0, 0.1]在上图中和颜色图数组cmap中,即cmap(300, :) = [1, 0, 0.1](请注意,矩阵值259获取颜色图中的索引300,因为颜色图的第一个条目是矩阵值0)。

问题:

为什么会这样?这是一个错误吗?有什么我做错了吗?

更新1:

  1. 我尝试切换CDataMappingdirector scaled,但没有任何区别。
  2. 我也尝试过使用imagesc而不是imshow,但它没有任何区别。
  3. 如果我先将图像转换为 RGB(即将 转换indexed imagetrue 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 平台上使用 Painters 渲染器时,尝试显示索引图像时应仅使用 256 色。较大的颜色图可能会导致意外的颜色,因为画家算法使用 Windows 256 调色板,已知图形驱动程序和图形硬件以不同方式处理。要解决此问题,请酌情使用 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] :图像包含foruint8[0 65535]for范围内的整数uint16,解释为当前颜色图中的索引。

因此有一个偏移量(范围从0或开始1),您应该小心。

这是与上面直接使用 IMAGE 函数的示例相同的示例(一次使用 double 数据类型,另一个使用 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 回答