Steve on Image Processing

June 8th, 2007

Upslope area - Plateau processing

[NOTE: After I originally wrote this post about handling plateaus, I discovered problems with the method, so I am no longer using it. I revisited the plateau issue in a later post. -SE]

Today I'll continue thinking about plateaus in a DEM and what they mean for calculating pixel flow. Here's a very tiny portion of my DEM array, just northwest of North Pond.

a = [120 118 123; 120 118 125; 119 119 126]
a =

   120   118   123
   120   118   125
   119   119   126

The center pixel doesn't have a downhill neighbor, so I'm calling it a plateau pixel. No matter that it's a very small plateau; we can't compute a pixel flow direction for it, and that will cause problems when we get around to computing upslope area.

One technique used in image processing to deal with plateaus is called the lower complete transformation. A lower complete image is one where the only pixels having no downhill neighors are the pixels belonging to regional minima. Roughly speaking, the lower complete transformation operates by elevating plateau pixels. Pixels further from the plateau edge get elevated more. Of course, pixels uphill from the plateau need to be elevated as well so that they remain uphill. I have read about this technique but have never implemented it myself. (For more information, I recommend P. Soille, Morphological Image Analysis: Principles and Applications, 2nd edition, Springer, 2003, pp. 222-226.)

I'm going to use a different technique, one that's based on the algorithm in the Image Processing Toolbox function roifill. This function fills in pixels in a particular region by smoothly interpolating from the pixels surrounding the region. It does so by solving a sparse linear system based on the notion that, in the filled output, each pixel in the filled region equals the average of its north, east, south, and west neighbors. (It's kind of an interesting method. Maybe that'll be a future blog topic.)

Here's the example (slightly modified) from the roifill documentation:

I = imread('eight.tif');
imshow(I)

c = [222 272 300 270 221 194 222];
r = [21 21 75 121 121 75 21];
hold on
plot(c,r,'r','LineWidth',4)
J = roifill(I,c,r);
imshow(J)

And here's what roifill does to our tiny snippet from the DEM:

mask = true(3, 3);
b = roifill(a, mask)
b =

  120.0000  118.0000  123.0000
  120.0000  120.5000  125.0000
  119.0000  119.0000  126.0000

You can see that the center pixel has been replaced by a new value, and that the center pixel now has a downhill neighbor.

Here's a slightly bigger example, where the two center pixels have no downhill neighbors:

a2 = pond(15:17, 19:22)
a2 =

   116   116   116   120
   117   115   115   117
   119   115   115   116

And the output of roifill

mask2 = true(3, 4);
b2 = roifill(a2, mask2)
b2 =

   116   116   116   120
   117   116   116   117
   119   115   115   116

Well, the two center pixels now have downhill neighbors, but WAIT! The (1,2) pixel no longer has a downhill neighbor! OK, time to 'fess up. I didn't really anticipate that this would be a problem. I'll have to give this some thought. My first reaction is: It'll be OK because we can use the original, unmodified DEM values to compute the pixel flow for the nonplateau pixels. We only need the modified DEM values to compute pixel flow for the plateau pixels. But I'll sleep on it.

Assuming I can resolve that problem successfully, we can use roifill to compute pixel flow directions for the midplateau pixels. It won't help us, though, for the plateau pixels that are part of regional maxima or regional minima. I'll figure out what to do about those next week.


Get the MATLAB code

Published with MATLAB® 7.4

5 Responses to “Upslope area - Plateau processing”

  1. Felix replied on :

    The example
    a =
    120 118 123
    120 118 125
    119 119 126
    being filled using roifill to give
    b =
    120.0000 118.0000 123.0000
    120.0000 120.5000 125.0000
    119.0000 119.0000 126.0000
    is hydrologically not sensible, as it introduced a local watershed at the center pixel. While in a, the water would be most likely to leave the 3×3 area through the 1,2 pixel, in b there are two pour points 1,2 and 3,2, so you wouldn’t want that. Instead you would want to assign a flow direction of the nearest pixel with the same elevation.
    For sinks (local minima) you would fill the sink to the minimum neighbouring elevation and assign it its flow direction. This way you make sure you dont change any hydrological properties.

  2. Steve replied on :

    Felix—I discovered this problem after I originally wrote the post above, and I revisited plateau handling later. See this post for details.

  3. Steve replied on :

    Felix—P.S. I added a note to the top of this post to refer readers to the later one.

  4. Felix replied on :

    Yes, sorry, I didnt find the rest of the blog entries before I read this… that’s what you get for smart assing around ;-)
    Found your tools now and your flow direction script works a treat! Thanks!

  5. Steve replied on :

    Felix—I’m glad to hear the code is working for you. I was also glad to get your comment, because it reminded me to put a note at the top to caution readers that I eventually implemented a different method.

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.