{"id":1612,"date":"2016-02-29T10:36:35","date_gmt":"2016-02-29T15:36:35","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=1612"},"modified":"2019-11-01T12:18:09","modified_gmt":"2019-11-01T16:18:09","slug":"matlab-image-display-scaled-indexed-images","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2016\/02\/29\/matlab-image-display-scaled-indexed-images\/","title":{"rendered":"MATLAB image display &#8211; scaled indexed images"},"content":{"rendered":"<div class=\"content\"><p>In my <a href=\"https:\/\/blogs.mathworks.com\/steve\/2016\/02\/22\/matlab-image-display-truecolor-and-indexed-images\/\">last post on pixel colors<\/a>, I described the truecolor and indexed image display models in MATLAB, and I promised to talk to soon about a third model. That model is the <i>scaled indexed image<\/i>, a variation on the indexed image. The function <tt>imagesc<\/tt> is often used to display a scaled indexed image.<\/p><p>Let me start by displaying a small magic square using the <tt>image<\/tt> function, and then I'll compare with a display using <tt>imagesc<\/tt>.<\/p><pre class=\"codeinput\">A = magic(5)\r\n<\/pre><pre class=\"codeoutput\">\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>Let's display <tt>A<\/tt> using <tt>image<\/tt> and a 256-color grayscale colormap.<\/p><pre class=\"codeinput\">image(A)\r\ncolormap(gray(256))\r\naxis <span class=\"string\">image<\/span>\r\naxis <span class=\"string\">ij<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/scaled_indexed_images_01.png\" alt=\"\"> <p>Notice the displayed image is very dark. That's because the values of <tt>A<\/tt> vary between 1 and 25, and so the image uses only the first 25 colors of the grayscale colormap, all of which are very dark.<\/p><p>Now compare with the display using <tt>imagesc<\/tt>:<\/p><pre class=\"codeinput\">imagesc(A)\r\ncolormap(gray(256))\r\naxis <span class=\"string\">image<\/span>\r\naxis <span class=\"string\">ij<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/scaled_indexed_images_02.png\" alt=\"\"> <p>The function <tt>imagesc<\/tt> displays the lowest value of <tt>A<\/tt>, which is 1, using the first colormap color, which is black. It displays the highest value <tt>A<\/tt>, which is 25, using the last colormap color, which is white. All the other values between 1 and 25 are mapped linearly onto the colormap. For example, the value 12 is displayed using the 118th colormap color, which is an intermediate shade of gray.<\/p><p>If you switch colormaps, the values of <tt>A<\/tt> will be scaled and displayed using the colors in the new colormap.<\/p><pre class=\"codeinput\">colormap(parula)\r\ntitle(<span class=\"string\">'Scaled image using parula colormap'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/scaled_indexed_images_03.png\" alt=\"\"> <pre class=\"codeinput\">colormap(cool)\r\ntitle(<span class=\"string\">'Scaled image using cool colormap'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/scaled_indexed_images_04.png\" alt=\"\"> <p>Now let's look at the graphics object properties that control this behavior. The functions <tt>image<\/tt> and <tt>imagesc<\/tt> both return an <tt>Image<\/tt> object if you call them with an output argument. (I'll close the figure so it isn't displayed here. For the moment, I just want to look at the <tt>Image<\/tt> object that gets returned.)<\/p><pre class=\"codeinput\">im1 = image(A)\r\nclose\r\n<\/pre><pre class=\"codeoutput\">\r\nim1 = \r\n\r\n  Image with properties:\r\n\r\n           CData: [5x5 double]\r\n    CDataMapping: 'direct'\r\n\r\n  Use GET to show all properties\r\n\r\n<\/pre><p><tt>Image<\/tt> objects have a property called <tt>CDataMapping<\/tt>. The <tt>image<\/tt> function creates an <tt>Image<\/tt> object with the <tt>CDataMapping<\/tt> property set to <tt>'direct'<\/tt> by default. With this setting, values of A are used <b>directly<\/b> as indices into the colormap.<\/p><p>Compare that with the <tt>Image<\/tt> object created using <tt>imagesc<\/tt>.<\/p><pre class=\"codeinput\">im2 = imagesc(A)\r\nclose\r\n<\/pre><pre class=\"codeoutput\">\r\nim2 = \r\n\r\n  Image with properties:\r\n\r\n           CData: [5x5 double]\r\n    CDataMapping: 'scaled'\r\n\r\n  Use GET to show all properties\r\n\r\n<\/pre><p>The <tt>imagesc<\/tt> function creates an image whose <tt>CDataMapping<\/tt> property is <tt>'scaled'<\/tt>. Values of <tt>A<\/tt> are <b>scaled<\/b> to form indices into the colormap. The specific formula is:<\/p><p>$$k = \\lfloor m (A_{ij} - c_{\\min} \/ (c_{\\max} - c_{\\min}) \\rfloor + 1$$<\/p><p>$A_{ij}$ is a value of an element of <tt>A<\/tt>, and $c_{\\min}$ and $c_{\\max}$ are the <i>color limits<\/i>. These limits come from the <tt>'CLim'<\/tt> property of the <tt>Axes<\/tt> object. Here's how to view the color limits.<\/p><pre class=\"codeinput\">h = imagesc(A);\r\nax = gca;\r\nax.CLim\r\nclose\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n     1    25\r\n\r\n<\/pre><p>It's not a coincidence that the the <tt>CLim<\/tt> property contains the minimum and maximum values of <tt>A<\/tt>. 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>.<\/p><pre class=\"codeinput\">imagesc(A,[10 15])\r\ncolormap(gray)\r\ntitle(<span class=\"string\">'imagesc(A,[10 15])'<\/span>)\r\naxis <span class=\"string\">image<\/span>\r\naxis <span class=\"string\">ij<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/scaled_indexed_images_05.png\" alt=\"\"> <p>In the image above, the value 10 (and also lower values) were displayed as black. The value 15 (and also greater values) were displayed as white. Values between 10 and 15 were displayed as shades of gray.<\/p><p>Scaled image display is very important for engineering and scientific applications of image processing because we are often looking at something that is not a \"picture\" in the ordinary sense. Rather, it's often an array containing measurements in some physical unit that's not related to light intensity. For example, I showed this image in my <a href=\"https:\/\/blogs.mathworks.com\/steve\/2016\/02\/09\/matlab-image-display-from-data-values-to-pixel-colors\/\">first image display post earlier this month<\/a>:<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/mt-monadnock-parula.jpg\" alt=\"\"> <\/p><p>This is a scaled-image display of a matrix containing terrain elevations in meters.<\/p><p>Next time I'll talk about grayscale and binary images.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_46b86caab4634bb6ab782b2724be649c() {\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='46b86caab4634bb6ab782b2724be649c ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 46b86caab4634bb6ab782b2724be649c';\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 2016 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_46b86caab4634bb6ab782b2724be649c()\"><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; R2015b<br><\/p><\/div><!--\r\n46b86caab4634bb6ab782b2724be649c ##### SOURCE BEGIN #####\r\n%%\r\n% In my\r\n% <https:\/\/blogs.mathworks.com\/steve\/2016\/02\/22\/matlab-image-display-truecolor-and-indexed-images\/\r\n% last post on pixel colors>, I described the truecolor and indexed image\r\n% display models in MATLAB, and I promised to talk to soon about a third\r\n% model. That model is the _scaled indexed image_, a variation on the\r\n% indexed image. The function |imagesc| is often used to display a scaled\r\n% indexed image.\r\n%\r\n% Let me start by displaying a small magic square using the |image|\r\n% function, and then I'll compare with a display using |imagesc|.\r\n\r\nA = magic(5)\r\n\r\n%%\r\n% Let's display |A| using |image| and a 256-color grayscale colormap.\r\n\r\nimage(A)\r\ncolormap(gray(256))\r\naxis image\r\naxis ij\r\n\r\n%%\r\n% Notice the displayed image is very dark. That's because the values of |A|\r\n% vary between 1 and 25, and so the image uses only the first 25 colors of\r\n% the grayscale colormap, all of which are very dark.\r\n%\r\n% Now compare with the display using |imagesc|:\r\n\r\nimagesc(A)\r\ncolormap(gray(256))\r\naxis image\r\naxis ij\r\n\r\n%%\r\n% The function |imagesc| displays the lowest value of |A|, which is 1, using\r\n% the first colormap color, which is black. It displays the highest value\r\n% |A|, which is 25, using the last colormap color, which is white. All the\r\n% other values between 1 and 25 are mapped linearly onto the colormap. For\r\n% example, the value 12 is displayed using the 118th colormap color, which\r\n% is an intermediate shade of gray.\r\n%\r\n% If you switch colormaps, the values of |A| will be scaled and displayed\r\n% using the colors in the new colormap.\r\n\r\ncolormap(parula)\r\ntitle('Scaled image using parula colormap')\r\n\r\n%%\r\n\r\ncolormap(cool)\r\ntitle('Scaled image using cool colormap')\r\n\r\n%%\r\n% Now let's look at the graphics object properties that control this\r\n% behavior. The functions |image| and |imagesc| both return an |Image|\r\n% object if you call them with an output argument. (I'll close the figure\r\n% so it isn't displayed here. For the moment, I just want to look at the\r\n% |Image| object that gets returned.)\r\n\r\nim1 = image(A)\r\nclose\r\n\r\n%%\r\n% |Image| objects have a property called |CDataMapping|. The |image|\r\n% function creates an |Image| object with the |CDataMapping| property set to\r\n% |'direct'| by default. With this setting, values of A are used *directly*\r\n% as indices into the colormap.\r\n%\r\n% Compare that with the |Image| object created using |imagesc|.\r\n\r\nim2 = imagesc(A)\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% $$k = \\lfloor m (A_{ij} - c_{\\min} \/ (c_{\\max} - c_{\\min}) \\rfloor + 1$$\r\n% \r\n% $A_{ij}$ is a value of an element of |A|, and $c_{\\min}$ and $c_{\\max}$ are\r\n% the _color limits_. These limits come from the |'CLim'| property of the\r\n% |Axes| object. Here's how to view the color limits.\r\n\r\nh = imagesc(A);\r\nax = gca;\r\nax.CLim\r\nclose\r\n\r\n%%\r\n% It's not a coincidence that the the |CLim| property contains the minimum\r\n% and maximum values of |A|. The |imagesc| function does that by default.\r\n% But you can also specify your own color limits using an optional second\r\n% argument to |imagesc|.\r\n\r\nimagesc(A,[10 15])\r\ncolormap(gray)\r\ntitle('imagesc(A,[10 15])')\r\naxis image\r\naxis ij\r\n\r\n%%\r\n% In the image above, the value 10 (and also lower values) were displayed as\r\n% black. The value 15 (and also greater values) were displayed as white.\r\n% Values between 10 and 15 were displayed as shades of gray.\r\n%\r\n% Scaled image display is very important for engineering and scientific\r\n% applications of image processing because we are often looking at something\r\n% that is not a \"picture\" in the ordinary sense. Rather, it's often an array\r\n% containing measurements in some physical unit that's not related to light\r\n% intensity. For example, I showed this image in my\r\n% <https:\/\/blogs.mathworks.com\/steve\/2016\/02\/09\/matlab-image-display-from-data-values-to-pixel-colors\/\r\n% first image display post earlier this month>:\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/steve\/files\/mt-monadnock-parula.jpg>>\r\n%\r\n% This is a scaled-image display of a matrix containing terrain elevations\r\n% in meters.\r\n%\r\n% Next time I'll talk about grayscale and binary images.\r\n##### SOURCE END ##### 46b86caab4634bb6ab782b2724be649c\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/steve\/files\/scaled_indexed_images_03.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>In my last post on pixel colors, I described the truecolor and indexed image display models in MATLAB, and I promised to talk to soon about a third model. That model is the scaled indexed image, a... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2016\/02\/29\/matlab-image-display-scaled-indexed-images\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":1605,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[13],"tags":[50,278,58,80,56,48,60,54,1093,52],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/1612"}],"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=1612"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/1612\/revisions"}],"predecessor-version":[{"id":1613,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/1612\/revisions\/1613"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media\/1605"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=1612"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=1612"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=1612"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}