{"id":3400,"date":"2019-08-30T16:08:16","date_gmt":"2019-08-30T20:08:16","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=3400"},"modified":"2019-11-01T22:47:03","modified_gmt":"2019-11-02T02:47:03","slug":"using-reshape-to-rearrange-image-color-components","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2019\/08\/30\/using-reshape-to-rearrange-image-color-components\/","title":{"rendered":"Using reshape to rearrange image color components"},"content":{"rendered":"<div class=\"content\"><p>I recently saw some code that transformed the RGB pixel values of an image into a Px3 matrix, such that each row contained the red, green, and blue color components of a single pixel. Today I want to show that code fragment, explain it, and then demonstrate what I think is the fastest possible to perform that transformation in MATLAB.<\/p><p>I tend to use the peppers sample image a lot, so I'll switch things up and use NGC6543 instead:<\/p><pre class=\"codeinput\">RGB = imread(<span class=\"string\">'ngc6543a.jpg'<\/span>);\r\nimshow(RGB)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/reshaping_rgb_images_01.png\" alt=\"\"> <p>Historical note: This was the first \"truecolor\" sample image to ship with MATLAB.<\/p><p><tt>RGB<\/tt> is a three-dimensional array:<\/p><pre class=\"codeinput\">size(RGB)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n   650   600     3\r\n\r\n<\/pre><p>The third dimension, which has length three, contains the red, green, and blue component images. Compare, for example, the red and green component images:<\/p><pre class=\"codeinput\">imshow(RGB(:,:,1))\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/reshaping_rgb_images_02.png\" alt=\"\"> <pre class=\"codeinput\">imshow(RGB(:,:,2))\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/reshaping_rgb_images_03.png\" alt=\"\"> <p>Here is the code that I saw for transforming this array into a Px3 matrix, where each row contains the three color component values of one pixel:<\/p><pre class=\"codeinput\">red = RGB(:,:,1);\r\ngreen = RGB(:,:,2);\r\nblue = RGB(:,:,3);\r\n\r\nA = [red(:) green(:) blue(:)];\r\n<\/pre><p>The first five pixels are along the uppermost left edge of the image, and they are all black:<\/p><pre class=\"codeinput\">A(1:5,:)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n  5&times;3 uint8 matrix\r\n\r\n   0   0   0\r\n   0   0   0\r\n   0   0   0\r\n   0   0   0\r\n   0   0   0\r\n\r\n<\/pre><p>The first three lines of code did not give me pause:<\/p><pre>red = RGB(:,:,1);\r\ngreen = RGB(:,:,2);\r\nblue = RGB(:,:,3);<\/pre><p>I have written code just like that approximately 2.7183 bazillion times. It was the next line that made me stop and scratch my head for a moment:<\/p><pre>A = [red(:) green(:) blue(:)];<\/pre><p>Hmm. The array is being split apart into three components, which are then immediately put back together into a matrix. That suggests ... <tt>reshape<\/tt>, maybe?<\/p><p>Yes, as it turns out, this can all be done with a call to <tt>reshape<\/tt>. And, there is a big advantage to doing so, as I'll explain in a moment. First, the new code:<\/p><pre class=\"codeinput\">B = reshape(RGB,[],3);\r\n<\/pre><p>That line of code says, \"MATLAB, reshape the array <tt>RGB<\/tt> so that it is Px3, and will you please just go ahead and figure out what P should be to make it work?\"<\/p><p>You see in a call to <tt>reshape<\/tt>, the number of elements must not change. Here are the number of elements of the array <tt>RGB<\/tt>:<\/p><pre class=\"codeinput\">numel(RGB)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n     1170000\r\n\r\n<\/pre><p>To reshape that successfully into a matrix with 3 columns, we can compute how many rows there must be:<\/p><pre class=\"codeinput\">P = numel(RGB) \/ 3\r\n<\/pre><pre class=\"codeoutput\">\r\nP =\r\n\r\n      390000\r\n\r\n<\/pre><p>The empty matrix as the second argument to <tt>reshape<\/tt> signals to MATLAB to compute that size automatically. That works out just fine:<\/p><pre class=\"codeinput\">size(B)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n      390000           3\r\n\r\n<\/pre><p>So, each column of <tt>B<\/tt> has 390,000 elements. The first column of <tt>B<\/tt> contains the first 390,000 elements (in memory order) of <tt>RGB<\/tt>. The second column of <tt>B<\/tt> contains the second 390,000 elements of <tt>RGB<\/tt>, and similarly for the third column. Because of the way MATLAB arrangements elements in memory, these columns are exactly the elements from the red component, the green component, and the blue component of <tt>RGB<\/tt>.<\/p><p>The big advantage of doing it this way is that MATLAB makes no memory copy of data when calling <tt>reshape<\/tt>. Because of this optimization, calls to <tt>reshape<\/tt> are almost instantaneous.<\/p><p>Let <tt>reshape<\/tt> be your friend.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_6dbcd25ce12844ac853eeef233490dd9() {\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='6dbcd25ce12844ac853eeef233490dd9 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 6dbcd25ce12844ac853eeef233490dd9';\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 2019 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_6dbcd25ce12844ac853eeef233490dd9()\"><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; R2019a<br><\/p><\/div><!--\r\n6dbcd25ce12844ac853eeef233490dd9 ##### SOURCE BEGIN #####\r\n%%\r\n% I recently saw some code that transformed the RGB pixel values of an\r\n% image into a Px3 matrix, such that each row contained the red, green, and\r\n% blue color components of a single pixel. Today I want to show that code\r\n% fragment, explain it, and then demonstrate what I think is the fastest\r\n% possible to perform that transformation in MATLAB.\r\n%\r\n% I tend to use the peppers sample image a lot, so I'll switch things up\r\n% and use NGC6543 instead:\r\n\r\nRGB = imread('ngc6543a.jpg');\r\nimshow(RGB)\r\n\r\n%%\r\n% Historical note: This was the first \"truecolor\" sample image to ship with\r\n% MATLAB.\r\n%\r\n% |RGB| is a three-dimensional array:\r\n\r\nsize(RGB)\r\n\r\n%%\r\n% The third dimension, which has length three, contains the red, green, and\r\n% blue component images. Compare, for example, the red and green component\r\n% images:\r\n\r\nimshow(RGB(:,:,1))\r\n\r\n%%\r\n\r\nimshow(RGB(:,:,2))\r\n\r\n%%\r\n% Here is the code that I saw for transforming this array into a Px3\r\n% matrix, where each row contains the three color component values of one\r\n% pixel:\r\n\r\nred = RGB(:,:,1);\r\ngreen = RGB(:,:,2);\r\nblue = RGB(:,:,3);\r\n\r\nA = [red(:) green(:) blue(:)];\r\n\r\n%%\r\n% The first five pixels are along the uppermost left edge of the image, and\r\n% they are all black:\r\n\r\nA(1:5,:)\r\n\r\n%%\r\n% The first three lines of code did not give me pause:\r\n%\r\n%  red = RGB(:,:,1);\r\n%  green = RGB(:,:,2);\r\n%  blue = RGB(:,:,3);\r\n%\r\n% I have written code just like that approximately 2.7183 bazillion times.\r\n% It was the next line that made me stop and scratch my head for a moment:\r\n%\r\n%  A = [red(:) green(:) blue(:)];\r\n%\r\n% Hmm. The array is being split apart into three components, which are then\r\n% immediately put back together into a matrix. That suggests ... |reshape|,\r\n% maybe?\r\n%\r\n% Yes, as it turns out, this can all be done with a call to |reshape|. And,\r\n% there is a big advantage to doing so, as I'll explain in a moment. First,\r\n% the new code:\r\n\r\nB = reshape(RGB,[],3);\r\n\r\n%%\r\n% That line of code says, \"MATLAB, reshape the array |RGB| so that it is\r\n% Px3, and will you please just go ahead and figure out what P should be to\r\n% make it work?\"\r\n%\r\n% You see in a call to |reshape|, the number of elements must not change.\r\n% Here are the number of elements of the array |RGB|:\r\n\r\nnumel(RGB)\r\n\r\n%%\r\n% To reshape that successfully into a matrix with 3 columns, we can compute\r\n% how many rows there must be:\r\n\r\nP = numel(RGB) \/ 3\r\n\r\n%%\r\n% The empty matrix as the second argument to |reshape| signals to MATLAB to\r\n% compute that size automatically. That works out just fine:\r\n\r\nsize(B)\r\n\r\n%%\r\n% So, each column of |B| has 390,000 elements. The first column of |B|\r\n% contains the first 390,000 elements (in memory order) of |RGB|. The\r\n% second column of |B| contains the second 390,000 elements of |RGB|, and\r\n% similarly for the third column. Because of the way MATLAB arrangements\r\n% elements in memory, these columns are exactly the elements from the red\r\n% component, the green component, and the blue component of |RGB|.\r\n%\r\n% The big advantage of doing it this way is that MATLAB makes no memory\r\n% copy of data when calling |reshape|. Because of this optimization, calls\r\n% to |reshape| are almost instantaneous.\r\n%\r\n% Let |reshape| be your friend.\r\n\r\n##### SOURCE END ##### 6dbcd25ce12844ac853eeef233490dd9\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/steve\/files\/reshaping_rgb_images_01.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>I recently saw some code that transformed the RGB pixel values of an image into a Px3 matrix, such that each row contained the red, green, and blue color components of a single pixel. Today I want to... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2019\/08\/30\/using-reshape-to-rearrange-image-color-components\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":3402,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[76,36,162,170,190],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/3400"}],"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=3400"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/3400\/revisions"}],"predecessor-version":[{"id":3408,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/3400\/revisions\/3408"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media\/3402"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=3400"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=3400"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=3400"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}