[Image-SIG] Two PIL based Hill Shading Implementations, using Python & Python/C.

Douglas Bagnall douglas at paradise.net.nz
Tue Feb 6 22:38:26 CET 2007

John Barratt wrote:

> http://www.langarson.com.au/blog/?p=14

This is an observation, not a recommendation, but you could *almost* do
all of this in pure PIL, without explicit loops.  You could find the
slope like so:

    dxfilter = ImageFilter((3,3), [1, 0, -1,
                                   2, 0, -2,
                                   1, 0, -1], 1)
    dyfilter = ImageFilter((3,3), [-1, -2, -1,
                                    0,  0,  0,
                                    1,  2, 1], 1)

    im_dx = img.filter(dxfilter)
    im_dy = img.filter(dyfilter)
    im_slope = ImageMath.eval("(a*a + b*b) ** 0.5)", a=im_dx, b=im_dy)

The simple trig functions could use Image.point:

    def _sin(x):
        return 128 + sin(x) *127  #scaled to save precision
    im_sin_slope = im_slope.point(_sin)

which should be quicker (though less accurate) than other methods,
because it builds a lookup table rather than calculating each point.

The tricky one looks to be the atan2 used to calculate the aspect.
Either it needs to be split into two functions, one calculating
atan(dy/dx), and the other calculating the correct quadrant, or it needs
to be approximated using arithmetic in ImageMath.

After that it is just a matter of back-scaling, multiplying and summing,
which ImageMath.eval and other functions can do.

but, as I said, I don't recommend it.


More information about the Image-SIG mailing list