MATLAB: How to use RGB2IND with the colormap approximation method to convert images with a pre-specified colormap in Image Processing Toolbox 3.2 (R13)

ditherImage Processing Toolboxrgb2ind

I want to convert my RGB image into an indexed image with a pre-specified colormap that contains all the colors in my image.
I tried using RGB2IND with the colormap approximation method with the following syntax:
gmap = [0:255;0:255;0:255]'/255; % this is the colormap
rgb1 = zeros(256,256,3); % create the gray-scale RGB image
rgb1(:,:,1) = repmat([0:255]/255,256,1);
rgb1(:,:,2) = repmat([0:255]/255,256,1);
rgb1(:,:,3) = repmat([0:255]/255,256,1);
rgb2 = rgb2ind(rgb1,gmap, 'nodither'); % convert RGB->index with colormap
rgb3 = ind2rgb(rgb2, gmap); % convert index->RGB with colormap
diff = sum(sum(sum(rgb1-rgb3))) % find the difference between original and new image
However, the difference between the original and converted image is not zero, which means the images are different.

Best Answer

To convert an RGB image into an indexed image using a pre-specified colormap, use the DITHER function rather than the RGB2IND function, specifiying the following values for the Qm and Qe parameters to DITHER: Qm = 8 and Qe = 7.
The following example illustrates this procedure.
% Create a colormap.
gmap = [0:255;0:255;0:255]'/255;
% Create an RGB image.
rgb1 = zeros(256,256,3);
rgb1(:,:,1) = repmat([0:255]/255,256,1);
rgb1(:,:,2) = repmat([0:255]/255,256,1);
rgb1(:,:,3) = repmat([0:255]/255,256,1);
% Use DITHER to convert the image,
% specifying the colormap and values
% for the Qe and Qm parameters.
rgb2 = dither(rgb1,gmap,8,7);
% To test this solution, convert the indexed image back into
% an RGB image and find the difference between the
% original image and the newly created image.
rgb3 = ind2rgb(rgb2, gmap);
diff = sum(sum(sum(rgb1-rgb3)))
The reason for using DITHER instead of RGB2IND is that when running RGB2IND with a specified colormap and the 'nodither' option, the function uses a method that quantizes the search space. Specifically, RGB2IND uses the following code:
dither(rgb,map,Qm,Qe)
With Qm = 5 and Qe = 4. Since Qe < Qm, no dithering is performed, which is the same when you specify the ‘nodither’ option with RGB2IND. Since Qm < 8, several of the 2^8 colors in the colormap get grouped together to perform the search. This is done to get reasonable performance since a brute-force nearest neighbor search is quite expensive to do for every pixel in an image.
Hence, to get the exact same colors back, using DITHER with Qm = 8 and Qe = 7. However, this is computationally more expensive than the previous method as the syntax forces DITHER to search through the entire colormap.