Steve on Image Processing

March 28th, 2007

Neighbor indexing

In response to my last post about connected component labeling algorithms, blog reader JanKees wanted to know how to find neighboring pixel pairs programmatically. Prompted by this question, I thought I would describe a MATLAB indexing technique that is useful for various kinds of neighbor searching applications.

To get started, let's first review linear indexing. If you use a single subscript to index into a matrix, you access elements in the matrix based on the way they are stored in memory, which is by columns. For example:

a = magic(3)
a =

     8     1     6
     3     5     7
     4     9     2

a(3,1) is the third element in the columnwise ordering of the elements of a, so a(3) gives you that element:

a(3)
ans =

     4

a(2,3) is the eighth columnwise element, so a(8) gives you that element:

a(8)
ans =

     7

We call this single subscript a ''linear index''. You can use signed offsets to linear indices to get from a particular matrix element to any of its neighbors. For example, if you subtract 1 from an element's linear index, you get the location of the element just above. For a matrix with M rows, adding M to an element's linear index gives you the element just to the right. (Caveat: This technique only works for elements that aren't on the outermost rows or columns of the matrix.)

Let's apply this technique to finding the 4-connected neighborhood pairs for a simple binary image matrix.

bw = logical([ ...
    0 0 0 0 0 0 0
    0 1 1 0 0 0 0
    0 1 1 0 0 0 0
    0 0 0 1 1 1 0
    0 0 0 1 1 1 0
    0 0 0 0 0 0 0 ])
bw =

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

Step 1: Given the size of the matrix, compute neighborhood index offsets.

[M,N] = size(bw);
north_offset = -1;
east_offset = M;
south_offset = 1;
west_offset = -M;

Step 2: Find the linear indices for all the nonzero matrix elements.

idx = find(bw)
idx =

     8
     9
    14
    15
    22
    23
    28
    29
    34
    35

Step 3: Compute the values of all the north neighbors.

north_idx = idx + north_offset;
north_neighbors = bw(north_idx)
north_neighbors =

     0
     1
     0
     1
     0
     1
     0
     1
     0
     1

Step 4: Construct the matrix of northern neighbor pairs. Here I'll use north_neighbors as a logical index to pick out elements where north_neighbors is nonzero.

north_pairs = [idx(north_neighbors), north_idx(north_neighbors)]
north_pairs =

     9     8
    15    14
    23    22
    29    28
    35    34

Step 5: Repeat steps 3 and 4 for the other directions.

east_idx = idx + east_offset;
east_neighbors = bw(east_idx);
east_pairs = [idx(east_neighbors), east_idx(east_neighbors)];

south_idx = idx + south_offset;
south_neighbors = bw(south_idx);
south_pairs = [idx(south_neighbors), south_idx(south_neighbors)];

west_idx = idx + west_offset;
west_neighbors = bw(west_idx);
west_pairs = [idx(west_neighbors), west_idx(west_neighbors)];

all_pairs = [north_pairs; east_pairs; south_pairs; west_pairs]
all_pairs =

     9     8
    15    14
    23    22
    29    28
    35    34
     8    14
     9    15
    22    28
    23    29
    28    34
    29    35
     8     9
    14    15
    22    23
    28    29
    34    35
    14     8
    15     9
    28    22
    29    23
    34    28
    35    29

Note: Generally, you need to prepad the matrix to make sure that no nonzero elements are on the boundaries. I didn't do that here because my sample matrix didn't need it. Just remember that prepadding changes the element locations and the neighbor offset values, so you'll need to compensate for that in your own code. The details will vary depending on exactly what you are doing with the neighbor values and locations.

For more information about MATLAB indexing, including linear and logical indexing, here's a MATLAB Digest article that Loren and I wrote a few years ago.


Get the MATLAB code

Published with MATLAB® 7.4

14 Responses to “Neighbor indexing”

  1. Xunkai Wei replied on :

    Dear Steve,

    Could you give me some hints about gray level run length matrix ?
    If possible, could you show me how to get the 45′ direction run length matrix ?

    I found that this essay contains some ideas of direction oriented neighbor search, but I do not know how to get all elements of the given direction in a specified matrix.

    Looking forward to your reply

    Best,
    Xunkai

  2. Xunkai Wei replied on :

    Dear Steve,

    the run length matrix is to count the occurrence times of each gray level. For 0′, I think this is easy, because I can handle each row without use of offset and count it and then accumulate all,finally I can get the run length matrix. But for 45, 135,when using offset [-1 1] and [-1,-1], the problems occur. Using the offset, I can get a shifted submatrix, my problem is how to collect all elements of 45 or 135 into a row vector, could you give me some suggestions ?

    Best

    Xunkai Wei

  3. Xunkai Wei replied on :

    Dear Steve,

    I got a solution. Thanks.

    Best,

    Xunkai

  4. Steve replied on :

    Xunkai—I’m glad to hear that you figured it out.

  5. Neha replied on :

    Steve,

    I’m facing similar problems. Can you suggest a solution to Xunkai’s problem?

    Thanks!

  6. Steve replied on :

    Neha—Tell me a little bit more specifically about what you are trying to do, what you have tried, and why it didn’t work.

  7. Reena replied on :

    Hello steave ,

    I have follwing image data,How I display image using it?

    [image data deleted from comment by Steve]

    Thank you

  8. Steve replied on :

    Reena—Use imshow. Pay attention to data type issues. For example, it matters whether your data is uint8 or double. Please read the introductory chapters of the Image Processing Toolbox Users Guide.

  9. Neha replied on :

    I was trying to find run lengths in diagonal directions, so wanted to use the neighbor offset to find that, but I found another solution, merely logical to it.
    Thanks!

  10. stefano replied on :

    when using no logical matrix , it doesnt work. for example A=[17 24 1 8 15;23 5 .....; 11 18 25 2 9]

    >>idx(east_neighbors)

    ??? Index exceeds matrix dimensions.

  11. Steve replied on :

    Stefano—It doesn’t have anything to do with whether the matrix is logical or not. It has to do whether it has nonzero elements on the borders. See the “Note” in the next-to-last paragraph.

  12. stefano replied on :

    Steve, I dont think so. I used as you say: B=[0 0 0 0 0;0 24 1 8 0;0 5 7 14 0;0 6 13 20 0;0 0 0 0 0]
    east_idx=idx+east_offset
    east_neighbors=B(east_idx)
    but..

    >> idx(east_neighbors)
    ??? Subscript indices must either be real positive integers or logicals.

    I dont know why get that error message. and the matrix has
    nonzero elements on the borders. what can it be?

  13. Steve replied on :

    Stefano—Your code idx(east_neighbors) is a mistake. I didn’t do that in my post, and I’m not sure why you are doing that. You already extracted the east neighbors in the line:

    east_neighbors = B(east_idx)
    
  14. Ferenc replied on :

    Thanks a lot Steve, this was xtremely useful.


MathWorks
Steve Eddins is a software development manager in the MATLAB and image processing areas at MathWorks. Steve coauthored Digital Image Processing Using MATLAB. He writes here about image processing concepts, algorithm implementations, and MATLAB.

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