{"id":1599,"date":"2016-02-22T16:28:45","date_gmt":"2016-02-22T21:28:45","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=1599"},"modified":"2019-11-01T12:17:05","modified_gmt":"2019-11-01T16:17:05","slug":"matlab-image-display-truecolor-and-indexed-images","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2016\/02\/22\/matlab-image-display-truecolor-and-indexed-images\/","title":{"rendered":"MATLAB image display &#8211; truecolor and indexed images"},"content":{"rendered":"<div class=\"content\"><!--introduction--><!--\/introduction--><h3>Contents<\/h3><div><ul><li><a href=\"#d0bce0bf-2384-4a9a-bc39-e39d71d959c3\">MATLAB image display - truecolor and indexed images<\/a><\/li><li><a href=\"#29d6e72c-a5da-4e67-ae78-73da2af73bd5\">Truecolor images<\/a><\/li><li><a href=\"#959116fd-c4e3-4077-9f0e-7434b9d55ae7\">Indexed images<\/a><\/li><\/ul><\/div><h4>MATLAB image display - truecolor and indexed images<a name=\"d0bce0bf-2384-4a9a-bc39-e39d71d959c3\"><\/a><\/h4><p><a href=\"https:\/\/blogs.mathworks.com\/steve\/2016\/02\/09\/matlab-image-display-from-data-values-to-pixel-colors\/\">Last time<\/a> I posed this question: How does MATLAB associate the value of particular array elements with a color displayed on the screen?  Let's start by exploring MATLAB's two basic pixel-color display models:<\/p><div><ul><li>3-D array element values specify pixel colors directly<\/li><li>2-D matrix element values specify pixel colors indirectly, through the figure or axes colormap<\/li><\/ul><\/div><h4>Truecolor images<a name=\"29d6e72c-a5da-4e67-ae78-73da2af73bd5\"><\/a><\/h4><p>I'll start by constructing a simple image containing just six pixels: red, green, blue, cyan, magenta, and yellow.<\/p><pre class=\"codeinput\">plane_1 = [1 0 0; 0 1 1];\r\nplane_2 = [0 1 0; 1 0 1];\r\nplane_3 = [0 0 1; 1 1 0];\r\n\r\nrgb = cat(3,plane_1,plane_2,plane_3);\r\nim = imshow(rgb,<span class=\"string\">'InitialMagnification'<\/span>,<span class=\"string\">'fit'<\/span>);\r\ntitle(<span class=\"string\">'Truecolor image with six pixels'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/truecolor_indexed_images_01.png\" alt=\"\"> <p>So, what's going on here? Look first at the size of <tt>rgb<\/tt>:<\/p><pre class=\"codeinput\">size(rgb)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n     2     3     3\r\n\r\n<\/pre><p>The first two numbers in the size of <tt>rgb<\/tt> tell you the number of rows and columns of pixels. There are two rows and three columns.<\/p><p>The size of <tt>rgb<\/tt> along the third dimension is 3. That's because we are using 3 different values to specify a pixel color. Here are the three values for the magenta color, which is row 2, column 2:<\/p><pre class=\"codeinput\">rgb(2,2,:)\r\n<\/pre><pre class=\"codeoutput\">\r\nans(:,:,1) =\r\n\r\n     1\r\n\r\n\r\nans(:,:,2) =\r\n\r\n     0\r\n\r\n\r\nans(:,:,3) =\r\n\r\n     1\r\n\r\n<\/pre><p>The three numbers represent an additive mix of red, green and blue light. The value 1 corresponds to full-intensity light, whereas the value 0 corresponds to no light. So the magenta color above is a mix of full-intensity red light, no green light, and full-intensity blue light. Similarly, here are the three values for the yellow pixel:<\/p><pre class=\"codeinput\">rgb(2,3,:)\r\n<\/pre><pre class=\"codeoutput\">\r\nans(:,:,1) =\r\n\r\n     1\r\n\r\n\r\nans(:,:,2) =\r\n\r\n     1\r\n\r\n\r\nans(:,:,3) =\r\n\r\n     0\r\n\r\n<\/pre><p>The yellow color is a mix of no red light, full-intensity green light, and full-intensity blue light.<\/p><p>This type of image, in which each pixel color is represented by three values, is often called a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Color_depth#True_color_.2824-bit.29\"><i>truecolor<\/i> image<\/a>.<\/p><p>Now let's peek at the Graphics <tt>image<\/tt> object, which was returned above by the call to <tt>imshow<\/tt>:<\/p><pre class=\"codeinput\">im\r\n<\/pre><pre class=\"codeoutput\">\r\nim = \r\n\r\n  Image with properties:\r\n\r\n           CData: [2x3x3 double]\r\n    CDataMapping: 'direct'\r\n<\/pre><p>The object display shows the most commonly used properties of the <tt>image<\/tt> object, <tt>CData<\/tt> and <tt>CDataMapping<\/tt>. (I won't be talking further about <tt>CDataMapping<\/tt> today. We'll come back to it in one of the next couple of blog posts.)<\/p><p><tt>CData<\/tt>, which stands for <i>color data<\/i>, contains the 2-by-3-by-3 array we created above.<\/p><pre class=\"codeinput\">im.CData\r\n<\/pre><pre class=\"codeoutput\">\r\nans(:,:,1) =\r\n\r\n     1     0     0\r\n     0     1     1\r\n\r\n\r\nans(:,:,2) =\r\n\r\n     0     1     0\r\n     1     0     1\r\n\r\n\r\nans(:,:,3) =\r\n\r\n     0     0     1\r\n     1     1     0\r\n\r\n<\/pre><p>We can change the values in this property directly to change the image colors. For example, if we lower the green value of the pixel in the first row, second column from 1.0 to 0.5, we make a darker shade of green.<\/p><pre class=\"codeinput\">im.CData(1,2,2) = 0.5;\r\nsnapnow\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/truecolor_indexed_images_02.png\" alt=\"\"> <p>With truecolor images, changing the colormap has no effect on the image colors displayed.<\/p><pre class=\"codeinput\">colormap(hot)\r\ntitle(<span class=\"string\">'Changing the figure colormap does not affect the pixel colors'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/truecolor_indexed_images_03.png\" alt=\"\"> <h4>Indexed images<a name=\"959116fd-c4e3-4077-9f0e-7434b9d55ae7\"><\/a><\/h4><p>If the image <tt>CData<\/tt> is two-dimensional, then the <tt>CData<\/tt> values are treated as lookup indices into the axes or the figure colormap.  As an example, let's use an indexed image that ships with MATLAB, clown.mat (<a href=\"https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/140947-ned-gulley\">Ned's<\/a> favorite).<\/p><pre class=\"codeinput\">s = load(<span class=\"string\">'clown'<\/span>)  <span class=\"comment\">% This the functional form of load.  This form returns<\/span>\r\n                   <span class=\"comment\">% a structure whose fields are the variables stored<\/span>\r\n                   <span class=\"comment\">% in the MAT-file.<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\ns = \r\n\r\n          X: [200x320 double]\r\n        map: [81x3 double]\r\n    caption: [2x1 char]\r\n\r\n<\/pre><p>The <tt>X<\/tt> and <tt>map<\/tt> variables stored in clown.mat are both necessary to display the image correctly.  <tt>X<\/tt> contains the pixel values, and <tt>map<\/tt> contains the associated colormap.<\/p><p>To get the color of the (5,5) pixel, first see what <tt>X(5,5)<\/tt> is:<\/p><pre class=\"codeinput\">s.X(5,5)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n    61\r\n\r\n<\/pre><p>Then use that value as a row index into the colormap matrix, map:<\/p><pre class=\"codeinput\">s.map(61,:)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n    0.9961    0.5781    0.1250\r\n\r\n<\/pre><p>These are the same three color components (red, green, and blue) that are used for truecolor images. So the (5,5) pixel has a lot of red, some green, and a small amount of blue.<\/p><p>To display the image, pass both the <tt>CData<\/tt> and the colormap to <tt>imshow<\/tt>.<\/p><pre class=\"codeinput\">imshow(s.X,s.map)\r\ntitle(<span class=\"string\">'Indexed image'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/truecolor_indexed_images_04.png\" alt=\"\"> <p>Unlike truecolor images, indexed images are affected by changed in the figure's colormap.<\/p><pre class=\"codeinput\">colormap(cool)\r\ntitle(<span class=\"string\">'Indexed image displays incorrectly if you use the wrong colormap'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/truecolor_indexed_images_05.png\" alt=\"\"> <p>In my <a href=\"https:\/\/blogs.mathworks.com\/steve\/2016\/02\/09\/matlab-image-display-from-data-values-to-pixel-colors\/\">previous post<\/a>, I suggested that there might really be three pixel-color display models in MATLAB instead of two.  The third display model is a variation of the indexed image model.<\/p><p>I'll talk about that next time.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_9bf9bc5b00174fc3b105c71e2695a7ae() {\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='9bf9bc5b00174fc3b105c71e2695a7ae ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 9bf9bc5b00174fc3b105c71e2695a7ae';\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_9bf9bc5b00174fc3b105c71e2695a7ae()\"><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\n9bf9bc5b00174fc3b105c71e2695a7ae ##### SOURCE BEGIN #####\r\n\r\n%% MATLAB image display - truecolor and indexed images\r\n%\r\n% <https:\/\/blogs.mathworks.com\/steve\/2016\/02\/09\/matlab-image-display-from-data-values-to-pixel-colors\/\r\n% Last time> I posed this question: How does MATLAB associate the value of\r\n% particular array elements with a color displayed on the screen?  Let's\r\n% start by exploring MATLAB's two basic pixel-color display models:\r\n%\r\n% * 3-D array element values specify pixel colors directly\r\n% * 2-D matrix element values specify pixel colors indirectly, through the\r\n% figure or axes colormap\r\n\r\n%% Truecolor images\r\n% I'll start by constructing a simple image containing just six pixels:\r\n% red, green, blue, cyan, magenta, and yellow.\r\n\r\nplane_1 = [1 0 0; 0 1 1];\r\nplane_2 = [0 1 0; 1 0 1];\r\nplane_3 = [0 0 1; 1 1 0];\r\n\r\nrgb = cat(3,plane_1,plane_2,plane_3);\r\nim = imshow(rgb,'InitialMagnification','fit');\r\ntitle('Truecolor image with six pixels')\r\n\r\n%%\r\n% So, what's going on here? Look first at the size of |rgb|:\r\n\r\nsize(rgb)\r\n\r\n%%\r\n% The first two numbers in the size of |rgb| tell you the number of rows and\r\n% columns of pixels. There are two rows and three columns.\r\n%\r\n% The size of |rgb| along the third dimension is 3. That's because we are\r\n% using 3 different values to specify a pixel color. Here are the three\r\n% values for the magenta color, which is row 2, column 2:\r\n\r\nrgb(2,2,:)\r\n\r\n%%\r\n% The three numbers represent an additive mix of red, green and blue light.\r\n% The value 1 corresponds to full-intensity light, whereas the value 0\r\n% corresponds to no light. So the magenta color above is a mix of\r\n% full-intensity red light, no green light, and full-intensity blue light.\r\n% Similarly, here are the three values for the yellow pixel:\r\n\r\nrgb(2,3,:)\r\n\r\n%%\r\n% The yellow color is a mix of no red light, full-intensity green light, and\r\n% full-intensity blue light.\r\n\r\n%%\r\n% This type of image, in which each pixel color is represented by three\r\n% values, is often called a\r\n% <https:\/\/en.wikipedia.org\/wiki\/Color_depth#True_color_.2824-bit.29\r\n% _truecolor_ image>.\r\n\r\n%%\r\n% Now let's peek at the Graphics |image| object, which was returned above by\r\n% the call to |imshow|:\r\n\r\nim\r\n\r\n%%\r\n% The object display shows the most commonly used properties of the |image|\r\n% object, |CData| and |CDataMapping|. (I won't be talking further about \r\n% |CDataMapping| today. We'll come back to it in one of the next couple of\r\n% blog posts.)\r\n%\r\n% |CData|, which stands for _color data_, contains the 2-by-3-by-3 array we\r\n% created above.\r\n\r\nim.CData\r\n\r\n%%\r\n% We can change the values in this property directly to change the image\r\n% colors. For example, if we lower the green value of the pixel in the first\r\n% row, second column from 1.0 to 0.5, we make a darker shade of green.\r\n\r\nim.CData(1,2,2) = 0.5;\r\nsnapnow\r\n\r\n%%\r\n% With truecolor images, changing the colormap has no effect on the image\r\n% colors displayed.\r\n\r\ncolormap(hot)\r\ntitle('Changing the figure colormap does not affect the pixel colors')\r\n\r\n%% Indexed images\r\n% If the image |CData| is two-dimensional, then the |CData| values are\r\n% treated as lookup indices into the axes or the figure colormap.  As an\r\n% example, let's use an indexed image that ships with MATLAB, clown.mat\r\n% (<https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/140947-ned-gulley\r\n% Ned's> favorite).\r\n\r\ns = load('clown')  % This the functional form of load.  This form returns\r\n                   % a structure whose fields are the variables stored\r\n                   % in the MAT-file.\r\n\r\n%%\r\n% The |X| and |map| variables stored in clown.mat are both necessary to\r\n% display the image correctly.  |X| contains the pixel values, and |map|\r\n% contains the associated colormap.\r\n%\r\n% To get the color of the (5,5) pixel, first see what |X(5,5)| is:\r\n\r\ns.X(5,5)\r\n\r\n%%\r\n% Then use that value as a row index into the colormap matrix, map:\r\n\r\ns.map(61,:)\r\n\r\n%%\r\n% These are the same three color components (red, green, and blue) that are\r\n% used for truecolor images. So the (5,5) pixel has a lot of red, some\r\n% green, and a small amount of blue.\r\n%\r\n% To display the image, pass both the |CData| and the colormap to |imshow|.\r\n%\r\n\r\nimshow(s.X,s.map)\r\ntitle('Indexed image')\r\n\r\n%%\r\n% Unlike truecolor images, indexed images are affected by changed in the\r\n% figure's colormap.\r\n\r\ncolormap(cool)\r\ntitle('Indexed image displays incorrectly if you use the wrong colormap')\r\n\r\n%%\r\n% In my\r\n% <https:\/\/blogs.mathworks.com\/steve\/2016\/02\/09\/matlab-image-display-from-data-values-to-pixel-colors\/\r\n% previous post>, I suggested that there might really be three pixel-color\r\n% display models in MATLAB instead of two.  The third display model is a\r\n% variation of the indexed image model.\r\n%\r\n% I'll talk about that next time.\r\n\r\n##### SOURCE END ##### 9bf9bc5b00174fc3b105c71e2695a7ae\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/steve\/files\/truecolor_indexed_images_01.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>ContentsMATLAB image display - truecolor and indexed imagesTruecolor imagesIndexed imagesMATLAB image display - truecolor and indexed imagesLast time I posed this question: How does MATLAB associate... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2016\/02\/22\/matlab-image-display-truecolor-and-indexed-images\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":1594,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[13],"tags":[46,58,1151,1149,36,362,190,1147,52],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/1599"}],"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=1599"}],"version-history":[{"count":2,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/1599\/revisions"}],"predecessor-version":[{"id":1601,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/1599\/revisions\/1601"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media\/1594"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=1599"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=1599"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=1599"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}