How to get a dithered color image
10 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
Categories
Find more on Red in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!