MATLAB:给定三种颜色生成一个颜色映射

4

我正在尝试使用MATLAB生成一张颜色映射图。给定三种颜色,高极值、零和低极值。我的思路是从高极值到中间循环,并将每个步骤存储到一个3xN的矩阵中(第一列为红色,第二列为绿色,第三列为蓝色)。因此我使用了以下代码:

%fade from high to zero
oldRed=high(1);
oldGreen=high(2);
oldBlue=high(3);
newRed=mid(1);
newGreen=mid(2);
newBlue=mid(3);

currentRed=oldRed; currentGreen=oldGreen; currentBlue=oldBlue;
for x=1:steps
    currentRed=oldRed+((x*(newRed-oldRed))/(steps-1));
    currentGreen=oldGreen+((x*(newRed-oldRed))/(steps-1));
    currentBlue=oldBlue+((x*(newRed-oldRed))/(steps-1));
    cmap=[cmap;[currentRed currentGreen currentBlue]];
end

然后我将从零值到最低极端进行相同的操作。 然而,我的代码没有给我任何有用的矩阵。 是否有人能够帮助我如何应对这种情况?


1
首先,当你可以使用逐元素算术时,为什么要使用循环呢? - Eitan T
我不确定你的意思。我可以使用什么算术表达式来实现颜色之间的渐变? - Sam
使用 linspace 或者 colon 运算符 (:)。你在循环中所做的一切都可以使用向量化表达式重写,而不需要循环。 - Eitan T
3个回答

5
您可以使用线性插值来扩展颜色。
 nCol = 256; % number of colors for the resulting map
 cmap = zeros( nCol, 3 ); % pre-allocate
 xi = linspace( 0, 1, nCols );
 for ci=1:3 % for each channel
     cmap(:,ci) = interp1( [0 .5 1], [low(ci) mid(ci) high(ci)], xi )';
 end

1
非常及时的问题和答案,因为我早上读到了这个问题,然后今天下午我不得不生成一些新的颜色映射。我对这个解决方案做出的一个改变是通过 ControlPoints = [r1 b1 g1;r2 b2 g2; <...> ;rn bn gn]/255 来处理任意数量的控制点,其中n表示点数,rn/gn/bn被实际数字替换。然后 [m,~] = size(ControlPoints);zi = (0:m-1)/(m-1);。然后 ziControlPonts(:,ci) 可以插入到倒数第二行中。这样,我可以在前面放置一个 switch...case 块来定义多个映射。 - craigim
很抱歉回复晚了。谢谢!这正是我在寻找的解决方案! - Sam

3
受 @Shai 答案启发,这里有一个小变化(我更喜欢它,因为它更灵活,避免使用 for 循环)。
你想要的 cmap 的形式是 nx3 数组。你还说你有三种颜色,想要在曲线上表示三个“断点”。这就需要插值!
% set the "breakpoints" for the color curve:
lowValue = 0;
midValue = 128;
highValue = 255;

% pick "any" three colors to correspond to the breakpoints:
lowColor = [255 0 0];
midColor = [40 40 40];
highColor = [0 255 255];

% create the colormap:
myMap = interp1( [lowValue midValue highValue], ...
  [lowColor; midColor; highColor]/255, ...
  linspace(lowValue, highValue, 256));

这确保了一张有256种颜色的地图,这些颜色从最低值(在颜色映射表中索引为1)的lowColor平滑过渡到最高值(在颜色映射表中索引为255)的highColor

我相信这正是您所需要的。而且,“看吧,没有循环!”


1
我会使用linspace:
cmap=[linspace(oldRed,newRed,steps)' ...
linspace(oldGreen,newGreen,steps)' ...
linspace(oldBlue,newBlue,steps)'];

然后对于下一步,做同样的操作并将它们连接起来:
cmap_full = [cmap;cmap2];

中间的颜色 mid 怎么样? - Shai
当你发布了更好的答案时,我正在添加它。 - Hugh Nolan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接