{"id":1949,"date":"2016-06-14T17:35:19","date_gmt":"2016-06-14T21:35:19","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=1949"},"modified":"2019-11-01T16:43:15","modified_gmt":"2019-11-01T20:43:15","slug":"image-binarization-otsus-method","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2016\/06\/14\/image-binarization-otsus-method\/","title":{"rendered":"Image binarization &#8211; Otsu&#8217;s method"},"content":{"rendered":"<div class=\"content\"><p>In my <a href=\"https:\/\/blogs.mathworks.com\/steve\/2016\/05\/16\/image-binarization-new-r2016a-functions\/\">16-May-2016 post<\/a> about image binarization, I talked about the new binarization functions in R2016a. Today I want to switch gears and talk about Otsu's method, one of the algorithms underlying <a href=\"https:\/\/www.mathworks.com\/help\/images\/ref\/imbinarize.html\"><tt>imbinarize<\/tt><\/a>.<\/p><p>(A bonus feature of today's blog post is a demo of <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/yyaxis.html\"><tt>yyaxis<\/tt><\/a>, a new feature of MATLAB R2016a.)<\/p><p>Otsu's method is named for Nobuyuki Otsu, who published it in <i>IEEE Transactions on Systems, Man, and Cybernetics<\/i>, vol. SMC-9, no. 1, January 1979. At this time, researchers had already explored a variety of ways to choose a threshold automatically by examining the histogram of image pixel values. The basic idea is to look for two peaks, representing foreground and background pixel values, and pick a point in between the two peaks as the threshold value.<\/p><p>Here's a simple example using the coins image.<\/p><pre class=\"codeinput\">I = imread(<span class=\"string\">'coins.png'<\/span>);\r\nimshow(I)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/binarization_otsu_method_01.png\" alt=\"\"> <pre class=\"codeinput\">imhist(I)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/binarization_otsu_method_02.png\" alt=\"\"> <p>The function <tt>imbinarize<\/tt> calls <tt>otsuthresh<\/tt> to get a normalized threshold value.<\/p><pre class=\"codeinput\">t = otsuthresh(histcounts(I,-0.5:255.5))\r\n<\/pre><pre class=\"codeoutput\">\r\nt =\r\n\r\n    0.4941\r\n\r\n<\/pre><p>Let's see where that threshold is.<\/p><pre class=\"codeinput\">hold <span class=\"string\">on<\/span>\r\nplot(255*[t t], ylim, <span class=\"string\">'r'<\/span>, <span class=\"string\">'LineWidth'<\/span>, 5)\r\nhold <span class=\"string\">off<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/binarization_otsu_method_03.png\" alt=\"\"> <p>And here is the thresholded coins image.<\/p><pre class=\"codeinput\">imshow(imbinarize(I,t))\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/binarization_otsu_method_04.png\" alt=\"\"> <p>How does this threshold selection work? It is based on entirely on the set of histogram counts. To show the computation, I'll adopt the notation from the paper. Pixels can take on the set of values $i = 1,2,\\ldots,L$. The histogram count for pixel value $i$ is $n_i$, and the associated probability is $p_i = n_i\/N$, where $N$ is the number of image pixels. (I'm using the word <i>probability<\/i> here somewhat loosely, in the relative frequency sense.)<\/p><p>The thresholding task is formulated as the problem of dividing image pixels into two classes. $C_0$ is the set of pixels with values $[1,\\ldots,k]$, and $C_1$ is the set of pixels with values in the range $[k+1,\\ldots,L]$.<\/p><p>The overall class probabilities, $\\omega_0$ and $\\omega_1$, are:<\/p><p>$$\\omega_0 = \\sum_{i=1}^k p_i = \\omega(k)$$<\/p><p>$$\\omega_1 = \\sum_{i=k+1}^L p_i = 1 - \\omega_0(k)$$<\/p><p>The class means, $\\mu_0$ and $\\mu_1$, are the mean values of the pixels in $C_0$ and $C_1$. They are given by:<\/p><p>$$\\mu_0 = \\sum_{i=1}^k i p_i \/ \\omega_0 = \\mu(k)\/\\omega(k)$$<\/p><p>$$\\mu_1 = \\sum_{i=k+1}^L i p_i \/ \\omega_1 = \\frac{\\mu_T - \\mu(k)}{1 -\r\n\\omega(k)}$$<\/p><p>where<\/p><p>$$\\mu(k) = \\sum_{i-1}^k i p_i$$<\/p><p>and $\\mu_T$, the mean pixel value for the total image, is:<\/p><p>$$\\mu_T = \\sum_{i=1}^L i p_i.$$<\/p><p>The class variances, $\\sigma_0^2$ and $\\sigma_1^2$, are:<\/p><p>$$\\sigma_0^2 = \\sum_{i = 1}^k (i - \\mu_0)^2 p_i \/ \\omega_0$$<\/p><p>$$\\sigma_1^2 = \\sum_{i = k+1}^L (i - \\mu_1)^2 pi \/ \\omega_1.$$<\/p><p>Otsu mentions three measures of \"good\" class separability: within-class variance ($\\lambda$), between-class variance ($\\kappa$), and total variance ($\\eta$). These are given by:<\/p><p>$$\\lambda = \\sigma_B^2$$<\/p><p>$$\\kappa = \\sigma_T^2\/\\sigma_W^2$$<\/p><p>$$\\eta = \\sigma_B^2\/\\sigma_T^2$$<\/p><p>where<\/p><p>$$\\sigma_W^2 = \\omega_0 \\sigma_0^2 + \\omega_1 \\sigma_1^2$$<\/p><p>$$\\sigma_B^2 = \\omega_0 (\\mu_0 - \\mu_T)^2 + \\omega_1 (\\mu_1 - \\mu_T)^2 =\r\n\\omega_0 \\omega_1 (\\mu_1 - \\mu_0)^2.$$<\/p><p>He goes on to point out that maximizing any of these criteria is equivalent to maximizing the others. Further, maximizing $\\eta$ is the same as maximizing $\\sigma_B^2$, which can be rewritten in terms of the selected threshold, $k$:<\/p><p>$$ \\sigma_B^2(k) = \\frac{[\\mu_T \\omega(k) - \\mu(k)]^2}{\\omega(k) [1 -\r\n\\omega(k)]}.$$<\/p><p>The equation above is the heart of the algorithm. $\\sigma_B^2$ is computed for all possible threshold values, and we choose as our threshold the value that maximizes it.<\/p><p>OK, that was a lot of equations, but there's really not that much involved in computing the key quantity, $\\sigma_B^2(k)$. Here's what the computation looks like for the coins image.<\/p><pre class=\"codeinput\">counts = imhist(I);\r\nL = length(counts);\r\np = counts \/ sum(counts);\r\nomega = cumsum(p);\r\nmu = cumsum(p .* (1:L)');\r\nmu_t = mu(end);\r\n\r\nsigma_b_squared = (mu_t * omega - mu).^2 .\/ (omega .* (1 - omega));\r\n<\/pre><p>Using <tt>yyaxis<\/tt>, a new R2016a feature, let's plot the histogram and $\\sigma_B^2$ together.<\/p><pre class=\"codeinput\">close <span class=\"string\">all<\/span>\r\nyyaxis <span class=\"string\">left<\/span>\r\nplot(counts)\r\nylabel(<span class=\"string\">'Histogram'<\/span>)\r\n\r\nyyaxis <span class=\"string\">right<\/span>\r\nplot(sigma_b_squared)\r\nylabel(<span class=\"string\">'\\sigma_B^2'<\/span>)\r\n\r\nxlim([1 256])\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/binarization_otsu_method_05.png\" alt=\"\"> <p>Otsu's method chooses the place where $\\sigma_B^2$ is the highest as the threshold.<\/p><pre class=\"codeinput\">[~,k] = max(sigma_b_squared);\r\nhold <span class=\"string\">on<\/span>\r\nplot([k k],ylim,<span class=\"string\">'LineWidth'<\/span>,5)\r\nhold <span class=\"string\">off<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/binarization_otsu_method_06.png\" alt=\"\"> <p>Here's another example. This is a public-domain light microscope image of Lily mitosis. (The <a href=\"http:\/\/www.cellimagelibrary.org\/images\/205\">original image<\/a> is courtesy Andrew S. Bajer, University of Oregon, Eugene, OR. This version is slightly cropped.)<\/p><pre class=\"codeinput\">url = <span class=\"string\">'https:\/\/blogs.mathworks.com\/steve\/files\/205.jpg'<\/span>;\r\nI = rgb2gray(imread(url));\r\nclf\r\nimshow(I)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/binarization_otsu_method_07.png\" alt=\"\"> <pre class=\"codeinput\">counts = imhist(I);\r\nL = length(counts);\r\np = counts \/ sum(counts);\r\nomega = cumsum(p);\r\nmu = cumsum(p .* (1:L)');\r\nmu_t = mu(end);\r\n\r\nsigma_b_squared = (mu_t * omega - mu).^2 .\/ (omega .* (1 - omega));\r\n\r\nclose <span class=\"string\">all<\/span>\r\nyyaxis <span class=\"string\">left<\/span>\r\nplot(counts)\r\nylabel(<span class=\"string\">'Histogram'<\/span>)\r\n\r\nyyaxis <span class=\"string\">right<\/span>\r\nplot(sigma_b_squared)\r\nylabel(<span class=\"string\">'\\sigma_B^2'<\/span>)\r\n\r\n[~,k] = max(sigma_b_squared);\r\nhold <span class=\"string\">on<\/span>\r\nplot([k k],ylim,<span class=\"string\">'LineWidth'<\/span>,5)\r\nhold <span class=\"string\">off<\/span>\r\n\r\nxlim([1 256])\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/binarization_otsu_method_08.png\" alt=\"\"> <pre class=\"codeinput\">clf\r\nimshow(imbinarize(I))\r\ntitle(<span class=\"string\">'Thresholded cell image'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/binarization_otsu_method_09.png\" alt=\"\"> <p>If <tt>imbinarize<\/tt> handles this computation automatically, then why did we also provide a function called <a href=\"https:\/\/www.mathworks.com\/help\/images\/ref\/otsuthresh.html\"><tt>otsuthresh<\/tt><\/a>? The answer is that <tt>imbinarize<\/tt> takes an image as input, although Otsu's method does not require the original image, only the image's histogram. If you have a situation where you want to compute a threshold based <b>only<\/b> on a histogram, then you can call <tt>otsuthresh<\/tt> directly. That's why it is there.<\/p><p>To wrap up this week's discussion, I want to point out that a couple of blog readers recommended something called the <i>Triangle method<\/i> for automatic gray-scale image thresholding. If you want to try this for yourself, there is an implementation on the File Exchange. I have not had a chance yet to experiment with it.<\/p><p>Next time I'll talk about the algorithm used by <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/28047-gray-image-thresholding-using-the-triangle-method\"><tt>imbinarize<\/tt><\/a> for locally adaptive thresholding.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_7a6499d359984c5bbbbf01f04253910a() {\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='7a6499d359984c5bbbbf01f04253910a ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 7a6499d359984c5bbbbf01f04253910a';\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        copyright = 'Copyright 2016 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 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');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\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_7a6499d359984c5bbbbf01f04253910a()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2016a<br><\/p><\/div><!--\r\n7a6499d359984c5bbbbf01f04253910a ##### SOURCE BEGIN #####\r\n%% \r\n% In my <https:\/\/blogs.mathworks.com\/steve\/2016\/05\/16\/image-binarization-new-r2016a-functions\/ \r\n% 16-May-2016 post> about image binarization, I talked about the new\r\n% binarization functions in R2016a. Today I want to switch gears and talk\r\n% about Otsu's method, one of the algorithms underlying \r\n% <https:\/\/www.mathworks.com\/help\/images\/ref\/imbinarize.html |imbinarize|>.\r\n%\r\n% (A bonus feature of today's blog post is a demo of\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/yyaxis.html |yyaxis|>, a new\r\n% feature of MATLAB R2016a.)\r\n%\r\n% Otsu's method is named for Nobuyuki Otsu, who published it in _IEEE\r\n% Transactions on Systems, Man, and Cybernetics_, vol. SMC-9, no. 1, January\r\n% 1979. At this time, researchers had already explored a variety of ways to\r\n% choose a threshold automatically by examining the histogram of image pixel\r\n% values. The basic idea is to look for two peaks, representing foreground\r\n% and background pixel values, and pick a point in between the two peaks as\r\n% the threshold value.\r\n%\r\n% Here's a simple example using the coins image.\r\n\r\nI = imread('coins.png');\r\nimshow(I)\r\n\r\n%%\r\nimhist(I)\r\n\r\n%%\r\n% The function |imbinarize| calls |otsuthresh| to get a normalized threshold\r\n% value.\r\n\r\nt = otsuthresh(histcounts(I,-0.5:255.5))\r\n\r\n%%\r\n% Let's see where that threshold is.\r\nhold on\r\nplot(255*[t t], ylim, 'r', 'LineWidth', 5)\r\nhold off\r\n\r\n%%\r\n% And here is the thresholded coins image.\r\nimshow(imbinarize(I,t))\r\n\r\n%%\r\n% How does this threshold selection work? It is based on entirely on the set\r\n% of histogram counts. To show the computation, I'll adopt the notation from\r\n% the paper. Pixels can take on the set of values $i = 1,2,\\ldots,L$. The\r\n% histogram count for pixel value $i$ is $n_i$, and the associated\r\n% probability is $p_i = n_i\/N$, where $N$ is the number of image pixels.\r\n% (I'm using the word _probability_ here somewhat loosely, in the relative\r\n% frequency sense.)\r\n%\r\n% The thresholding task is formulated as the problem of dividing image\r\n% pixels into two classes. $C_0$ is the set of pixels with values\r\n% $[1,\\ldots,k]$, and $C_1$ is the set of pixels with values in the range\r\n% $[k+1,\\ldots,L]$.\r\n%\r\n% The overall class probabilities, $\\omega_0$ and $\\omega_1$, are:\r\n%\r\n% $$\\omega_0 = \\sum_{i=1}^k p_i = \\omega(k)$$\r\n%\r\n% $$\\omega_1 = \\sum_{i=k+1}^L p_i = 1 = \\omega(k)$$\r\n%\r\n% The class means, $\\mu_0$ and $\\mu_1$, are the mean values of the pixels in\r\n% $C_0$ and $C_1$. They are given by:\r\n%\r\n% $$\\mu_0 = \\sum_{i=1}^k i p_i \/ \\omega_0 = \\mu(k)\/\\omega(k)$$\r\n%\r\n% $$\\mu_1 = \\sum_{i=k+1}^L i p_i \/ \\omega_1 = \\frac{\\mu_T - \\mu(k)}{1 -\r\n% \\omega(k)}$$\r\n%\r\n% where\r\n%\r\n% $$\\mu(k) = \\sum_{i-1}^k i p_i$$\r\n%\r\n% and $\\mu_T$, the mean pixel value for the total image, is:\r\n%\r\n% $$\\mu_T = \\sum_{i=1}^L i p_i.$$\r\n%\r\n% The class variances, $\\sigma_0^2$ and $\\sigma_1^2$, are:\r\n%\r\n% $$\\sigma_0^2 = \\sum_{i = 1}^k (i - \\mu_0)^2 p_i \/ \\omega_0$$\r\n%\r\n% $$\\sigma_1^2 = \\sum_{i = k+1}^L (i - \\mu_1)^2 pi \/ \\omega_1.$$\r\n%\r\n% Otsu mentions three measures of \"good\" class separability: within-class\r\n% variance ($\\lambda$), between-class variance ($\\kappa$), and total\r\n% variance ($\\eta$). These are given by:\r\n%\r\n% $$\\lambda = \\sigma_B^2$$\r\n%\r\n% $$\\kappa = \\sigma_T^2\/\\sigma_W^2$$\r\n%\r\n% $$\\eta = \\sigma_B^2\/\\sigma_T^2$$\r\n%\r\n% where\r\n%\r\n% $$\\sigma_W^2 = \\omega_0 \\sigma_0^2 + \\omega_1 \\sigma_1^2$$\r\n%\r\n% $$\\sigma_B^2 = \\omega_0 (\\mu_0 - \\mu_T)^2 + \\omega_1 (\\mu_1 - \\mu_T)^2 =\r\n% \\omega_0 \\omega_1 (\\mu_1 - \\mu_0)^2.$$\r\n%\r\n% He goes on to point out that maximizing any of these criteria is\r\n% equivalent to maximizing the others. Further, maximizing $\\eta$ is the\r\n% same as maximizing $\\sigma_B^2$, which can be rewritten in terms of the\r\n% selected threshold, $k$:\r\n%\r\n% $$ \\sigma_B^2(k) = \\frac{[\\mu_T \\omega(k) - \\mu(k)]^2}{\\omega(k) [1 -\r\n% \\omega(k)]}.$$\r\n%\r\n% The equation above is the heart of the algorithm. $\\sigma_B^2$ is computed\r\n% for all possible threshold values, and we choose as our threshold the\r\n% value that maximizes it.\r\n%\r\n% OK, that was a lot of equations, but there's really not that much involved\r\n% in computing the key quantity, $\\sigma_B^2(k)$. Here's what the\r\n% computation looks like for the coins image.\r\n\r\ncounts = imhist(I);\r\nL = length(counts);\r\np = counts \/ sum(counts);\r\nomega = cumsum(p);\r\nmu = cumsum(p .* (1:L)');\r\nmu_t = mu(end);\r\n\r\nsigma_b_squared = (mu_t * omega - mu).^2 .\/ (omega .* (1 - omega));\r\n\r\n%%\r\n% Using |yyaxis|, a new R2016a feature, let's plot the histogram and\r\n% $\\sigma_B^2$ together.\r\n\r\nclose all\r\nyyaxis left\r\nplot(counts)\r\nylabel('Histogram')\r\n\r\nyyaxis right\r\nplot(sigma_b_squared)\r\nylabel('\\sigma_B^2')\r\n\r\nxlim([1 256])\r\n\r\n%%\r\n% Otsu's method chooses the place where $\\sigma_B^2$ is the highest as the\r\n% threshold.\r\n\r\n[~,k] = max(sigma_b_squared);\r\nhold on\r\nplot([k k],ylim,'LineWidth',5)\r\nhold off\r\n\r\n%%\r\n% Here's another example. This is a public-domain light microscope image of\r\n% Lily mitosis. (The <http:\/\/www.cellimagelibrary.org\/images\/205 original\r\n% image> is courtesy Andrew S. Bajer, University of Oregon, Eugene, OR. This\r\n% version is slightly cropped.)\r\n\r\nurl = 'https:\/\/blogs.mathworks.com\/steve\/files\/205.jpg';\r\nI = rgb2gray(imread(url));\r\nclf\r\nimshow(I)\r\n\r\n%%\r\ncounts = imhist(I);\r\nL = length(counts);\r\np = counts \/ sum(counts);\r\nomega = cumsum(p);\r\nmu = cumsum(p .* (1:L)');\r\nmu_t = mu(end);\r\n\r\nsigma_b_squared = (mu_t * omega - mu).^2 .\/ (omega .* (1 - omega));\r\n\r\nclose all\r\nyyaxis left\r\nplot(counts)\r\nylabel('Histogram')\r\n\r\nyyaxis right\r\nplot(sigma_b_squared)\r\nylabel('\\sigma_B^2')\r\n\r\n[~,k] = max(sigma_b_squared);\r\nhold on\r\nplot([k k],ylim,'LineWidth',5)\r\nhold off\r\n\r\nxlim([1 256])\r\n\r\n%%\r\nclf\r\nimshow(imbinarize(I))\r\ntitle('Thresholded cell image')\r\n\r\n%%\r\n% If |imbinarize| handles this computation automatically, then why did we\r\n% also provide a function called \r\n% <https:\/\/www.mathworks.com\/help\/images\/ref\/otsuthresh.html |otsuthresh|>?\r\n% The answer is that |imbinarize| takes an image as input, although Otsu's\r\n% method does not require the original image, only the image's histogram. If\r\n% you have a situation where you want to compute a threshold based *only* on\r\n% a histogram, then you can call |otsuthresh| directly. That's why it is\r\n% there.\r\n\r\n%%\r\n% To wrap up this week's discussion, I want to point out that a couple of\r\n% blog readers recommended something called the _Triangle method_ for\r\n% automatic gray-scale image thresholding. If you want to try this for\r\n% yourself, there is an implementation on the File Exchange. I have not had\r\n% a chance yet to experiment with it.\r\n%\r\n% Next time I'll talk about the algorithm used by \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/28047-gray-image-thresholding-using-the-triangle-method |imbinarize|> for locally\r\n% adaptive thresholding.\r\n\r\n##### SOURCE END ##### 7a6499d359984c5bbbbf01f04253910a\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/steve\/files\/binarization_otsu_method_08.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>In my 16-May-2016 post about image binarization, I talked about the new binarization functions in R2016a. Today I want to switch gears and talk about Otsu's method, one of the algorithms underlying... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2016\/06\/14\/image-binarization-otsus-method\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":1958,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[178,278,128,1161,90,1155,464,76,36,705,122,1157,68,104,126,52,360,96,1163],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/1949"}],"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=1949"}],"version-history":[{"count":4,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/1949\/revisions"}],"predecessor-version":[{"id":1998,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/1949\/revisions\/1998"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media\/1958"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=1949"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=1949"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=1949"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}