Is there an alternative to rgb2ind that produces a linear, monotonic colormap?

The function rgb2ind outputs indices for each pixel and a corresponding colormap. The colormap is nonlinear and nonmonotonic. Thus because adjacent pixels have random relationships with one another the indexed matrix cannot be manipulated (e.g., filtered), as stated in the note here:
Is there a way to force color indexing to be ordered so that I could do some kind of spatial filtering operation on the indexed matrix?
Ultimately what I want is take an nxnx3 RGB matrix, for instance X:
X = imread('peppers.png');
and collapse it down to nxn without discarding the original color information. Indexing the colors seems like a good solution, but only if the resultant indexed colormap is well ordered.
I have looked at the solutions presented here:
and while this article does provide a means of processing indexed color images, the original color information is irreversibly thrown out and replaced by another well-ordered colormap such as grayscale.

Answers (3)

I do not get the problem. Why don't you use:
[X, M] = rgb2ind(RGB)
and sort the color map M like you want to afterwards? Then renumbering X is trivial also.

4 Comments

Your solution definitely sounds like it would solve my problem. Maybe I'm just dense, but I don't see how I would sort the colormap to be linear and monotonic in colorspace. Lets take a concrete example:
[X,M] = rgb2ind(imread('peppers.png'),512);
image(X)
colormap(M);
colorbar
The colormap is clearly disordered here as shown by the lack of smooth transitions in the colorbar. How would you sort the map to make it smooth without losing any information?
What does sorting mean in the 3D color space? Why should the colormap be "smooth", when the corresponding pixels are not existing in the picture?
It's an interesting question. I suppose having a "smooth" colormap is impossible for an indexed natural image because, as you implied, not every intermediate color is necessarily represented in the original image. But smoothness should not be necessary to preserve the relationship whereby "nearby" colors (in color space) are represented by "nearby" numbers (on the number line) in the index matrix, X.
One way that I have tried to do this is in the HSV domain, sorting by hue then value. This gets closer to a solution in that the colorbar looks reasonably well ordered followed this sorting operation. However, the renumbered index matrix still looks like noise devoid of structure, so it would still be inappropriate to do some kind of mathematical analysis (e.g., wavelet decomposition) with this matrix.
But smoothness should not be necessary to preserve the relationship whereby "nearby" colors (in color space) are represented by "nearby" numbers (on the number line) in the index matrix, X.
Nothing can preserve that relationship if you are mapping an infinite space to fewer dimensions. It is some theorem or other: distances will increase without bound.
In a finite space (0-255 in each of 3 panes gives you 16777216 possibilities, but that is still finite), it can be done, but only at the cost of defining "nearby on the number line" to be on the order of N^3/2 positions away for a cube of length N on each side.

Sign in to comment.

Color representation for humans requires at least 3 attributes, such as R,G,B or H,S,v or Y,Cr,Cb . Even if it only required 2 attributes, the problem of sorting it would be like the problem of sorting complex numbers: you cannot do it without having a "jump" between values that are "nearby" in the original space.
You don't filter the indexed image. You don't even view it with a colormap that is wasn't built with. For example if you view it in gray scale (using the gray(256) colormap), or look at the array in the variable editor, it will look like garbage. It doesn't make sense to do anything with that indexed image at all EXCEPT to view it with the colormap that was created at the same time as it.
If you want a smooth image to filter or whatever, then use rgb2gray() instead.

5 Comments

I'm aware that you can't filter the indexed image. That's why I was asking for an alternative function that can give me an output suitable for subsequent analysis. Based on the discussion here, it sounds like such a thing probably doesn't exist.
rgb2gray() throws away the color information, so that does not help.
Well then I don't understand. What do you want to do? What image do you want to filter? The color one or the gray scale one? What does "collapse it down to nxn" mean? You mean imresize()? Or do you mean you want to quantize the colors, like discussed in http://en.wikipedia.org/wiki/Color_quantization. Or do you want to do it via
[indexedImage, cmap] = rgb2ind(colorImage);
quantizedRGBImage = ind2rgb(indexedImage, cmap);
?????
I want to perform a wavelet decomposition on a color image. I initially turned to http://www.mathworks.com/help/wavelet/gs/wavelets-working-with-images.html, but there is no discussion of how to preprocess the image so that the original color information is not lost.
The image itself is unimportant, so lets just go with the built in example I gave above: peppers.png.
By "collapse it down to nxn" I mean that instead of having 3 matrices, corresponding to R, G, and B separately, I would like to capture the color information in a single matrix. Color quantization seems like a good way to go about this, so thank you for giving me that vocabulary. The problem is in how it is instantiated. Do you know of a way to quantize the color in such a way that is conducive to some kind of downstream analysis like wavelet decomposition?
You can't have a single matrix that represents color, like Walter was telling you. You can have a true color 3D RGB image with separate planes for each color band, or you can have an indexed image where you have one integer image (not even really a grayscale image) with an associated color map (the pair of which make up an indexed image), or you can have the hue information, saturation information, and value (lightness) information in a 3D HSV image. Or you can have three arrays in other color spaces (CIE LAB, HSL, HSI, YCbCr, etc.). But you can't have color in just a single 2D numerical matrix. I'm not that familiar with wavelets, so you might be best off posting a new question with a subject line and Products list that really targets those people who deal with wavelets (I think Wayne, Greg, etc.). A subject something like "Want wavelet decomposition of color image" and list Wavelet Toolbox in the Products list. Also give motivation for WHY you want that so they can tell you if doing that is the best way to achieve what you want to achieve - perhaps there is another way, maybe even one that doesn't involve wavelets at all, who knows?
Thank you for your input. I'll try to go about it another way.

Sign in to comment.

Asked:

on 25 Apr 2013

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!