Image enhance recipes in Pillow

By Martin McBride, 2020-10-11
Tags: image processing recipes colour contrast brightness sharpness
Categories: pillow


The ImageEnhance module can be used to adjust colour, contrast, brightness and sharpness.

_Enhance interface

Each image enhance function is implemented as an object that implements the _Enhance interface. The interface provides a single method:

enhance(factor)

For example, the ImageEnhance.Brightness class controls the brightness of an image, It has an enhance method that it inherits from _Enhance.

factor is a number that controls the effect. For example, for Brightness a factor of less than 1.0 makes the image darker (and a value of 0.0 makes the image completely black). A factor of greater than 1.0 makes the image brighter. A factor of exactly 1.0 leaves the original image unchanged.

The basic pattern for any image enhancement is:

  • Create an enhancer object, passing in the source image.
  • Call enhance on the object, which returns a new, enhanced Image object.

ImageEnhance.Color

The Color object can be used to increase of decrease the amount of colour in an image. Here is the code to change the colour by an amount factor:

im = Image.open('carousel.jpg')
im_out = ImageEnhance.Color(im).enhance(factor)
im_out.write('out.jpg')

This image shows the effect of applying various factors in the code above. Factors greater than 1.0 make the colours stronger, less than 1.0 reduce the colours. A factor of 0.0 creates a greyscale image:

As for all enhancements, a factor of 1.0 would leave the image unchanged.

ImageEnhance.Brightness

The Brightness object can be used to increase of decrease the overall brightness an image. Here is the code to change the brightness by an amount factor:

im = Image.open('carousel.jpg')
im_out = ImageEnhance.Brightness(im).enhance(factor)
im_out.write('out.jpg')

This image shows the effect of applying various factors in the code above. Factors greater than 1.0 make the image brighter, less than 1.0 makes the image darker. A factor of 0.0 results in a completely black image:

ImageEnhance.Contrast

The Contrast object can be used to increase of decrease the overall contrast an image.

As we saw above, changing the brightness makes the entire image brighter or darker. Increasing the contrast is slightly different - it makes the light areas lighter, and the dark areas darker.

Here is the code to change the contrast by an amount factor:

im = Image.open('carousel.jpg')
im_out = ImageEnhance.Contrast(im).enhance(factor)
im_out.write('out.jpg')

This image shows the effect of applying various factors in the code above. Factors greater than 1.0 increase the brightness range, making light colours k lighter and dark colours darker. At very high contrast values, every pixel if either black or white, and generally only the basic shapes of the image are visible.

Factors less than 1.0 decrease the brightness range, pulling all the colours towards a middle grey. A factor of 0.0 results in a completely grey image:

ImageEnhance.Sharpness

The Sharpness object can be used to blur or sharpen an image.

Here is the code to sharpen by an amount factor:

im = Image.open('carousel.jpg')
im_out = ImageEnhance.Sharpness(im).enhance(factor)
im_out.write('out.jpg')

Applying sharpening with a factor greater than 1.0 applies a sharpening filter to the image. This filter enhances edges in the image, making them appear better defined. Of course, if an image is blurred to start with, the filter can't recover blurred out details, but a small amount of sharpening can make the image look better. Applying too much sharpening can make the image look odd though.

Sharpening of less than 1.0 does the opposite, it blurs the image, softening it.

If you found this article useful, you might be interested in the book NumPy Recipes or other books by the same author.

Join the PythonInformer Newsletter

Sign up using this form to receive an email when new content is added:

Popular tags

2d arrays abstract data type alignment and angle animation arc array arrays bar chart bar style behavioural pattern bezier curve built-in function callable object chain circle classes clipping close closure cmyk colour combinations comparison operator comprehension context context manager conversion count creational pattern data science data types decorator design pattern device space dictionary drawing duck typing efficiency ellipse else encryption enumerate fill filter font font style for loop formula function function composition function plot functools game development generativepy tutorial generator geometry gif global variable gradient greyscale higher order function hsl html image image processing imagesurface immutable object in operator index inner function input installing iter iterable iterator itertools join l system lambda function latex len lerp line line plot line style linear gradient linspace list list comprehension logical operator lru_cache magic method mandelbrot mandelbrot set map marker style matplotlib monad mutability named parameter numeric python numpy object open operator optimisation optional parameter or pandas partial application path pattern permutations pie chart pil pillow polygon pong positional parameter print product programming paradigms programming techniques pure function python standard library radial gradient range recipes rectangle recursion reduce regular polygon repeat rgb rotation roundrect scaling scatter plot scipy sector segment sequence setup shape singleton slice slicing sound spirograph sprite square str stream string stroke structural pattern subpath symmetric encryption template tex text text metrics tinkerbell fractal transform translation transparency triangle truthy value tuple turtle unpacking user space vectorisation webserver website while loop zip zip_longest