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

John Barratt jb at langarson.com.au
Thu Feb 8 12:49:44 CET 2007

```Hi Douglas,
It's good to see an example (albeit partial) like this, I haven't
really used ImageMath and ImageFilter.  Would be interesting to compare
with equivalent numpy implementations performance-wise for some image
processing problems.

Cheers,

JB.

Douglas Bagnall wrote:
> 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.
>
>
> douglas
>

--
John Barratt - www.langarson.com.au
Python, Zope, GIS, Weather
```