我有一张图片,我想将此图片导入matlab。我使用以下代码。我遇到的问题是,当我将图像转换为灰度时,所有内容都将被更改,转换后的图像与原始图像不同。换句话说,我想保留原始图像中的值(或者说图像)。有没有办法做到这一点?
I = imread('myimage.png');
figure, imagesc(I), axis equal tight xy
I2 = rgb2gray(I);
figure, imagesc(I2), axis equal tight xy
答案 0 :(得分:1)
您的原始图片已使用jet
色彩图。问题是,当您将其转换为灰度时,您会丢失一些重要信息。见下图。
在原始图片中,您有一张热图。蓝色区域通常表示“低值”,而红色区域表示“高值”。但是当转换为灰度时,两个区域都表示低值,因为它们接近暗像素(参见箭头)。
可能的解决方案是:
你拍摄图像的每个像素,找到最近的(最近的)
jet
色彩图中的颜色值,并将其索引用作灰色值。
我将首先向您展示最终的代码和结果。解释如下:
I = im2double(imread('myimage.png'));
map = jet(256);
Irgb = reshape(I, size(I, 1) * size(I, 2), 3);
Igray = zeros(size(I, 1), size(I, 2), 'uint8');
for ii = 1:size(Irgb, 1)
[~, idx] = min(sum((bsxfun(@minus, Irgb(ii, :), map)) .^ 2, 2));
Igray(ii) = idx - 1;
end
clear Irgb;
subplot(2,1,1), imagesc(I), axis equal tight xy
subplot(2,1,2), imagesc(Igray), axis equal tight xy
结果:
>> whos I Igray
Name Size Bytes Class Attributes
I 110x339x3 894960 double
Igray 110x339 37290 uint8
<强>解释强>
首先,你得到jet
色彩映射,如下所示:
map = jet(256);
它将返回一个256x3
色彩图,其中可能的颜色位于喷射调色板上,其中每一行都是RGB像素。 map(1,:)
会是一种深蓝色,map(256,:)
会像预期的那样呈暗红色。
然后,你这样做:
Irgb = reshape(I, size(I, 1) * size(I, 2), 3);
...将您的110x339x3
图片转换为37290x3
矩阵,其中每一行都是RGB像素。
现在,对于每个像素,您将该像素的欧几里德距离取为map
像素。您获取最近的索引并将其用作灰色值。减一(-1
)是因为索引在1..256范围内,但灰度值在0..255范围内。
注意:欧几里德距离最后取平方根,但由于我们只是想找到最接近的值,所以没有必要这样做。
修改强>
这是代码的速度提高了10倍:
I = im2double(imread('myimage.png'));
map = jet(256);
[C, ~, IC] = unique(reshape(I, size(I, 1) * size(I, 2), 3), 'rows');
equiv = zeros(size(C, 1), 1, 'uint8');
for ii = 1:numel(equiv)
[~, idx] = min(sum((bsxfun(@minus, C(ii, :), map)) .^ 2, 2));
equiv(ii) = idx - 1;
end
Irgb = reshape(equiv(IC), size(I, 1), size(I, 2));
Irgb = Irgb(end:-1:1,:);
clear equiv C IC;
它运行得更快,因为它利用了图像上的颜色仅限于jet
调色板中的颜色这一事实。然后,它计算unique
颜色并仅将它们与调色板值匹配。由于匹配的像素更少,算法运行得更快。以下是时间:
<强>之前:强>
经过的时间是0.619049秒。
<强>后:强>
经过的时间是0.061778秒。
答案 1 :(得分:0)
在第二张图片中,您使用的是默认colormap
,即jet
。如果您想要灰度,请尝试使用colormap(gray)
。