{"id":132,"date":"2007-04-15T12:28:00","date_gmt":"2007-04-15T16:28:00","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/2007\/04\/15\/connected-component-labeling-part-4\/"},"modified":"2019-10-23T12:50:36","modified_gmt":"2019-10-23T16:50:36","slug":"connected-component-labeling-part-4","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2007\/04\/15\/connected-component-labeling-part-4\/","title":{"rendered":"Connected component labeling &#8211; Part 4"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p>In the <a href=\"https:\/\/blogs.mathworks.com\/steve\/2007\/03\/20\/connected-component-labeling-part-3\/\">previous post in this series<\/a> I talked about forming a graph based on pixel neighbor relationships, and then finding the connected components of the graph.\r\n      Another approach starts by finding a foreground pixel and then iteratively searching that pixel's neighbors to find the connected\r\n      component. Sometimes this technique is called the <i>flood fill<\/i> approach. I'll demonstrate the basic idea using a small sample image and a series of diagrams.\r\n   <\/p>\r\n   <p>The matrix below and on the left is our binary image. Using 4-connected neighbors, the image has two connected components.\r\n       The matrix on the right is going to become our label matrix when we're done.  It is initialized to contain all zeros.\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/132\/floodfill1.png\"> <\/p>\r\n   <p>Step 1: Find a foreground pixel.  Set the corresponding label matrix pixel to 1, which is the first label.<\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/132\/floodfill2.png\"> <\/p>\r\n   <p>Step 2: Set the pixels that were just labeled to 0, and then find all the nonzero 4-connected neighbors. Set the corresponding\r\n      pixels in the label matrix to 1.\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/132\/floodfill3.png\"> <\/p>\r\n   <p>Step 3: Set the pixels that were just labeled to 0, and then find all the nonzero 4-connected neighbors. Set the corresponding\r\n      pixels in the label matrix to 1.  (This step should seem familiar.)\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/132\/floodfill4.png\"> <\/p>\r\n   <p>Step 4: Set the pixels that were just labeled to 0, and then find all the nonzero 4-connected neighbors.  Oops, there aren't\r\n      any!\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/132\/floodfill5.png\"> <\/p>\r\n   <p>Step 5: We have finished labeling object 1. Now search for the next nonzero pixel. Set the corresponding pixel in the label\r\n      matrix to 2, which is the next object label.\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/132\/floodfill6.png\"> <\/p>\r\n   <p>Step 6: Set the pixels that were just labeled to 0, and then find all the nonzero 4-connected neighbors. Set the corresponding\r\n      pixels in the label matrix to 2.\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/132\/floodfill7.png\"> <\/p>\r\n   <p>Step 7: Set the pixels that were just labeled to 0, and then find all the nonzero 4-connected neighbors. Set the corresponding\r\n      pixels in the label matrix to 2.\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/132\/floodfill8.png\"> <\/p>\r\n   <p>Step 8: Set the pixels that were just labeled to 0, and then find all the nonzero 4-connected neighbors. Since there aren't\r\n      any, we know we have finished labeling object 2.  Furthermore, since there are no nonzero pixels left in the image, we know\r\n      we have completed the labeling operation.\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/132\/floodfill9.png\"> <\/p>\r\n   <p>Now let's talk about how you might program this in MATLAB. I'd use the <a href=\"https:\/\/blogs.mathworks.com\/steve\/2007\/03\/28\/neighbor-indexing\/\">neighbor indexing technique<\/a> that I wrote about a couple of weeks ago. Start from this point:\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/132\/floodfill3.png\"> <\/p>\r\n   <p>Call the matrix on the left <tt>bw<\/tt>, and call the matrix on the right <tt>L<\/tt>.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">bw = logical([0 0 0 0 0 0 0\r\n    0 0 1 0 0 0 0\r\n    0 1 0 1 1 1 0\r\n    0 1 0 0 1 0 0\r\n    0 0 0 0 0 0 0]);\r\n\r\nL = [0 0 0 0 0 0 0\r\n    0 1 1 0 0 0 0\r\n    0 1 0 0 0 0 0\r\n    0 0 0 0 0 0 0\r\n    0 0 0 0 0 0 0];<\/pre><p>The linear indices of the pixels that were just labeled are 8 and 12:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">idx = [8; 12];<\/pre><p>Here are the neighbor offsets for a four-connected neighborhood:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">offsets = [-1; 5; 1; -5];<\/pre><p>\"Set the pixels that were just labeled to 0\".<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">bw(idx) = 0;<\/pre><p>\"Find all the nonzero 4-connected neighbors.\" Do this by adding all neighbor offsets to all pixels in the current set.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">neighbors = bsxfun(@plus, idx, offsets')<\/pre><pre style=\"font-style:oblique\">\r\nneighbors =\r\n\r\n     7    13     9     3\r\n    11    17    13     7\r\n\r\n<\/pre><p>Remove duplicates.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">neighbors = unique(neighbors(:))<\/pre><pre style=\"font-style:oblique\">\r\nneighbors =\r\n\r\n     3\r\n     7\r\n     9\r\n    11\r\n    13\r\n    17\r\n\r\n<\/pre><p>Keep only the neighbors that are nonzero.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">idx = neighbors(bw(neighbors))<\/pre><pre style=\"font-style:oblique\">\r\nidx =\r\n\r\n    13\r\n\r\n<\/pre><p>\"Set the corresponding pixels in the label matrix to 1.\"<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">L(idx) = 1;<\/pre><p>You'd repeat these operations in a loop until <tt>idx<\/tt> was empty, indicating that a connected component has been completely labeled.\r\n   <\/p>\r\n   <p>I've covered two connected components methods in this series so far. In my next post I'll start to explain a third method\r\n      - the one used by the Image Processing Toolbox functions <tt>bwlabel<\/tt> and <tt>bwlabeln<\/tt>.\r\n   <\/p>\r\n\r\n<p>\r\nPS. Good luck to everyone running in the Boston Marathon tomorrow!\r\n<\/p>\r\n\r\n<script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_5a177edded89450390feb9f994a806f5() {\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='5a177edded89450390feb9f994a806f5 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 5a177edded89450390feb9f994a806f5';\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_5a177edded89450390feb9f994a806f5()\"><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.4<br><\/p>\r\n<\/div>\r\n<!--\r\n5a177edded89450390feb9f994a806f5 ##### SOURCE BEGIN #####\r\n%% Connected component labeling - Part 4\r\n% In the <https:\/\/blogs.mathworks.com\/steve\/2007\/03\/20\/connected-component-labeling-part-3\/ \r\n% previous post in this series> I talked about forming a graph based\r\n% on pixel neighbor relationships, and then finding the connected\r\n% components of the graph.  Another approach starts by finding a foreground\r\n% pixel and then iteratively searching that pixel's neighbors to find the\r\n% connected component. Sometimes this technique is called the _flood fill_\r\n% approach. I'll demonstrate the basic idea using a small sample image and a\r\n% series of diagrams.\r\n%\r\n% The matrix below and on the left is our binary image. Using 4-connected\r\n% neighbors, the image has two connected components.  The matrix on the\r\n% right is going to become our label matrix when we're done.  It is\r\n% initialized to contain all zeros.\r\n%\r\n% <<floodfill1.png>>\r\n%\r\n% Step 1: Find a foreground pixel.  Set the corresponding label matrix\r\n% pixel to 1, which is the first label.\r\n%\r\n% <<floodfill2.png>>\r\n%\r\n% Step 2: Set the pixels that were just labeled to 0, and then find all the\r\n% nonzero 4-connected neighbors. Set the corresponding pixels in the label\r\n% matrix to 1.\r\n%\r\n% <<floodfill3.png>>\r\n%\r\n% Step 3: Set the pixels that were just labeled to 0, and then find all the\r\n% nonzero 4-connected neighbors. Set the corresponding pixels in the label\r\n% matrix to 1.  (This step should seem familiar.)\r\n%\r\n% <<floodfill4.png>>\r\n%\r\n% Step 4: Set the pixels that were just labeled to 0, and then find all the\r\n% nonzero 4-connected neighbors.  Oops, there aren't any!\r\n%\r\n% <<floodfill5.png>>\r\n%\r\n% Step 5: We have finished labeling object 1. Now search for the next\r\n% nonzero pixel. Set the corresponding pixel in the label matrix to 2,\r\n% which is the next object label.\r\n%\r\n% <<floodfill6.png>>\r\n%\r\n% Step 6: Set the pixels that were just labeled to 0, and then find all the\r\n% nonzero 4-connected neighbors. Set the corresponding pixels in the label\r\n% matrix to 2.\r\n%\r\n% <<floodfill7.png>>\r\n%\r\n% Step 7: Set the pixels that were just labeled to 0, and then find all the\r\n% nonzero 4-connected neighbors. Set the corresponding pixels in the label\r\n% matrix to 2.\r\n%\r\n% <<floodfill8.png>>\r\n%\r\n% Step 8: Set the pixels that were just labeled to 0, and then find all the\r\n% nonzero 4-connected neighbors. Since there aren't any, we know we have\r\n% finished labeling object 2.  Furthermore, since there are no nonzero\r\n% pixels left in the image, we know we have completed the labeling\r\n% operation.\r\n%\r\n% <<floodfill9.png>>\r\n%\r\n% Now let's talk about how you might program this in MATLAB. I'd use the\r\n% <https:\/\/blogs.mathworks.com\/steve\/2007\/03\/28\/neighbor-indexing\/ \r\n% neighbor indexing technique> that I wrote about a couple of weeks ago.\r\n% Start from this point:\r\n%\r\n% <<floodfill3.png>>\r\n%\r\n% Call the matrix on the left |bw|, and call the matrix on the right |L|.\r\n\r\nbw = logical([0 0 0 0 0 0 0\r\n    0 0 1 0 0 0 0\r\n    0 1 0 1 1 1 0\r\n    0 1 0 0 1 0 0\r\n    0 0 0 0 0 0 0]);\r\n\r\nL = [0 0 0 0 0 0 0\r\n    0 1 1 0 0 0 0\r\n    0 1 0 0 0 0 0\r\n    0 0 0 0 0 0 0\r\n    0 0 0 0 0 0 0];\r\n\r\n%%\r\n% The linear indices of the pixels that were just labeled are 8 and 12:\r\n\r\nidx = [8; 12];\r\n\r\n%%\r\n% Here are the neighbor offsets for a four-connected neighborhood:\r\n\r\noffsets = [-1; 5; 1; -5];\r\n\r\n%%\r\n% \"Set the pixels that were just labeled to 0\".\r\n\r\nbw(idx) = 0;\r\n\r\n%%\r\n% \"Find all the nonzero 4-connected neighbors.\" Do this by adding all\r\n% neighbor offsets to all pixels in the current set.\r\nneighbors = bsxfun(@plus, idx, offsets')\r\n\r\n%%\r\n% Remove duplicates.\r\nneighbors = unique(neighbors(:))\r\n\r\n%%\r\n% Keep only the neighbors that are nonzero.\r\nidx = neighbors(bw(neighbors))\r\n\r\n%%\r\n% \"Set the corresponding pixels in the label matrix to 1.\"\r\n\r\nL(idx) = 1;\r\n\r\n%%\r\n% You'd repeat these operations in a loop until |idx| was empty, indicating\r\n% that a connected component has been completely labeled.\r\n%\r\n% I've covered two connected components methods in this series so far. In\r\n% my next post I'll start to explain a third method - the one used by the\r\n% Image Processing Toolbox functions |bwlabel| and |bwlabeln|.\r\n##### SOURCE END ##### 5a177edded89450390feb9f994a806f5\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   In the previous post in this series I talked about forming a graph based on pixel neighbor relationships, and then finding the connected components of the graph.\r\n      Another approach starts... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2007\/04\/15\/connected-component-labeling-part-4\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[16],"tags":[320,330,350],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/132"}],"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=132"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/132\/revisions"}],"predecessor-version":[{"id":3528,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/132\/revisions\/3528"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=132"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=132"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=132"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}