{"id":343,"date":"2010-10-07T12:54:39","date_gmt":"2010-10-07T16:54:39","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/2010\/10\/07\/disconnected-component-labeling-part-2\/"},"modified":"2019-10-29T13:36:11","modified_gmt":"2019-10-29T17:36:11","slug":"disconnected-component-labeling-part-2","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2010\/10\/07\/disconnected-component-labeling-part-2\/","title":{"rendered":"Disconnected component labeling: part 2"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p><a href=\"https:\/\/blogs.mathworks.com\/steve\/2010\/10\/01\/disconnected-component-labeling-part-1\/\">Last week I wrote<\/a> about a user's request to perform connected-component labeling with an unusual connectivity definition:\r\n   <\/p><pre>  [1 0 1 0 1]<\/pre><p>This definition, which is not supported by Image Processing Toolbox functions, has the effect of dividing an image into two\r\n      noninteracting subimages, one containing the even columns and one containing the odd columns.\r\n   <\/p>\r\n   <p>That description gives us our needed clue about how to implement such a thing. We split the image up into the two subimages,\r\n      find the connected components in each subimage, and then merge the results.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">bw = [1     1     1     0     0     0     0     0\r\n    1     1     1     0     1     1     0     0\r\n    1     1     1     0     1     1     0     0\r\n    1     1     1     0     0     0     1     0\r\n    1     1     1     0     0     0     1     0\r\n    1     1     1     0     0     0     1     0\r\n    1     1     1     0     0     1     1     0\r\n    1     1     1     0     0     0     0     0]<\/pre><pre style=\"font-style:oblique\">\r\nbw =\r\n\r\n     1     1     1     0     0     0     0     0\r\n     1     1     1     0     1     1     0     0\r\n     1     1     1     0     1     1     0     0\r\n     1     1     1     0     0     0     1     0\r\n     1     1     1     0     0     0     1     0\r\n     1     1     1     0     0     0     1     0\r\n     1     1     1     0     0     1     1     0\r\n     1     1     1     0     0     0     0     0\r\n\r\n<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">bw1 = bw(:,1:2:end)<\/pre><pre style=\"font-style:oblique\">\r\nbw1 =\r\n\r\n     1     1     0     0\r\n     1     1     1     0\r\n     1     1     1     0\r\n     1     1     0     1\r\n     1     1     0     1\r\n     1     1     0     1\r\n     1     1     0     1\r\n     1     1     0     0\r\n\r\n<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">bw2 = bw(:,2:2:end)<\/pre><pre style=\"font-style:oblique\">\r\nbw2 =\r\n\r\n     1     0     0     0\r\n     1     0     1     0\r\n     1     0     1     0\r\n     1     0     0     0\r\n     1     0     0     0\r\n     1     0     0     0\r\n     1     0     1     0\r\n     1     0     0     0\r\n\r\n<\/pre><p>Find connected components in each subimage assuming that each pixel is connected only to its east and west neighbors.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">cc1 = bwconncomp(bw1, [0 0 0; 1 1 1; 0 0 0])<\/pre><pre style=\"font-style:oblique\">\r\ncc1 = \r\n\r\n    Connectivity: [3x3 double]\r\n       ImageSize: [8 4]\r\n      NumObjects: 12\r\n    PixelIdxList: {1x12 cell}\r\n\r\n<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">cc2 = bwconncomp(bw2, [0 0 0; 1 1 1; 0 0 0])<\/pre><pre style=\"font-style:oblique\">\r\ncc2 = \r\n\r\n    Connectivity: [3x3 double]\r\n       ImageSize: [8 4]\r\n      NumObjects: 11\r\n    PixelIdxList: {[1]  [2]  [3]  [4]  [5]  [6]  [7]  [8]  [18]  [19]  [23]}\r\n\r\n<\/pre><p>Now we have to go through a bit of work to modify the PixelIdxList for each connected component.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">size_bw1 = size(bw1);\r\nsize_bw = size(bw);\r\n<span style=\"color: #0000FF\">for<\/span> k = 1:numel(cc1.PixelIdxList)\r\n    idx = cc1.PixelIdxList{k};\r\n    [r,c] = ind2sub(size_bw1, idx);\r\n    new_idx = sub2ind(size_bw, r, 2*c-1);\r\n    cc1.PixelIdxList{k} = new_idx;\r\n<span style=\"color: #0000FF\">end<\/span>\r\n\r\nsize_bw2 = size(bw2);\r\n<span style=\"color: #0000FF\">for<\/span> k = 1:numel(cc2.PixelIdxList)\r\n    idx = cc2.PixelIdxList{k};\r\n    [r,c] = ind2sub(size_bw2, idx);\r\n    new_idx = sub2ind(size_bw, r, 2*c);\r\n    cc2.PixelIdxList{k} = new_idx;\r\n<span style=\"color: #0000FF\">end<\/span><\/pre><p>Now the pixel index lists for each connected component have been corrected to refer to pixel locations in the original image.\r\n      Next we make a new connected component struct containing both sets of components.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">cc = cc1;\r\ncc.ImageSize = size_bw;\r\ncc.NumObjects = cc1.NumObjects + cc2.NumObjects;\r\ncc.PixelIdxList = [cc1.PixelIdxList, cc2.PixelIdxList]<\/pre><pre style=\"font-style:oblique\">\r\ncc = \r\n\r\n    Connectivity: [3x3 double]\r\n       ImageSize: [8 8]\r\n      NumObjects: 23\r\n    PixelIdxList: {1x23 cell}\r\n\r\n<\/pre><p>Finally, let's visualize what we ended up with by converting to a label matrix:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">L = labelmatrix(cc)<\/pre><pre style=\"font-style:oblique\">\r\nL =\r\n\r\n    1   13    1    0    0    0    0    0\r\n    2   14    2    0    2   21    0    0\r\n    3   15    3    0    3   22    0    0\r\n    4   16    4    0    0    0    9    0\r\n    5   17    5    0    0    0   10    0\r\n    6   18    6    0    0    0   11    0\r\n    7   19    7    0    0   23   12    0\r\n    8   20    8    0    0    0    0    0\r\n\r\n<\/pre><p>So it can be done, although it takes some extra coding. I confess, though, that I'm still not exactly sure why one might want\r\n      to do connected component labeling this way.\r\n   <\/p>\r\n   <p>Anyone have any inspiration about this? Creative ideas you'd like to share? Post your comments here.<\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_a58aba85e437451c99cdc8f37571cbb5() {\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='a58aba85e437451c99cdc8f37571cbb5 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' a58aba85e437451c99cdc8f37571cbb5';\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 2010 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_a58aba85e437451c99cdc8f37571cbb5()\"><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.11<br><\/p>\r\n<\/div>\r\n<!--\r\na58aba85e437451c99cdc8f37571cbb5 ##### SOURCE BEGIN #####\r\n%%\r\n% <https:\/\/blogs.mathworks.com\/steve\/2010\/10\/01\/disconnected-component-labeling-part-1\/ \r\n% Last week I wrote> about a user's request to perform connected-component \r\n% labeling with an unusual connectivity definition:\r\n%\r\n%    [1 0 1 0 1]\r\n%\r\n% This definition, which is not supported by Image Processing Toolbox\r\n% functions, has the effect of dividing an image into two noninteracting\r\n% subimages, one containing the even columns and one containing the odd\r\n% columns.\r\n%\r\n% That description gives us our needed clue about how to implement such a\r\n% thing. We split the image up into the two subimages, find the connected components\r\n% in each subimage, and then merge the results.\r\n\r\nbw = [1     1     1     0     0     0     0     0\r\n    1     1     1     0     1     1     0     0\r\n    1     1     1     0     1     1     0     0\r\n    1     1     1     0     0     0     1     0\r\n    1     1     1     0     0     0     1     0\r\n    1     1     1     0     0     0     1     0\r\n    1     1     1     0     0     1     1     0\r\n    1     1     1     0     0     0     0     0]\r\n\r\n%%\r\nbw1 = bw(:,1:2:end)\r\n\r\n%%\r\nbw2 = bw(:,2:2:end)\r\n\r\n%%\r\n% Find connected components in each subimage assuming that each pixel is\r\n% connected only to its east and west neighbors.\r\ncc1 = bwconncomp(bw1, [0 0 0; 1 1 1; 0 0 0])\r\n\r\n%%\r\ncc2 = bwconncomp(bw2, [0 0 0; 1 1 1; 0 0 0])\r\n\r\n%%\r\n% Now we have to go through a bit of work to modify the PixelIdxList for\r\n% each connected component.\r\n\r\nsize_bw1 = size(bw1);\r\nsize_bw = size(bw);\r\nfor k = 1:numel(cc1.PixelIdxList)\r\n    idx = cc1.PixelIdxList{k};\r\n    [r,c] = ind2sub(size_bw1, idx);\r\n    new_idx = sub2ind(size_bw, r, 2*c-1);\r\n    cc1.PixelIdxList{k} = new_idx;\r\nend\r\n\r\nsize_bw2 = size(bw2);\r\nfor k = 1:numel(cc2.PixelIdxList)\r\n    idx = cc2.PixelIdxList{k};\r\n    [r,c] = ind2sub(size_bw2, idx);\r\n    new_idx = sub2ind(size_bw, r, 2*c);\r\n    cc2.PixelIdxList{k} = new_idx;\r\nend\r\n\r\n%%\r\n% Now the pixel index lists for each connected component have been\r\n% corrected to refer to pixel locations in the original image. Next we make\r\n% a new connected component struct containing both sets of components.\r\n\r\ncc = cc1;\r\ncc.ImageSize = size_bw;\r\ncc.NumObjects = cc1.NumObjects + cc2.NumObjects;\r\ncc.PixelIdxList = [cc1.PixelIdxList, cc2.PixelIdxList]\r\n\r\n%%\r\n% Finally, let's visualize what we ended up with by converting to a label\r\n% matrix:\r\n\r\nL = labelmatrix(cc)\r\n\r\n%%\r\n% So it can be done, although it takes some extra coding. I confess,\r\n% though, that I'm still not exactly sure why one might want to do\r\n% connected component labeling this way.\r\n%\r\n% Anyone have any inspiration about this? Creative ideas you'd like to\r\n% share? Post your comments here.\r\n\r\n##### SOURCE END ##### a58aba85e437451c99cdc8f37571cbb5\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   Last week I wrote about a user's request to perform connected-component labeling with an unusual connectivity definition:\r\n     [1 0 1 0 1]This definition, which is not supported by Image... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2010\/10\/07\/disconnected-component-labeling-part-2\/\">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":[561,470,563,162,190,468],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/343"}],"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=343"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/343\/revisions"}],"predecessor-version":[{"id":3699,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/343\/revisions\/3699"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}