{"id":250,"date":"2009-02-27T15:44:25","date_gmt":"2009-02-27T20:44:25","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/2009\/02\/27\/using-ismember-with-the-output-of-regionprops\/"},"modified":"2019-10-28T15:27:31","modified_gmt":"2019-10-28T19:27:31","slug":"using-ismember-with-the-output-of-regionprops","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2009\/02\/27\/using-ismember-with-the-output-of-regionprops\/","title":{"rendered":"Using ismember with the output of regionprops"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p>I recently heard a MathWorks application engineer (hi, <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/911\">Brett<\/a>!) say that a short little paragraph in the <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2008b\/toolbox\/images\/regionprops.html\">regionprops documentation<\/a> was very \"powerful.\" Here it is:\r\n   <\/p>\r\n   <p>The function <tt>ismember<\/tt> is useful in conjunction with <tt>regionprops<\/tt> for selecting regions based on certain criteria. For example, these commands create a binary image containing only the regions\r\n      whose area is greater than 80.\r\n   <\/p><pre>   idx = find([stats.Area] &gt; 80);\r\n   BW2 = ismember(L,idx);<\/pre><p>When I heard Brett's comment, I immediately pulled out my high-tech note-taking device (index card) from my back pocket and\r\n      wrote: \"regionprops - ismember - blog topic.\"\r\n   <\/p>\r\n   <p>The basic idea is this: If I have a binary image containing objects, how can I make a new binary image containing a subset\r\n      of the objects satisfying certain criteria? The answer is in three parts:\r\n   <\/p>\r\n   <p>1. Use <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2008b\/toolbox\/images\/bwlabel.html\"><tt>bwlabel<\/tt><\/a> and <tt>regionprops<\/tt> to compute measurements of the objects.\r\n   <\/p>\r\n   <p>2. Compute a vector of labels for the objects satisfying the criteria. Sometimes a special structure syntax called the \"comma-separated\r\n      list\" is very useful for this step; I'll show that syntax below.\r\n   <\/p>\r\n   <p>3. Use <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/ismember.html\"><tt>ismember<\/tt><\/a> to compute the desired binary image.\r\n   <\/p>\r\n   <p>I've posted several examples using <tt>bwlabel<\/tt> and <tt>regionprops<\/tt>, so I won't go into much detail about them.  You label objects in a binary image using <tt>bwlabel<\/tt>, and then you compute geometric measurements of the labeled objects using <tt>regionprops<\/tt>.\r\n   <\/p>\r\n   <p>Let's use the blobs.png image for our example.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">bw = imread(<span style=\"color: #A020F0\">'blobs.png'<\/span>);\r\nimshow(bw)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/regionprops_ismember_01.png\"> <pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">L = bwlabel(bw);\r\ns = regionprops(L, <span style=\"color: #A020F0\">'Area'<\/span>, <span style=\"color: #A020F0\">'BoundingBox'<\/span>);\r\ns(1)<\/pre><pre style=\"font-style:oblique\">\r\nans = \r\n\r\n           Area: 35\r\n    BoundingBox: [0.5000 0.5000 14 14]\r\n\r\n<\/pre><p><tt>regionprops<\/tt> returns a structure array containing the desired measurements for each object.\r\n   <\/p>\r\n   <p>The comma-separated list syntax for structures offers an easy way to convert a particular field from a structure array into\r\n      a vector, assuming that the field value is always a scalar.  Here's how it works.  When <tt>s<\/tt> is a structure array with field foo, and you write the following expression:\r\n   <\/p><pre>   s.foo<\/pre><p>MATLAB translates that into this \"comma-separated list\":<\/p><pre>   s(1).foo, s(2).foo, ..., s(end).foo<\/pre><p>Therefore, if <tt>s(k).foo<\/tt> is a scalar, you can create a vector of all the <tt>foo<\/tt> values by enclosing <tt>s.foo<\/tt> in brackets, like this:\r\n   <\/p><pre>   foo_fector = [s.foo];<\/pre><p>Here's how it works for the <tt>'Area'<\/tt> measurements we computed above for the blobs.png image.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">area_values = [s.Area]<\/pre><pre style=\"font-style:oblique\">\r\narea_values =\r\n\r\n  Columns 1 through 7\r\n\r\n          35         393          19         139          36          58         736\r\n\r\n  Columns 8 through 14\r\n\r\n          53           2           2           1           2           2           2\r\n\r\n  Columns 15 through 21\r\n\r\n           1         196        3940        4326         504          40         422\r\n\r\n  Columns 22 through 28\r\n\r\n         966         655         175          40          39        1108          35\r\n\r\n<\/pre><p>Suppose we want a list of all the objects whos area is between 100 and 1000. We can do that using <tt>find<\/tt> and relational operators, like this:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">idx = find((100 &lt;= area_values) &amp; (area_values &lt;= 1000))<\/pre><pre style=\"font-style:oblique\">\r\nidx =\r\n\r\n     2     4     7    16    19    21    22    23    24\r\n\r\n<\/pre><p>And that brings us to <tt>ismember<\/tt>. We can construct a binary image containing all the objects whos area is between 100 and 1000 by passing <tt>L<\/tt> and <tt>idx<\/tt> to ismember.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">bw2 = ismember(L, idx);\r\nimshow(bw2)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/regionprops_ismember_02.png\"> <p>Let's try that with another measurement, <i>solidity<\/i>.  Solidity is defined as the area of the region divided by the area of the convex hull of the region.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">s = regionprops(L, {<span style=\"color: #A020F0\">'Solidity'<\/span>});\r\nsolidity = [s.Solidity]<\/pre><pre style=\"font-style:oblique\">\r\nsolidity =\r\n\r\n  Columns 1 through 9\r\n\r\n    0.2397    0.9680    0.6786    0.0700    0.8000    0.1321    0.4461    0.7910    1.0000\r\n\r\n  Columns 10 through 18\r\n\r\n    1.0000    1.0000    1.0000    1.0000    1.0000    1.0000    1.0000    0.0972    0.1681\r\n\r\n  Columns 19 through 27\r\n\r\n    1.0000    0.2235    0.0386    0.1505    0.9791    0.9669    0.2260    0.2191    0.5604\r\n\r\n  Column 28\r\n\r\n    0.2397\r\n\r\n<\/pre><p>Here are all the objects with a solidity of 0.9 or higher:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">imshow(ismember(L, find(solidity &gt;= 0.9)))<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/regionprops_ismember_03.png\"> <p>And here are all the objects with a solidity of 0.25 or lower:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">imshow(ismember(L, find(solidity &lt;= 0.25)))<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/regionprops_ismember_04.png\"> <script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_dd8da52196b44fbb93a3e6cba2199870() {\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='dd8da52196b44fbb93a3e6cba2199870 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' dd8da52196b44fbb93a3e6cba2199870';\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 = '';\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_dd8da52196b44fbb93a3e6cba2199870()\"><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\ndd8da52196b44fbb93a3e6cba2199870 ##### SOURCE BEGIN #####\r\n%%\r\n% I recently heard a MathWorks application engineer (hi, \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/911 Brett>!) say\r\n% that a short little paragraph in the \r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2008b\/toolbox\/images\/regionprops.html\r\n% regionprops documentation> was very\r\n% \"powerful.\" Here it is: \r\n%\r\n% The function |ismember| is useful in conjunction with |regionprops| for selecting\r\n% regions based on certain criteria. For example, these commands create a binary\r\n% image containing only the regions whose area is greater than 80.  \r\n%\r\n%     idx = find([stats.Area] > 80);\r\n%     BW2 = ismember(L,idx);\r\n%\r\n% When I heard Brett's comment, I immediately pulled out my high-tech\r\n% note-taking device (index card) from my back pocket and wrote:\r\n% \"regionprops - ismember - blog topic.\" \r\n%\r\n% The basic idea is this: If I have a binary image containing objects, how can I\r\n% make a new binary image containing a subset of the objects satisfying certain\r\n% criteria? The answer is in three parts:\r\n%\r\n% 1. Use <https:\/\/www.mathworks.com\/help\/releases\/R2008b\/toolbox\/images\/bwlabel.html \r\n% |bwlabel|> and |regionprops| to compute measurements of the objects.\r\n%\r\n% 2. Compute a vector of labels for the objects satisfying the criteria.\r\n% Sometimes a special structure syntax called the \"comma-separated list\" is very\r\n% useful for this step; I'll show that syntax below.\r\n%\r\n% 3. Use <https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/ismember.html \r\n% |ismember|> to compute the desired binary image.\r\n%\r\n% I've posted several examples using |bwlabel| and |regionprops|, so I won't go\r\n% into much detail about them.  You label objects in a binary image using\r\n% |bwlabel|, and then you compute geometric measurements of the labeled objects\r\n% using |regionprops|.\r\n%\r\n% Let's use the blobs.png image for our example.\r\n\r\nbw = imread('blobs.png');\r\nimshow(bw)\r\n\r\n%%\r\nL = bwlabel(bw);\r\ns = regionprops(L, 'Area', 'BoundingBox');\r\ns(1)\r\n\r\n%%\r\n% |regionprops| returns a structure array containing the desired measurements\r\n% for each object.\r\n%\r\n% The comma-separated list syntax for structures offers an easy way to convert a\r\n% particular field from a structure array into a vector, assuming that the field\r\n% value is always a scalar.  Here's how it works.  When |s| is a structure array\r\n% with field foo, and you write the following expression:\r\n%\r\n%     s.foo\r\n%\r\n% MATLAB translates that into this \"comma-separated list\":\r\n%\r\n%     s(1).foo, s(2).foo, ..., s(end).foo\r\n%\r\n% Therefore, if |s(k).foo| is a scalar, you can create a vector of all the |foo|\r\n% values by enclosing |s.foo| in brackets, like this:\r\n%\r\n%     foo_fector = [s.foo];\r\n%\r\n% Here's how it works for the |'Area'| measurements we computed above for the\r\n% blobs.png image.\r\n\r\narea_values = [s.Area]\r\n\r\n%%\r\n% Suppose we want a list of all the objects whos area is between 100 and 1000.\r\n% We can do that using |find| and relational operators, like this:\r\n\r\nidx = find((100 <= area_values) & (area_values <= 1000))\r\n\r\n%%\r\n% And that brings us to |ismember|. We can construct a binary image containing\r\n% all the objects whos area is between 100 and 1000 by passing |L| and |idx| to\r\n% ismember.\r\n\r\nbw2 = ismember(L, idx);\r\nimshow(bw2)\r\n\r\n%%\r\n% Let's try that with another measurement, _solidity_.  Solidity is defined as\r\n% the area of the region divided by the area of the convex hull of the region.\r\n\r\ns = regionprops(L, {'Solidity'});\r\nsolidity = [s.Solidity]\r\n\r\n%%\r\n% Here are all the objects with a solidity of 0.9 or higher:\r\n\r\nimshow(ismember(L, find(solidity >= 0.9)))\r\n\r\n%%\r\n% And here are all the objects with a solidity of 0.25 or lower:\r\n\r\nimshow(ismember(L, find(solidity <= 0.25)))\r\n\r\n\r\n##### SOURCE END ##### dd8da52196b44fbb93a3e6cba2199870\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   I recently heard a MathWorks application engineer (hi, Brett!) say that a short little paragraph in the regionprops documentation was very \"powerful.\" Here it is:\r\n   \r\n   The function ismember... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2009\/02\/27\/using-ismember-with-the-output-of-regionprops\/\">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":[166,348,76,36,422,168],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/250"}],"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=250"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/250\/revisions"}],"predecessor-version":[{"id":3617,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/250\/revisions\/3617"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}