【问题标题】:To imread Parula image in Matlab without losing resolution在 Matlab 中读取 Parula 图像而不丢失分辨率
【发布时间】:2015-07-11 11:28:06
【问题描述】:

RGB 和 Parula 之间没有双射,讨论了 here。 我在想如何在 Parula 中做好文件的图像处理。 这个挑战是从这个thread 发展而来的,关于通过将案例扩展到 Parula 颜色的一般问题来从 ECG 图像中去除黑色。

数据:

生成
[X,Y,Z] = peaks(25);
imgParula = surf(X,Y,Z);
view(2);
axis off;

在您的解决方案中使用此代码来读取第二张图像不是该线程的重点。

代码:

[imgParula, map, alpha] = imread('http://i.stack.imgur.com/tVMO2.png'); 

其中map[]alpha 是全白图像。做imshow(imgParula)给了

您会看到很多干扰和分辨率损失,因为 Matlab 将图像读取为 RGB,尽管实际的颜色图是 Parula。 调整此图片的大小不会提高分辨率。

如何在 Matlab 中将图像读入相应的颜色图? 我没有找到任何参数来指定阅读时的颜色图。

【问题讨论】:

  • 好的。如果您不知道 caxis 的设置是什么(颜色图的范围),则存在不确定性。例如,蓝色可以是任何值,具体取决于此设置...例如,解决方案将为您提供一个介于 0 和 1 之间的数组,这可能不是初始数据范围。
  • 图像文件不是用来表示任意数据,而是图形,它可能代表也可能不代表数据。如果要存储在 Matlab 中生成的数据,请使用 mat 文件或其他二进制或基于文本的文件格式。
  • 我想我知道该怎么做,如果中间没有发布解决方案,我会在几个小时内/明天回家时尝试解决方案。
  • 我认为可以通过以下方式完成:将黑色线条转换为白色,在非白色像素上应用 regionprops,使用重心将区域映射到规则网格上,最后,平均区域上的颜色,并通过查看最接近的颜色将其映射到 parula 颜色图。不幸的是,第一步在很大程度上取决于初始图像的生成方式(格式、分辨率),以及黑色网格并非完全黑色的事实。
  • @Ratbert:请参阅下面的尝试。我不确定我是否涵盖了问题的各个方面——至少正如你所详述的那样——但我确实实施了一个解决方案来找到“最接近”的颜色。

标签: image matlab image-processing resolution


【解决方案1】:

问题

parula 颜色图中的索引颜色到 RGB 三元组有一个one-to-one mapping。但是,不存在这样的一对一映射来反转此过程以将parula 索引颜色转换回 RGB(实际上有无数种方法可以这样做)。因此,两个空格之间没有一一对应或bijection。下图显示了每个 parula 索引的 R、G 和 B 值,更清楚地说明了这一点。

大多数索引颜色都是这种情况。这个问题的任何解决方案都不是唯一的。


内置解决方案

在玩了一会儿之后,我意识到已经有一个内置函数可能就足够了:rgb2ind,它将 RGB 图像数据转换为索引图像数据。这个函数使用dither(它又调用了mex函数ditherc)来执行逆颜色图变换。

这是一个使用 JPEG 压缩来添加噪点并扭曲原始parula 索引数据中的颜色的演示:

img0 = peaks(32);                     % Generate sample data
img0 = img0-min(img0(:));
img0 = floor(255*img0./max(img0(:))); % Convert to 0-255
fname = [tempname '.jpg'];            % Save file in temp directory
map = parula(256);                    % Parula colormap
imwrite(img0,map,fname,'Quality',50); % Write data to compressed JPEG
img1 = imread(fname);                 % Read RGB JPEG file data

img2 = rgb2ind(img1,map,'nodither');  % Convert RGB data to parula colormap

figure;
image(img0);                          % Original indexed data
colormap(map);
axis image;

figure;
image(img1);                          % RGB JPEG file data
axis image;

