PIL has an ImageFilter module that has a useful selection of filters for enhancing certain characteristics of images such as sharpening features that were blurred. Ten of these filters are demonstrated in the following recipe.
Use the images russian_doll.png
from the folder /constr/pics1
. Create a folder /constr/picsx
for the resulting filtered images. Using a separate folder for the results helps prevent the folder pics1
from becoming overcrowded with a heap of redundant images and work-in-progress. After each execution, we can delete the contents of picsx
without the fear of losing source images for the recipes.
Open the folder /constr/picsx
on your screen before you execute the following code and watch as the images appear once the execution is complete. The source image was chosen to have a blurred Russian doll on an in-focus background because it allows the effects of the different filters to be readily distinguished.
# image_pileof_filters_1.py # >>>>>>>>>>>>>>>>>>> import ImageFilter im_1 = Image.open("/constr/pics1/russian_doll.png") im_2 = im_1.filter(ImageFilter.BLUR) im_3 = im_1.filter(ImageFilter.CONTOUR) im_4 = im_1.filter(ImageFilter.DETAIL) im_5 = im_1.filter(ImageFilter.EDGE_ENHANCE) im_6 = im_1.filter(ImageFilter.EDGE_ENHANCE_MORE) im_7 = im_1.filter(ImageFilter.EMBOSS) im_8 = im_1.filter(ImageFilter.FIND_EDGES) im_9 = im_1.filter(ImageFilter.SMOOTH) im_10 = im_1.filter(ImageFilter.SMOOTH_MORE) im_11 = im_1.filter(ImageFilter.SHARPEN) im_2.save("/constr/picsx/russian_doll_BLUR.png") im_3.save("/constr/picsx/ russian_doll_CONTOUR.png") im_4.save("/constr/picsx/ russian_doll_DETAIL.png") im_5.save("/constr/picsx/ russian_doll_EDGE_ENHANCE.png") im_6.save("/constr/picsx/ russian_doll_EDGE_ENHANCE_MORE.png") im_7.save("/constr/picsx/ russian_doll_EMBOSS.png") im_8.save("/constr/picsx/ russian_doll_FIND_EDGES.png") im_9.save("/constr/picsx/ russian_doll_SMOOTH.png") im_10.save("/constr/picsx/ russian_doll_SMOOTH_MORE.png") im_11.save("/constr/picsx/ russian_doll_SHARPEN.png")
This recipe shows that the best filtering results are highly dependent on both the feature of the image we wish to enhance or suppress, as well as some subtle characteristics of the individual image being worked on. In the particular example of the Russian doll used here, the EDGE_ENHANCE
filter is particularly effective for counteracting the poor focus of the doll. It improves the color contrast in comparison to the SHARPEN
filter. Re-size and paste for synthetic rotation
We want to create an animation that makes an image apparently rotate around a vertical axis in the middle of the picture. In this recipe, we see how the basic sequences of images for the animation are prepared.
We want to make a sequence of images that are progressively narrower as if they were a poster on a board that was being gradually rotated. Then, we want to paste these narrow images in the middle of a standard-sized black background. If this sequence were displayed as a time-controlled series of frames, we would see the image apparently rotating around a central vertical axis.
We use the image 100_canary.png
in a directory /constr/pics1
and we place the results in /constr/picsx
to avoid cluttering our source folder /constr/pics1
.
Again open the folder /constr/picsx
on your screen before you execute the following code and watch as the images appear once the execution is complete. This is not necessary but it is interesting to watch the results materialize before your eyes.
# image_rotate_resize_1.py # >>>>>>>>>>>>>>>>>>>> import Image import math THETADEG = 5.0 # degrees THETARAD = math.radians(THETADEG) im_1 = Image.open("/constr/pics1/blank.png") im_seed = Image.open("/constr/pics1/100_canary.png") # THE SEED IMAGE im_seq_name = "canary" #GET IMAGE WIDTH AND HEIGHT - not done here # For the time being assume the image is 100 x 100 width = 100 height = 100 num_images = int(math.pi/(2*THETARAD)) Q = [] for j in range(0,2*num_images + 1): Q.append(j) for i in range(0, num_images): new_size = width * math.cos(i*THETARAD) # Width for reduced # image im_temp = im_seed.resize((new_size, height), Image.NEAREST) im_width = im_temp.size[0] # Get the width of the reduced image x_start = 50 -im_width/2 # Centralize new image in a 100x100 # square. im_1.paste(im_temp,( x_start,10)) # Paste: This creates the # annoying ghosting. stri = str(i) # Save the reduced image Q[i] = "/constr/picsx/" + im_seq_name + stri + ".gif" im_1.save(Q[i]) # Flip horizontally and save the reduced image. im_transpose = im_temp.transpose(Image.FLIP_LEFT_RIGHT) im_1.paste(im_transpose,( x_start,10)) strj = str(2 * num_images - i) Q[ 2 * num_images - i ] = "/constr/picsx/" + im_seq_name + strj + ".gif" im_1.save(Q[ 2 * num_images - i ])
To mimic the effect of rotation, we reduce the width of each image to cosine(new_angle)
where new_angle
is increased by 5 degrees of rotation for each image. Then we take this narrowed image and paste it onto a blank black square. Finally we name each picture in the sequence in a systematic way such as canary0.gif, canary1.gif
, and so on until the last image is named canary36.gif
.
This example demonstrates the kind of task the Python Imaging Library is well-suited to - when you need to repeatedly perform a controlled transformation on an image or collection of images. The images could be the frames of a video film. Effects like fade-in and fade-out, zoom-out, color-shift, sharpen, and blur are the obvious ones that can be used but your programmer's imagination will be able to come up with many others.
3.145.87.161