{"id":2511,"date":"2017-03-07T16:01:06","date_gmt":"2017-03-07T21:01:06","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=2511"},"modified":"2019-11-01T17:05:45","modified_gmt":"2019-11-01T21:05:45","slug":"logical-indexing-2","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2017\/03\/07\/logical-indexing-2\/","title":{"rendered":"Logical indexing"},"content":{"rendered":"<div class=\"content\"><!--introduction--><!--\/introduction--><p>One of my favorite aspects of MATLAB for image processing is how I can use a binary image to index directly into a grayscale image. The technique is called <i>logical indexing<\/i>, and I'm going to show you how it works today.<\/p><p><i>Note: this is an update of a post I originally wrote in <a href=\"https:\/\/blogs.mathworks.com\/steve\/2008\/01\/28\/logical-indexing\/\">2008<\/a><\/i>.<\/p><p>Let me start with a small example. (As regular readers know, I like to use magic squares for small matrix examples.)<\/p><pre class=\"codeinput\">A = magic(5)\r\n<\/pre><pre class=\"codeoutput\">\r\nA =\r\n\r\n    17    24     1     8    15\r\n    23     5     7    14    16\r\n     4     6    13    20    22\r\n    10    12    19    21     3\r\n    11    18    25     2     9\r\n\r\n<\/pre><p>Every MATLAB user is familiar with ordinary matrix indexing notation.<\/p><pre class=\"codeinput\">A(2,3)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n     7\r\n\r\n<\/pre><p><tt>A(2,3)<\/tt> extracts the 2nd row, 3rd column of the matrix <tt>A<\/tt>. You can extract more than one row and column at the same time:<\/p><pre class=\"codeinput\">A(2:4, 3:5)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n     7    14    16\r\n    13    20    22\r\n    19    21     3\r\n\r\n<\/pre><p>When an indexing expression appears on the left-hand side of the equals sign, that's an assigment. You are changing one or more of the values of the variable on the left-hand side.<\/p><pre class=\"codeinput\">A(5,5) = 100\r\n<\/pre><pre class=\"codeoutput\">\r\nA =\r\n\r\n    17    24     1     8    15\r\n    23     5     7    14    16\r\n     4     6    13    20    22\r\n    10    12    19    21     3\r\n    11    18    25     2   100\r\n\r\n<\/pre><p>Here is a frequently-asked MATLAB question: <i>How do I replace all the NaNs in my matrix B with 0s?<\/i><\/p><p>An experienced MATLAB user will immediately answer:<\/p><pre>B(isnan(B)) = 0;<\/pre><p>For example:<\/p><pre class=\"codeinput\">B = rand(3,3);\r\nB(2, 2:3) = NaN\r\n<\/pre><pre class=\"codeoutput\">\r\nB =\r\n\r\n    0.2217    0.3188    0.0855\r\n    0.1174       NaN       NaN\r\n    0.2967    0.5079    0.8010\r\n\r\n<\/pre><p>Replace the NaNs with zeros:<\/p><pre class=\"codeinput\">B(isnan(B)) = 0\r\n<\/pre><pre class=\"codeoutput\">\r\nB =\r\n\r\n    0.2217    0.3188    0.0855\r\n    0.1174         0         0\r\n    0.2967    0.5079    0.8010\r\n\r\n<\/pre><p>The expression <tt>B(isnan(B))<\/tt> is an example of <i>logical indexing<\/i>. Logical indexing is a compact and expressive notation that's very useful for many image processing operations.<\/p><p>Let's talk about the basic rules of logical indexing, and then we'll reexamine the expression <tt>B(isnan(B))<\/tt>.<\/p><p>If <tt>C<\/tt> and <tt>D<\/tt> are matrices, then <tt>C(D)<\/tt> is a logical indexing expression if <tt>D<\/tt> is a <i>logical<\/i> matrix.<\/p><p><i>Logical<\/i> is one of the fundamental data types for MATLAB arrays. Relational operators, such as <tt>==<\/tt> or <tt>&gt;<\/tt>, produce logical arrays automatically.<\/p><pre class=\"codeinput\">C = hilb(4)\r\n<\/pre><pre class=\"codeoutput\">\r\nC =\r\n\r\n    1.0000    0.5000    0.3333    0.2500\r\n    0.5000    0.3333    0.2500    0.2000\r\n    0.3333    0.2500    0.2000    0.1667\r\n    0.2500    0.2000    0.1667    0.1429\r\n\r\n<\/pre><pre class=\"codeinput\">D = C &gt; 0.4\r\n<\/pre><pre class=\"codeoutput\">\r\nD =\r\n\r\n  4&times;4 logical array\r\n\r\n   1   1   0   0\r\n   1   0   0   0\r\n   0   0   0   0\r\n   0   0   0   0\r\n\r\n<\/pre><p>If we use <tt>D<\/tt> as an index into <tt>C<\/tt> with the expression <tt>C(D)<\/tt>, then we will extract all the values of <tt>C<\/tt> corresponding to nonzero values of <tt>D<\/tt> and returns them as a column vector. It is equivalent to <tt>C(find(D))<\/tt>.<\/p><pre class=\"codeinput\">C(D)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n    1.0000\r\n    0.5000\r\n    0.5000\r\n\r\n<\/pre><p>Now we know enough to break down the <tt>B(isnan(B))<\/tt> expression to see how it works.<\/p><pre class=\"codeinput\">B = rand(3,3);\r\nB(2, 2:3) = NaN;\r\n\r\nnan_locations = isnan(B)\r\n<\/pre><pre class=\"codeoutput\">\r\nnan_locations =\r\n\r\n  3&times;3 logical array\r\n\r\n   0   0   0\r\n   0   1   1\r\n   0   0   0\r\n\r\n<\/pre><pre class=\"codeinput\">B(nan_locations)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n   NaN\r\n   NaN\r\n\r\n<\/pre><pre class=\"codeinput\">B(nan_locations) = 0\r\n<\/pre><pre class=\"codeoutput\">\r\nB =\r\n\r\n    0.0292    0.4886    0.4588\r\n    0.9289         0         0\r\n    0.7303    0.2373    0.5468\r\n\r\n<\/pre><p>Functions in the Image Processing Toolbox, as well as the MATLAB functions <tt>imread<\/tt> and <tt>imwrite<\/tt>, follow the convention that logical matrices are treated as binary (black and white) images.  For example, when you read a 1-bit image file using <tt>imread<\/tt>, it returns a logical matrix:<\/p><pre class=\"codeinput\">bw = imread(<span class=\"string\">'text.png'<\/span>);\r\nwhos <span class=\"string\">bw<\/span>\r\n<\/pre><pre class=\"codeoutput\">  Name        Size             Bytes  Class      Attributes\r\n\r\n  bw        256x256            65536  logical              \r\n\r\n<\/pre><p>This convention, together with logical indexing, makes it very convenient and expressive to use binary images as pixel masks for extracting or operating on sets of pixels.<\/p><p>Here's an example showing how to use logical indexing to compute the histogram of a subset of image pixels. Specifically, given a grayscale image and a binary segmentation, compute the histogram of just the foreground pixels in the image.<\/p><p>Here's our original image:<\/p><pre class=\"codeinput\">I = imread(<span class=\"string\">'rice.png'<\/span>);\r\nimshow(I)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/logical_indexing_01.png\" alt=\"\"> <p>Here's a segmentation result (computed and saved earlier), represented as a binary image:<\/p><pre class=\"codeinput\">url = <span class=\"string\">'https:\/\/blogs.mathworks.com\/images\/steve\/192\/rice_bw.png'<\/span>;\r\nbw = imread(url);\r\nimshow(bw)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/logical_indexing_02.png\" alt=\"\"> <p>Now use the segmentation result as a logical index into the original image to extract the foreground pixel values.<\/p><pre class=\"codeinput\">foreground_pixels = I(bw);\r\nwhos <span class=\"string\">foreground_pixels<\/span>\r\n<\/pre><pre class=\"codeoutput\">  Name                       Size            Bytes  Class    Attributes\r\n\r\n  foreground_pixels      17597x1             17597  uint8              \r\n\r\n<\/pre><p>Finally, compute the histogram of the foreground pixels.<\/p><pre class=\"codeinput\">figure\r\nimhist(foreground_pixels)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/logical_indexing_03.png\" alt=\"\"> <p>As another example, you could complement the binary image to compute something based on the background pixels.<\/p><pre class=\"codeinput\">imhist(I(~bw))\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/logical_indexing_04.png\" alt=\"\"> <p><i>PS. I expect that this will be the last blog post that I write using R2016b. Keep an eye on the <a href=\"https:\/\/www.mathworks.com\/downloads\">downloads page!<\/a><\/i><\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_e286582d3ff74f9f8ff5c3de3b9c3809() {\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='e286582d3ff74f9f8ff5c3de3b9c3809 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' e286582d3ff74f9f8ff5c3de3b9c3809';\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 2017 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_e286582d3ff74f9f8ff5c3de3b9c3809()\"><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; R2016b<br><\/p><\/div><!--\r\ne286582d3ff74f9f8ff5c3de3b9c3809 ##### SOURCE BEGIN #####\r\n\r\n%%\r\n% One of my favorite aspects of MATLAB for image processing is how I can\r\n% use a binary image to index directly into a grayscale image. The\r\n% technique is called _logical indexing_, and I'm going to show you how it\r\n% works today.\r\n%\r\n% _Note: this is an update of a post I originally wrote in \r\n% <https:\/\/blogs.mathworks.com\/steve\/2008\/01\/28\/logical-indexing\/ 2008>_.\r\n%\r\n% Let me start with a small example. (As regular readers know, I like\r\n% to use magic squares for small matrix examples.)\r\n\r\nA = magic(5)\r\n\r\n%%\r\n% Every MATLAB user is familiar with ordinary matrix indexing\r\n% notation.\r\n\r\nA(2,3)\r\n\r\n%%\r\n% |A(2,3)| extracts the 2nd row, 3rd column of the matrix |A|. You\r\n% can extract more than one row and column at the same time:\r\n\r\nA(2:4, 3:5)\r\n\r\n%%\r\n% When an indexing expression appears on the left-hand side of\r\n% the equals sign, that's an assigment. You are changing one or more of the\r\n% values of the variable on the left-hand side.\r\n\r\nA(5,5) = 100\r\n\r\n\r\n%%\r\n% Here is a frequently-asked MATLAB question: _How do I replace all the\r\n% NaNs in my matrix B with 0s?_\r\n%\r\n% An experienced MATLAB user will immediately answer:\r\n%\r\n%  B(isnan(B)) = 0;\r\n%\r\n% For example:\r\n\r\nB = rand(3,3);\r\nB(2, 2:3) = NaN\r\n\r\n%%\r\n% Replace the NaNs with zeros:\r\nB(isnan(B)) = 0\r\n\r\n%%\r\n% The expression |B(isnan(B))| is an example of _logical indexing_.\r\n% Logical indexing is a compact and expressive notation that's very useful\r\n% for many image processing operations.\r\n%\r\n% Let's talk about the basic rules of logical indexing, and then\r\n% we'll reexamine the expression |B(isnan(B))|.\r\n%\r\n% If |C| and |D| are matrices, then |C(D)| is a logical indexing\r\n% expression if |D| is a _logical_ matrix.\r\n% \r\n% _Logical_ is one of the fundamental data types for MATLAB arrays.\r\n% Relational operators, such as |==| or |>|, produce logical\r\n% arrays automatically.\r\n\r\nC = hilb(4)\r\n\r\n%%\r\n\r\nD = C > 0.4\r\n\r\n%%\r\n% If we use |D| as an index into |C| with the expression |C(D)|, then we\r\n% will extract all the values of |C| corresponding to nonzero values of |D|\r\n% and returns them as a column vector. It is equivalent to |C(find(D))|.\r\n\r\nC(D)\r\n\r\n%%\r\n% Now we know enough to break down the |B(isnan(B))| expression to see \r\n% how it works.\r\n\r\nB = rand(3,3);\r\nB(2, 2:3) = NaN;\r\n\r\nnan_locations = isnan(B)\r\n\r\n%%\r\nB(nan_locations)\r\n\r\n%%\r\nB(nan_locations) = 0\r\n\r\n%%\r\n% Functions in the Image Processing Toolbox, as well as the\r\n% MATLAB functions |imread| and |imwrite|, follow the convention that\r\n% logical matrices are treated as binary (black and white)\r\n% images.  For example, when you read a 1-bit image file using\r\n% |imread|, it returns a logical matrix:\r\n\r\nbw = imread('text.png');\r\nwhos bw\r\n\r\n%%\r\n% This convention, together with logical indexing, makes it very\r\n% convenient and expressive to use binary images as pixel masks\r\n% for extracting or operating on sets of pixels.\r\n\r\n%% \r\n% Here's an example showing how to use logical indexing to\r\n% compute the histogram of a subset of image pixels.\r\n% Specifically, given a grayscale image and a binary\r\n% segmentation, compute the histogram of just the foreground\r\n% pixels in the image.\r\n%\r\n% Here's our original image:\r\n\r\nI = imread('rice.png');\r\nimshow(I)\r\n\r\n%%\r\n% Here's a segmentation result (computed and saved earlier), \r\n% represented as a binary image:\r\n\r\nurl = 'https:\/\/blogs.mathworks.com\/images\/steve\/192\/rice_bw.png';\r\nbw = imread(url);\r\nimshow(bw)\r\n\r\n%%\r\n% Now use the segmentation result as a logical index into the\r\n% original image to extract the foreground pixel values.\r\n\r\nforeground_pixels = I(bw);\r\nwhos foreground_pixels\r\n\r\n%%\r\n% Finally, compute the histogram of the foreground pixels.\r\n\r\nfigure\r\nimhist(foreground_pixels)\r\n\r\n%%\r\n% As another example, you could complement the binary image to compute\r\n% something based on the background pixels.\r\n\r\nimhist(I(~bw))\r\n\r\n%%\r\n% _PS. I expect that this will be the last blog post that I write using\r\n% R2016b. Keep an eye on the <https:\/\/www.mathworks.com\/downloads \r\n% downloads page!>_\r\n##### SOURCE END ##### e286582d3ff74f9f8ff5c3de3b9c3809\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/logical_indexing_04.png\" onError=\"this.style.display ='none';\" \/><\/div><p>One of my favorite aspects of MATLAB for image processing is how I can use a binary image to index directly into a grayscale image. The technique is called logical indexing, and I'm going to show you... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2017\/03\/07\/logical-indexing-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":[348,462,464,76,36,376,54,460,306],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/2511"}],"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=2511"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/2511\/revisions"}],"predecessor-version":[{"id":2512,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/2511\/revisions\/2512"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=2511"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=2511"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=2511"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}