{"id":244,"date":"2008-12-31T18:41:28","date_gmt":"2008-12-31T23:41:28","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/2008\/12\/31\/dilation-with-linear-structuring-elements\/"},"modified":"2019-10-28T09:51:32","modified_gmt":"2019-10-28T13:51:32","slug":"dilation-with-linear-structuring-elements","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2008\/12\/31\/dilation-with-linear-structuring-elements\/","title":{"rendered":"Dilation with linear structuring elements"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p>For my <a href=\"https:\/\/blogs.mathworks.com\/steve\/category\/dilation-algorithms\/\">series on dilation algorithms<\/a>, I've followed my unfortunate custom of dragging a series out way too long.  :-)\r\n   <\/p>\r\n   <p>So let's wrap it up with a mention of the last key algorithmic idea implemented in the Image Processing Toolbox morphology\r\n      functions: grayscale dilation and erosion with horizontal and vertical structuring elements.\r\n   <\/p>\r\n   <p>Normally, the time required to perform dilation and erosion is proportional to the number of elements in the domain of the\r\n      structuring element. But there are specialized algorithms that achieve better performance for certain classes of structuring\r\n      elements. In particular, <tt>imdilate<\/tt> and <tt>imerode<\/tt> use the algorithm described in M. van Herk, \"A fast algorithm for local minimum and maximum filters on rectangular and octagonal\r\n      kernels,\" <i>Pattern Recognition Letters<\/i>, 13:517-521, 1992.  There's a helpful description of this algorithm in P. Soille, <i>Morphological Image Analysis: Principles and Applications<\/i>, 2nd ed., 2007, 89-90.\r\n   <\/p>\r\n   <p>This algorithm can perform flat grayscale dilation using horizontal and vertical linear structuring elements in time independent\r\n      of the length of the strel.\r\n   <\/p>\r\n   <p>Let's test that. \r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">I = imread(<span style=\"color: #A020F0\">'rice.png'<\/span>);\r\nlengths = 5:2:31;\r\ntimes = zeros(size(lengths));\r\n<span style=\"color: #0000FF\">for<\/span> k = 1:numel(lengths)\r\n   se = strel(ones(1, lengths(k)));\r\n   times(k) = timeit(@() imdilate(I, se));\r\n<span style=\"color: #0000FF\">end<\/span>\r\n\r\nplot(lengths, 1000*times)\r\nylim([0 max(1000*times)])\r\nxlabel(<span style=\"color: #A020F0\">'Linear structuring element length'<\/span>)\r\nylabel(<span style=\"color: #A020F0\">'Dilation time (milliseconds)'<\/span>)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2008\/dilate_linear_01.png\"> <p>For rectangular structuring elements, this algorithm interacts especially nicely with <a href=\"https:\/\/blogs.mathworks.com\/steve\/2008\/09\/17\/dilation-structuring-element-decomposition\/\">structuring element decomposition<\/a>. The functions <tt>imdilate<\/tt> and <tt>imerode<\/tt> automatically detect flat, rectangular structuring elements and decompose them into horizontal and vertical line structuring\r\n      elements. Therefore, grayscale dilation and erosion with flat, rectangular structuring elements can also be performed in time\r\n      independent of the structuring element size.\r\n   <\/p>\r\n   <p>Here's a test for square structuring elements.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">lengths = 5:2:31;\r\ntimes = zeros(size(lengths));\r\n<span style=\"color: #0000FF\">for<\/span> k = 1:numel(lengths)\r\n   se = strel(ones(lengths(k), lengths(k)));\r\n   times(k) = timeit(@() imdilate(I, se));\r\n<span style=\"color: #0000FF\">end<\/span>\r\n\r\nplot(lengths, 1000*times)\r\nylim([0 max(1000*times)])\r\nxlabel(<span style=\"color: #A020F0\">'Square structuring element width'<\/span>)\r\nylabel(<span style=\"color: #A020F0\">'Dilation time (milliseconds)'<\/span>)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2008\/dilate_linear_02.png\"> <p>That's a nice result, especially since using rectangular structuring elements is fairly common.<\/p>\r\n   <p>To recap, the main dilation and erosion algorithm ideas exploited by Image Processing Toolbox morphology functions are:<\/p>\r\n   <div>\r\n      <ul>\r\n         <li>structuring element decomposition<\/li>\r\n         <li>binary bit packing<\/li>\r\n         <li>specialized algorithms for horizontal and linear strels<\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p>You can see all the posts in the series by clicking on the <a href=\"https:\/\/blogs.mathworks.com\/steve\/category\/dilation-algorithms\/\">\"Dilation algorithms\"<\/a> category link on the right side of the page.\r\n   <\/p>\r\n   <p>OK, that's it - I'm signing off for 2008.<\/p>\r\n   <p>Happy New Year, everyone!<\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_cbf50f7be607442ba3a4c6c35b768908() {\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='cbf50f7be607442ba3a4c6c35b768908 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' cbf50f7be607442ba3a4c6c35b768908';\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_cbf50f7be607442ba3a4c6c35b768908()\"><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.7<br><\/p>\r\n<\/div>\r\n<!--\r\ncbf50f7be607442ba3a4c6c35b768908 ##### SOURCE BEGIN #####\r\n%%\r\n% For my \r\n% <https:\/\/blogs.mathworks.com\/steve\/category\/dilation-algorithms\/ \r\n% series on dilation algorithms>, I've followed my unfortunate\r\n% custom of dragging a series out way too long.  :-)\r\n%\r\n% So let's wrap it up with a mention of the last key algorithmic\r\n% idea implemented in the Image Processing Toolbox morphology\r\n% functions: grayscale dilation and erosion with horizontal and\r\n% vertical structuring elements.\r\n%\r\n% Normally, the time required to perform dilation and erosion is\r\n% proportional to the number of elements in the domain of the\r\n% structuring element. But there are specialized algorithms that\r\n% achieve better performance for certain classes of structuring\r\n% elements. In particular, |imdilate| and |imerode| use the\r\n% algorithm described in M. van Herk, \"A fast algorithm for local\r\n% minimum and maximum filters on rectangular and octagonal kernels,\"\r\n% _Pattern Recognition Letters_, 13:517-521, 1992.  There's a\r\n% helpful description of this algorithm in P. Soille, _Morphological\r\n% Image Analysis: Principles and Applications_, 2nd ed., 2007,\r\n% 89-90.\r\n%\r\n% This algorithm can perform flat grayscale dilation using\r\n% horizontal and vertical linear structuring elements in time\r\n% independent of the length of the strel.\r\n%\r\n% Let's test that.  (You can get\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/18798\r\n% timeit.m> from the MATLAB Central File Exchange.\r\n\r\nI = imread('rice.png');\r\nlengths = 5:2:31;\r\ntimes = zeros(size(lengths));\r\nfor k = 1:numel(lengths)\r\n   se = strel(ones(1, lengths(k)));\r\n   times(k) = timeit(@() imdilate(I, se));\r\nend\r\n\r\nplot(lengths, 1000*times)\r\nylim([0 max(1000*times)])\r\nxlabel('Linear structuring element length')\r\nylabel('Dilation time (milliseconds)')\r\n\r\n%%\r\n% For rectangular structuring elements, this algorithm interacts\r\n% especially nicely with <https:\/\/blogs.mathworks.com\/steve\/2008\/09\/17\/dilation-structuring-element-decomposition\/ \r\n% structuring element decomposition>. The functions |imdilate| and\r\n% |imerode| automatically detect flat, rectangular structuring\r\n% elements and decompose them into horizontal and vertical line\r\n% structuring elements. Therefore, grayscale dilation and erosion\r\n% with flat, rectangular structuring elements can also be performed\r\n% in time independent of the structuring element size.\r\n%\r\n% Here's a test for square structuring elements.\r\n\r\nlengths = 5:2:31;\r\ntimes = zeros(size(lengths));\r\nfor k = 1:numel(lengths)\r\n   se = strel(ones(lengths(k), lengths(k)));\r\n   times(k) = timeit(@() imdilate(I, se));\r\nend\r\n\r\nplot(lengths, 1000*times)\r\nylim([0 max(1000*times)])\r\nxlabel('Square structuring element width')\r\nylabel('Dilation time (milliseconds)')\r\n\r\n%%\r\n% That's a nice result, especially since using rectangular\r\n% structuring elements is fairly common.\r\n%\r\n% To recap, the main dilation and erosion algorithm ideas exploited\r\n% by Image Processing Toolbox morphology functions are:\r\n%\r\n% * structuring element decomposition\r\n% * binary bit packing\r\n% * specialized algorithms for horizontal and linear strels\r\n%\r\n% You can see all the posts in the series by clicking on the\r\n% <https:\/\/blogs.mathworks.com\/steve\/category\/dilation-algorithms\/ \r\n% \"Dilation algorithms\"> category link on the right side of the\r\n% page. \r\n%\r\n% OK, that's it - I'm signing off for 2008.\r\n%\r\n% Happy New Year, everyone!\r\n\r\n##### SOURCE END ##### cbf50f7be607442ba3a4c6c35b768908\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   For my series on dilation algorithms, I've followed my unfortunate custom of dragging a series out way too long.  :-)\r\n   \r\n   So let's wrap it up with a mention of the last key algorithmic idea... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2008\/12\/31\/dilation-with-linear-structuring-elements\/\">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":[124,76,162,288,68,190,106,474,94,96,298,130],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/244"}],"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=244"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/244\/revisions"}],"predecessor-version":[{"id":2641,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/244\/revisions\/2641"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=244"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=244"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=244"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}