imwrite() saved colormap incorrectly
17 次查看(过去 30 天)
显示 更早的评论
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 个评论
Walter Roberson
2021-7-9
编辑:Walter Roberson
2021-7-9
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.
回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
