{"id":4556,"date":"2013-05-10T09:00:49","date_gmt":"2013-05-10T13:00:49","guid":{"rendered":"https:\/\/blogs.mathworks.com\/pick\/?p=4556"},"modified":"2013-05-09T13:58:06","modified_gmt":"2013-05-09T17:58:06","slug":"colorspaces-out-the-wazoo","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/pick\/2013\/05\/10\/colorspaces-out-the-wazoo\/","title":{"rendered":"Colorspaces out the Wazoo!"},"content":{"rendered":"\r\n<div class=\"content\"><!--introduction--><!--\/introduction--><p><a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/911\">Brett<\/a>'s Pick this week is <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/28790-colorspace-transformations\">\"Colorspace Transformations\"<\/a>, by <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/14582\">Pascal Getreuer<\/a>.<\/p><p>For inspiration for this week's Pick, I went back to <a href=\"https:\/\/blogs.mathworks.com\/pick\/2012\/04\/13\/what-is-your-favorite-unrecognized-file-exchange-submission\/\">my post<\/a> 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.<\/p><p>File Exchange champ <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/29192\">Oliver Woodford<\/a> casually suggested \"a couple of useful ones.\" (His other selection was featured <a href=\"https:\/\/blogs.mathworks.com\/pick\/2012\/08\/17\/shaded-error-bars\/\">last August<\/a> by Jiro.) Both of his \"Picks\" are quite useful.<\/p><p>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 <a href=\"\">MEX interface<\/a>) to make them faster.<\/p><p>Colorspace Transformations facilitates conversion to any of these colorspaces:<\/p><pre>'RGB'              sRGB IEC 61966-2-1\r\n'YCbCr'            Luma + Chroma (\"digitized\" version of Y'PbPr)\r\n'JPEG-YCbCr'       Luma + Chroma space used in JFIF JPEG\r\n'YDbDr'            SECAM Y'DbDr Luma + Chroma\r\n'YPbPr'            Luma (ITU-R BT.601) + Chroma\r\n'YUV'              NTSC PAL Y'UV Luma + Chroma\r\n'YIQ'              NTSC Y'IQ Luma + Chroma\r\n'HSV' or 'HSB'     Hue Saturation Value\/Brightness\r\n'HSL' or 'HLS'     Hue Saturation Luminance\r\n'HSI'              Hue Saturation Intensity\r\n'XYZ'              CIE 1931 XYZ\r\n'Lab'              CIE 1976 L*a*b* (CIELAB)\r\n'Luv'              CIE L*u*v* (CIELUV)\r\n'LCH'              CIE L*C*H* (CIELCH)\r\n'CAT02 LMS'        CIE CAT02 LMS<\/pre><p>That's a lot of different ways to represent a color image!<\/p><p>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 href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/19-delta-sigma-toolbox-explorergb\">a utility<\/a> 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:<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/pick\/files\/peppers.png\" alt=\"\"> <\/p><p>I might consider (ironically) starting from the blue chrominance image (i.e., the second colorplane of the YCbCr representation of the image):<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/pick\/files\/bluechrominance.png\" alt=\"\"> <\/p><p>Starting with that image plane:<\/p><pre class=\"language-matlab\">mask = ~im2bw(img,0.24);\r\ncc = bwconncomp(mask);\r\nstats = regionprops(cc,<span class=\"string\">'Area'<\/span>);\r\nA = [stats.Area];\r\n[~,biggest] = max(A);\r\nmask(labelmatrix(cc)~=biggest) = 0;\r\nmask = imfill(mask,<span class=\"string\">'holes'<\/span>);\r\nimshow(<span class=\"string\">'peppers.png'<\/span>)\r\nshowMaskAsOverlay(0.7,mask,<span class=\"string\">'c'<\/span>);\r\n<\/pre><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/pick\/files\/segmentedPepper.png\" alt=\"\"> <\/p><p>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.<\/p><p>(<a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/22108-showmaskasoverlay\"><tt>showMaskAsOverlay<\/tt><\/a> is a utility I shared for overlaying a transparent mask on an image.)<\/p><p>Okay, so back to Pascal's file.<\/p><p>With a little bit of code, I can use \"Colorspace Transforms\" to examine quickly many additional representations of the original image:<\/p><pre class=\"language-matlab\">cs = {<span class=\"string\">'RGB'<\/span>,<span class=\"string\">'YCbCr'<\/span>,<span class=\"string\">'JPEG-YCbCr'<\/span>,<span class=\"string\">'YDbDr'<\/span>,<span class=\"string\">'YPbPr'<\/span>,<span class=\"string\">'YUV'<\/span>,<span class=\"keyword\">...<\/span>\r\n<span class=\"string\">'YIQ'<\/span>,<span class=\"string\">'HSV'<\/span>,<span class=\"string\">'HSL'<\/span>,<span class=\"string\">'HSI'<\/span>,<span class=\"keyword\">...<\/span>\r\n<span class=\"string\">'XYZ'<\/span>,<span class=\"string\">'Lab'<\/span>,<span class=\"string\">'Luv'<\/span>,<span class=\"string\">'LCH'<\/span>,<span class=\"string\">'CAT02 LMS'<\/span>};\r\npeppers = imread(<span class=\"string\">'peppers.png'<\/span>);\r\nfigure(<span class=\"string\">'color'<\/span>,<span class=\"string\">'w'<\/span>);\r\nax = tight_subplot(numel(cs),4);\r\nind = 1;\r\n<span class=\"keyword\">for<\/span> ii = 1:numel(cs)\r\n    newim = colorspace([<span class=\"string\">'-&gt;'<\/span> cs{ii}],peppers);\r\n    <span class=\"keyword\">if<\/span> max(newim(:)) &gt; 1\r\n        newim = newim\/max(newim(:));\r\n    <span class=\"keyword\">end<\/span>\r\n    axes(ax(ind));\r\n    imshow(newim,[]);title(cs{ii});\r\n    <span class=\"keyword\">for<\/span> jj = 1:3\r\n        ind = ind+1;\r\n        axes(ax(ind));\r\n        imshow(newim(:,:,jj),[]);title(sprintf(<span class=\"string\">'%s(:,:,%i)'<\/span>,cs{ii},jj));\r\n    <span class=\"keyword\">end<\/span>\r\n    ind = ind+1;\r\n<span class=\"keyword\">end<\/span>\r\nexpandAxes(ax)\r\n<\/pre><p>(<a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/27991-tight-subplot-nh--nw--gap--marg-h--marg-w--tight-subplot\"><tt>tight_subplot<\/tt><\/a> was a previous Pick-of-the-Week.)<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/pick\/files\/colorspaceList.png\" alt=\"\"> <\/p><p>Now I have a lot more options at my disposal for segmenting images!<\/p><p>P.S. I know you can't really see what's happening in those tiny thumbnails*, but then that's the beauty of <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/18291-expandaxes-hndls-rotenable--expandaxes\"><tt>expandAxes<\/tt><\/a>; 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>*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 <a href=\"\">\"cdata\"<\/a> container a full copy of the image it reflects.<\/p><p>Thank you, Oliver, for the suggestion. And thank <i>you<\/i>, Pascal, for the very useful submission. Swag on the way to both of you!<\/p><p>As always, I welcome your <a href=\"https:\/\/blogs.mathworks.com\/pick\/?p=4556#respond\">thoughts and comments<\/a>. Or leave feedback for Pascal <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/28790-colorspace-transformations#comments\">here<\/a>.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_b7763c2fc1234b029827c0f68bbf81b4() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='b7763c2fc1234b029827c0f68bbf81b4 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' b7763c2fc1234b029827c0f68bbf81b4';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2013 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_b7763c2fc1234b029827c0f68bbf81b4()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2013a<br><\/p><p class=\"footer\"><br>\r\n      Published with MATLAB&reg; R2013a<br><\/p><\/div><!--\r\nb7763c2fc1234b029827c0f68bbf81b4 ##### SOURCE BEGIN #####\r\n%% Colorspaces out the Wazoo!\r\n%% \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/911 Brett>'s Pick this week is\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/28790-colorspace-transformations \"Colorspace Transformations\">, by\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/14582 Pascal Getreuer>.\r\n\r\n%%\r\n% For inspiration for this week's Pick, I went back to <https:\/\/blogs.mathworks.com\/pick\/2012\/04\/13\/what-is-your-favorite-unrecognized-file-exchange-submission\/ my post>\r\n% from April\r\n% of last year, in which I asked readers to suggest files to feature. I\r\n% started to write up Pascal's submission long ago, but somehow got\r\n% sidetracked, and I wanted to circle back around to it.\r\n\r\n%%\r\n% File Exchange champ <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/29192 Oliver Woodford> \r\n% casually suggested \"a couple of useful ones.\" (His other selection was featured \r\n% <https:\/\/blogs.mathworks.com\/pick\/2012\/08\/17\/shaded-error-bars\/ last August>\r\n% by Jiro.) Both of his \"Picks\" are quite useful.\r\n\r\n%%\r\n% So, what's so great about this colorspace converter? In particular,\r\n% I really like the fact that Pascal's code extends the colorspace conversion\r\n% capabilities beyond those offered by the Image Processing Toolbox, and\r\n% that Pascal has included C-code (and instructions for calling it via the\r\n% < MEX interface>)\r\n% to make them faster. \r\n\r\n%% \r\n% Colorspace Transformations facilitates conversion to any of these\r\n% colorspaces:\r\n%\r\n%  'RGB'              sRGB IEC 61966-2-1\r\n%  'YCbCr'            Luma + Chroma (\"digitized\" version of Y'PbPr)\r\n%  'JPEG-YCbCr'       Luma + Chroma space used in JFIF JPEG\r\n%  'YDbDr'            SECAM Y'DbDr Luma + Chroma\r\n%  'YPbPr'            Luma (ITU-R BT.601) + Chroma \r\n%  'YUV'              NTSC PAL Y'UV Luma + Chroma\r\n%  'YIQ'              NTSC Y'IQ Luma + Chroma\r\n%  'HSV' or 'HSB'     Hue Saturation Value\/Brightness\r\n%  'HSL' or 'HLS'     Hue Saturation Luminance\r\n%  'HSI'              Hue Saturation Intensity\r\n%  'XYZ'              CIE 1931 XYZ\r\n%  'Lab'              CIE 1976 L*a*b* (CIELAB)\r\n%  'Luv'              CIE L*u*v* (CIELUV)\r\n%  'LCH'              CIE L*C*H* (CIELCH)\r\n%  'CAT02 LMS'        CIE CAT02 LMS\r\n\r\n%%\r\n% That's a lot of different ways to represent a color image!\r\n\r\n%%\r\n% Whenever I am asked to segment a color imageREPLACE_WITH_DASH_DASHand trust me, that's pretty\r\n% often!REPLACE_WITH_DASH_DASHmy initial thought is to look at the R,G, and B colorplanes\r\n% individually to understand where the information I'm after lies. I do\r\n% this so often that I wrote and shared\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/19-delta-sigma-toolbox-explorergb a\r\n% utility> that facilitates this exploration process. (In \"Advanced Mode,\"\r\n% ExploreRGB showsREPLACE_WITH_DASH_DASHin addition to RGB [and R, G, and B]REPLACE_WITH_DASH_DASHHSV, YCbCr, and\r\n% L*a*b* versions of the image. I can often find a single-plane version of\r\n% the original image in one of these transformed colorspaces that makes the\r\n% segmentation easy. For instance, if I needed to isolate the central\r\n% yellow pepper in the \"peppers.png\" image that ships with the Image\r\n% Processing Toolbox:\r\n\r\n%%\r\n% \r\n% <<https:\/\/blogs.mathworks.com\/pick\/files\/peppers.png>>\r\n% \r\n\r\n%%\r\n% I might consider (ironically) starting from the blue chrominance image\r\n% (i.e., the second colorplane of the YCbCr representation of the image):\r\n\r\n%%\r\n% \r\n% <<https:\/\/blogs.mathworks.com\/pick\/files\/bluechrominance.png>>\r\n% \r\n\r\n%%\r\n% Starting with that image plane:\r\n%\r\n%   mask = ~im2bw(img,0.24);\r\n%   cc = bwconncomp(mask);\r\n%   stats = regionprops(cc,'Area');\r\n%   A = [stats.Area];\r\n%   [~,biggest] = max(A);\r\n%   mask(labelmatrix(cc)~=biggest) = 0;\r\n%   mask = imfill(mask,'holes');\r\n%   imshow('peppers.png')\r\n%   showMaskAsOverlay(0.7,mask,'c');\r\n\r\n%%\r\n% \r\n% <<https:\/\/blogs.mathworks.com\/pick\/files\/segmentedPepper.png>>\r\n% \r\n\r\n%%\r\n% Working in a non-standard colorspace made this segmentation problem\r\n% easier than it might otherwise have been, and certainly easier than doing\r\n% it in RGB-space would be.\r\n\r\n%%\r\n% (<https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/22108-showmaskasoverlay |showMaskAsOverlay|> is a utility I shared for overlaying a transparent mask on an image.)\r\n\r\n%%\r\n% Okay, so back to Pascal's file.\r\n\r\n%%\r\n% With a little bit of code, I can use \"Colorspace Transforms\" to examine\r\n% quickly many additional representations of the original image:\r\n\r\n%%\r\n%   cs = {'RGB','YCbCr','JPEG-YCbCr','YDbDr','YPbPr','YUV',...\r\n%   'YIQ','HSV','HSL','HSI',...\r\n%   'XYZ','Lab','Luv','LCH','CAT02 LMS'};\r\n%   peppers = imread('peppers.png');\r\n%   figure('color','w');\r\n%   ax = tight_subplot(numel(cs),4);\r\n%   ind = 1;\r\n%   for ii = 1:numel(cs)\r\n%       newim = colorspace(['->' cs{ii}],peppers);\r\n%       if max(newim(:)) > 1\r\n%           newim = newim\/max(newim(:));\r\n%       end\r\n%       axes(ax(ind));\r\n%       imshow(newim,[]);title(cs{ii});\r\n%       for jj = 1:3\r\n%           ind = ind+1;\r\n%           axes(ax(ind));\r\n%           imshow(newim(:,:,jj),[]);title(sprintf('%s(:,:,%i)',cs{ii},jj));\r\n%       end\r\n%       ind = ind+1;\r\n%   end\r\n%   expandAxes(ax)\r\n\r\n%%\r\n% (<https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/27991-tight-subplot-nh--nw--gap--marg-h--marg-w--tight-subplot |tight_subplot|> was a previous Pick-of-the-Week.) \r\n\r\n%%\r\n% \r\n% <<https:\/\/blogs.mathworks.com\/pick\/files\/colorspaceList.png>>\r\n% \r\n\r\n%%\r\n% Now I have a lot more options at my disposal for segmenting images!\r\n\r\n%% \r\n% P.S. I know you can't really see what's happening in those tiny thumbnails*,\r\n% but then that's the beauty of\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/18291-expandaxes-hndls-rotenable--expandaxes |expandAxes|>;\r\n% if you were to run the code snippet above, you would be able to click on\r\n% any of those tiny axes and expand them to full-frame. And you could\r\n% right-click on any expanded axes to export the image to the Workspace!\r\n\r\n%% \r\n% *P.P.S. If your image is large, doing what I just did could be a very bad\r\n% idea. These aren't really \"thumbnails\"; even if the visualization is small, \r\n% each of those image objects has in its < \"cdata\">\r\n% container a full copy of the image it reflects.\r\n\r\n%% \r\n% Thank you, Oliver, for the suggestion. And thank _you_, Pascal, for the\r\n% very useful submission. Swag on the way to both of you!\r\n\r\n%%\r\n% As always, I welcome your\r\n% <https:\/\/blogs.mathworks.com\/pick\/?p=4556#respond thoughts and comments>.\r\n% Or leave feedback for Pascal <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/28790-colorspace-transformations#comments here>.\r\n##### SOURCE END ##### b7763c2fc1234b029827c0f68bbf81b4\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/pick\/files\/peppers.png\" onError=\"this.style.display ='none';\" \/><\/div><p>\r\nBrett'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... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/pick\/2013\/05\/10\/colorspaces-out-the-wazoo\/\">read more >><\/a><\/p>","protected":false},"author":34,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[16],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/4556"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/users\/34"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/comments?post=4556"}],"version-history":[{"count":22,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/4556\/revisions"}],"predecessor-version":[{"id":4582,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/4556\/revisions\/4582"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/media?parent=4556"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/categories?post=4556"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/tags?post=4556"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}