{"id":168,"date":"2007-09-04T07:00:20","date_gmt":"2007-09-04T11:00:20","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/2007\/09\/04\/clearing-border-components\/"},"modified":"2019-10-23T13:50:33","modified_gmt":"2019-10-23T17:50:33","slug":"clearing-border-components","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2007\/09\/04\/clearing-border-components\/","title":{"rendered":"Clearing border components"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p>I saw an application recently where someone wanted to handle NaNs in an image differently depending on whether they were \"interior.\"\r\n      In other words, a set of connected NaN pixels surrounded by non-NaN pixels are handled one way, and a set of connected NaN\r\n      pixels that touches the image border are handled another way.\r\n   <\/p>\r\n   <p>Coincidentally, another person recently commented on the need in some measurement situations to remove objects that touch\r\n      the image border.\r\n   <\/p>\r\n   <p>So I thought it would be good time to show how to use the Image Processing Toolbox function <tt>imclearborder<\/tt>.  This function removes all connected components of a binary image that touch any image border. Here's an example.  (To run\r\n      the example, download aug31.png from <a href=\"https:\/\/blogs.mathworks.com\/images\/steve\/168\/aug31.png\">here<\/a>.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">BW = imread(<span style=\"color: #A020F0\">'aug31.png'<\/span>);\r\nimshow(BW)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/168\/clear_border_01.jpg\"> <pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">BW2 = imclearborder(BW);\r\nimshow(BW2)\r\ntitle(<span style=\"color: #A020F0\">'Objects touching image borders removed'<\/span>)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/168\/clear_border_02.jpg\"> <p>Now back to the NaN problem.  Here's a small example:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">f = magic(5);\r\nf(2:5,1:2) = NaN;\r\nf(3:4,4) = NaN<\/pre><pre style=\"font-style:oblique\">\r\nf =\r\n\r\n    17    24     1     8    15\r\n   NaN   NaN     7    14    16\r\n   NaN   NaN    13   NaN    22\r\n   NaN   NaN    19   NaN     3\r\n   NaN   NaN    25     2     9\r\n\r\n<\/pre><p>The NaNs on the left make up a group touching the border.  The NaNs in the fourth column are an interior group.  We can distinguish\r\n      between the two groups by using <tt>imclearboder<\/tt> and some logical operations.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">nan_mask = isnan(f)<\/pre><pre style=\"font-style:oblique\">\r\nnan_mask =\r\n\r\n     0     0     0     0     0\r\n     1     1     0     0     0\r\n     1     1     0     1     0\r\n     1     1     0     1     0\r\n     1     1     0     0     0\r\n\r\n<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">border_nans = nan_mask &amp; ~imclearborder(nan_mask)<\/pre><pre style=\"font-style:oblique\">\r\nborder_nans =\r\n\r\n     0     0     0     0     0\r\n     1     1     0     0     0\r\n     1     1     0     0     0\r\n     1     1     0     0     0\r\n     1     1     0     0     0\r\n\r\n<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">interior_nans = nan_mask &amp; ~border_nans<\/pre><pre style=\"font-style:oblique\">\r\ninterior_nans =\r\n\r\n     0     0     0     0     0\r\n     0     0     0     0     0\r\n     0     0     0     1     0\r\n     0     0     0     1     0\r\n     0     0     0     0     0\r\n\r\n<\/pre><p>You can use also <tt>imclearborder<\/tt> on gray scale images.  As the documentation describes, the function \"suppresses structures that are lighter than their surroundings\r\n      and that are connected to the image border.\"  You can see the effect using the rice.png image:\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\nimshow(I)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/168\/clear_border_03.jpg\"> <pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">J = imclearborder(I);\r\nimshow(J)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/168\/clear_border_04.jpg\"> <p>The modified image looks darker.  As the documentation notes, for gray scale images <tt>imclearborder<\/tt> \"tends to reduce the overall intensity level in addition to suppressing border structures.\"  Using the display scaling syntax\r\n      of <tt>imshow<\/tt> helps to see the result clearly:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">imshow(J, [])<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/168\/clear_border_05.jpg\"> <p>So what happened to those two dark grains (on the left and on the right)? If we zoom into the original image to look closely\r\n      at the grain on the right, we can see that there are a couple of slightly darker gray pixels connecting the grain to its neighbor\r\n      on the right.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">imshow(I)\r\naxis([200 256 81 137])<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/168\/clear_border_06.jpg\"> <p>But that grain on the right touches the border.  So when <tt>imclearborder<\/tt> removes it, it also has the affect of lowering the gray level of its neighbor.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">imshow(J, [])\r\naxis([200 256 81 137])<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/168\/clear_border_07.jpg\"> <p>Have you found <tt>imclearborder<\/tt> to be useful?  Let me know - I'd like to hear about it.\r\n   <\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_7be10d2f860b47a68a133a7fb5ff6345() {\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='7be10d2f860b47a68a133a7fb5ff6345 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 7be10d2f860b47a68a133a7fb5ff6345';\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 2007 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_7be10d2f860b47a68a133a7fb5ff6345()\"><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.5<br><\/p>\r\n<\/div>\r\n<!--\r\n7be10d2f860b47a68a133a7fb5ff6345 ##### SOURCE BEGIN #####\r\n%% Clearing border components\r\n% I saw an application recently where someone wanted to handle NaNs in an\r\n% image differently depending on whether they were \"interior.\"  In other\r\n% words, a set of connected NaN pixels surrounded by non-NaN pixels are\r\n% handled one way, and a set of connected NaN pixels that touches the image\r\n% border are handled another way.\r\n%\r\n% Coincidentally, another person recently commented on the need in some\r\n% measurement situations to remove objects that touch the image border.\r\n%\r\n% So I thought it would be good time to show how to use the Image\r\n% Processing Toolbox function |imclearborder|.  This function removes all\r\n% connected components of a binary image that touch any image border.\r\n% Here's an example.  (To run the example, download aug31.png from \r\n% <https:\/\/blogs.mathworks.com\/images\/steve\/168\/aug31.png here>.\r\n\r\nBW = imread('aug31.png');\r\nimshow(BW)\r\n\r\n%%\r\nBW2 = imclearborder(BW);\r\nimshow(BW2)\r\ntitle('Objects touching image borders removed')\r\n\r\n%%\r\n% Now back to the NaN problem.  Here's a small example:\r\n\r\nf = magic(5);\r\nf(2:5,1:2) = NaN;\r\nf(3:4,4) = NaN\r\n\r\n%%\r\n% The NaNs on the left make up a group touching the border.  The NaNs in\r\n% the fourth column are an interior group.  We can distinguish between the\r\n% two groups by using |imclearboder| and some logical operations.\r\n\r\nnan_mask = isnan(f)\r\n\r\n%%\r\nborder_nans = nan_mask & ~imclearborder(nan_mask)\r\n\r\n%%\r\ninterior_nans = nan_mask & ~border_nans\r\n\r\n%%\r\n% You can use also |imclearborder| on gray scale images.  As the\r\n% documentation describes, the function \"suppresses structures that are\r\n% lighter than their surroundings and that are connected to the image\r\n% border.\"  You can see the effect using the rice.png image:\r\n\r\nI = imread('rice.png');\r\nimshow(I)\r\n\r\n%%\r\nJ = imclearborder(I);\r\nimshow(J)\r\n\r\n%%\r\n% The modified image looks darker.  As the documentation notes,\r\n% for gray scale images |imclearborder| \"tends to reduce the overall intensity level in addition\r\n% to suppressing border structures.\"  Using the display scaling syntax of\r\n% |imshow| helps to see the result clearly:\r\n\r\nimshow(J, [])\r\n\r\n%%\r\n% So what happened to those two dark grains (on the left and on the right)?\r\n% If we zoom into the original image to look closely at the grain on the \r\n% right, we can see that there are a couple of slightly darker gray pixels \r\n% connecting the grain to its neighbor on the right.\r\n\r\nimshow(I)\r\naxis([200 256 81 137])\r\n\r\n%%\r\n% But that grain on the right touches the border.  So when |imclearborder|\r\n% removes it, it also has the affect of lowering the gray level of its \r\n% neighbor.\r\n\r\nimshow(J, [])\r\naxis([200 256 81 137])\r\n\r\n%%\r\n% Have you found |imclearborder| to be useful?  Let me know - I'd like to\r\n% hear about it.\r\n\r\n##### SOURCE END ##### 7be10d2f860b47a68a133a7fb5ff6345\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   I saw an application recently where someone wanted to handle NaNs in an image differently depending on whether they were \"interior.\"\r\n      In other words, a set of connected NaN pixels... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2007\/09\/04\/clearing-border-components\/\">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":[50,404,76,36,376,54,52],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/168"}],"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=168"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/168\/revisions"}],"predecessor-version":[{"id":3560,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/168\/revisions\/3560"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=168"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=168"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}