How to create a custom colormap and then apply it to an image?
65 次查看(过去 30 天)
显示 更早的评论
I am trying to express an image using only 29 colors. The HEX values of colors are as follows:
C0C0C0 808080 404040 000000 FF99CC 9999FF 3333FF 000099 3399FF 0066CC 99CCFF 66B2FF 66FFFF 006633 00CC66 66FF66 00FF00 009900 FFFF99 FFFF00 CCCC00 FFB266 CC6600 994C00 FF9999 FF0000 CC0000 990000
I need colors to be exactly these; without any changes in darkness/lightness.
I found a function to create a costum colormap on file exchange: https://www.mathworks.com/matlabcentral/fileexchange/42450-custom-colormap Maybe I it will help, but I was not sure how to use it and if it will solve my problem.
Please help.
1 个评论
Stephan Gleis
2020-11-18
Hello,
is there a source (publication or similar) that can be quoted regarding the color map?
This colormap seems to me very suitable for some of my illustrations, and I would like to use it...
回答(4 个)
Image Analyst
2018-12-21
Try this:
hexMap = {'C0C0C0', '808080', '404040', '000000', 'FF99CC', '9999FF', '3333FF', '000099', '3399FF', '0066CC', '99CCFF', '66B2FF', '66FFFF', '006633', '00CC66', '66FF66', '00FF00', '009900', 'FFFF99', 'FFFF00', 'CCCC00', 'FFB266', 'CC6600', '994C00', 'FF9999', 'FF0000', 'CC0000', '990000'}
myColorMap = zeros(length(hexMap), 3); % Preallocate
for k = 1 : length(hexMap)
thisCell = hexMap{k}
r = hex2dec(thisCell(1:2))
g = hex2dec(thisCell(3:4))
b = hex2dec(thisCell(5:6))
myColorMap(k, :) = [r, g, b]
end
myColorMap = myColorMap / 255; % Normalize to range 0-1
imshow('moon.tif');
colormap(myColorMap);
colorbar;
7 个评论
Image Analyst
2018-12-21
编辑:Image Analyst
2018-12-21
You have called your m-file colormap.m, which you can't do. That is a built-in function name. Pick another name for your m-file, like colormap_test.m or something.
If you want hte moon in grayscale, just don't do anything - don't call colormap - and it will be in gray scale.
If you're working with RGB images, you cannot apply a colormap. Colormaps can only be applied to indexed images, meaning they are single values/gray scale/monochrome. If you want, you can take one of the color channels, or call rgb2gray() and then apply the colormap to that instead of the RGB image.
Walter Roberson
2018-12-21
After creating the colormap, use rgb2ind() on your RGB image passing in the color map, and then use ind2rgb with the results and the colormap. The result would be a color image approximated by only the given colors.
Image Analyst
2020-11-19
For what it's worth, here is an example of how to create a custom colormap in code. This program recreates a cool colormap I once saw used by the ODYSSEA project.
% Displays an image with a cool colormap that has been used for the ODYSSEA project.
% http://www.rac-spa.org/node/1694
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 18;
fprintf('Beginning to run %s.m ...\n', mfilename);
echo off;
%===============================================================================
% Read in the ODYSSEA color map from a .mat file, if it exists already.
% fileName = 'ODYSSEA_Color_map.mat';
% if isfile(fileName)
% s = load(fileName)
% customColorMap = s.customColorMap;
% end
%===============================================================================
% Create the custom color map from scratch.
% First, create red waveform:
r = zeros(256, 1);
r(1:57) = 1;
r(58:75) = linspace(1, 0, length(58:75));
r(150:170) = linspace(0, 1, length(150:170));
r(171:238) = 1;
r(239:256) = linspace(1, 0.5, length(239:256));
% Create green waveform:
g = zeros(256, 1);
g(1:33) = 1;
g(34:75) = linspace(1, 0, length(34:75));
g(76:93) = linspace(0, 1, length(76:93));
g(94:203) = 1;
g(204:219) = linspace(1, 0, length(204:219));
% Create blue waveform:
b = zeros(256, 1);
b(1:61) = 1;
b(62:73) = linspace(1, 0.5, length(62:73));
b(74:88) = linspace(0.5, 1, length(74:88));
b(89:130) = 1;
b(131:150) = linspace(1, 0, length(131:150));
% Now that the individual color channel mappings have been created,
% stitch the red, green, and blue vectors together to create the 256-by-3 colormap matrix.
customColorMap = [r, g, b];
%===============================================================================
% Plot the red, green, and blue components of the custom colormap so we can see what it looks like.
igs = 0 : length(r) - 1; % Input gray scale axis.
subplot(1, 2, 2);
plot(igs, r, 'r-', 'LineWidth', 3);
hold on;
plot(igs, g, 'g-', 'LineWidth', 3);
plot(igs, b, 'b-', 'LineWidth', 3);
grid on;
caption = sprintf('ODYSSEA Color Map with %d Rows', length(r));
title(caption, 'FontSize', fontSize);
xlabel('Input Gray Level', 'FontSize', fontSize);
ylabel('Output Color Channel Level', 'FontSize', fontSize);
xlim([1, 256]);
%===============================================================================
% OPTIONAL : Save the colormap to disk file 'ODYSSEA_Color_map.mat' for next time,
% in case we don't want to recreate it or want to use it elsewhere (a different m-file).
% save('ODYSSEA_Color_map.mat', 'customColorMap')
%===============================================================================
% Read in gray scale image from disk.
folder = pwd;
% baseFileName = 'cameraman.tif';
% baseFileName = 'moon.tif';
% baseFileName = 'cell.tif';
% baseFileName = 'rice.png';
baseFileName = 'AT3_1m4_01.tif';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
% Didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(baseFileName);
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows, columns, numberOfColorBands] = size(grayImage);
% If it's RGB instead of grayscale, convert it to gray scale.
if numberOfColorBands > 1
grayImage = rgb2gray(grayImage);
end
%===============================================================================
% Display the original gray scale image with the custom colormap applied.
subplot(1, 2, 1);
imshow(grayImage, 'ColorMap', customColorMap);
axis on;
colorbar; % Display the colorbar to the right of the image.
caption = sprintf('Original Image with ODYSSEA Color Map Applied: "%s"', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'none');
impixelinfo;
% Enlarge figure to full screen.
g = gcf;
g.Name = 'Demo by ImageAnalyst'; % Show this in the title bar.
g.NumberTitle = 'off' % Don't show Figure 1 in title bar.
g.WindowState = 'maximized'
0 个评论
Image Analyst
2020-11-19
For what it's worth, I was wondering what your colormap would look like if it were smoother -- if it used 256 levels instead of 28. Here is that code:
% Code to create a custom 28 level colormap, then rescale it to 256 levels to be smoother.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 18;
fprintf('Beginning to run %s.m ...\n', mfilename);
echo off;
hexMap = {'C0C0C0', '808080', '404040', '000000', 'FF99CC', '9999FF', '3333FF', '000099', '3399FF', '0066CC', '99CCFF', '66B2FF', '66FFFF', '006633', '00CC66', '66FF66', '00FF00', '009900', 'FFFF99', 'FFFF00', 'CCCC00', 'FFB266', 'CC6600', '994C00', 'FF9999', 'FF0000', 'CC0000', '990000'}
myColorMap = zeros(length(hexMap), 3); % Preallocate
numLevels = length(hexMap);
r = zeros(numLevels, 1);
g = zeros(numLevels, 1);
b = zeros(numLevels, 1);
for k = 1 : numLevels
thisCell = hexMap{k}
r(k) = hex2dec(thisCell(1:2))
g(k) = hex2dec(thisCell(3:4))
b(k) = hex2dec(thisCell(5:6))
end
% Now that the individual color channel mappings have been created,
% stitch the red, green, and blue vectors together to create the 256-by-3 colormap matrix.
myColorMap = [r, g, b]
myColorMap = myColorMap / 255; % Normalize to range 0-1
% Scale to 256 gray levels, instead of the current 28.
numLevels = 256;
myColorMap = imresize(myColorMap, [numLevels, 3]);
% Sometimes it exceeds 1 so rescale 0-1
myColorMap = rescale(myColorMap, 0, 1);
%===============================================================================
% Plot the red, green, and blue components of the custom colormap so we can see what it looks like.
r = myColorMap(:, 1);
g = myColorMap(:, 2);
b = myColorMap(:, 3);
igs = 0 : length(r) - 1; % Input gray scale axis.
subplot(1, 2, 2);
plot(igs, r, 'r-', 'LineWidth', 3);
hold on;
plot(igs, g, 'g-', 'LineWidth', 3);
plot(igs, b, 'b-', 'LineWidth', 3);
grid on;
caption = sprintf('Color Map with %d Rows', length(r));
title(caption, 'FontSize', fontSize);
xlabel('Input Gray Level', 'FontSize', fontSize);
ylabel('Output Color Channel Level', 'FontSize', fontSize);
xlim([min(igs), max(igs)]);
%===============================================================================
% Display the image on the left with the custom colormap applied.
subplot(1, 2, 1);
imshow('moon.tif', 'ColorMap', myColorMap);
colorbar;
title('moon.tif with custom colormap', 'FontSize', 18);
0 个评论
DGM
2023-1-15
How about an answer that is complete in what it demonstrates? The main lesson here is to use rgb2ind()/ind2rgb(), so let's actually do that.
% convert the colortable to numeric
CT = 'C0C0C0 808080 404040 000000 FF99CC 9999FF 3333FF 000099 3399FF 0066CC 99CCFF 66B2FF 66FFFF 006633 00CC66 66FF66 00FF00 009900 FFFF99 FFFF00 CCCC00 FFB266 CC6600 994C00 FF9999 FF0000 CC0000 990000';
CT = hex2uint(split(CT)); % MIMT (attached)
CT = im2double(CT); % rgb2ind() expects float tables only
% read a screenshot of what looks like a JPG
inpict = imread('stopusingscreenshots.png');
% scale back to approximate original size
inpict = imresize(inpict,1/2);
% apply colormap to create an indexed image
outind = rgb2ind(inpict,CT,'dither');
imshow(outind,CT)
colorbar
% if you want RGB output, convert the result back to RGB using the same map
figure
outrgb = ind2rgb(outind,CT);
imshow(outrgb)
If you want to save the image, save the image. Saving images shouldn't involve taking a screenshot, a photo of the monitor, or the use of crayons.
imwrite(outrgb,'pixeldogrgb.png')
imwrite(outind,CT,'pixeldogind.png') % PNG supports indexed images too
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Orange 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!