我注意到MATLAB有时会错误地显示我的颜色。我不确定这是否是我的编程错误,或者它是否是MATLAB中的实际错误。在过去一年左右的时间里,我注意到这种行为具有一定的规律性。
这一次,我决定拍摄一张有关错误的数字的快照(在Windows 7,64位的MATLAB 2011b上拍摄):
显示相关图片的代码如下:
figure;
clf;
cla;
imshow(matrix, []);
colormap(cmap);
set(gca, 'Clim', [0 highest_index]);
其中:
matrix
属于uint32
类型(虽然我在调用matrix
之前尝试过double
imshow
,但matrix
中的值介于0
和900
cmap
有901
个条目highest_index
是900
259
中值matrix
的RGB条目在上图和颜色图数组[1, 0, 0.1]
中均为cmap
,即cmap(300, :) = [1, 0, 0.1]
(通知矩阵值259
获取色彩映射中的索引300
,因为色彩映射的第一个条目用于矩阵值0
)。
为什么会这样?这是一个错误吗?我有什么问题吗?
CDataMapping
切换为direct
或scaled
,但这没有任何区别。imagesc
代替imshow
,但它没有任何区别。如果我首先将图像转换为RGB(即将indexed image
转换为true color
图像; see here以获取更多信息),即使用{{1} },错误消失,图像显示正确。
不幸的是,如果我显示i_rgb = ind2rgb(i_indexed, cmap)
图像,数据提示不再显示每种颜色的原始矩阵中的索引,而只是显示RGB矢量(即这是合乎逻辑的,因为MATLAB不知道原始索引了。)
以下是一些示例代码:
true color
上面的代码导致:
答案 0 :(得分:8)
[由于这个答案与我以前的答案完全无关,我不是在编辑第一个答案]
您提到的链接(http://www.mathworks.com/help/matlab/creating_plots/image-types.html) 表示:
注意在Windows平台上使用画家渲染器时,在尝试显示索引时应该只使用256种颜色 图片。较大的色彩图可能会导致意想不到的颜色,因为 painters算法使用Windows 256调色板,哪些图形 已知驱动程序和图形硬件的处理方式不同。上班 围绕此问题,请根据需要使用Zbuffer或OpenGL渲染器。 有关MATLAB中图形渲染器的更多信息,请参阅 技术说明1201:The Technical Support Guide to Graphics Rendering and Troubleshooting。
所以似乎问题是你的色彩图有超过256个值。它还解释了为什么如果不使用索引图像,问题就会消失。尝试使用其他渲染器,如注释中的技术支持链接所示:
set(gcf, 'Renderer', 'opengl')
或
set(gcf, 'Renderer', 'Zbuffer')
答案 1 :(得分: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,则必须了解索引图像数据类型:
[1 length(cmap)]
中的整数作为当前色彩映射中的索引[0 255]
范围内的uint8
或[0 65535]
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
答案 2 :(得分: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...