{"id":33,"date":"2006-02-10T07:00:34","date_gmt":"2006-02-10T12:00:34","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=33"},"modified":"2022-05-29T19:58:37","modified_gmt":"2022-05-29T23:58:37","slug":"all-about-pixel-colors-part-3","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2006\/02\/10\/all-about-pixel-colors-part-3\/","title":{"rendered":"All about pixel colors: Scaled indexed images"},"content":{"rendered":"<div class=\"alert alert-info\">\r\n<span class=\"alert_icon icon-alert-info-reverse\"><\/span>\r\n<p class=\"alert_heading\"><strong>Note<\/strong><\/p>\r\n<p>See the following posts for new or updated information about this topic:<\/p>\r\n<li><a href=\"https:\/\/blogs.mathworks.com\/steve\/2016\/02\/09\/matlab-image-display-from-data-values-to-pixel-colors\/\">MATLAB image display - from data values to pixel colors<\/a><\/li>\r\n<li><a href=\"https:\/\/blogs.mathworks.com\/steve\/2016\/02\/22\/matlab-image-display-truecolor-and-indexed-images\/\">MATLAB image display - truecolor and indexed images<\/a><\/li>\r\n<li><a href=\"https:\/\/blogs.mathworks.com\/steve\/2016\/02\/29\/matlab-image-display-scaled-indexed-images\/\">MATLAB image display - scaled indexed images<\/a><\/li>\r\n<li><a href=\"https:\/\/blogs.mathworks.com\/steve\/2016\/03\/14\/matlab-image-display-grayscale-and-binary-images\/\">MATLAB image display - grayscale and binary images<\/a><\/li>\r\n<li>MATLAB image display - autoscaling values with imshow<\/li>\r\n<\/div>\r\n<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p>In my <a href=\"https:\/\/blogs.mathworks.com\/steve\/?p=32\">last post on pixel colors<\/a>, I described the truecolor and indexed image display models in MATLAB, and I promised to discuss an important variation on\r\n      the indexed image model. That variation is the <b>scaled indexed image,<\/b> and the relevant MATLAB image display function is <tt>imagesc<\/tt>.\r\n   <\/p>\r\n   <p>Suppose, for example, we use a small magic square:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">A = magic(5)<\/pre><pre style=\"font-style:oblique\">\r\nA =\r\n\r\n    17    24     1     8    15\r\n    23     5     7    14    16\r\n     4     6    13    20    22\r\n    10    12    19    21     3\r\n    11    18    25     2     9\r\n\r\n<\/pre><p>Now let's display <tt>A<\/tt> using <tt>image<\/tt> and a 256-color grayscale colormap:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">map = gray(256);\r\nimage(A)\r\ncolormap(map)\r\ntitle(<span style=\"color: #A020F0\">'Displayed using image'<\/span>)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/33\/scaled_indexed_01.png\"> <p>The displayed image is very dark. That's because the element values of A vary between 1 and 25, so only the first 25 entries\r\n      of the colormap are being used.  All these values are dark.\r\n   <\/p>\r\n   <p>Compare that with using <tt>imagesc<\/tt>:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">imagesc(A)\r\ncolormap(map)\r\ntitle(<span style=\"color: #A020F0\">'Displayed using imagesc'<\/span>)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/33\/scaled_indexed_02.png\"> <p>Here's what's going on.  The lowest value of A, which is 1, is displayed using the first colormap color, which is black. \r\n      The highest value of A, which is 25, is displayed using the last colormap color, which is white. All the other values between\r\n      1 and 25 are mapped linearly onto the colormap.  For example, the value 12 is displayed using the 118th colormap color, which\r\n      is an intermediate shade of gray.\r\n   <\/p>\r\n   <p>You can switch colormaps on the fly, and the values of A will be mapped onto the new colormap.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">colormap(jet)\r\ntitle(<span style=\"color: #A020F0\">'Scaled image using jet colormap'<\/span>)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/33\/scaled_indexed_03.png\"> <p>Let's dig into the low-level Handle Graphics properties that are controlling these behaviors.  Image objects have a property\r\n      called CDataMapping.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">close <span style=\"color: #A020F0\">all<\/span>\r\nh = image(A);\r\nget(h, <span style=\"color: #A020F0\">'CDataMapping'<\/span>)\r\nclose<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\ndirect\r\n\r\n<\/pre><p>You can see that its default value is 'direct'.  This means that values of <tt>A<\/tt> are used <b>directly<\/b> as indices into the colormap.  Compare that with using <tt>imagesc<\/tt>:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">h = imagesc(A);\r\nget(h, <span style=\"color: #A020F0\">'CDataMapping'<\/span>)\r\nclose<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\nscaled\r\n\r\n<\/pre><p>The <tt>imagesc<\/tt> function creates an image whose CDataMapping property is 'scaled'.  Values of <tt>A<\/tt> are <b>scaled<\/b> to form indices into the colormap. The specific formula is:\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/33\/scaled_indexed_eq114838.png\"> <\/p>\r\n   <p>C is a value in <tt>A<\/tt>, and c_min and c_max come from the CLim property of the axes object.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">h = imagesc(A);\r\nget(gca, <span style=\"color: #A020F0\">'CLim'<\/span>)\r\nclose<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n     1    25\r\n\r\n<\/pre><p>It's not a coincidence that the CLim (color limits) vector contains the minimum and maximum values of A.  The <tt>imagesc<\/tt> function does that by default.  But you can also specify your own color limits using an optional second argument to <tt>imagesc<\/tt>:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">imagesc(A, [10 15])\r\ncolormap(gray)\r\ntitle(<span style=\"color: #A020F0\">'imagesc(A, [10 15])'<\/span>)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/33\/scaled_indexed_04.png\"> <p>10 (and values below 10) were displayed as black.  15 (and values above 15 were displayed as white.  Values between 10 and\r\n      15 were displayed as shades of gray.\r\n   <\/p>\r\n   <p>Scaled image display is very important to engineering and scientific applications of image processing, because often what\r\n      we are looking at it isn't a \"picture\" in the ordinary sense.  Instead, it's an array containing measurements in some sort\r\n      of physical unit that's not related to light intensity.  For example, I showed this image in my <a href=\"https:\/\/blogs.mathworks.com\/steve\/?p=31\">first \"All about pixel colors\" post<\/a>:\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/31\/dem_snippet_gray.png\"> <\/p>\r\n   <p>This is a scaled-image display of a matrix containing terrain elevations in meters.<\/p>\r\n <script language=\"JavaScript\"> \r\n<!--\r\n    function grabCode_33() {\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='33 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 33';\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_33()\"><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.1<br><\/p>\r\n<\/div>\r\n<!--\r\n33 ##### SOURCE BEGIN #####\r\n%% \r\n% In my <https:\/\/blogs.mathworks.com\/steve\/?p=33 last post on pixel colors>,\r\n% I described the truecolor and indexed image display models in MATLAB, and\r\n% I promised to discuss an important variation on the indexed image model.\r\n% That variation is the *scaled indexed image,* and the relevant MATLAB\r\n% image display function is |imagesc|.\r\n%\r\n% Suppose, for example, we use a small magic square:\r\n\r\nA = magic(5)\r\n\r\n%%\r\n% Now let's display |A| using |image| and a 256-color grayscale colormap:\r\n\r\nmap = gray(256);\r\nimage(A)\r\ncolormap(map)\r\ntitle('Displayed using image')\r\n\r\n%%\r\n% The displayed image is very dark. That's because the element values of A\r\n% vary between 1 and 25, so only the first 25 entries of the colormap are\r\n% being used.  All these values are dark.\r\n%\r\n% Compare that with using |imagesc|:\r\n\r\nimagesc(A)\r\ncolormap(map)\r\ntitle('Displayed using imagesc')\r\n\r\n%%\r\n% Here's what's going on.  The lowest value of A, which is 1, is displayed\r\n% using the first colormap color, which is black.  The highest value of A,\r\n% which is 25, is displayed using the last colormap color, which is white.\r\n% All the other values between 1 and 25 are mapped linearly onto the\r\n% colormap.  For example, the value 12 is displayed using the 118th\r\n% colormap color, which is an intermediate shade of gray.\r\n%\r\n% You can switch colormaps on the fly, and the values of A will be mapped\r\n% onto the new colormap.\r\n\r\ncolormap(jet)\r\ntitle('Scaled image using jet colormap')\r\n\r\n%%\r\n% Let's dig into the low-level Handle Graphics properties that are\r\n% controlling these behaviors.  Image objects have a property called\r\n% CDataMapping.\r\n\r\nclose all\r\nh = image(A);\r\nget(h, 'CDataMapping')\r\nclose\r\n\r\n%%\r\n% You can see that its default value is 'direct'.  This means that values\r\n% of |A| are used *directly* as indices into the colormap.  Compare that\r\n% with using |imagesc|:\r\n\r\nh = imagesc(A);\r\nget(h, 'CDataMapping')\r\nclose\r\n\r\n%%\r\n% The |imagesc| function creates an image whose CDataMapping property is\r\n% 'scaled'.  Values of |A| are *scaled* to form indices into the colormap.\r\n% The specific formula is:\r\n%\r\n% $$ i = \\lfloor m (C - c_{\\min} \/ (c_{\\max} - c_{\\min}) \\rfloor + 1$$\r\n%\r\n% C is a value in |A|, and c_min and c_max come from the CLim property of\r\n% the axes object.\r\n\r\nh = imagesc(A);\r\nget(gca, 'CLim')\r\nclose\r\n\r\n%%\r\n% It's not a coincidence that the CLim (color limits) vector contains the\r\n% minimum and maximum values of A.  The |imagesc| function does that by\r\n% default.  But you can also specify your own color limits using an\r\n% optional second argument to |imagesc|:\r\n\r\nimagesc(A, [10 15])\r\ncolormap(gray)\r\ntitle('imagesc(A, [10 15])')\r\n\r\n%%\r\n% 10 (and values below 10) were displayed as black.  15 (and values above\r\n% 15 were displayed as white.  Values between 10 and 15 were displayed as\r\n% shades of gray.\r\n\r\n%%\r\n% Scaled image display is very important to engineering and scientific\r\n% applications of image processing, because often what we are looking at it\r\n% isn't a \"picture\" in the ordinary sense.  Instead, it's an array\r\n% containing measurements in some sort of physical unit that's not related\r\n% to light intensity.  For example, I showed this image in my <https:\/\/blogs.mathworks.com\/steve\/?p=31 \r\n% first \"All about pixel colors\" post>:\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/steve\/wp-content\/images\/31\/dem_snippet_gray.png>>\r\n%\r\n% This is a scaled-image display of a matrix containing terrain elevations\r\n% in meters.\r\n##### SOURCE END ##### 33\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n\r\nNote\r\nSee the following posts for new or updated information about this topic:\r\nMATLAB image display - from data values to pixel colors\r\nMATLAB image display - truecolor and indexed... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2006\/02\/10\/all-about-pixel-colors-part-3\/\">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":[58,56,48,60,54,52],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/33"}],"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=33"}],"version-history":[{"count":4,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/33\/revisions"}],"predecessor-version":[{"id":5549,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/33\/revisions\/5549"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=33"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=33"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=33"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}