Steve on Image Processing

April 26th, 2007

Upslope area - D-infinity flow

A few weeks ago I promised a series on developing a MATLAB algorithm to compute upslope area. Now I'm ready to begin that project in earnest.

First, though, I'd like to comment on the motivation for this series. Specifically, why look at a method from the area of hydrology in a blog about image processing algorithms? There are two reasons:

  • MATLAB users are in all disciplines of engineering and science, and the ones who use image processing methods use them for a variety of gridded data sets, not just for processing pictures. Applying image processing techniques to digital elevation models (DEMs), for example, is common.
  • Several techniques originally developed for the computational analysis of DEMs have turned out to be broadly useful for processing other kinds of image data. Perhaps the most well-known example is the watershed transform.

The first thing we need to think about is computing the flow direction for a given pixel. That is, based on the height of a pixel and its neighbors, in which direction will water run off from the center of that pixel? The Tarboton 1997 paper says the earliest method is to say the flow direction is toward whichever of the eight neigbhors has the steepest downward slope. Because the flow direction can take on one of 8 possible values, this is called the D8 method.

Tarboton proposes a new flow direction method, called D-infinity because flow direction assigned to a pixel can take on any value between 0 and 2*pi. The method examines eight triangular facets for each pixel. Each facet has a vertex at the pixel center and two vertices at the centers of neighboring pixels.

The flow direction for a particular facet is the direction of the steepest downward slope on the facet. The function facetFlow below computes this value for the east-northeast facet. Variable names in the code are based on this diagram:

type facetFlow
function [r,s] = facetFlow(e0, e1, e2, d1, d2)
% facetFlow Facet flow direction.
% [r, s] = facetFlow(e0, e1, e2, d1, d2) computes the facet flow direction
% for an east-northeast pixel facet.  e0 is the height of the center pixel.
% e1 is the height of the east neighbor.  e2 is the height of the northeast
% neighbor.  d1 is the horizontal pixel center spacing.  d2 is the vertical
% pixel center spacing.  d1 and d2 are optional; if omitted, a value of 1.0
% is assumed.
%
% r is the facet flow direction in radians, and s is the magnitude of the
% corresponding slope.

% Steve Eddins
% Copyright 2007 The MathWorks, Inc.

% Reference: Tarboton, "A new method for the determination of flow
% directions and upslope areas in grid digital elevation models," Water
% Resources Research, vol. 33, no. 2, pages 309-319, February 1997.

if nargin < 4
    d1 = 1;
    d2 = 1;
end

s1 = (e0 - e1)/d1;             % eqn (1)
s2 = (e1 - e2)/d2;             % eqn (2)

r = atan2(s2, s1);             % eqn (3)
s = hypot(s1, s2);             % eqn (3)

diagonal_angle    = atan2(d2, d1);
diagonal_distance = hypot(d1, d2);

if r < 0
    % eqn (4)
    r = 0;
    s = s1;

elseif r > diagonal_angle
    % eqn (5)
    r = diagonal_angle;
    s = (e0 - e2)/diagonal_distance;
end


This same computation can be applied to all the facets via rotations or flips. Tarboton provides a lookup table of facet transformations that can be used directly in the implementation. The function pixelFlow below uses facetFlow and the lookup table to find both the flow direction and flow magnitude for a given pixel inside a DEM matrix. The flow direction for the pixel is the flow direction with the highest magnitude for each of the eight facets.

type pixelFlow
function [r, s] = pixelFlow(E, i, j, d1, d2)
% pixelFlow Downslope flow direction from a pixel in a DEM.
% [r, s] = pixelFlow(E, i, j, d1, d2) computes the flow direction for a
% single DEM pixel E(i, j).  d1 is the horizontal pixel center spacing.  d2
% is the vertical pixel center spacing.  d1 and d2 are optional; if
% omitted, a value of 1.0 is assumed.
%
% r is the facet flow direction in radians, and s is the magnitude of the
% corresponding slope.

% Steve Eddins
% Copyright 2007 The MathWorks, Inc.

% Reference: Tarboton, "A new method for the determination of flow
% directions and upslope areas in grid digital elevation models," Water
% Resources Research, vol. 33, no. 2, pages 309-319, February 1997.

if nargin < 4
    d1 = 1;
    d2 = 1;
