{"id":8577,"date":"2017-05-12T09:00:52","date_gmt":"2017-05-12T13:00:52","guid":{"rendered":"https:\/\/blogs.mathworks.com\/pick\/?p=8577"},"modified":"2017-05-15T10:13:39","modified_gmt":"2017-05-15T14:13:39","slug":"detecting-circles-revisited","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/pick\/2017\/05\/12\/detecting-circles-revisited\/","title":{"rendered":"Detecting Circles, Revisited"},"content":{"rendered":"<div class=\"content\"><!--introduction--><!--\/introduction--><\/p>\n<p><a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/911\">Brett<\/a>&#8216;s Pick this week is <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/34365-circle-finder\"><tt>circleFinder<\/tt><\/a>, an app for, well, finding circles in images.<\/p>\n<p>Many of you know already that I am a big fan of apps&#8211;those that are built into MathWorks toolboxes, and ones that I build myself. I do a tremendous amount of image and video processing, and know my way around the functionality of the Image Processing Toolbox pretty well. Still, finding the &#8220;best&#8221; set of parameters for some of our functions can be challenging&#8211;even for a seasoned user.<\/p>\n<p>Consider, for example, the task of finding circles in an image. This topic comes up quite often&#8211;in imagery from diverse fields. Circle detection is so common, in fact, that I selected <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/9168-detect-circles-with-various-radii-in-grayscale-image-via-hough-transform\">Tao Peng&#8217;s circle detector<\/a> (CircularHough_Grd) as a Pick of the Week back in 2008. At the time, it was one of the one of the best implementations of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Circle_Hough_Transform\">circular Hough transforms<\/a> that I could find.<\/p>\n<p>In the nine years since I wrote about Tao&#8217;s File Exchange submission, the Image Processing Toolbox team hit a home run with their release of our own version of a (Hough) circle detector, with a function called <tt>imfindcircles<\/tt>. Because of that function, detecting circles today is even easier&#8211;and faster than ever before!<\/p>\n<p>However, looking at the documentation for <tt>imfindcircles<\/tt>, you can imagine that it can be difficult to find the working parameters for detecting challenging circles.<\/p>\n<pre class=\"language-matlab\">doc(<span class=\"string\">'imfindcircles'<\/span>)\r\n<\/pre>\n<p>There are two required input arguments (the image, and either the radius or the range of radii of the target circles), and four input parameter-value pairs:<\/p>\n<div>\n<ol>\n<li>&#8216;ObjectPolarity&#8217;, with which we indicate whether whether the circular objects are brighter or darker than the background;<\/li>\n<li>&#8216;Method&#8217;, which specifies the the technique used to compute the accumulator array;<\/li>\n<li>&#8216;Sensitivity&#8217;, to specify the sensitivity for the circular Hough transform accumulator array; and<\/li>\n<li>&#8216;EdgeThreshold&#8217;, which sets the gradient threshold for determining edge pixels in the image.<\/li>\n<\/ol>\n<\/div>\n<p>We can readily use the <a href=\"https:\/\/www.mathworks.com\/help\/images\/ref\/imdistline.html\"><tt>imdistline<\/tt><\/a> tool to measure the radii. And of course we can (usually) ascertain the &#8216;ObjectPolarity&#8217; just by visual inspection. But what about the other parameters?<\/p>\n<pre class=\"language-matlab\">img = imread(<span class=\"string\">'coins.png'<\/span>);\r\n[centers, radii, metric] = imfindcircles(img, [20 30], <span class=\"keyword\">...<\/span>\r\n   <span class=\"string\">'ObjectPolarity'<\/span>, <span class=\"string\">'Bright'<\/span>);\r\nimshow(img)\r\nviscircles(centers,radii);\r\n<\/pre>\n<p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/pick\/files\/coinsDetected.png\" alt=\"\"> <\/p>\n<p>That detection worked beautifully with default input parameters. But say we wanted to detect (and count) cells in this blood-smear image from the Centers for Disease Control (CDC)?<\/p>\n<pre class=\"language-matlab\">img = imread(<span class=\"string\">'Babesia_thin_giemsa_tetrad4.jpg'<\/span>);\r\n[centers, radii, metric] = imfindcircles(img, [20 30], <span class=\"keyword\">...<\/span>\r\n   <span class=\"string\">'ObjectPolarity'<\/span>, <span class=\"string\">'Dark'<\/span>);\r\nimshow(img)\r\nviscircles(centers,radii);\r\n<\/pre>\n<p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/pick\/files\/bloodSmear1.png\" alt=\"\"> <\/p>\n<p>Default parameters fail entirely!<\/p>\n<p>That&#8217;s where the circleFinder app comes in:<\/p>\n<p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/pick\/files\/circleFinder1.png\" alt=\"\"> <\/p>\n<p>Check out this video showing it in action!<\/p>\n<p>\n<embed src=\"https:\/\/blogs.mathworks.com\/pick\/files\/circeFinderVideoAsMP4.mp4\" height=\"450\" width=\"800\">\n<\/p>\n<p>Give it a try next time you need to detect circles. If you like it, you can even <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/matlab.apputil.install.html\">install it as an app<\/a> in your Apps Toolbar. And make sure you check out <a href=\"https:\/\/www.youtube.com\/watch?v=dgxvBBn_oIQ\">Valerie&#8217;s really nice video<\/a> on the tool!<\/p>\n<p>As always, I welcome your <a href=\"https:\/\/blogs.mathworks.com\/pick\/?p=8577#respond\">thoughts and comments<\/a>.<\/p>\n<p><script language=\"JavaScript\"> <!-- \n    function grabCode_b417bfcbc3384ffca097aa2f29898a82() {\n        \/\/ Remember the title so we can use it in the new page\n        title = document.title;\n\n        \/\/ Break up these strings so that their presence\n        \/\/ in the Javascript doesn't mess up the search for\n        \/\/ the MATLAB code.\n        t1='b417bfcbc3384ffca097aa2f29898a82 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\n        t2='##### ' + 'SOURCE END' + ' #####' + ' b417bfcbc3384ffca097aa2f29898a82';\n    \n        b=document.getElementsByTagName('body')[0];\n        i1=b.innerHTML.indexOf(t1)+t1.length;\n        i2=b.innerHTML.indexOf(t2);\n \n        code_string = b.innerHTML.substring(i1, i2);\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\n\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \n        \/\/ in the XML parser.\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\n        \/\/ doesn't go ahead and substitute the less-than character. \n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\n\n        copyright = 'Copyright 2017 The MathWorks, Inc.';\n\n        w = window.open();\n        d = w.document;\n        d.write('\n\n<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\n\n\\n');\n\n        d.title = title + ' (MATLAB code)';\n        d.close();\n    }   \n     --> <\/script><\/p>\n<p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><a href=\"javascript:grabCode_b417bfcbc3384ffca097aa2f29898a82()\"><span style=\"font-size: x-small;        font-style: italic;\">Get<br \/>\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><\/p>\n<p>      Published with MATLAB&reg; R2017a<\/p>\n<\/div>\n<p><!--\nb417bfcbc3384ffca097aa2f29898a82 ##### SOURCE BEGIN #####\n%% Detecting Circles in Images, Revisited\n%% \n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/911 Brett>'s Pick this week\n% is\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/34365-circle-finder |circleFinder|>,\n% an app for, well, finding circles in images.\n%\n% Many of you know already that I am a big fan of appsREPLACE_WITH_DASH_DASHthose that are\n% built into MathWorks toolboxes, and ones that I build myself. I do a\n% tremendous amount of image and video processing, and know my way\n% around the functionality of the Image Processing Toolbox pretty\n% well. Still, finding the \"best\" set of parameters for some of our\n% functions can be challengingREPLACE_WITH_DASH_DASHeven for a seasoned user. \n%\n% Consider, for example, the task of finding circles in an image. This\n% topic comes up quite oftenREPLACE_WITH_DASH_DASHin imagery from diverse fields. Circle \n% detection is so common, in fact, that I selected\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/9168-detect-circles-with-various-radii-in-grayscale-image-via-hough-transform Tao Peng's circle detector> \n% (CircularHough_Grd) as a Pick of the Week back in 2008. At the time, it was one of the one of the best\n% implementations of <https:\/\/en.wikipedia.org\/wiki\/Circle_Hough_Transform circular Hough transforms> that I could find. \n\n%%\n% In the nine years since I wrote about Tao's File Exchange\n% submission, the Image Processing Toolbox team hit a home run with\n% their release of our own version of a (Hough) circle detector, with\n% a function called |imfindcircles|. Because of that function,\n% detecting circles today is even easierREPLACE_WITH_DASH_DASHand faster than ever before!\n\n%%\n% However, looking at the documentation for |imfindcircles|, you can\n% imagine that it can be difficult to find the working parameters for\n% detecting challenging circles.\n\n%%\n%   doc('imfindcircles')\n\n%%\n% There are two required input arguments (the image, and either the\n% radius or the range of radii of the target circles), and four input\n% parameter-value pairs:\n\n%%\n% \n% # 'ObjectPolarity', with which we indicate whether whether the\n% circular objects are brighter or darker than the background;\n% # 'Method', which specifies the the technique used to compute the\n% accumulator array;\n% # 'Sensitivity', to specify the sensitivity for the circular Hough\n% transform accumulator array;\n% and\n% # 'EdgeThreshold', which sets the gradient threshold for determining\n% edge pixels in the image.\n\n%% \n% We can readily use the <https:\/\/www.mathworks.com\/help\/images\/ref\/imdistline.html |imdistline|> tool to measure the radii. And\n% of course we can (usually) ascertain the 'ObjectPolarity' just by\n% visual inspection. But what about the other parameters?\n\n%%\n%   img = imread('coins.png');\n%   [centers, radii, metric] = imfindcircles(img, [20 30], ...\n%      'ObjectPolarity', 'Bright');\n%   imshow(img)\n%   viscircles(centers,radii);\n\n%%\n% \n% <<https:\/\/blogs.mathworks.com\/pick\/files\/coinsDetected.png>>\n% \n\n%% \n% That detection worked beautifully with default input parameters. But\n% say we wanted to detect (and count) cells in this blood-smear image\n% from the Centers for Disease Control (CDC)?\n%%\n%   img = imread('Babesia_thin_giemsa_tetrad4.jpg');\n%   [centers, radii, metric] = imfindcircles(img, [20 30], ...\n%      'ObjectPolarity', 'Dark');\n%   imshow(img)\n%   viscircles(centers,radii);\n%%\n% \n% <<https:\/\/blogs.mathworks.com\/pick\/files\/bloodSmear1.png>>\n% \n\n%% \n% Default parameters fail entirely!\n\n%%\n% That's where the circleFinder app comes in:\n%%\n% \n% <<https:\/\/blogs.mathworks.com\/pick\/files\/circleFinder1.png>>\n% \n\n%%\n% Check out this video showing it in action!\n\n%%\n% https:\/\/blogs.mathworks.com\/pick\/files\/circeFinderVideoAsMP4.mp4\n% \n\n%% \n% Give it a try next time you need to detect circles. If you like it,\n% you can even <https:\/\/www.mathworks.com\/help\/matlab\/ref\/matlab.apputil.install.html install it as an app>\n% in your Apps Toolbar. And make\n% sure you check out <https:\/\/www.youtube.com\/watch?v=dgxvBBn_oIQ Valerie's really nice video> on the tool!\n%%\n% As always, I welcome your\n% <https:\/\/blogs.mathworks.com\/pick\/?p=8577#respond thoughts and comments>.\n##### SOURCE END ##### b417bfcbc3384ffca097aa2f29898a82\n--><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/pick\/files\/coinsDetected.png\" onError=\"this.style.display ='none';\" \/><\/div>\n<p>\nBrett&#8216;s Pick this week is circleFinder, an app for, well, finding circles in images.<br \/>\nMany of you know already that I am a big fan of apps&#8211;those that are built into MathWorks toolboxes,&#8230; <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/pick\/2017\/05\/12\/detecting-circles-revisited\/\">read more >><\/a><\/p>\n","protected":false},"author":34,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[16],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/8577"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/users\/34"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/comments?post=8577"}],"version-history":[{"count":11,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/8577\/revisions"}],"predecessor-version":[{"id":8598,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/8577\/revisions\/8598"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/media?parent=8577"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/categories?post=8577"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/tags?post=8577"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}