{"id":3170,"date":"2019-03-17T22:55:30","date_gmt":"2019-03-18T02:55:30","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=3170"},"modified":"2019-11-01T22:36:11","modified_gmt":"2019-11-02T02:36:11","slug":"a-new-image-tiling-function-in-matlab","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2019\/03\/17\/a-new-image-tiling-function-in-matlab\/","title":{"rendered":"A new image tiling function in MATLAB"},"content":{"rendered":"<div class=\"content\"><p>I was noodling around recently with a future blog topic (multiresolution pyramids; stay tuned) when I was reminded of a recent addition to MATLAB: the function <tt>imtile<\/tt>, introduced in R2018b.<\/p><p>This function has an interesting design history. (Interesting to me, anyway.) The Image Processing Toolbox team has moved several functions into MATLAB over the past few years to support basic image processing workflows in products such as the Deep Learning Toolbox. Examples include <tt>imshow<\/tt>, <tt>imresize<\/tt>, and <tt>rgb2gray<\/tt>. For similar reasons, the team was acting on a request to move the <tt>montage<\/tt> function into MATLAB. This prompted a review of the function's design.<\/p><p>And, well, we weren't convinced that the <tt>montage<\/tt> function was what we really wanted to put into MATLAB.<\/p><p>This function is one of the oldest functions in the toolbox, dating back to the initial version 1.0 release in 1993. It's been steadily tinkered with over all those years, but the function we have today still isn't meeting everyone's needs. It is also a little confused about whether it is primarily a display function or a computation function. It tries to do both, but using it as a computation function is awkward.<\/p><p>So, the team took a fresh look at all the sources of feedback we have about <tt>montage<\/tt>. For example, there are a lot of questions and discussions about <tt>montage<\/tt> on MATLAB Answers. The team wrote internal design documents summarizing the feedback.<\/p><p>As I reread those documents to prepare this post, I thought that two pains associated with <tt>montage<\/tt> particularly stood out. The first pain is that, as I mentioned above, it is awkward to get the tiled image that <tt>montage<\/tt> creates because <tt>montage<\/tt> doesn't return it directly as an output argument. Instead, you have to get the <tt>CData<\/tt> property of the image object that <tt>montage<\/tt> displays on the screen.<\/p><p>The second pain is that it's very difficult to achieve adequate control over the resolution of the tiled image, especially when the tiled image has more pixels than the display.<\/p><p>Following this analysis, the toolbox team recommended a new function, <tt>imtile<\/tt>, that would act purely as a computation function. It creates and returns a new array of pixels, using exactly the original image pixels - The new function does not display anything. If you want to write a script that tiles images and writes the result to a file, with no intermediate result appearing on the screen, you can easily do it with <tt>imtile<\/tt>. If you want to display the tiled result, use <tt>imshow<\/tt>.<\/p><p>Here is a little snippet of code that creates a tiled image out of the three color components of the peppers.png image. The code specifies the size of the border to be used between the tiles, the background color between the tiles, and the size of the tile grid. Then the code displays the tiled image using <tt>imshow<\/tt>.<\/p><pre class=\"codeinput\">rgb = imread(<span class=\"string\">'peppers.png'<\/span>);\r\ntiled_components = imtile(rgb,<span class=\"string\">'BorderSize'<\/span>,20,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'BackgroundColor'<\/span>,[72 162 63]\/255,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'GridSize'<\/span>,[1 3]);\r\nimshow(tiled_components)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/image_tiling_01.png\" alt=\"\"> <p>The array returned by <tt>imtile<\/tt> can be written directly out to an image file.<\/p><pre class=\"codeinput\">imwrite(tiled_components,<span class=\"string\">'tiled_components.png'<\/span>)\r\n<\/pre><p>I hope you find that the new function is a useful addition to MATLAB.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_59041b013aa84b1398b4f785d059824b() {\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='59041b013aa84b1398b4f785d059824b ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 59041b013aa84b1398b4f785d059824b';\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_59041b013aa84b1398b4f785d059824b()\"><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; R2018b<br><\/p><\/div><!--\r\n59041b013aa84b1398b4f785d059824b ##### SOURCE BEGIN #####\r\n%%\r\n% I was noodling around recently with a future blog topic (multiresolution\r\n% pyramids; stay tuned) when I was reminded of a recent addition to MATLAB:\r\n% the function |imtile|, introduced in R2018b.\r\n%\r\n% This function has an interesting design history. (Interesting to me,\r\n% anyway.) The Image Processing Toolbox team has moved several functions\r\n% into MATLAB over the past few years to support basic image processing\r\n% workflows in products such as the Deep Learning Toolbox. Examples include\r\n% |imshow|, |imresize|, and |rgb2gray|. For similar reasons, the team was\r\n% acting on a request to move the |montage| function into MATLAB. This\r\n% prompted a review of the function's design.\r\n%\r\n% And, well, we weren't convinced that the |montage| function was what we\r\n% really wanted to put into MATLAB.\r\n%\r\n% This function is one of the oldest functions in the toolbox, dating back\r\n% to the initial version 1.0 release in 1993. It's been steadily tinkered\r\n% with over all those years, but the function we have today still isn't\r\n% meeting everyone's needs. It is also a little confused about whether it\r\n% is primarily a display function or a computation function. It tries to do\r\n% both, but using it as a computation function is awkward.\r\n%\r\n% So, the team took a fresh look at all the sources of feedback we have\r\n% about |montage|. For example, there are a lot of questions and\r\n% discussions about |montage| on MATLAB Answers. The team wrote internal\r\n% design documents summarizing the feedback.\r\n%\r\n% As I reread those documents to prepare this post, I thought that two\r\n% pains associated with |montage| particularly stood out. The first pain is\r\n% that, as I mentioned above, it is awkward to get the tiled image that\r\n% |montage| creates because |montage| doesn't return it directly as an\r\n% output argument. Instead, you have to get the |CData| property of the\r\n% image object that |montage| displays on the screen.\r\n%\r\n% The second pain is that it's very difficult to achieve adequate control\r\n% over the resolution of the tiled image, especially when the tiled image\r\n% has more pixels than the display.\r\n%\r\n% Following this analysis, the toolbox team recommended a new function,\r\n% |imtile|, that would act purely as a computation function. It creates and\r\n% returns a new array of pixels, using exactly the original image pixels -\r\n% The new function does not display anything. If you\r\n% want to write a script that tiles images and writes the result to a file,\r\n% with no intermediate result appearing on the screen, you can easily do it\r\n% with |imtile|. If you want to display the tiled result, use |imshow|.\r\n%\r\n% Here is a little snippet of code that creates a tiled image out of the\r\n% three color components of the peppers.png image. The code specifies the\r\n% size of the border to be used between the tiles, the background color\r\n% between the tiles, and the size of the tile grid. Then the code displays\r\n% the tiled image using |imshow|.\r\n\r\nrgb = imread('peppers.png');\r\ntiled_components = imtile(rgb,'BorderSize',20,...\r\n    'BackgroundColor',[72 162 63]\/255,...\r\n    'GridSize',[1 3]);\r\nimshow(tiled_components)\r\n\r\n%%\r\n% The array returned by |imtile| can be written directly out to an image\r\n% file.\r\n\r\nimwrite(tiled_components,'tiled_components.png')\r\n\r\n%%\r\n% I hope you find that the new function is a useful addition to MATLAB.\r\n##### SOURCE END ##### 59041b013aa84b1398b4f785d059824b\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/steve\/files\/image_tiling_01.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>I was noodling around recently with a future blog topic (multiresolution pyramids; stay tuned) when I was reminded of a recent addition to MATLAB: the function imtile, introduced in R2018b.This... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2019\/03\/17\/a-new-image-tiling-function-in-matlab\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":3174,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[76,36,1235,164],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/3170"}],"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=3170"}],"version-history":[{"count":2,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/3170\/revisions"}],"predecessor-version":[{"id":3178,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/3170\/revisions\/3178"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media\/3174"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=3170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=3170"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=3170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}