imwrite() saved colormap incorrectly
17 views (last 30 days)
Show older comments
imwrite() was used to save indexed images along with its colormap. Suppose we use 'givenMap' to denote the colormap provided to imwrite() and 'savedMap' to denote the colormap obtained using imread() on the saved image.
The weird things were that:
1) For some colormaps, exact values in 'givenMap' and 'savedMap' were different. The magnitude of differences was in the order of 10%-20%;
2) But for other colormaps, the content in 'givenMap' and 'savedMap' were the same.
Below are exemplar codes:
% file path for saving image
savedFilePath = 'D:\BMP\imwriteTest';
if ~exist(savedFilePath,'dir')
mkdir(savedFilePath);
end
% load image data
givenData = load('clown.mat');
givenData = givenData.X;
% set range of image to 0-1
minImg = min(givenData(:));
maxImg = max(givenData(:));
givenData = (givenData-minImg)./(maxImg-minImg);
% set image to uint8 type
givenData = givenData*255;
givenData = uint8(givenData);
Exemplar colormap that remained the same after imwrite():
% create a colormap
defaultMap = (0:255)'*[1,1,1]; % 256*3
defaultMap = defaultMap./255;
givenMap = defaultMap;
% use imwrite to save both data and colormap
imwrite(givenData,givenMap,[savedFilePath,'\copperclown.bmp'],'bmp');
% load saved data and colormap
[~,savedMap] = imread([savedFilePath,'\copperclown.bmp']);
% sum of differences
diffMap = sum(abs(givenMap(:)-savedMap(:)));
Exemplar colormap that changed after imwrite():
% create a colormap
defaultMap = (0:255)'*[1,1,1]; % 256*3
defaultMap = defaultMap./255;
givenMap = defaultMap;
% modify centeral part of colormap
centralMapValue = (0:200)/200;
givenMap(2:202,:) = repmat(centralMapValue(:),1,3);
% use imwrite to save both data and colormap
imwrite(givenData,givenMap,[savedFilePath,'\copperclown.bmp'],'bmp');
% load saved data and colormap
[~,savedMap] = imread([savedFilePath,'\copperclown.bmp']);
% sum of differences
diffMap = sum(abs(givenMap(:)-savedMap(:)));
Below are first 10 rows of 'givenMap' and 'savedMap', it's obvious that they were quite different:

Moreever, we can see that differences of adjacent rows was fixed at 0.05 in 'givenMap', but the value oscillate at '0.39' and '0.78' in 'savedMap'.
% show differences in adjacent rows of colormap
modifiedMapIndex = 2:202;
diffGivenMap_adjacentRow = diff(givenMap(modifiedMapIndex,1));
diffSavedMap_adjacentRow = diff(savedMap(modifiedMapIndex,1));
diffGivenMap_adjacentRow = [0;diffGivenMap_adjacentRow(:)];
diffSavedMap_adjacentRow = [0;diffSavedMap_adjacentRow(:)];
maxDiffMap_adjacentRow = max(abs([diffGivenMap_adjacentRow(:);diffSavedMap_adjacentRow(:)]));
maxDiffMap_adjacentRow = maxDiffMap_adjacentRow*(1+0.05*sign(maxDiffMap_adjacentRow));
minDiffMap_adjacentRow = 0;
figure;
fontSize = 15;
subplot(1,2,1)
plot(modifiedMapIndex,diffGivenMap_adjacentRow,'ko')
xlim([2 202])
ylim([minDiffMap_adjacentRow maxDiffMap_adjacentRow])
xlabel('#Row','FontSize',fontSize)
ylabel('mapDiff\_adjacentRow','FontSize',fontSize)
title('Difference in Adjacent Row@givenMap','FontSize',fontSize)
subplot(1,2,2)
plot(modifiedMapIndex,diffSavedMap_adjacentRow,'ro')
xlim([2 202])
ylim([minDiffMap_adjacentRow maxDiffMap_adjacentRow])
xlabel('#Row','FontSize',fontSize)
ylabel('mapDiff\_adjacentRow','FontSize',fontSize)
title('Difference in Adjacent Row@savedMap','FontSize',fontSize)

More detailled comparison can see the attached code.
My question is: are these differences caused by
1) the innate 'imprecision' of imwrite() or imread()?
or
2) my misuse of imwrite() or imread()?
5 Comments
Walter Roberson
on 9 Jul 2021
Edited: Walter Roberson
on 9 Jul 2021
Representing colors using at most one byte per component (0:255) is inherent in bitmap format. With some options, even fewer bits are used.
I have to wonder about that first map. 0.005 * 255 is about 1 1/4 so if that table 0.005 apart were to continue to 256 entries you would be dealing with relative intensity greater than 1.
Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!