{"id":384,"date":"2011-08-05T07:00:22","date_gmt":"2011-08-05T11:00:22","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/2011\/08\/05\/dealing-with-really-big-images-viewing\/"},"modified":"2019-10-29T16:51:03","modified_gmt":"2019-10-29T20:51:03","slug":"dealing-with-really-big-images-viewing","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2011\/08\/05\/dealing-with-really-big-images-viewing\/","title":{"rendered":"Dealing with &#8220;Really Big&#8221; Images: Viewing"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <introduction>\r\n      <p><i>I'd like to welcome guest blogger <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/15472\">Brendan Hannigan<\/a>, a MathWorks developer who worked on improving our set of large-image tools over the course of several releases.<\/i><\/p>\r\n   <\/introduction>\r\n   <h3>Contents<\/h3>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"#5\">\"I can't even LOOK AT my image!\"<\/a><\/li>\r\n         <li><a href=\"#10\">\"That's cute, but I need to see my ACTUAL image, not some decimated imposter!\"<\/a><\/li>\r\n         <li><a href=\"#17\">\"Ok yea that's not bad, but I need to do more than just view the data!\"<\/a><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p>I want to thank Steve for letting me guest blog about some recent work we did to help our large data users work with their\r\n      imagery in MATLAB using the Image Processing Toolbox.\r\n   <\/p>\r\n   <p>Several releases ago, we had been hearing from customers that they had \"really big\" images that they couldn't work with because\r\n      they were too large to load into memory.  How big are these images?  \"<em>VERY<\/em> big\", they assured us.  They couldn't even LOOK\r\n      at them, much less operate on them in MATLAB!  They could do nothing!  They were very frustrated.  Well, over the never several\r\n      releases we worked hard to provide better tools to help these customers out.\r\n   <\/p>\r\n   <p>Over the next few weeks I'll discuss a series of (relatively) new features that have taken these users from hitting Out of\r\n      Memory errors at every turn, to being able to visually explore their large imagery in a smooth, interactive tool, to being\r\n      able to process their images incrementally from disc, all while working with arbitrarily large images of arbitrary file format!\r\n       A much improved workflow!\r\n   <\/p>\r\n   <p>For this example we'll be working with a (relatively) large TIFF file that ships with the Mapping Toolbox, <tt>boston.tif<\/tt>.  This file is only about 37 MB in memory, so not problematic in itself, but the tools I discuss here will scale to any size\r\n      image.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">tiff_filename = <span style=\"color: #A020F0\">'boston.tif'<\/span>;\r\nimfinfo(tiff_filename)<\/pre><pre style=\"font-style:oblique\">\r\nans = \r\n\r\n                     Filename: 'C:\\MATLABs\\R2011a\\toolbox\\map\\mapdemos\\boston.tif'\r\n                  FileModDate: '04-Jun-2007 17:12:10'\r\n                     FileSize: 38729900\r\n                       Format: 'tif'\r\n                FormatVersion: []\r\n                        Width: 4481\r\n                       Height: 2881\r\n                     BitDepth: 24\r\n                    ColorType: 'truecolor'\r\n              FormatSignature: [77 77 0 42]\r\n                    ByteOrder: 'big-endian'\r\n               NewSubFileType: 0\r\n                BitsPerSample: [8 8 8]\r\n                  Compression: 'Uncompressed'\r\n    PhotometricInterpretation: 'RGB'\r\n                 StripOffsets: [12x1 double]\r\n              SamplesPerPixel: 3\r\n                 RowsPerStrip: 256\r\n              StripByteCounts: [12x1 double]\r\n                  XResolution: 300\r\n                  YResolution: 300\r\n               ResolutionUnit: 'Inch'\r\n                     Colormap: []\r\n          PlanarConfiguration: 'Chunky'\r\n                    TileWidth: []\r\n                   TileLength: []\r\n                  TileOffsets: []\r\n               TileByteCounts: []\r\n                  Orientation: 1\r\n                    FillOrder: 1\r\n             GrayResponseUnit: 0.0100\r\n               MaxSampleValue: [255 255 255]\r\n               MinSampleValue: [1 1 1]\r\n                 Thresholding: 1\r\n                       Offset: 38729291\r\n             ImageDescription: '\"GeoEye\"'\r\n                     DateTime: '2007:02:23 21:46:13'\r\n                    Copyright: '\"(c) GeoEye\"'\r\n           ModelPixelScaleTag: [3x1 double]\r\n             ModelTiepointTag: [6x1 double]\r\n           GeoKeyDirectoryTag: [24x1 double]\r\n            GeoAsciiParamsTag: 'State Plane Zone 2001 NAD = 83|'\r\n\r\n<\/pre><h3>\"I can't even LOOK AT my image!\"<a name=\"5\"><\/a><\/h3>\r\n   <p>Our first foray into large data viewing was simply producing an \"overview\" style image.  If your image is too large to load\r\n      into memory then it is not possible to view it using <tt>imshow<\/tt> with any of the standard syntaxes.  Before committing the time and resources necessary work with a large image (moving it,\r\n      copying it, converting to a different format, etc) users just want to do a \"sanity\" check on the data.\r\n   <\/p>\r\n   <p>To help them accomplish this task we provided (in release R2008a) a very simple option to the <tt>imshow<\/tt> function, the <tt>'Reduce'<\/tt> parameter.  When set to true, <tt>imshow<\/tt> will subsample a large TIFF file and display a reduced version of that image. The subsampling ratio is based on your reported\r\n      screen resolution.\r\n   <\/p>\r\n   <p>This parameter is only valid for TIFF images.  We started with the TIFF format in the beginning because MATLAB has excellent\r\n      support for incremental reading and writing of TIFF images using the <tt>Tiff<\/tt> class. We recognize that most users will not be working exclusively with TIFF imagery and will want to view files in other\r\n      formats as well.\r\n   <\/p>\r\n   <p>Now... I don't want to scoop my subsequent blog posts too much, but let's just say we hope that we have sufficiently \"adapted\"\r\n      (&lt;== hint) to these customers' needs.\r\n   <\/p>\r\n   <p>Let's view a reduced version of our image.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">imshow(tiff_filename,<span style=\"color: #A020F0\">'Reduce'<\/span>,true,<span style=\"color: #A020F0\">'InitialMagnification'<\/span>,<span style=\"color: #A020F0\">'fit'<\/span>);<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2011\/blockproc_1_01.jpg\"> <p>You'll notice that if you zoom in using the figure zoom tool that you will not see higher resolution imagery.  Here's a closer\r\n      look at Fenway Park.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\"><span style=\"color: #228B22\">% Simulate interactive zoom<\/span>\r\nxlim([44 390])\r\nylim([2638 2858])<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2011\/blockproc_1_02.jpg\"> <p>It's clear here that you are actually viewing a reduced-resolution version of the original image.  This <tt>'Reduce'<\/tt> parameter is intended for users who just want to get a \"quick &amp; dirty\" overview of a large TIFF image, and is not appropriate\r\n      for seeing details in large images.\r\n   <\/p>\r\n   <h3>\"That's cute, but I need to see my ACTUAL image, not some decimated imposter!\"<a name=\"10\"><\/a><\/h3>\r\n   <p>Next we wanted to provide some \"real\", industrial strength large image viewing tool.  To provide the best interactive viewing\r\n      experience possible, we must create a multiresolution version of large images so that we can pull in pixels from the appropriate\r\n      zoom-level as you pan and zoom through the data set.\r\n   <\/p>\r\n   <p>Most users will be familiar with this behavior; it's very similar to how online mapping tools work.  As you navigate around\r\n      online maps, you will see tiles of data at discrete zoom levels (resolutions) being assembled to make up the current map view.\r\n   <\/p>\r\n   <p>To provide this feature we delivered a new function (in release R2009a), <tt>rsetwrite<\/tt>, which allows you to create a reduced resolution data set (R-Set) from a large TIFF or NITF file. Creating the R-Set can\r\n      take some time depending on the size of the image, but it is a one-time, up front cost.\r\n   <\/p>\r\n   <p>To create an R-Set, the syntax is very straightforward.  Let's build an R-Set from our large <tt>boston.tif<\/tt> image.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">rset_filename = <span style=\"color: #A020F0\">'boston.rset'<\/span>;\r\nrsetwrite(tiff_filename,rset_filename);<\/pre><p>Now that you have your R-Set file, you can simply view it using the Image Tool as you would any other supported image file:<\/p><pre>   imtool(rset_filename)<\/pre><p>Here's a screenshot:<\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2011\/blockproc_1_imtool_screenshot_1.jpg\"> <\/p>\r\n   <p>Using the Image Tool's pan &amp; zoom tools you can now zoom into Fenway Park and see that, using the R-Set, we are now displaying\r\n      the full resolution image data.\r\n   <\/p>\r\n   <p>Here's another screenshot:<\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2011\/blockproc_1_imtool_screenshot_2.jpg\"> <\/p>\r\n   <p>With R-Sets, you can zoom and pan around images of ANY SIZE, and the Image Tool will pull in only the data that it needs.\r\n       Navigation of large imagery has never looked so good!\r\n   <\/p>\r\n   <h3>\"Ok yea that's not bad, but I need to do more than just view the data!\"<a name=\"17\"><\/a><\/h3>\r\n   <p>There are still many issues that I have not covered here such as, \"I need to do more than just view my images\", and \"I'm not\r\n      using TIFF or NITF files, what now?\".  These are excellent questions that I'll discuss next time.  Stay Tuned!\r\n   <\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_be3b38edbe704087b1ace74028c6a550() {\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='be3b38edbe704087b1ace74028c6a550 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' be3b38edbe704087b1ace74028c6a550';\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 2011 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-->\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_be3b38edbe704087b1ace74028c6a550()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n            the MATLAB code \r\n            <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; 7.12<br><\/p>\r\n<\/div>\r\n<!--\r\nbe3b38edbe704087b1ace74028c6a550 ##### SOURCE BEGIN #####\r\n%%\r\n% _I'd like to welcome guest blogger\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/15472\r\n% Brendan Hannigan>, a MathWorks developer who worked on improving our set\r\n% of large-image tools over the course of several releases._\r\n\r\n%% \r\n% I want to thank Steve for letting me guest blog about some recent work we\r\n% did to help our large data users work with their imagery in MATLAB using\r\n% the Image Processing Toolbox.\r\n\r\n%%\r\n% Several releases ago, we had been hearing from customers that they had\r\n% \"really big\" images that they couldn't work with because they were too\r\n% large to load into memory.  How big are these images?  \"_VERY_ big\", they\r\n% assured us.  They couldn't even LOOK at them, much less operate on them\r\n% in MATLAB!  They could do nothing!  They were very frustrated.  Well,\r\n% over the never several releases we worked hard to provide better tools to\r\n% help these customers out.\r\n\r\n%% \r\n% Over the next few weeks I'll discuss a series of (relatively) new\r\n% features that have taken these users from hitting Out of Memory errors at\r\n% every turn, to being able to visually explore their large imagery in a\r\n% smooth, interactive tool, to being able to process their images\r\n% incrementally from disc, all while working with arbitrarily large images\r\n% of arbitrary file format!  A much improved workflow!\r\n\r\n%%\r\n% For this example we'll be working with a (relatively) large TIFF file\r\n% that ships with the Mapping Toolbox, |boston.tif|.  This file is only\r\n% about 37 MB in memory, so not problematic in itself, but the tools I\r\n% discuss here will scale to any size image.\r\n\r\ntiff_filename = 'boston.tif';\r\nimfinfo(tiff_filename)\r\n\r\n\r\n%% \"I can't even LOOK AT my image!\"\r\n% Our first foray into large data viewing was simply producing an\r\n% \"overview\" style image.  If your image is too large to load into memory\r\n% then it is not possible to view it using |imshow| with any of the\r\n% standard syntaxes.  Before committing the time and resources necessary\r\n% work with a large image (moving it, copying it, converting to a different\r\n% format, etc) users just want to do a \"sanity\" check on the data.\r\n%\r\n% To help them accomplish this task we provided (in release R2008a) a very\r\n% simple option to the |imshow| function, the |'Reduce'| parameter.  When\r\n% set to true, |imshow| will subsample a large TIFF file and display a\r\n% reduced version of that image. The subsampling ratio is based on your\r\n% reported screen resolution.\r\n\r\n%%\r\n% This parameter is only valid for TIFF images.  We started with the TIFF\r\n% format in the beginning because MATLAB has excellent support for\r\n% incremental reading and writing of TIFF images using the |Tiff| class. We\r\n% recognize that most users will not be working exclusively with TIFF\r\n% imagery and will want to view files in other formats as well.\r\n%\r\n% Now... I don't want to scoop my subsequent blog posts too much, but let's\r\n% just say we hope that we have sufficiently \"adapted\" (<== hint) to these\r\n% customers' needs.\r\n\r\n%%\r\n% Let's view a reduced version of our image.\r\n\r\nimshow(tiff_filename,'Reduce',true,'InitialMagnification','fit');\r\n\r\n%%\r\n% You'll notice that if you zoom in using the figure zoom tool that you\r\n% will not see higher resolution imagery.  Here's a closer look at Fenway\r\n% Park.\r\n\r\n% Simulate interactive zoom\r\nxlim([44 390])\r\nylim([2638 2858])\r\n\r\n%%\r\n% It's clear here that you are actually viewing a reduced-resolution\r\n% version of the original image.  This |'Reduce'| parameter is intended for\r\n% users who just want to get a \"quick & dirty\" overview of a large TIFF\r\n% image, and is not appropriate for seeing details in large images.\r\n\r\n%% \"That's cute, but I need to see my ACTUAL image, not some decimated imposter!\"\r\n% Next we wanted to provide some \"real\", industrial strength large image\r\n% viewing tool.  To provide the best interactive viewing experience\r\n% possible, we must create a multiresolution version of large images so\r\n% that we can pull in pixels from the appropriate zoom-level as you pan and\r\n% zoom through the data set.\r\n\r\n%%\r\n% Most users will be familiar with this behavior; it's very similar to how\r\n% online mapping tools work.  As you navigate around online maps, you will\r\n% see tiles of data at discrete zoom levels (resolutions) being assembled\r\n% to make up the current map view.\r\n\r\n%%\r\n% To provide this feature we delivered a new function (in release R2009a),\r\n% |rsetwrite|, which allows you to create a reduced resolution data set\r\n% (R-Set) from a large TIFF or NITF file. Creating the R-Set can take some\r\n% time depending on the size of the image, but it is a one-time, up front\r\n% cost.\r\n\r\n%%\r\n% To create an R-Set, the syntax is very straightforward.  Let's build an\r\n% R-Set from our large |boston.tif| image.\r\n\r\nrset_filename = 'boston.rset';\r\nrsetwrite(tiff_filename,rset_filename);\r\n\r\n%%\r\n% Now that you have your R-Set file, you can simply view it using the Image\r\n% Tool as you would any other supported image file:\r\n%\r\n%     imtool(rset_filename)\r\n%\r\n% Here's a screenshot:\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/images\/steve\/2011\/blockproc_1_imtool_screenshot_1.jpg>>\r\n\r\n%%\r\n% Using the Image Tool's pan & zoom tools you can now zoom into Fenway Park\r\n% and see that, using the R-Set, we are now displaying the full resolution\r\n% image data.\r\n%\r\n% Here's another screenshot:\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/images\/steve\/2011\/blockproc_1_imtool_screenshot_2.jpg>>\r\n\r\n%%\r\n% With R-Sets, you can zoom and pan around images of ANY SIZE, and the\r\n% Image Tool will pull in only the data that it needs.  Navigation of large\r\n% imagery has never looked so good!\r\n\r\n%% \"Ok yea that's not bad, but I need to do more than just view the data!\"\r\n% There are still many issues that I have not covered here such as, \"I need\r\n% to do more than just view my images\", and \"I'm not using TIFF or NITF\r\n% files, what now?\".  These are excellent questions that I'll discuss next\r\n% time.  Stay Tuned!\r\n\r\n\r\n##### SOURCE END ##### be3b38edbe704087b1ace74028c6a550\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   \r\n      I'd like to welcome guest blogger Brendan Hannigan, a MathWorks developer who worked on improving our set of large-image tools over the course of several releases.\r\n   \r\n   Contents\r\n  ... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2011\/08\/05\/dealing-with-really-big-images-viewing\/\">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":[332,36,180,665,360,298],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/384"}],"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=384"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/384\/revisions"}],"predecessor-version":[{"id":3749,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/384\/revisions\/3749"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=384"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=384"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=384"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}