Steve on Image Processing

May 13th, 2008

Lookup tables for binary image processing—makelut and applylut

This is the second in a short series on using lookup tables for binary image neighborhood operations. See the first post for the basic idea.

The Image Processing Toolbox has two related functions:

  • applylut - Process binary image using lookup table
  • makelut - Utility function to help you construct a lookup table.

Since you have to have a lookup table in order to use applylut, let's start with makelut. It's syntax is:

 lut = makelut(f, n)

f is a function handle, and n is either 2 or 3, depending on whether your lookup table is to be used with 2-by-2 or 3-by-3 neighborhoods.

For 3-by-3 neighborhoods, makelut will call your function handle f 512 times. In each call, makelut will pass as an argument to f one of the 512 possible 3-by-3 binary neighborhoods. f simply has to return the desired output value for a given neighborhood.

For example, suppose we want the output pixel to be 1 if and only if the corresponding input neighborhood looks like this:

  1 0 0
  0 1 0
  0 0 1

The you would call makelut as follows:

pattern = [1 0 0; 0 1 0; 0 0 1];
lut = makelut(@(neighborhood) isequal(neighborhood, pattern), 3);
size(lut)
ans =

   512     1

Let's try that on a small sample image.

bw = eye(5) | fliplr(eye(5))
bw =

     1     0     0     0     1
     0     1     0     1     0
     0     0     1     0     0
     0     1     0     1     0
     1     0     0     0     1

bw2 = applylut(bw, lut)
bw2 =

     0     0     0     0     0
     0     1     0     0     0
     0     0     0     0     0
     0     0     0     1     0
     0     0     0     0     0

So we see that only two input pixels, (2,2) and (4,4), have neighborhoods that exactly match the pattern.

Here's another example: Find all "endpoint" pixels. I'll define an endpoint pixel as a foreground pixel with exactly one foreground neighbor.

endpoint_fcn = @(nhood) (nhood(2,2) ~= 0) && (sum(nhood(:)) == 2);
endpoint_lut = makelut(endpoint_fcn, 3);

Here's the result on sample image from above:

bw3 = applylut(bw, endpoint_lut)
bw3 =

     1     0     0     0     1
     0     0     0     0     0
     0     0     0     0     0
     0     0     0     0     0
     1     0     0     0     1

Only the four corner pixels are endpoints.

In my next post on this topic, I'll use makelut and applylut to play Conway's Game of Life. Look for it in a week or so.


Get the MATLAB code

Published with MATLAB® 7.6

4 Responses to “Lookup tables for binary image processing—makelut and applylut”

  1. Mark Hayworth replied on :

    Steve, it looks like this could be used to do two operations that are missing from bwmorph, and they are to identify crossings (triple and quad branch points) and (like you said) end points. Right now I’m getting end points by computing the spur and subtracting it from the original (is the lut method better than that method?). I have no way of computing crossings of skeleton lines where the shape is a “Y” or a “+” so maybe this could be used for that purpose. Even better would be to add these in to bwmorph as options - any chance of that?

  2. Steve replied on :

    Mark—The lut method would probably be faster than what you are currently doing to detect end points. If a crossing configuration can be determined using only a 3-by-3 neighborhood, then that also could be done using applylut. Your suggestion about about adding these options to bwmorph is a good one; I’ll follow up with you by e-mail about that.

  3. Pete replied on :

    Interesting. I haven’t made much use of lookup tables. Although rather more limited, where possible I convert binary images to uint8 and use imfilter to add up the number of pixels in the neighborhood.

    Therefore, for example, to compute end-points in a thinned/skeletonised binary image (bw) I have used,

    bwEnds = imfilter(uint8(bw), ones(3)) == 2 & bw;

    Crossover points might be,

    bwCrossover = imfilter(uint8(bw), ones(3)) > 3) & bw;

    My decidedly untrustworthy memory had told me that I compared both methods once upon a time and found imfilter to be faster, but when I tried them tonight (to locate end points in 768×768 pixel binary images) they each took almost exactly the same length of time (around 0.06 s). I wish to believe this is due to the R2007b optimisations rather than that I was mistaken, although I can’t be sure.

  4. Steve replied on :

    Pete—I don’t think the lookup table optimization made in R2007b would make any difference for the operations you describe.

Leave a Reply

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>

If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).


Steve Eddins manages the Image & Geospatial development team at The MathWorks and coauthored Digital Image Processing Using MATLAB. He writes here about image processing concepts, algorithm implementations, and MATLAB.

  • murat: Hi Steve, I have an rgb image of a kind of cream and it contains some small black particles (black dots). In...
  • Steve: Ernest—Look at setting the FaceColor property. The code for setting that is shown on the page you asked...
  • Ernest Miller: Hi Steve, Understood. However, can you explain how to change the colors? Thanks, Ernest
  • Jan: Hi Steve Very useful code, yet what if I parts of my rotated+translated object are outside the original...
  • Steve: MoHDa—It might be possible. You’ll need to use one of the options that produces closed edge...
  • MoHDa: I have one question about the ROIPOLY: I have an image with stripes, I use the “edge” command for...
  • Steve: Shahn—My November 17, 2006 post shows you how to do it.
  • Steve: Kay-Uwe—Thanks for following up. I am planning to make it easier to use test directories in a package....
  • shahn: Hello Steve Instead of superimposing a star on the image to show the centroide. How would you superimpose a...
  • Kay-Uwe: Having TestSuite.fromPackag e() would be nice to have, but so far using simple “test” subdirs...

These postings are the author's and don't necessarily represent the opinions of The MathWorks.