File Exchange Pick of the Week

Colorspaces out the Wazoo!

Posted by Brett Shoelson,

Brett's Pick this week is "Colorspace Transformations", by Pascal Getreuer.

For inspiration for this week's Pick, I went back to my post from April of last year, in which I asked readers to suggest files to feature. I started to write up Pascal's submission long ago, but somehow got sidetracked, and I wanted to circle back around to it.

File Exchange champ Oliver Woodford casually suggested "a couple of useful ones." (His other selection was featured last August by Jiro.) Both of his "Picks" are quite useful.

So, what's so great about this colorspace converter? In particular, I really like the fact that Pascal's code extends the colorspace conversion capabilities beyond those offered by the Image Processing Toolbox, and that Pascal has included C-code (and instructions for calling it via the MEX interface) to make them faster.

Colorspace Transformations facilitates conversion to any of these colorspaces:

'RGB'              sRGB IEC 61966-2-1
'YCbCr'            Luma + Chroma ("digitized" version of Y'PbPr)
'JPEG-YCbCr'       Luma + Chroma space used in JFIF JPEG
'YDbDr'            SECAM Y'DbDr Luma + Chroma
'YPbPr'            Luma (ITU-R BT.601) + Chroma
'YUV'              NTSC PAL Y'UV Luma + Chroma
'YIQ'              NTSC Y'IQ Luma + Chroma
'HSV' or 'HSB'     Hue Saturation Value/Brightness
'HSL' or 'HLS'     Hue Saturation Luminance
'HSI'              Hue Saturation Intensity
'XYZ'              CIE 1931 XYZ
'Lab'              CIE 1976 L*a*b* (CIELAB)
'Luv'              CIE L*u*v* (CIELUV)
'LCH'              CIE L*C*H* (CIELCH)
'CAT02 LMS'        CIE CAT02 LMS

That's a lot of different ways to represent a color image!

Whenever I am asked to segment a color image--and trust me, that's pretty often!--my initial thought is to look at the R,G, and B colorplanes individually to understand where the information I'm after lies. I do this so often that I wrote and shared a utility that facilitates this exploration process. (In "Advanced Mode," ExploreRGB shows--in addition to RGB [and R, G, and B]--HSV, YCbCr, and L*a*b* versions of the image. I can often find a single-plane version of the original image in one of these transformed colorspaces that makes the segmentation easy. For instance, if I needed to isolate the central yellow pepper in the "peppers.png" image that ships with the Image Processing Toolbox:

I might consider (ironically) starting from the blue chrominance image (i.e., the second colorplane of the YCbCr representation of the image):

Starting with that image plane:

mask = ~im2bw(img,0.24);
cc = bwconncomp(mask);
stats = regionprops(cc,'Area');
A = [stats.Area];
[~,biggest] = max(A);
mask(labelmatrix(cc)~=biggest) = 0;
mask = imfill(mask,'holes');
imshow('peppers.png')
showMaskAsOverlay(0.7,mask,'c');

Working in a non-standard colorspace made this segmentation problem easier than it might otherwise have been, and certainly easier than doing it in RGB-space would be.

(showMaskAsOverlay is a utility I shared for overlaying a transparent mask on an image.)

Okay, so back to Pascal's file.

With a little bit of code, I can use "Colorspace Transforms" to examine quickly many additional representations of the original image:

cs = {'RGB','YCbCr','JPEG-YCbCr','YDbDr','YPbPr','YUV',...
'YIQ','HSV','HSL','HSI',...
'XYZ','Lab','Luv','LCH','CAT02 LMS'};
peppers = imread('peppers.png');
figure('color','w');
ax = tight_subplot(numel(cs),4);
ind = 1;
for ii = 1:numel(cs)
    newim = colorspace(['->' cs{ii}],peppers);
    if max(newim(:)) > 1
        newim = newim/max(newim(:));
    end
    axes(ax(ind));
    imshow(newim,[]);title(cs{ii});
    for jj = 1:3
        ind = ind+1;
        axes(ax(ind));
        imshow(newim(:,:,jj),[]);title(sprintf('%s(:,:,%i)',cs{ii},jj));
    end
    ind = ind+1;
end
expandAxes(ax)

(tight_subplot was a previous Pick-of-the-Week.)

Now I have a lot more options at my disposal for segmenting images!

P.S. I know you can't really see what's happening in those tiny thumbnails*, but then that's the beauty of expandAxes; if you were to run the code snippet above, you would be able to click on any of those tiny axes and expand them to full-frame. And you could right-click on any expanded axes to export the image to the Workspace!

*P.P.S. If your image is large, doing what I just did could be a very bad idea. These aren't really "thumbnails"; even if the visualization is small, each of those image objects has in its "cdata" container a full copy of the image it reflects.

Thank you, Oliver, for the suggestion. And thank you, Pascal, for the very useful submission. Swag on the way to both of you!

As always, I welcome your thoughts and comments. Or leave feedback for Pascal here.


Get the MATLAB code

Published with MATLAB® R2013a

Comments are closed.

These postings are the author's and don't necessarily represent the opinions of MathWorks.