RGB histogram using bitshift in matlab

I'm trying to create a mozaic image in Matlab. The database consists of mostly RGB images but also some gray scale images.
I need to calculate the histograms - like in the example of the Wikipedia article about color histograms - for the RGB images and thought about using the bitshift operator in Matlab to combine the R,G and B channels.
nbins = 4;
nbits = 8;
index = bitshift(bitshift(image(:,:,1), log2(nbins)-nbits), 2*log2(nbins)) + ...
+ bitshift(bitshift(image(:,:,2), log2(nbins)-nbits), log2(nbins)) + ...
+ bitshift(image(:,:,3), log2(nbins)-nbits) + 1;
index is now a matrix of the same size as image with the index to the corresponding bin for the pixel value.
How can I sum the occurences of all unique values in this matrix to get the histogram of the RGB image?
I want for example the 4x4x4 histogram of each image. The histogram would then be a vector of size 1x64.
Is there a better approach than bitshift to calculate the histogram of an RGB image?

 Akzeptierte Antwort

Jonas
Jonas am 8 Jun. 2014

0 Stimmen

The problem was solved by using the accumarray() function in matlab. First I had to reshape the index matrix into a column vector and then sum all elements with weight of one using accumarray. In that way I received the histogram of the RGB image.
The full answer to my question can be read in this question on StackOverflow

1 Kommentar

Image Analyst
Image Analyst am 8 Jun. 2014
Wow. Looks really complicated. And I can't tell if you get separate histograms or one histogram for the entire image regardless of color channels (which would be not very useful). Do you have a screenshot of your final histogram(s) that you can share so we can tell what you wanted?

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Image Analyst
Image Analyst am 7 Jun. 2014

0 Stimmen

Wow, what a horrible article in Wikipedia on color histograms. for crying out loud, they don't even show a single histogram! Anyway, I have no idea what you want. I don't know why you want the histogram to be an image the same as the image you're taking the histogram of. Can you give a screenshot? I don't know why bitshift would be needed.
To get a mosaic of images you can use montage() though if you have more than a few, you will run out of memory because it essentially stitched the images together at full resolution.
I attach my RGB histogram demo, for what it's worth.

7 Kommentare

Jonas
Jonas am 7 Jun. 2014
I don't want the histogram to be the same size as the input image!
I want the color histogram for each image in the database to compare with the color histogram of a part of my query image.
I don't want to compare each color channel. I want to compare histograms with all channels combined. That's why I use bitshift.
Is there a better way? How may I combine the histograms for each channel if I use such approach?
Image Analyst
Image Analyst am 7 Jun. 2014
Have you run the demo I gave you yet? What's wrong with that?
Jonas
Jonas am 7 Jun. 2014
I thought it would be more efficient to compare 64 bin histograms instead of three 4 bin histograms.
How would I combine the three color histograms to get the most similar image? Sum the differences in mean values?
Image Analyst
Image Analyst am 7 Jun. 2014
The demo creates 3 256-bin histograms, not 3 4-bin histograms.
What does "combine the three color histograms to get the most similar image" mean? Do you mean something like this fun web site: http://www.npr.org/blogs/thetwo-way/2010/12/10/131960390/color-picker-sorts-flickr-photos-for-fun
Jonas
Jonas am 7 Jun. 2014
I know. 3 4-bin histograms was just an example, as in my original question.
Yeah, like that web site.
We have a query image separated into sub-images. Each sub-image should be replaced by an image from our database based on the sub-image's color.
What is the "subimage"? Do you mean one color channel of the RGB image? Or some cropped portion of a larger image?
Certainly one simplistic way to get started is to just compute the mean of each color channel for all test and database images.
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
redMean = mean2(redChannel);
greenMean = mean2(greenChannel);
blueMean = mean2(blueChannel);
You'd be better off converting the mean RGBs into LAB color space and compute the delta E (color difference in 3-dimensional color space). The database image with the lowest delta E from your image is the closest in color space to your test image.
colorSpaceTransform = makecform('srgb2lab');
lab_meansTest = applycform([redMean, greenMean, blueMean], colorSpaceTransform);
% Do above for all the DB images and the test image(s).
deltaL = lab_meansTest(1) - lab_meansDB(1);
deltaA = lab_meansTest(2) - lab_meansDB(2);
deltaB = lab_meansTest(3) - lab_meansDB(3);
deltaE = sqrt(deltaL^2 + deltaA^2 + deltaB^2);
Jonas
Jonas am 8 Jun. 2014
The subimage is a part (say 20x20 pixel large part) of the original RGB image. So the subimage is a RGB image.
Solved the problem with help from StackOverflow.

Melden Sie sich an, um zu kommentieren.

Gefragt:

am 7 Jun. 2014

Kommentiert:

am 8 Jun. 2014

Community Treasure Hunt

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

Start Hunting!

Translated by