在不丢失分辨率的情况下在 Matlab 中读取 Parula 图像

To imread Parula image in Matlab without losing resolution

RGB 和 Parula 之间没有双射,已讨论 。 我在想如何在Parula中做好文件的图像处理。 这个挑战是从这个 发展而来的,关于通过将案例扩展到具有 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 中将图像读入相应的颜色图中? 我没有找到任何参数来指定阅读中的颜色图。

问题

两个space之间有一个one-to-one mapping from indexed colors in the parula colormap to RGB triplets. However, no such one-to-one mapping exists to reverse this process to convert a parula indexed color back to RGB (indeed there are an infinite number ways to do so). Thus, there is no one-to-one correspondence or bijection。下图显示了每个 parula 指数的 R、G 和 B 值,使这一点更加清晰。

大多数索引颜色都是这种情况。此问题的任何解决方案都是 non-unique.


一个Built-in解

我玩了一会儿之后,我意识到已经有一个 built-in 函数可能就足够了:rgb2ind, which converts RGB image data to indexed image data. This function uses 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 值之间的差异进行比较。执行此操作的标准方法是通过图像处理工具箱中的 calculating ΔE in the CIE L*a*b* color space. I've implemented a form of this in a general function called rgb2map that can be downloaded from my GitHub. This code relies on makecform and applycform 将 RGB 转换为 1976 CIE L*a*b* 颜色 space.

以下代码将生成与右上图类似的图像:

img3 = rgb2map(img1,map);

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

对于输入图像中的每个 RGB 像素,rgb2map 使用 CIE 1976 标准计算它与输入颜色图中每个 RGB 三元组之间的色差。 min函数用于寻找最小值ΔE的索引(如果存在多个最小值,则第一个的索引为returned) .在多个ΔE极小值的情况下,可以使用更复杂的手段来select"best"颜色,但它们的成本会更高。


结论

作为最后一个例子,我使用了an image of the namesake Parula bird to compare the two methods in the figure below. The two results are quite different for this image. If you manually adjust rgb2map to use the more complex CIE 1994色差标准,你会得到另一个效果图。但是,对于与原始 parula 颜色图(如上)更接近的图像,两者应该 return 更相似的结果。重要的是,rgb2ind 受益于调用 mex 函数,并且比 rgb2map 快将近 100 倍,尽管我的代码进行了多次优化(如果使用 CIE 1994 标准,它大约快 700 倍)。

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

2015 年 6 月 20 日更新: rgb2map 上述代码已更新为使用不同的颜色 space 转换,这几乎提高了速度两个。