I really wanted to finish this article last week, but I just didn’t get around to it. This post is going to be on the things you can do with the Python Imaging Library when you implement your own kernels. Remember that depending on the kernel arguments you supply, you may get radically different results. The results may not even be a smoothed image; they could be embossed images, edge maps, etc. With that out of the way, let’s get started.

There are a couple different ways you can implement your own image filters using PIL. The first way is easy for one-off filters that you probably won’t use throughout your code. I mean, you could if you wanted to keep writing the same line of code over and over, but that’s up to you. The way this is done is by making use of PIL’s ImageFilter.Kernel class. You can create an object from this class that has all the common image filter arguments (size, kernel, scale, and offset).

That’s the quick and dirty way to implement your own image filters. It uses the same filter arguments as ImageFilter.SMOOTH so it yields an identical result.

The second way to implement your own image filters is to do it just like PIL does. For each image filter class that PIL provides, you’ll see that they inherit from the ImageFilter.BuiltinFilter class which in turn inherits from the ImageFilter.Kernel class. The stock implementation for ImageFilter.SMOOTH is as follows:

Where filterargs is the size of the kernel (3, 3), the scale factor (13), the offset (0), and the kernel itself. Now since the stock PIL filters are boring and I don’t want this post to be about how the stock filters are implemented, I implemented my own image filter.

The result of running this filter on my picture is this:

Pretty cool, eh? I highly encourage you to implement your own filters and dig into the stock PIL image filters to see how they achieve certain effects. With your own image filters and the stock PIL image filters at your command, you may never have to write your own image processing algorithms at all.

3 Responses to “Follow Up: Fun with Image Smoothing in Python”

  1. Tom Counsell Says:

    I am working with custom filters in the PIL, but I need a larger kernel size. Specifically 15×15 in my case. Do you have any ideas on how to achieve this? I previously was using numpy to change the image data to an array and writing my own functions for applying filters, but PIL’s filters run many times faster than mine do. In addition I ran into some problems because the axis are switched. Any thoughts are greatly appreciated. You have a great website - very clean! I plan to do the same in the next couple months so I can contribute publicly as well.
    Cheers, Tom

  2. Erez Says:

    I wanted to echo Tom’s question. I really want to be able to do some large kernel filtering using PIL but I can’t…any ideas?

    Great site!

  3. jstults Says:

    David,

    I really appreciate all of the python image processing posts, thanks!

    Tom and Erez,

    I recently wrote about using F2Py along with PIL so you can put your kernels in Fortran and call them from Python; it might be of interest to you based on your comments:
    http://j-stults.blogspot.com/2008/12/treating-image-edges.html

    Hope this helps with your number crunching.

    Cheers!

Leave a Reply