{"id":229,"date":"2008-09-29T14:36:07","date_gmt":"2008-09-29T18:36:07","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/2008\/09\/29\/dilation-algorithms-decomposing-more-shapes\/"},"modified":"2019-10-28T09:43:43","modified_gmt":"2019-10-28T13:43:43","slug":"dilation-algorithms-decomposing-more-shapes","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2008\/09\/29\/dilation-algorithms-decomposing-more-shapes\/","title":{"rendered":"Dilation algorithms&mdash;decomposing more shapes"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p>In my <a href=\"https:\/\/blogs.mathworks.com\/steve\/2008\/09\/17\/dilation-structuring-element-decomposition\/\">previous post on dilation algorithms<\/a> I discussed structuring element decomposition.  We looked at the decomposition of structuring elements with rectangular domains.\r\n      Today I want to follow up on the idea by looking at decompositions of other structuring element shapes.\r\n   <\/p>\r\n   <p>The <tt>strel<\/tt> function offers a variety of flat structuring element shapes:\r\n   <\/p>\r\n   <div>\r\n      <ul>\r\n         <li>diamond<\/li>\r\n         <li>disk<\/li>\r\n         <li>line<\/li>\r\n         <li>octagon<\/li>\r\n         <li>pair<\/li>\r\n         <li>periodicline<\/li>\r\n         <li>rectangle<\/li>\r\n         <li>square<\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p>(The <tt>strel<\/tt> function also offers nonflat shapes, and shapes with arbitrary domains.)\r\n   <\/p>\r\n   <p>Let's look at the <tt>'diamond'<\/tt> shape.  The doc says <tt>SE = strel('diamond', R)<\/tt> creates a flat, diamond-shaped structuring element, where <tt>R<\/tt> specifies the distance from the structuring element origin to the points of the diamond.\" For example:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">se1 = strel(<span style=\"color: #A020F0\">'diamond'<\/span>, 5)<\/pre><pre style=\"font-style:oblique\"> \r\nse1 =\r\n \r\nFlat STREL object containing 61 neighbors.\r\nDecomposition: 4 STREL objects containing a total of 17 neighbors\r\n\r\nNeighborhood:\r\n     0     0     0     0     0     1     0     0     0     0     0\r\n     0     0     0     0     1     1     1     0     0     0     0\r\n     0     0     0     1     1     1     1     1     0     0     0\r\n     0     0     1     1     1     1     1     1     1     0     0\r\n     0     1     1     1     1     1     1     1     1     1     0\r\n     1     1     1     1     1     1     1     1     1     1     1\r\n     0     1     1     1     1     1     1     1     1     1     0\r\n     0     0     1     1     1     1     1     1     1     0     0\r\n     0     0     0     1     1     1     1     1     0     0     0\r\n     0     0     0     0     1     1     1     0     0     0     0\r\n     0     0     0     0     0     1     0     0     0     0     0\r\n\r\n \r\n<\/pre><p>The display says the structuring element has 61 neighbors in its domain, but the four decomposed structuring elements have\r\n      a total of only 17 neighbors.\r\n   <\/p>\r\n   <p>What shapes makes up the decomposition?  We can use <tt>getsequence<\/tt> and <tt>getnhood<\/tt> to find out.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">se1_seq = getsequence(se1);\r\n<span style=\"color: #0000FF\">for<\/span> k = 1:numel(se1_seq)<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">    getnhood(se1_seq(k))<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n     0     1     0\r\n     1     1     1\r\n     0     1     0\r\n\r\n<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n     0     1     0\r\n     1     0     1\r\n     0     1     0\r\n\r\n<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n     0     0     1     0     0\r\n     0     0     0     0     0\r\n     1     0     0     0     1\r\n     0     0     0     0     0\r\n     0     0     1     0     0\r\n\r\n<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n     0     1     0\r\n     1     0     1\r\n     0     1     0\r\n\r\n<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\"><span style=\"color: #0000FF\">end<\/span><\/pre><p>This decomposition comes from Rein van den Boomgard and Richard van Balen, \"Methods for Fast Morphological Image Transforms\r\n      Using Bitmapped Binary Images,\" <i>Computer Vision, Graphics, and Image Processing: Models and Image Processing<\/i>, vol. 54, no. 3, May 1992, pp. 252-254.  (That journal name sure is a mouthful!)\r\n   <\/p>\r\n   <p>Now let's look at the <tt>'disk'<\/tt> structuring element.  By default, <tt>strel('disk',R)<\/tt> actually gives you an <i>approximation<\/i> to a disk shape, where the approximation is based on a technique called <i>radial decomposition using periodic lines<\/i>.  The reference sources are:\r\n   <\/p>\r\n   <div>\r\n      <ul>\r\n         <li>Rolf Adams, \"Radial Decomposition of Discs and Spheres,\" <i>Computer Vision, Graphics, and Image Processing: Graphical Models and Image Processing<\/i>, vol. 55, no. 5, September 1993, pp. 325-332.\r\n         <\/li>\r\n         <li>Ronald Jones and Pierre Soille, \"Periodic lines: Definition, cascades, and application to granulometries,\" <i>Pattern Recognition Letters<\/i>, vol. 17, 1996, 1057-1063.\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">se2 = strel(<span style=\"color: #A020F0\">'disk'<\/span>, 5)<\/pre><pre style=\"font-style:oblique\"> \r\nse2 =\r\n \r\nFlat STREL object containing 69 neighbors.\r\nDecomposition: 6 STREL objects containing a total of 18 neighbors\r\n\r\nNeighborhood:\r\n     0     0     1     1     1     1     1     0     0\r\n     0     1     1     1     1     1     1     1     0\r\n     1     1     1     1     1     1     1     1     1\r\n     1     1     1     1     1     1     1     1     1\r\n     1     1     1     1     1     1     1     1     1\r\n     1     1     1     1     1     1     1     1     1\r\n     1     1     1     1     1     1     1     1     1\r\n     0     1     1     1     1     1     1     1     0\r\n     0     0     1     1     1     1     1     0     0\r\n\r\n \r\n<\/pre><p>Similar to the <tt>'diamond'<\/tt> shape above, the <tt>'disk'<\/tt> shape is decomposed into a sequence of smaller structuring elements:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">se2_seq = getsequence(se2);\r\n<span style=\"color: #0000FF\">for<\/span> k = 1:numel(se2_seq)<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">    getnhood(se2_seq(k))<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n     1\r\n     1\r\n     1\r\n\r\n<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n     1     0     0\r\n     0     1     0\r\n     0     0     1\r\n\r\n<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n     1     1     1\r\n\r\n<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n     0     0     1\r\n     0     1     0\r\n     1     0     0\r\n\r\n<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n     1     1     1\r\n\r\n<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n     1\r\n     1\r\n     1\r\n\r\n<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\"><span style=\"color: #0000FF\">end<\/span><\/pre><p>I mentioned above that <tt>strel('disk',R)<\/tt> gives you an approximation to a disk. Let's see what that approximation looks like with a larger radius:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">se3 = strel(<span style=\"color: #A020F0\">'disk'<\/span>, 21);\r\nimshow(getnhood(se3), <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\/2008\/dilation_3_01.png\"> <p>Well, that's definitely an approximation.  It looks a lot more like an octagon than a circle.  The syntax <tt>strel('disk',R,N)<\/tt> gives you more control over the approximation.  <tt>N<\/tt> can be 0, 4, 6, or 8.  The values 4, 6, and 8 indicate different levels of approximation.  The default value is 4.  With\r\n      <tt>N<\/tt> equal to 8, the result looks closer to a circle, but dilation is a little slower because the decomposition isn't as efficient.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">se4 = strel(<span style=\"color: #A020F0\">'disk'<\/span>, 21, 8);\r\nimshow(getnhood(se4), <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\/2008\/dilation_3_02.png\"> <p>Setting <tt>N = 0<\/tt> asks <tt>strel<\/tt> to construct a disk shape with no decomposition approximation.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">se5 = strel(<span style=\"color: #A020F0\">'disk'<\/span>, 21, 0);\r\nimshow(getnhood(se5), <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\/2008\/dilation_3_03.png\"> <p>Using <tt>getsequence<\/tt> we can see that there is no decomposition for <tt>se5<\/tt>:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">numel(getsequence(se5))<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n     1\r\n\r\n<\/pre><p>Next time we'll do some timing experiments with the decomposed structuring elements.<\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_13432f70bea94632aabb934b8d06ee7c() {\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='13432f70bea94632aabb934b8d06ee7c ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 13432f70bea94632aabb934b8d06ee7c';\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 2008 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_13432f70bea94632aabb934b8d06ee7c()\"><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.6<br><\/p>\r\n<\/div>\r\n<!--\r\n13432f70bea94632aabb934b8d06ee7c ##### SOURCE BEGIN #####\r\n%%\r\n% In my \r\n% <https:\/\/blogs.mathworks.com\/steve\/2008\/09\/17\/dilation-structuring-element-decomposition\/ \r\n% previous post on dilation algorithms> I discussed structuring element\r\n% decomposition.  We looked at the decomposition of structuring elements with\r\n% rectangular domains.  Today I want to follow up on the idea by looking at\r\n% decompositions of other structuring element shapes.\r\n%\r\n% The |strel| function offers a variety of flat structuring element shapes:\r\n%\r\n% * diamond\r\n% * disk\r\n% * line\r\n% * octagon\r\n% * pair\r\n% * periodicline\r\n% * rectangle\r\n% * square\r\n%\r\n% (The |strel| function also offers nonflat shapes, and shapes with arbitrary\r\n% domains.)\r\n%\r\n% Let's look at the |'diamond'| shape.  The \r\n% <https:\/\/www.mathworks.com\/help\/images\/index.htmlstrel.html \r\n% doc> says |SE = strel('diamond', R)|\r\n% creates a flat, diamond-shaped structuring element, where |R| specifies the\r\n% distance from the structuring element origin to the points of the diamond.\"\r\n% For example:\r\n\r\nse1 = strel('diamond', 5)\r\n\r\n%%\r\n% The display says the structuring element has 61 neighbors in its domain, but\r\n% the four decomposed structuring elements have a total of only 17 neighbors.\r\n%\r\n% What shapes makes up the decomposition?  We can use |getsequence| and\r\n% |getnhood| to find out.\r\n\r\nse1_seq = getsequence(se1);\r\nfor k = 1:numel(se1_seq)\r\n    %%\r\n    getnhood(se1_seq(k))\r\nend\r\n\r\n%%\r\n% This decomposition comes from Rein van den Boomgard and Richard van Balen,\r\n% \"Methods for Fast Morphological Image Transforms Using Bitmapped Binary\r\n% Images,\" _Computer Vision, Graphics, and Image Processing: Models and Image\r\n% Processing_, vol. 54, no. 3, May 1992, pp. 252-254.  (That journal name sure\r\n% is a mouthful!)\r\n%\r\n% Now let's look at the |'disk'| structuring element.  By default,\r\n% |strel('disk',R)| actually gives you an _approximation_ to a disk shape, where\r\n% the approximation is based on a technique called _radial decomposition using\r\n% periodic lines_.  The reference sources are:\r\n%\r\n% * Rolf Adams, \"Radial Decomposition of Discs and Spheres,\" _Computer Vision,\r\n% Graphics, and Image Processing: Graphical Models and Image Processing_, vol.\r\n% 55, no. 5, September 1993, pp. 325-332.  \r\n% * Ronald Jones and Pierre Soille, \"Periodic lines: Definition, cascades, and\r\n% application to granulometries,\" _Pattern Recognition Letters_, vol. 17, 1996,\r\n% 1057-1063.  \r\n\r\nse2 = strel('disk', 5)\r\n\r\n%%\r\n% Similar to the |'diamond'| shape above, the |'disk'| shape is decomposed into\r\n% a sequence of smaller structuring elements:\r\n\r\nse2_seq = getsequence(se2);\r\nfor k = 1:numel(se2_seq)\r\n    %%\r\n    getnhood(se2_seq(k))\r\nend\r\n\r\n%%\r\n% I mentioned above that |strel('disk',R)| gives you an approximation to a disk.\r\n% Let's see what that approximation looks like with a larger radius:\r\n\r\nse3 = strel('disk', 21);\r\nimshow(getnhood(se3), 'InitialMagnification', 'fit')\r\n\r\n%%\r\n% Well, that's definitely an approximation.  It looks a lot more like an octagon\r\n% than a circle.  The syntax |strel('disk',R,N)| gives you more control over the\r\n% approximation.  |N| can be 0, 4, 6, or 8.  The values 4, 6, and 8 indicate\r\n% different levels of approximation.  The default value is 4.  With |N| equal to\r\n% 8, the result looks closer to a circle, but dilation is a little slower\r\n% because the decomposition isn't as efficient.\r\n\r\nse4 = strel('disk', 21, 8);\r\nimshow(getnhood(se4), 'InitialMagnification', 'fit')\r\n\r\n%%\r\n% Setting |N = 0| asks |strel| to construct a disk shape with no decomposition\r\n% approximation.\r\n\r\nse5 = strel('disk', 21, 0);\r\nimshow(getnhood(se5), 'InitialMagnification', 'fit')\r\n\r\n%%\r\n% Using |getsequence| we can see that there is no decomposition for |se5|:\r\n\r\nnumel(getsequence(se5))\r\n\r\n%%\r\n% Next time we'll do some timing experiments with the decomposed structuring\r\n% elements.\r\n##### SOURCE END ##### 13432f70bea94632aabb934b8d06ee7c\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   In my previous post on dilation algorithms I discussed structuring element decomposition.  We looked at the decomposition of structuring elements with rectangular domains.\r\n      Today I want to... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2008\/09\/29\/dilation-algorithms-decomposing-more-shapes\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[18],"tags":[518,516,36,162,106],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/229"}],"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=229"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/229\/revisions"}],"predecessor-version":[{"id":2270,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/229\/revisions\/2270"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=229"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=229"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=229"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}