如何在不使用MATLAB的B=ind2gray(A,map)
的情况下将RGB或索引图像转换为灰度?
答案 0 :(得分:1)
我不明白为什么你不能使用ind2gray
....但如果你真的必须从第一原则实施这个,那实际上并不是太糟糕。 ind2gray
做什么(IIRC)是它采用索引图像和颜色图,它将图像转换为彩色图像。完成后,将生成的彩色图像转换为灰度。索引图像实际上是一个跨越[1,N]
的查找值网格。此外,颜色映射是N x 3
数组,其中每一行是RGB元组/颜色。应该注意的是,颜色映射是double
精度,其中每个组件跨越[0,1]
。因此,对于索引图像中的每个位置,它会告诉您来自查找表的哪个元组映射到此位置。例如,如果我们有一个索引图像,那么:
X =
[1 2
3 4]
...我们有一个4 x 3的彩色地图,这意味着左上角获得了地图第一行所表示的第一种颜色,右上角获得了第二种颜色,左下角获得第三种颜色,最后右下角获得第四种颜色。
最简单的方法是使用X
索引输入映射的每一列,然后将所有结果连接成一个单独的3D矩阵。完成后,您可以将图像转换为亮度/灰度对应图像。假设您有一个名为X
的索引图像及其对应的颜色图,请执行以下操作:
colour_image = cat(3, map(X), map(X + size(map,1)), map(X + 2*size(map,1)));
gray = sum(bsxfun(@times, colour_image, permute([0.2126 0.7152 0.0722], [3 1 2])), 3);
第一个陈述非常简单。请注意map
为N x 3
,X
的范围为[1,N]
。如果我们使用X
并直接索引到map
,您只会抓取第一列值或颜色/红色的第一个组成部分。我们需要以正确的顺序访问第二列的相同值,并且由于MATLAB以列主格式访问元素,我们只需要通过N
添加所有偏移量,以便我们可以访问第二列获取颜色/绿色的第二个组成部分。最后,您将2N
偏移以获得颜色/蓝色的第三个组成部分。我们将每个红色,绿色和蓝色通道连接在一起,以获得3D图像。
一旦我们得到这个3D图像,就是将彩色图像转换成亮度的问题。我使用SMPTE Rec. 709 standard将颜色像素转换为亮度。这种关系是:
Y = 0.2126 R + 0.7152 G + 0.0722 B
这是第二个陈述的目的。我们将采用每个组件,将它们乘以各自的权重并将所有值相加。你应该得到你的亮度图像。
要检查这是否有效,我们可以使用图像处理工具箱中的trees
数据集。这附带索引图像X
,后跟彩色地图map
:
load trees;
%// Previous code
colour_image = cat(3, map(X), map(X + size(map,1)), map(X + 2*size(map,1)));
gray = sum(bsxfun(@times, colour_image, permute([0.2126 0.7152 0.0722], [3 1 2])), 3);
%// Show colour image as well as resulting gray image
figure; subplot(1,2,1);
imshow(colour_image);
subplot(1,2,2);
imshow(gray);
我们得到:
我们实际上可以通过使用ind2gray
将图像转换为灰度来显示这确实是正确的输出,然后显示两个图像之间的差异。如果图像相同,则意味着生成的图像应为黑色,这意味着上述过程和ind2gray
生成的输出是准确的。
因此:
gray2 = ind2gray(X, map);
figure;
imshow(abs(gray-gray2));
我们得到:
...是... zilch,没有,零,notta ....所以我与ind2gray
相比实现的基本上是相同的。