【问题标题】:converting rgb image to double and keeping the values in matlab将 rgb 图像转换为 double 并将值保留在 matlab 中
【发布时间】:2014-05-03 17:40:00
【问题描述】:

我有一张图片,我想将此图片导入 matlab。我正在使用以下代码。我遇到的问题是,当我将图像转换为灰度时,一切都会改变,并且转换后的图像与原始图像不相似。换句话说,我想保持原始图像中的值(或者说图像)。有没有办法做到这一点?

I = imread('myimage.png');
figure, imagesc(I), axis equal tight xy

I2 = rgb2gray(I);
figure, imagesc(I2), axis equal tight xy

【问题讨论】:

    标签: image matlab image-processing computer-vision


    【解决方案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 秒。

    【讨论】:

    • 很高兴为您提供帮助!我已经编辑了我的答案,以包含一个快 10 倍的代码版本。 :)
    • 非常感谢,这对我来说太多了 :)
    【解决方案2】:

    在第二张图片中,您使用的是默认的colormap,即jet。如果您想要灰度,请尝试使用colormap(gray)

    【讨论】:

    • 我需要它的值,因为转换为灰度后,值会发生变化,而颜色图不会改变图像
    • @Sam:那么不清楚你在问什么。通过转换为灰度,您会丢弃信息(即色调和饱和度)。您无法恢复该信息。
    • 那我怎么才能拥有相同的图像(通过使用其他任何东西)?因为原始图像的值对我来说非常重要,我想把它放在一个二维矩阵中。
    • @Sam:如果原始RGB图像的值很重要,那就不要转灰度!
    • 实际上我想在二维矩阵中拥有该图像,这就是为什么我要转换为灰度!是否有另一种方法可以避免转换为灰度并将原始图像保存在二维矩阵中?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 2020-03-04
    • 2013-12-05
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 1970-01-01
    相关资源
    最近更新 更多