{"id":359,"date":"2011-01-11T14:05:40","date_gmt":"2011-01-11T19:05:40","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/2011\/01\/11\/freehand-segmentation-in-the-a-b-plane\/"},"modified":"2019-10-29T13:52:13","modified_gmt":"2019-10-29T17:52:13","slug":"freehand-segmentation-in-the-a-b-plane","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2011\/01\/11\/freehand-segmentation-in-the-a-b-plane\/","title":{"rendered":"Freehand segmentation in the a*-b* plane"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p>Today I return to examining this picture of M&amp;Ms:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">url = <span style=\"color: #A020F0\">'https:\/\/blogs.mathworks.com\/images\/steve\/2010\/mms.jpg'<\/span>;\r\nrgb = imread(url);\r\nimshow(rgb)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2011\/freehand_segment_01.jpg\"> <p><a href=\"https:\/\/blogs.mathworks.com\/steve\/2010\/12\/23\/two-dimensional-histograms\/\">Previously I showed<\/a> how to convert pixel colors to the L*a*b* space and how to compute a two-dimensional histogram of the a* and b* color components:\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2010\/two_dim_histogram_05.jpg\"> <\/p>\r\n   <p>Now I want to segment the image based on one of the blobs in this histogram. I used <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2010b\/toolbox\/images\/ref\/imfreehand.html\"><tt>imfreehand<\/tt><\/a> to draw around the blob on the left-left. I can't directly show this interactive operation here, but here's a screen shot:\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2011\/freehand-segment-screenshot.png\"> <\/p>\r\n   <p>Here's the code I used to draw the shape and to get the coordinates of its outline:<\/p><pre>  h = imfreehand(gca);\r\n  % draw shape using mouse\r\n  ab = getPosition(h);<\/pre><p>I stored the P-by-2 matrix of a*-b* coordinates in a MAT-file so I can reproduce the results in this blog post. Here's the\r\n      code copy this MAT-file from its online location to a temporary location and then load it into MATLAB.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">matfile_url = <span style=\"color: #A020F0\">'https:\/\/blogs.mathworks.com\/images\/steve\/2011\/freehand_segment.mat'<\/span>;\r\ntemp_matfile = [tempname <span style=\"color: #A020F0\">'.mat'<\/span>];\r\nurlwrite(matfile_url, temp_matfile);\r\ns = load(temp_matfile);\r\ndelete(temp_matfile)<\/pre><p>Here are the first few saved a*-b* values:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">s.ab(1:5,:)<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n  -71.5173   65.6792\r\n  -70.9335   65.6792\r\n  -70.9335   65.0954\r\n  -70.3497   64.5116\r\n  -69.7659   63.9277\r\n\r\n<\/pre><p>Now I want to ask the question, \"Which original image pixel values have a*-b* values that fall within this shape?\" I'll answer\r\n      the question using <tt>inpolygon<\/tt>.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">lab = lab2double(applycform(rgb, makecform(<span style=\"color: #A020F0\">'srgb2lab'<\/span>)));\r\na = lab(:,:,2);\r\nb = lab(:,:,3);\r\n\r\nin = inpolygon(a, b, s.ab(:,1), s.ab(:,2));\r\nimshow(in)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2011\/freehand_segment_02.jpg\"> <p>That looks promising, but I'd like to visualize this result superimposed over the original image. To do that, I'll fill in\r\n      the holes, find the perimeter of the result, thicken the perimeter a bit to make it easier to see, and then overlay it in\r\n      black. (NOTE: <tt>imoverlay<\/tt> is not part of the Image Processing Toolbox. You can download it from the <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/10502-image-overlay\">MATLAB Central File Exchange<\/a>.)\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">in_filled = imfill(in, <span style=\"color: #A020F0\">'holes'<\/span>);\r\nin_filled_perimeter = bwperim(in_filled);\r\nin_filled_perimeter_thickened = imdilate(in_filled_perimeter, ones(3,3));\r\n\r\nrgb2 = imoverlay(rgb, in_filled_perimeter_thickened, [0 0 0]);\r\nimshow(rgb2)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2011\/freehand_segment_03.jpg\"> <p>Not bad! It looks like we found all the green M&amp;Ms.<\/p>\r\n   <p>There are a couple more things I want to try with this image before giving it a rest. I think that next time I'll look at\r\n      how one might implement a nearest-neighbor classifier.\r\n   <\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_3b349a6020a441daa242b85d09b9b1d0() {\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='3b349a6020a441daa242b85d09b9b1d0 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 3b349a6020a441daa242b85d09b9b1d0';\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 2011 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_3b349a6020a441daa242b85d09b9b1d0()\"><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\n3b349a6020a441daa242b85d09b9b1d0 ##### SOURCE BEGIN #####\r\n%%\r\n% Today I return to examining this picture of M&Ms:\r\n\r\nurl = 'https:\/\/blogs.mathworks.com\/images\/steve\/2010\/mms.jpg';\r\nrgb = imread(url);\r\nimshow(rgb)\r\n\r\n%%\r\n% <https:\/\/blogs.mathworks.com\/steve\/2010\/12\/23\/two-dimensional-histograms\/ \r\n% Previously I showed> how to convert pixel colors to the L*a*b* space and\r\n% how to compute a two-dimensional histogram of the a* and b* color\r\n% components:\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/images\/steve\/2010\/two_dim_histogram_05.jpg>>\r\n%\r\n% Now I want to segment the image based on one of the blobs in this\r\n% histogram. I used \r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2010b\/toolbox\/images\/ref\/imfreehand.html \r\n% |imfreehand|> to draw around the blob on the left-left.\r\n% I can't directly show this interactive operation here, but here's a\r\n% screen shot:\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/images\/steve\/2011\/freehand-segment-screenshot.png>>\r\n%\r\n% Here's the code I used to draw the shape and to get the coordinates of\r\n% its outline:\r\n%\r\n%    h = imfreehand(gca);\r\n%    % draw shape using mouse\r\n%    ab = getPosition(h);\r\n%\r\n% I stored the P-by-2 matrix of a*-b* coordinates in a MAT-file so I can\r\n% reproduce the results in this blog post. Here's the code copy this\r\n% MAT-file from its online location to a temporary location and then load\r\n% it into MATLAB.\r\n\r\nmatfile_url = 'https:\/\/blogs.mathworks.com\/images\/steve\/2011\/freehand_segment.mat';\r\ntemp_matfile = [tempname '.mat'];\r\nurlwrite(matfile_url, temp_matfile);\r\ns = load(temp_matfile);\r\ndelete(temp_matfile)\r\n\r\n%%\r\n% Here are the first few saved a*-b* values:\r\n\r\ns.ab(1:5,:)\r\n\r\n%%\r\n% Now I want to ask the question, \"Which original image pixel values have\r\n% a*-b* values that fall within this shape?\" I'll answer the question using\r\n% |inpolygon|.\r\n\r\nlab = lab2double(applycform(rgb, makecform('srgb2lab')));\r\na = lab(:,:,2);\r\nb = lab(:,:,3);\r\n\r\nin = inpolygon(a, b, s.ab(:,1), s.ab(:,2));\r\nimshow(in)\r\n\r\n%%\r\n% That looks promising, but I'd like to visualize this result superimposed\r\n% over the original image. To do that, I'll fill in the holes, find the\r\n% perimeter of the result, thicken the perimeter a bit to make it easier to\r\n% see, and then overlay it in black. (NOTE: |imoverlay| is not part of the\r\n% Image Processing Toolbox. You can download it from the\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/10502-image-overlay\r\n% MATLAB Central File Exchange>.)\r\n\r\nin_filled = imfill(in, 'holes');\r\nin_filled_perimeter = bwperim(in_filled);\r\nin_filled_perimeter_thickened = imdilate(in_filled_perimeter, ones(3,3));\r\n\r\nrgb2 = imoverlay(rgb, in_filled_perimeter_thickened, [0 0 0]);\r\nimshow(rgb2)\r\n\r\n%%\r\n% Not bad! It looks like we found all the green M&Ms.\r\n%\r\n% There are a couple more things I want to try with this image before\r\n% giving it a rest. I think that next time I'll look at how one might\r\n% implement a nearest-neighbor classifier.\r\n\r\n##### SOURCE END ##### 3b349a6020a441daa242b85d09b9b1d0\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   Today I return to examining this picture of M&amp;Ms:url = 'https:\/\/blogs.mathworks.com\/images\/steve\/2010\/mms.jpg';\r\nrgb = imread(url);\r\nimshow(rgb) Previously I showed how to convert pixel... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2011\/01\/11\/freehand-segmentation-in-the-a-b-plane\/\">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":[114,140,733,727,124,136,416,737,76,36,735,721,362,112,288,729,731],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/359"}],"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=359"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/359\/revisions"}],"predecessor-version":[{"id":3717,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/359\/revisions\/3717"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=359"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=359"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=359"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}