Как создать собственную цветовую карту программно?

Я хотел бы создать цветовую карту в Matlab. Я хочу уменьшить цвет в соответствии с уровнем серого пикселя.

Например:

from 255 to 160 -> white 
from 159 to 120 -> pink
from 119 to 50 -> brown
from 49 to 0 -> dark

person ispanico    schedule 21.06.2013    source источник


Ответы (2)


Из документов:

Цветовая карта представляет собой матрицу m на 3 действительных чисел от 0,0 до 1,0. Каждая строка представляет собой вектор RGB, определяющий один цвет. k-я строка палитры определяет k-й цвет, где map(k,:) = [r(k) g(k) b(k)]) определяет интенсивность красного, зеленого и синего.

Итак, для начала мы создадим матрицу m на 3, в вашем случае m равно 161:

m = 161;
map = zeros(m , 3);

Теперь вам нужно, чтобы нижняя часть была темной (я использую черный), а 50-я точка была коричневой. но давайте возьмем красный в качестве примера, так как это проще. Тройки RGB для черного и красного соответственно: [0,0,0] и [1,0,0]

Итак, в настоящее время наша цветовая карта enitre черная. Мы знаем, что хотим map(50,:) = [1, 0 ,0], то есть красный, но теперь нам нужен градиент между ними, верно? Так что давайте использовать для этого linspace (обратите внимание, что есть лучший метод, использующий interp1 вместо linspace в конце этого ответа):

R0to50 = linspace(0,1,50)';

помещая это в карту:

map(1:50, 1) = R0to50;

Теперь давайте используем коричневый вместо красного, чтобы получить тройку из этой ссылки, разделите каждый компонент цвета на 255, поэтому наша тройка равна t = [101, 67, 33]./255. Итак, теперь просто повторите эту процедуру linspace для каждого цвета:

R = linspace(0,t(1),50);
G = linspace(0,t(2),50);
B = linspace(0,t(3),50);

T = [R', G', B'];

map(1:50, :) = T;

А теперь повторите для каждого из ваших других узлов.

Например:

I = linspace(0,1,161);
imagesc(I(:, ones(10)))
colormap(map)

введите здесь описание изображения


Альтернативой использованию linspace один раз для каждого канала отдельно и повторению этого для каждого цвета является использование линейной интерполяции.

Создайте матрицу, где каждая строка представляет собой тройку цветов.

T = [0,   0,   0          %// dark
     101, 67,  33         %// brown
     255, 105, 180        %// pink
     255, 255, 255        %// white
     255, 255, 255]./255; %// white again  -> note that this means values between 161 and 255 will be indistinguishable

А теперь создайте вектор того, в каком диапазоне должен быть каждый цвет (т.е. этот вектор определяет расстояние между цветами, они не должны быть регулярно/равноудаленными):

x = [0
     50
     120
     160
     255];

И, наконец, вы можете создать всю карту с помощью одной простой интерполяции:

map = interp1(x/255,T,linspace(0,1,255));

тестирование

I = linspace(0,1,255);
imagesc(I(ones(1,10),:)')
colormap(map)

введите здесь описание изображения

person Dan    schedule 21.06.2013
comment
Большое спасибо, очень полезно...но другой вопрос...хочу ли я изменить коричневый цвет на розовый? - person ispanico; 21.06.2013
comment
Вы должны быть в состоянии решить это на основе ответа выше. Но вместо map(1:50... вы бы использовали map(51:120..., а вместо linspace(0,t(1),50) вы бы использовали linspace(t(1), t_pink(1), 70) и т. д. - person Dan; 21.06.2013
comment
Я не читал ваш ответ, но я сделал это. Это работает отлично! Большое спасибо за вашу помощь - person ispanico; 21.06.2013
comment
Создание карты с помощью interp1 — это умно! - person Some Guy; 31.12.2015

В качестве альтернативы вы можете использовать функцию AdvancedColormap из FEX. Если вам нужна гладкая цветовая карта, вы можете сделать это следующим образом:

map = AdvancedColormap('kbpw',256,[0 50 120 255]/255);
person anandr    schedule 21.06.2013