figure;
image(img2);                          % rgb2ind indexed image data
colormap(map);
axis image;

这应该会产生类似于下面前三个的图像。


替代解决方案:色差

完成此任务的另一种方法是将 RGB 图像中的颜色差异与对应于每个颜色图索引的 RGB 值进行比较。执行此操作的标准方法是在CIE L*a*b* 颜色空间中使用calculating ΔE。我已经在一个名为rgb2map 的通用函数中实现了这种形式,它可以是downloaded from my GitHub。此代码依赖于图像处理工具箱中的makecformapplycform 将RGB 转换为1976 CIE L*a*b* 颜色空间。

下面的代码会产生一个像右上图那样的图像:

img3 = rgb2map(img1,map);

figure;
image(img3);                          % rgb2map indexed image data
colormap(map);
axis image;

对于输入图像中的每个 RGB 像素,rgb2map 使用CIE 1976 标准计算它与输入颜色图中每个 RGB 三元组之间的色差。 min 函数用于查找最小值 ΔE 的索引(如果存在多个最小值,则返回第一个的索引)。在多个 ΔE 最小值的情况下,可以使用更复杂的方法来选择“最佳”颜色,但它们的成本会更高。


结论

作为最后一个例子,我使用an image of the namesake Parula bird来比较下图中的两种方法。此图像的两个结果完全不同。如果您手动调整rgb2map 以使用更复杂的CIE 1994 色差标准,您将获得另一个渲染。但是,对于与原始parula 颜色图(如上)更接近的图像,两者都应该返回更相似的结果。重要的是,rgb2ind 受益于调用 mex 函数,并且几乎比 rgb2map 快 100 倍,尽管我的代码中进行了一些优化(如果使用 CIE 1994 标准,它大约快 700 倍)。

最后,想要了解更多关于 Matlab 中的颜色图的人,应该阅读 Steve Eddins 的 four-part MathWorks blog post 关于新的parula 颜色图。

2015 年 6 月 20 日更新: 上述rgb2map 代码已更新为使用不同的色彩空间变换,这将其速度提高了近两倍。

【讨论】:

  • rgb2map 在所有颜色中似乎都比rgb2ind 更好看。 rgb2map 似乎被黄色烧透了。 为什么rgb2map会出现这种烧穿现象?有什么方法可以避免吗? - 另一个希望是,如果您可以在某些示例中保持垂直和水平线的网格。我想看看不同的功能如何影响不同环境中的线路。出于特定原因,这些台词特别适合挑战。
  • @Masi:我猜这是因为只使用了一个简单的min 函数来查找最接近的颜色匹配。在极端情况下,即接近黑色、白色和完全饱和的颜色,可能会有多个最小值,在这种情况下将使用第一个最小值。这导致许多像素显示为颜色图上的极值之一。解决此问题的潜在方法:1) 重新排序颜色图,以便始终选择不同的颜色,2) 当存在多个最小值时随机选择(或其他方案),3) 使用加权来偏置特定通道或其组合以改变选择。
  • parula 颜色图不包括黑白。尽管使用了索引颜色,但您的图像似乎是屏幕抓取并且有黑线,因为您不是将数据视为图像,而是通过surf 将数据视为 3-D 对象(无论数据如何,黑色都是默认的边缘颜色) .将需要完全不同的过程或特殊情况来处理此问题。最好通过不同的方式预处理和保存文件来避免这个问题。
  • 处理网格线等伪影的最简单方法可能是稍微修改颜色图。使用map = [0 0 0; parula(254); 1 1 1]; 尝试我的答案中的示例。
  • Parula 中是否为网格选择了任何标准颜色?如果不是,那么再次为网格选择任何颜色将只是一个选择。
猜你喜欢
  • 2012-01-18
  • 2016-10-13
  • 1970-01-01
  • 2020-10-16
  • 2011-04-04
  • 2019-04-26
  • 1970-01-01
  • 1970-01-01
  • 2012-01-30
相关资源
最近更新 更多