{"id":192,"date":"2008-01-28T10:46:08","date_gmt":"2008-01-28T15:46:08","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/2008\/01\/28\/logical-indexing\/"},"modified":"2019-10-24T13:53:27","modified_gmt":"2019-10-24T17:53:27","slug":"logical-indexing","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2008\/01\/28\/logical-indexing\/","title":{"rendered":"Logical indexing"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p>This is the first post in a short series on index techniques that are particularly useful for image processing in MATLAB.\r\n      I'll start with logical indexing today.  Later I'll cover linear indexing, and then a technique I like to call neighbor indexing.\r\n   <\/p>\r\n   <p>Every MATLAB user is familiar with ordinary matrix indexing notation.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">A = magic(5)<\/pre><pre style=\"font-style:oblique\">\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><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">A(2,3)<\/pre><pre style=\"font-style:oblique\">\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:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">A(2:4, 3:5)<\/pre><pre style=\"font-style:oblique\">\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, it's assignment:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">A(5,5) = 100<\/pre><pre style=\"font-style:oblique\">\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>About every 13.6 days, someone asks this question on <a>comp.soft-sys.matlab<\/a>:\r\n   <\/p><pre> How do I replace all the NaNs in my matrix B with 0s?<\/pre><p>This is generally followed 4.8 minutes later with this reply from one of the newsgroup regulars:<\/p><pre> B(isnan(B)) = 0;<\/pre><p>For example:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">B = rand(3,3);\r\nB(2, 2:3) = NaN<\/pre><pre style=\"font-style:oblique\">\r\nB =\r\n\r\n    0.5470    0.1890    0.3685\r\n    0.2963       NaN       NaN\r\n    0.7447    0.1835    0.7802\r\n\r\n<\/pre><p>Replace the NaNs with zeros:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">B(isnan(B)) = 0<\/pre><pre style=\"font-style:oblique\">\r\nB =\r\n\r\n    0.5470    0.1890    0.3685\r\n    0.2963         0         0\r\n    0.7447    0.1835    0.7802\r\n\r\n<\/pre><p>The expression<\/p><pre> B(isnan(B))<\/pre><p>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.\r\n   <\/p>\r\n   <p>Let's talk about the basic rules of logical indexing, and then we'll reexamine the expression <tt>B(isnan(B))<\/tt>.\r\n   <\/p>\r\n   <p>If <tt>C<\/tt> and <tt>D<\/tt> are matrices, then <tt>C(D)<\/tt> is a logical indexing expression if <tt>C<\/tt> and <tt>D<\/tt> are the same size, and <tt>D<\/tt> is a <i>logical<\/i> matrix.\r\n   <\/p>\r\n   <p>\"Logical\" is one of the builtin types, or classes, of MATLAB matrices.  Relational operators, such as <tt>==<\/tt> or <tt>&gt;<\/tt>, produce logical matrices.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">C = hilb(4)<\/pre><pre style=\"font-style:oblique\">\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 style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">D = C &gt; 0.4<\/pre><pre style=\"font-style:oblique\">\r\nD =\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><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">whos <span style=\"color: #A020F0\">D<\/span><\/pre><pre style=\"font-style:oblique\">  Name      Size            Bytes  Class      Attributes\r\n\r\n  D         4x4                16  logical              \r\n\r\n<\/pre><p>You can see from the output of whos that the class of the variable <tt>D<\/tt> is <i>logical<\/i>.  The logical indexing expression <tt>C(D)<\/tt> extracts all the values of <tt>C<\/tt> corresponding to nonzero values of <tt>D<\/tt> and returns them as a column vector.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">C(D)<\/pre><pre style=\"font-style:oblique\">\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 B(isnan(B)) example to see how it works.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">B = rand(3,3);\r\nB(2, 2:3) = NaN;\r\n\r\nnan_locations = isnan(B)<\/pre><pre style=\"font-style:oblique\">\r\nnan_locations =\r\n\r\n     0     0     0\r\n     0     1     1\r\n     0     0     0\r\n\r\n<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">whos <span style=\"color: #A020F0\">nan_locations<\/span><\/pre><pre style=\"font-style:oblique\">  Name               Size            Bytes  Class      Attributes\r\n\r\n  nan_locations      3x3                 9  logical              \r\n\r\n<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">B(nan_locations)<\/pre><pre style=\"font-style:oblique\">\r\nans =\r\n\r\n   NaN\r\n   NaN\r\n\r\n<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">B(nan_locations) = 0<\/pre><pre style=\"font-style:oblique\">\r\nB =\r\n\r\n    0.0811    0.4868    0.3063\r\n    0.9294         0         0\r\n    0.7757    0.4468    0.5108\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\r\n      a 1-bit image file using imread, it returns a logical matrix:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">bw = imread(<span style=\"color: #A020F0\">'text.png'<\/span>);\r\nwhos <span style=\"color: #A020F0\">bw<\/span><\/pre><pre style=\"font-style:oblique\">  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\r\n      for extracting or operating on sets of pixels.\r\n   <\/p>\r\n   <p>Here's an example showing how to use logical indexing to compute the histogram of a subset of image pixels. Specifically,\r\n      given a gray-scale image and a binary segmentation, compute the histogram of just the foreground pixels in the image.\r\n   <\/p>\r\n   <p>Here's our original image:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">I = imread(<span style=\"color: #A020F0\">'rice.png'<\/span>);\r\nimshow(I)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/192\/logical_indexing_example_01.png\"> <p>Here's a segmentation result (computed and saved earlier), represented as a binary image:<\/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\/192\/rice_bw.png'<\/span>;\r\nbw = imread(url);\r\nimshow(bw)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/192\/logical_indexing_example_02.png\"> <p>Now use the segmentation result as a logical index into the original image to extract the foreground pixel values.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">foreground_pixels = I(bw);\r\nwhos <span style=\"color: #A020F0\">foreground_pixels<\/span><\/pre><pre style=\"font-style:oblique\">  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 style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">imhist(foreground_pixels)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/192\/logical_indexing_example_03.png\"> <p>Or use logical indexing with the complement of the segmentation result to compute the histogram of the background pixels.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">imhist(I(~bw))<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/192\/logical_indexing_example_04.png\"> <script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_a3334751af464bd5b84dae189b7d216f() {\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='a3334751af464bd5b84dae189b7d216f ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' a3334751af464bd5b84dae189b7d216f';\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 2008 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_a3334751af464bd5b84dae189b7d216f()\"><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.5<br><\/p>\r\n<\/div>\r\n<!--\r\na3334751af464bd5b84dae189b7d216f ##### SOURCE BEGIN #####\r\n%%\r\n% This is the first post in a short series on index techniques\r\n% that are particularly useful for image processing in MATLAB.\r\n% I'll start with logical indexing today.  Later I'll cover\r\n% linear indexing, and then a technique I like to call neighbor \r\n% indexing.\r\n%\r\n% Every MATLAB user is familiar with ordinary matrix indexing\r\n% notation.\r\n\r\nA = magic(5)\r\n\r\n%%\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, it's assignment:\r\n\r\nA(5,5) = 100\r\n\r\n\r\n%%\r\n% About every 13.6 days, someone asks this question on\r\n% <http:\/\/ \r\n% comp.soft-sys.matlab>:\r\n%\r\n%   How do I replace all the NaNs in my matrix B with 0s?\r\n%\r\n% This is generally followed 4.8 minutes later with this reply\r\n% from one of the newsgroup regulars:\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\r\n%\r\n%   B(isnan(B))\r\n%\r\n% is an example of _logical indexing_.  Logical indexing is a\r\n% compact and expressive notation that's very useful for many\r\n% 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 |C| and |D| are the same size, and |D| is a _logical_\r\n% matrix.\r\n% \r\n% \"Logical\" is one of the builtin types, or classes, of MATLAB\r\n% matrices.  Relational operators, such as |==| or |>|, produce logical\r\n% matrices.\r\n\r\nC = hilb(4)\r\n\r\n%%\r\n\r\nD = C > 0.4\r\n\r\n%%\r\n\r\nwhos D\r\n\r\n%%\r\n% You can see from the output of whos that the class of the\r\n% variable |D| is _logical_.  The logical indexing expression\r\n% |C(D)| extracts all the values of |C| corresponding to nonzero\r\n% values of |D| and returns them as a column vector.\r\n\r\nC(D)\r\n\r\n%%\r\n% Now we know enough to break down the B(isnan(B)) example 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\nwhos nan_locations\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 gray-scale 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\nimhist(foreground_pixels)\r\n\r\n%%\r\n% Or use logical indexing with the complement of the segmentation\r\n% result to compute the histogram of the background pixels.\r\n\r\nimhist(I(~bw))\r\n\r\n##### SOURCE END ##### a3334751af464bd5b84dae189b7d216f\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   This is the first post in a short series on index techniques that are particularly useful for image processing in MATLAB.\r\n      I'll start with logical indexing today.  Later I'll cover linear... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2008\/01\/28\/logical-indexing\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[17],"tags":[462,464,76,36,376,54,460,306],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/192"}],"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=192"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/192\/revisions"}],"predecessor-version":[{"id":2744,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/192\/revisions\/2744"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=192"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=192"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=192"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}