end

% Table 1, page 311
e0 = E(i, j);
e1 = [E(i,j+1) E(i-1,j) E(i-1,j) E(i,j-1) ...
      E(i,j-1) E(i+1,j) E(i+1,j) E(i,j+1)];

e2 = [E(i-1,j+1) E(i-1,j+1) E(i-1,j-1) E(i-1,j-1) ...
      E(i+1,j-1) E(i+1,j-1) E(i+1,j+1) E(i+1,j+1)];

ac = [0  1  1  2  2  3  3  4];
af = [1 -1  1 -1  1 -1  1 -1];

rp = zeros(1, 8);
sp = zeros(1, 8);

for k = 1:8
    [rp(k), sp(k)] = facetFlow(e0, e1(k), e2(k), d1, d2);
end

% Find the facet with the maximum down-slope.
[s, k_max] = max(sp);

if s > 0
    % Maximum down-slope is positive.
    r = (af(k_max) * rp(k_max)) + (ac(k_max) * pi / 2);
else
    % The pixel is in a flat area or is a pit.  Flow direction angle is
    % unresolved.
    r = NaN;
end

    

Note: At this point in algorithm development, I am primarily concerned with getting a correct implementation of the method described in the paper. It's way too early yet to be worrying about performance. Also, note the cross-references in my code to specific equation and page numbers. This is a really good habit to get into. (I learned that lesson the hard way.)

Next up: Try this pixel flow computation on some simple test cases, and start to think about what to do for plateaus.


Get the MATLAB code

Published with MATLAB® 7.4

7 Responses to “Upslope area - D-infinity flow”

  1. ali replied on :

    hi
    i am writing my tese and subject is flow direction
    i need determine flow accumulation by dinf algorithm,
    but tau dem don’t don’t drawing drinage line by dinf.
    how do i get your program?
    sincerely

  2. Steve replied on :

    Ali—My upslope area code can be downloaded from the MATLAB Central File Exchange.

  3. Ali replied on :

    hi
    thank you for guidance.
    i need help too compute and draw flow accumulation for d-infinity.
    arc gis extract drinage line for d8 algorithm(toolbox archydro)but don’t extrac drinage line for d infinity(taudem).
    what do you think about drinageline for d-infinity?
    sincerely

  4. Steve replied on :

    Ali—This whole series of posts is about D-infinity flow accumulation computation. I have MATLAB code posted on the File Exchange which you can use. If you are asking about how to do it in Arc GIS, then well, you’re asking the wrong company. :-)

  5. Liu Jintao replied on :

    Hi, Steve

    I am trying to implement your program for Tarboton’s algorithm. But I have some questions about his equation (3) as s = hypot(s1, s2). Since it gives a positive or zero value. What is the meaning for the following in your program.

    if s > 0
        % Maximum down-slope is positive.
        r = (af(k_max) * rp(k_max)) + (ac(k_max) * pi / 2);
    else
        % The pixel is in a flat area or is a pit.  Flow direction angle is
        % unresolved.
        r = NaN;
    end
    
  6. Steve replied on :

    Liu—The else-branch is followed when s equals 0.

    I posted my complete upslope area implementation to the MATLAB Central File Exchange: http://www.mathworks.com/matlabcentral/fileexchange/15818

  7. Liu Jintao replied on :

    thank you!! I have managed to solve it.

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.

  • Sana: hi steve, could you explain to me how i would be able to use the dir function, to do a loop through a directory...
  • Nishtha: Sir, I have preprocessed the image in following steps: [1] adaptive histogram equalization [2] thresholding...
  • Kristof: I also strongly support the idea. I have just recently bumped into the problem that im2single was not...
  • Steve: David—I’ m glad you found it useful!
  • David Lalejini: I found your example very useful for finding connected nodes in a large set of input pairs. I start...
  • tommy: Dear Steve, I have a question,please if you are kind to help me regarding the accumulator array dimensions of...
  • Steve: Abc—I don’t know how to distinguish the faces. You might try posting your question in the MATLAB...
  • Manju: well if we have a few ovals within each other like in a cell how do we measure the distance from the center...
  • Steve: Manju—What do you mean? How is each region defined?
  • Manju: if we have 2-3 regions within each other how do we measure the regions of each one?

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