Marcel
Marcel

Reputation: 3268

How to have a partial grayscale image using Python Pillow (PIL)?

Example:

partial grayscale

I know PIL has the method PIL.ImageOps.grayscale(image) that returns the 4th image, but it doesn't have parameters to produce the 2nd and 3rd ones (partial grayscale).

Upvotes: 1

Views: 1168

Answers (2)

Marcel
Marcel

Reputation: 3268

from PIL import ImageEnhance
# value: float between 0.0 (grayscale) and 1.0 (original)
ImageEnhance.Color(image).enhance(value)

P.S.: Mark's solution works, but it seems to be increasing the exposure.

Upvotes: 1

Mark Setchell
Mark Setchell

Reputation: 207728

When you convert an image to greyscale, you are essentially desaturating it to remove saturated colours. So, in order to achieve your desired effect, you probably want to convert to HSV mode, reduce the saturation and convert back to RGB mode.

from PIL import Image

# Open input image
im = Image.open('potato.png')

# Convert to HSV mode and separate the channels
H, S, V = im.convert('HSV').split()

# Halve the saturation - you might consider 2/3 and 1/3 saturation
S = S.point(lambda p: p//2)

# Recombine channels
HSV = Image.merge('HSV', (H,S,V))

# Convert to RGB and save
result = HSV.convert('RGB')
result.save('result.png')

enter image description here


If you prefer to do your image processing in Numpy rather than PIL, you can achieve the same result as above with this code:

from PIL import Image
import numpy as np

# Open input image
im = Image.open('potato.png')

# Convert to HSV and go to Numpy
HSV = np.array(im.convert('HSV'))

# Halve the saturation with Numpy. Hue will be channel 0, Saturation is channel 1, Value is channel 2
HSV[..., 1] = HSV[..., 1] // 2

# Go back to "PIL Image", go back to RGB and save
Image.fromarray(HSV, mode="HSV").convert('RGB').save('result.png')

Of course, set the entire Saturation channel to zero for full greyscale.

Upvotes: 1

Related Questions