How to get a dithered color image
4 views (last 30 days)
Show older comments
I know that
X = dither(RGB, map);
returns an indexed image approximation to the given RGB image. I have two questions:
(1) Is there a second step that converts the indexed image to an RGB image using the provided colormap?
(2) How to design a colormap that matches the original colors of the image?
Note: I want a dithered color image not an indexed image.
Any hint/help is appreciated!
0 Comments
Accepted Answer
Image Analyst
on 31 Jul 2015
I've never used dither() so I don't know what it does. But to answer your questions:
(1) Yes. It's called ind2rgb().
rgbImage = ind2rgb(indexedImage, customColorMap);
(2) Call rgb2ind():
[indexedImage, customColorMap] = rgb2ind(grayImage, numColors);
2 Comments
DGM
on 27 Sep 2023
If you don't already have a map appropriate for a given RGB image, then I don't see that there's any reason to be using dither() at all.
% the inputs
nlevels = 16; % maximum number of unique colors
inpict = imread('peppers.png');
% rgb2ind() defaults are dithered already
% if you need to use rgb2ind() to get the optimized map
% then there's no point in ever calling dither()
[idx map] = rgb2ind(inpict,nlevels);
imshow(idx,map,'border','tight')
xlim([242 388]); ylim([155 274]) % zoom in
% ind2rgb() cannot change the presence or absence of dithering
% so if the output isn't dithered, then either the input was never dithered
% or it's simply being displayed incorrectly somehow
outpict = ind2rgb(idx,map);
imshow(outpict,'border','tight')
xlim([242 388]); ylim([155 274]) % zoom in
% there are at most (nlevels) colors
allcolors = unique(reshape(outpict,[],3),'rows');
numcolors = size(allcolors,1)
There's no way that dithering channels independently returns an appropriate result, or a result compatible with any optimized color table. I have no idea what was attempted, but I can guess.
% create an effectively 3-bit color image by
% naively calling dither() on each channel
junk3b = zeros(size(inpict),'uint8');
for c = 1:3
junk3b(:,:,c) = im2uint8(dither(inpict(:,:,c)));
end
imshow(junk3b,'border','tight')
xlim([242 388]); ylim([155 274]) % zoom in
% there are at most 8 colors
allcolors = unique(reshape(junk3b,[],3),'rows');
numcolors = size(allcolors,1)
Or less likely:
% do graylevel dithering on each channel
% dither() doesn't really have a good way to do this
junkgl = zeros(size(inpict),'uint8');
CT = gray(nlevels); % dummy map
for c = 1:3
thischannel = repmat(inpict(:,:,c),[1 1 3]); % expand
junkgl(:,:,c) = dither(thischannel,CT);
end
junkgl = im2uint8(double(junkgl)/(nlevels-1)); % rescale
imshow(junkgl,'border','tight')
xlim([242 388]); ylim([155 274]) % zoom in
% ... and there are far more unique colors than specified (at most nlevels^3)
allcolors = unique(reshape(junkgl,[],3),'rows');
numcolors = size(allcolors,1)
More Answers (0)
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!