{"id":57,"date":"2006-05-09T08:22:36","date_gmt":"2006-05-09T12:22:36","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=57"},"modified":"2019-10-22T11:33:02","modified_gmt":"2019-10-22T15:33:02","slug":"a-lab-based-uniform-color-scale","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2006\/05\/09\/a-lab-based-uniform-color-scale\/","title":{"rendered":"A Lab-based uniform color scale"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <introduction><\/introduction>\r\n   \r\n   <h3>DSP Tips &amp; Tricks<a name=\"1\"><\/a><\/h3>\r\n   <p>One of my favorite professional publications is  <i>IEEE Signal Processing Magazine<\/i>.  It has a regular feature called \"DSP Tips &amp; Tricks.\"  In the January 2006 issue, James McNames wrote a tips &amp; tricks article\r\n      called \"An Effective Color Scale for Simultaneous Color and Gray-Scale Publications.\"  Professor McNames, of Portland State\r\n      University, wrote that while \"color is increasingly available for electronic publications at no additional cost ... most color\r\n      scales are distored when converted to gray scale. [... This] article proposes a color scale that appears as a monotonic gray\r\n      scale in printed form and significantly enhances the image resolution when viewed in color.\"\r\n   <\/p>\r\n   <p>McNames gives four design principles for selecting an effective color scale (or <i>colormap<\/i>, in MATLAB terminology):\r\n   <\/p>\r\n   <div>\r\n      <ul>\r\n         <li>\"[The] color scale should cover as much of the range of available colors as possible, subject to the constraint that the luminance\r\n            increases monotonically (for gray scale publications).\r\n         <\/li>\r\n         <li>\"Neighboring colors throughout the scale should be as distinct as possible.\"<\/li>\r\n         <li>\"The perceptual difference between two colors should be approximately proportional to the difference between their positions\r\n            along the color scale.\"\r\n         <\/li>\r\n         <li>\"The color scale should be intuitive.\"<\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p>The article goes on to show some math and some MATLAB code for creating such a color scale.  Professor McNames provides a\r\n      full MATLAB implementation of the idea (ColorSpiral.m) on his <a href=\"\">web site<\/a>.\r\n   <\/p>\r\n   <h3>A path through L*a*b* color space<a name=\"2\"><\/a><\/h3>\r\n   <p>The McNames article describes a method for constructing a path through RGB space that has the desired properties, at least\r\n      approximately.  I thought it might be conceptually simpler to form a color scale by constructing a path through a different color\r\n      space, L*a*b*.  This color space separates luminance, L*, from two color difference components, a* and b*.\r\n   <\/p>\r\n   <p>If you convert a* and b* to polar coordinates, the angle corresponds to hue, and the radius corresponds to chroma, or vividness\r\n      of hue.\r\n   <\/p>\r\n   <p>Let's make a color scale that is a uniform ramp in L*.  In the a*-b* plane, trace a semicircular path of radius 50, with angle\r\n      varying between 0 and pi\/2.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">radius = 50;\r\ntheta = linspace(0, pi\/2, 256).';\r\na = radius * cos(theta);\r\nb = radius * sin(theta);\r\nL = linspace(0, 100, 256).';\r\nLab = [L, a, b];<\/pre><p>Now convert the L*a*b* values to sRGB so we can use it as a MATLAB colormap.  Use the Image Processing Toolbox functions <tt>makecform<\/tt> and <tt>applycform<\/tt>.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">map = applycform(Lab, makecform(<span style=\"color: #A020F0\">'lab2srgb'<\/span>));<\/pre><h3>Radon example<a name=\"4\"><\/a><\/h3>\r\n   <p>Let's use this colormap for looking at a Radon transform image.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">I = zeros(100,100);\r\nI(25:75, 25:75) = 1;\r\ntheta = 0:180;\r\n[R,xp] = radon(I,theta);\r\nimshow(R,[],<span style=\"color: #A020F0\">'InitialMagnification'<\/span>,<span style=\"color: #A020F0\">'fit'<\/span>)\r\ncolormap(map)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/57\/color_scale_demo_01.png\"> <h3>Color scale function on MATLAB Central<a name=\"5\"><\/a><\/h3>\r\n   <p>The function <tt>color_scale<\/tt> on MATLAB Central lets you easily create color scales like this.  You can choose different values for the radius and the\r\n      starting angle, and you specify a clockwise or counterclockwise path through a*-b* space.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">colormap(color_scale)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/57\/color_scale_demo_02.png\"> <h3>Color scale GUI<a name=\"6\"><\/a><\/h3>\r\n   <p>The same MATLAB Central submission contains the <tt>color_scale_tool<\/tt> function, which is a GUI that lets you control the color scale parameters with sliders.  It also shows you both the color\r\n      scale and the approximate grayscale equivalent.  Here's a screen shot:\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/57\/screenshot_half.jpg\"> <\/p>\r\n   <p>Give it a try.<\/p>\r\n<script language=\"JavaScript\"> \r\n<!--\r\n    function grabCode_57() {\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='57 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 57';\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        author = 'Steve Eddins';\r\n        copyright = 'Copyright 2006 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 author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\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-->\r\n      <\/script>\r\n<noscript>\r\n<em>A JavaScript-enabled browser is required to use the \"Get the MATLAB code\" link.<\/em>\r\n<\/noscript>\r\n<p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_57()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n            the MATLAB code<\/span><\/a><br><br>\r\n      Published with MATLAB&reg; 7.2<br><\/p>\r\n<\/div>\r\n<!--\r\n57 ##### SOURCE BEGIN #####\r\n%% Colormap for both color and gray-scale publications\r\n\r\n%% DSP Tips & Tricks\r\n% One of my favorite professional publications is  _IEEE Signal Processing\r\n% Magazine_.  It has a regular feature called \"DSP Tips & Tricks.\"  In the\r\n% January 2006 issue, James McNames wrote a tips & tricks article called\r\n% \"An Effective Color Scale for Simultaneous Color and Gray-Scale\r\n% Publications.\"  Professor McNames, of Portland State University, wrote\r\n% that while \"color is increasingly available for electronic publications\r\n% at no additional cost ... most color scales are distored when converted\r\n% to gray scale. [... This] article proposes a color scale that appears as\r\n% a monotonic gray scale in printed form and significantly enhances the\r\n% image resolution when viewed in color.\"\r\n%\r\n% McNames gives four design principles for selecting an effective color\r\n% scale (or _colormap_, in MATLAB terminology):\r\n% \r\n% * \"[The] color scale should cover as much of the range of available\r\n% colors as possible, subject to the constraint that the luminance\r\n% increases monotonically (for gray scale publications).\r\n% * \"Neighboring colors throughout the scale should be as distinct as\r\n% possible.\"\r\n% * \"The perceptual difference between two colors should be approximately\r\n% proportional to the difference between their positions along the color\r\n% scale.\"\r\n% * \"The color scale should be intuitive.\"\r\n% \r\n% The article goes on to show some math and some MATLAB code for creating\r\n% such a color scale.  Professor McNames provides a full MATLAB\r\n% implementation of the idea (ColorSpiral.m) on his \r\n% < web site>.\r\n\r\n%% A path through L*a*b* color space\r\n% The McNames article describes a method for constructing a path through\r\n% RGB space that has the desired properties, at least approximately.  I\r\n% thought it might conceptually simpler to form a color scale by\r\n% constructing a path through a different color space, L*a*b*.  This color\r\n% space separates luminance, L*, from two color difference components, a*\r\n% and b*.\r\n%\r\n% If you convert a* and b* to polar coordinates, the angle corresponds to\r\n% hue, and the radius corresponds to chroma, or vividness of hue.\r\n%\r\n% Let's make a color scale that is a uniform ramp in L*.  In the a*-b* \r\n% plane, trace a semicircular path of radius 50, with angle varying between\r\n% 0 and pi\/2.\r\n\r\nradius = 50;\r\ntheta = linspace(0, pi\/2, 256).';\r\na = radius * cos(theta);\r\nb = radius * sin(theta);\r\nL = linspace(0, 100, 256).';\r\nLab = [L, a, b];\r\n\r\n%%\r\n% Now convert the L*a*b* values to sRGB so we can use it as a MATLAB\r\n% colormap.  Use the Image Processing Toolbox functions \r\n% <https:\/\/www.mathworks.com\/help\/images\/index.htmlmakecform.html \r\n% |makecform|> and \r\n% <https:\/\/www.mathworks.com\/help\/images\/index.htmlmakecform.html \r\n% |applycform|>.\r\n\r\nmap = applycform(Lab, makecform('lab2srgb'));\r\n\r\n%% Radon example\r\n% Let's use this colormap for looking at a Radon transform image.\r\n\r\nI = zeros(100,100);\r\nI(25:75, 25:75) = 1;\r\ntheta = 0:180;\r\n[R,xp] = radon(I,theta);\r\nimshow(R,[],'InitialMagnification','fit')\r\ncolormap(map)\r\n\r\n%% Color scale function on MATLAB Central\r\n% The function \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/loadFile.do?objectId=11037&objectType=FILE \r\n% |color_scale|> on MATLAB Central lets you easily create color \r\n% scales like this.  You can choose different values for the radius and the\r\n% starting angle, and you specify a clockwise or counterclockwise path\r\n% through a*-b* space.\r\n\r\ncolormap(color_scale)\r\n\r\n%% Color scale GUI\r\n% The same MATLAB Central submission contains the |color_scale_tool|\r\n% function, which is a GUI that lets you control the color scale parameters\r\n% with sliders.  It also shows you both the color scale and the approximate\r\n% grayscale equivalent.  Here's a screen shot:\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/images\/steve\/57\/screenshot_half.jpg>>\r\n%\r\n% Give it a try.\r\n\r\n##### SOURCE END ##### 57\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   \r\n   \r\n   DSP Tips &amp; Tricks\r\n   One of my favorite professional publications is  IEEE Signal Processing Magazine.  It has a regular feature called \"DSP Tips &amp; Tricks.\"  In the January... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2006\/05\/09\/a-lab-based-uniform-color-scale\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[114,58,74,36,32,132,34,130],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/57"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=57"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/57\/revisions"}],"predecessor-version":[{"id":2184,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/57\/revisions\/2184"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=57"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=57"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=57"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}