{"id":262,"date":"2009-05-29T07:00:09","date_gmt":"2009-05-29T11:00:09","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/2009\/05\/29\/continental-divide-6-watershed\/"},"modified":"2019-10-28T15:35:12","modified_gmt":"2019-10-28T19:35:12","slug":"continental-divide-6-watershed","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2009\/05\/29\/continental-divide-6-watershed\/","title":{"rendered":"Locating the US continental divide, part 6 &#8211; Final computation and visualization"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p>Today's post in my <a href=\"https:\/\/blogs.mathworks.com\/steve\/category\/continental-divide\/\">continental divide series<\/a> demonstrates the final computational step and shows one procedure for visualizing the Pacific and Atlantic catchment basins.\r\n   <\/p>\r\n   <p>In my previous post, I modified the DEM (digital elevation model) data set so that its only regional minima were the two oceans.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">s = load(<span style=\"color: #A020F0\">'continental_divide'<\/span>);\r\ndem_modified = s.dem_modified;\r\nimshow(dem_modified, [-500 3000], <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\/2009\/continental_divide_part_6_01.jpg\"> <p>Since the modified DEM has only two regional minima, we expect to get only two catchment basins when we compute the watershed\r\n      transform.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">L = watershed(dem_modified);\r\nmax(L(:))<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n     2\r\n\r\n<\/pre><p>I'll use <tt>label2rgb<\/tt> to display the Pacific catchment basin in green, the Atlantic catchment basin in blue, and the watershed ridge pixels (the\r\n      continental divide) in red.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">pacific = [0.2 1 0.2];\r\natlantic = [0.3 0.3 1];\r\nridge = [1 0 0];\r\nrgb = label2rgb(L, [pacific; atlantic], ridge);\r\nimshow(rgb, <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\/2009\/continental_divide_part_6_02.jpg\"> <p>In a <a href=\"https:\/\/blogs.mathworks.com\/steve\/2009\/02\/18\/image-overlay-using-transparency\/\">February blog post<\/a>, I showed how to overlay one image transparently over another.  We can use that technique here to achieve an effect similar\r\n      to the visualization that Brian Hayes used in his <a href=\"http:\/\/bit-player.org\/2009\/long-division\">blog post on the continental divide<\/a>, where the ocean catchment basins are shown shaded with two different colors.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">imshow(dem, [-500 3000], <span style=\"color: #A020F0\">'InitialMagnification'<\/span>, <span style=\"color: #A020F0\">'fit'<\/span>)\r\nhold <span style=\"color: #A020F0\">on<\/span>\r\nh = imshow(rgb);\r\nset(h, <span style=\"color: #A020F0\">'AlphaData'<\/span>, 0.2);<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/continental_divide_part_6_03.jpg\"> <p>It would be nice if we could make the watershed ridge line itself more visible.  For example, if we could use <tt>plot<\/tt>, then we could use a thick line. But right now we just have the ridge line represented as zero-valued elements of a raster,\r\n      instead of the x and y vectors we would need to pass to <tt>plot<\/tt>.  We could use <tt>find<\/tt> to get the coordinates of the ridge pixels, but we wouldn't get them in the right order.  One solution is to use <tt>bwboundaries<\/tt> to \"trace\" the zero-valued ridge pixels.  Note that I specify 4-connectivity in the call to <tt>bwboundaries<\/tt> below. I've found that I get better results using 4-connectivity when tracing a single-pixel-wide stroke that's not a closed\r\n      loop.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">b = bwboundaries(L == 0, 4);\r\nb1 = b{1};  <span style=\"color: #228B22\">% There's only 1 boundary found here - the ridge line.<\/span>\r\nx = b1(:,2);\r\ny = b1(:,1);\r\nplot(x, y, <span style=\"color: #A020F0\">'r'<\/span>, <span style=\"color: #A020F0\">'LineWidth'<\/span>, 2);<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/continental_divide_part_6_04.jpg\"> <p>I have one more post planned for this series.  Next time I'll gather together all the computational steps in a single, short\r\n      script.\r\n   <\/p>\r\n   <p><i>About this Series<\/i><\/p>\r\n   <p><a href=\"https:\/\/blogs.mathworks.com\/steve\/category\/continental-divide\/\">This series<\/a> explores the problem of computing the location of the continental divide for the United States.  The divide separates the\r\n      Atlantic and Pacific Ocean catchment basins for the North American continent.\r\n   <\/p>\r\n   <p>As an algorithm development problem, computing the divide lets us explore aspects of data import and visualization, manipulating\r\n      binary image masks, label matrices, regional minima, and the watershed transform.\r\n   <\/p>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"https:\/\/blogs.mathworks.com\/steve\/2009\/04\/24\/continental-divide-1-intro\/\">Part 1<\/a> - Introduction. Data import and display. <tt>multibandread<\/tt>, <tt>imshow<\/tt>.\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"https:\/\/blogs.mathworks.com\/steve\/2009\/05\/01\/continental-divide-2-watershed\/\">Part 2<\/a> - Watershed transform. <tt>watershed<\/tt>, <tt>label2rgb<\/tt>.\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"https:\/\/blogs.mathworks.com\/steve\/2009\/05\/08\/continental-divide-3-regmin\/\">Part 3<\/a> - Regional minima. <tt>imerode<\/tt>, <tt>imregionalmin<\/tt>.\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"https:\/\/blogs.mathworks.com\/steve\/2009\/05\/15\/continental-divide-4-oceans\/\">Part 4<\/a> - Ocean masks. binary image manipulation, <tt>bwselect<\/tt>.\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"https:\/\/blogs.mathworks.com\/steve\/2009\/05\/22\/continental-divide-5-imposemin\/\">Part 5<\/a> - Minima imposition. <tt>imimposemin<\/tt>.\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"https:\/\/blogs.mathworks.com\/steve\/2009\/05\/29\/continental-divide-6-watershed\/\">Part 6<\/a> - Computing and visualizing the divide. <tt>watershed<\/tt>, <tt>label2rgb<\/tt>, <tt>bwboundaries<\/tt>.\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"https:\/\/blogs.mathworks.com\/steve\/2009\/06\/05\/continental-divide-7-all-steps\/\">Part 7<\/a> - Putting it all together. One script that does everything, from data import through computation and visualization\r\n            of the divide.\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p>Data credit: <i>GLOBE Task Team and others (Hastings, David A., Paula K. Dunbar, Gerald M. Elphingstone, Mark Bootz, Hiroshi Murakami, Hiroshi\r\n         Maruyama, Hiroshi Masaharu, Peter Holland, John Payne, Nevin A. Bryant, Thomas L. Logan, J.-P. Muller, Gunter Schreier, and\r\n         John S. MacDonald), eds., 1999. The Global Land One-kilometer Base Elevation (GLOBE) Digital Elevation Model, Version 1.0.\r\n         National Oceanic and Atmospheric Administration, National Geophysical Data Center, 325 Broadway, Boulder, Colorado 80305-3328,\r\n         U.S.A. Digital data base on the World Wide Web (URL: <a href=\"http:\/\/www.ngdc.noaa.gov\/mgg\/topo\/globe.html\">http:\/\/www.ngdc.noaa.gov\/mgg\/topo\/globe.html<\/a>) and CD-ROMs.<\/i><\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_cab09423fdc24aef841f2b9e15f782c4() {\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='cab09423fdc24aef841f2b9e15f782c4 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' cab09423fdc24aef841f2b9e15f782c4';\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 2009 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_cab09423fdc24aef841f2b9e15f782c4()\"><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.8<br><\/p>\r\n<\/div>\r\n<!--\r\ncab09423fdc24aef841f2b9e15f782c4 ##### SOURCE BEGIN #####\r\n%%\r\n% Today's post in my \r\n% <https:\/\/blogs.mathworks.com\/steve\/category\/continental-divide\/\r\n% continental divide series> demonstrates the final computational step and\r\n% shows one procedure for visualizing the Pacific and Atlantic catchment\r\n% basins.\r\n%\r\n% In my previous post, I modified the DEM (digital elevation model) data\r\n% set so that its only regional minima were the two oceans.\r\n\r\ns = load('continental_divide');\r\ndem_modified = s.dem_modified;\r\nimshow(dem_modified, [-500 3000], 'InitialMagnification', 'fit');\r\n\r\n%%\r\n% Since the modified DEM has only two regional minima, we expect to get\r\n% only two catchment basins when we compute the watershed transform.\r\n\r\nL = watershed(dem_modified);\r\nmax(L(:))\r\n\r\n%%\r\n% I'll use |label2rgb| to display the Pacific catchment basin in green, the\r\n% Atlantic catchment basin in blue, and the watershed ridge pixels (the\r\n% continental divide) in red.\r\npacific = [0.2 1 0.2];\r\natlantic = [0.3 0.3 1];\r\nridge = [1 0 0];\r\nrgb = label2rgb(L, [pacific; atlantic], ridge);\r\nimshow(rgb, 'InitialMagnification', 'fit')\r\n\r\n%%\r\n% In a\r\n% <https:\/\/blogs.mathworks.com\/steve\/2009\/02\/18\/image-overlay-using-transparency\/ February blog post>, \r\n% I showed how to overlay one image transparently over another.  We can use\r\n% that technique here to achieve an effect similar to the visualization\r\n% that Brian Hayes used in his <http:\/\/bit-player.org\/2009\/long-division\r\n% blog post on the continental divide>, where \r\n% the ocean catchment basins are shown shaded with two different colors.\r\n\r\nimshow(dem, [-500 3000], 'InitialMagnification', 'fit')\r\nhold on\r\nh = imshow(rgb);\r\nset(h, 'AlphaData', 0.2);\r\n\r\n%%\r\n% It would be nice if we could make the watershed ridge line itself more\r\n% visible.  For example, if we could use |plot|, then we could use a thick\r\n% line. But right now we just have the ridge line represented as\r\n% zero-valued elements of a raster, instead of the x and y vectors we would\r\n% need to pass to |plot|.  We could use |find| to get the coordinates of\r\n% the ridge pixels, but we wouldn't get them in the right order.  One\r\n% solution is to use |bwboundaries| to \"trace\" the zero-valued ridge\r\n% pixels.  Note that I specify 4-connectivity in the call to\r\n% |bwboundaries| below. I've found that I get better results using\r\n% 4-connectivity when tracing a single-pixel-wide stroke that's not a\r\n% closed loop.\r\n\r\nb = bwboundaries(L == 0, 4); \r\nb1 = b{1};  % There's only 1 boundary found here - the ridge line.\r\nx = b1(:,2);\r\ny = b1(:,1);\r\nplot(x, y, 'r', 'LineWidth', 2);\r\n\r\n%%\r\n% I have one more post planned for this series.  Next time I'll gather\r\n% together all the computational steps in a single, short script.\r\n\r\n%%\r\n% _About this Series_ \r\n%\r\n% <https:\/\/blogs.mathworks.com\/steve\/category\/continental-divide\/ This\r\n% series> explores the problem of computing the location of the \r\n% continental divide for the United States.  The divide separates the\r\n% Atlantic and Pacific Ocean catchment basins for the North American\r\n% continent.\r\n%\r\n% As an algorithm development problem, computing the divide lets us\r\n% explore aspects of data import and visualization, manipulating binary\r\n% image masks, label matrices, regional minima, and the watershed\r\n% transform.\r\n%\r\n% * Part 1 - Introduction. Data import and display. |multibandread|,\r\n% |imshow|. \r\n%\r\n% * Part 2 - Watershed transform. |watershed|, |label2rgb|.\r\n%\r\n% * Part 3 - Regional minima. |imerode|, |imregionalmin|.\r\n%\r\n% * Part 4 - Ocean masks. binary image manipulation, |bwselect|.\r\n%\r\n% * Part 5 - Minima imposition. |imimposemin|.\r\n%\r\n% * Part 6 - Computing and visualizing the divide. |watershed|,\r\n% |label2rgb|, |bwboundaries|. \r\n%\r\n% * Part 7 - Putting it all together. One script that does everything, from\r\n% data import through computation and visualization of the divide.\r\n%\r\n% Data credit: _GLOBE Task Team and others (Hastings, David A., Paula K.\r\n% Dunbar, Gerald M. Elphingstone, Mark Bootz, Hiroshi Murakami, Hiroshi\r\n% Maruyama, Hiroshi Masaharu, Peter Holland, John Payne, Nevin A. Bryant,\r\n% Thomas L. Logan, J.-P. Muller, Gunter Schreier, and John S. MacDonald),\r\n% eds., 1999. The Global Land One-kilometer Base Elevation (GLOBE) Digital\r\n% Elevation Model, Version 1.0. National Oceanic and Atmospheric\r\n% Administration, National Geophysical Data Center, 325 Broadway, Boulder,\r\n% Colorado 80305-3328, U.S.A. Digital data base on the World Wide Web (URL:\r\n% http:\/\/www.ngdc.noaa.gov\/mgg\/topo\/globe.html) and CD-ROMs._\r\n\r\n##### SOURCE END ##### cab09423fdc24aef841f2b9e15f782c4\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   Today's post in my continental divide series demonstrates the final computational step and shows one procedure for visualizing the Pacific and Atlantic catchment basins.\r\n   \r\n   In my previous... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2009\/05\/29\/continental-divide-6-watershed\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[19],"tags":[88,90,36,152,362,122,68,150],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/262"}],"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=262"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/262\/revisions"}],"predecessor-version":[{"id":3635,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/262\/revisions\/3635"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=262"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=262"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=262"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}