Sam
Sam

Reputation: 405

MATLAB: generating a colormap given three colors

I'm trying to generate a colormap in MATLAB given three colors, a high extreme, zero, and low extreme. My thought process has been to loop from the high extreme to the middle and store each step to a a 3xN (first column is R, second is G, and third is B)matrix. So I'm using:

%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

Then I would do the same thing going from the zero value to the low extreme. However my code is not giving me any kind of useful matrix. Would someone be able to help me with how I should approach this?

Upvotes: 4

Views: 1031

Answers (3)

Shai
Shai

Reputation: 114786

You can use linear interpolation to expand the color

 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

Upvotes: 5

Floris
Floris

Reputation: 46365

Inspired by @Shai's answer, here is a small twist on his solution (which I prefer - it is more flexible, and avoids use of a for loop).

The form of the cmap that you want is an nx3 array. Further you say that you have three colors that you want to represent three "breakpoints" on your curve. This screams "interpolation"!

% 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));

This ensures a map with 256 colors that go smoothly from lowColor at the lowest value (index 1 into the colormap) to highColor at the highest value (index 255 into the colormap).

I believe this is exactly what you are looking for. And "look ma, no loops!".

Upvotes: 3

Hugh Nolan
Hugh Nolan

Reputation: 2519

I would use linspace:

cmap=[linspace(oldRed,newRed,steps)' ...
linspace(oldGreen,newGreen,steps)' ...
linspace(oldBlue,newBlue,steps)'];

And then for do the same for your next step, and concatenate them:

cmap_full = [cmap;cmap2];

Upvotes: 1

Related Questions