I am looking to convert images to grayscale, but would like to limit the amount of shades to 4-5. The reason for this is because I am trying to create a layered 'paper cutout' effect of the images so that I can use it as a base for some artwork I am working on in which I have 5 shades of black-white to work with.
If you have better ideas of how to achieve this with Python, I'm all ears. It would be super convenient if a filter like this already existed in Python but I can't seem to find anything. Appreciate it.
The project end result is to look something like this: Image
You can use PIL to quantize this:
into this:
like this:
#!/usr/bin/env python3
from PIL import Image
# Load image and make greyscale
im = Image.open('artistic-swirl.jpg').convert('L')
# Quantize down to 5 shades and save
qu = im.quantize(5)
qu.save('result.png')
print(f'Colours: {qu.getcolors()}')
Sample Output
You can see the list of 5 resulting colours (palette indices) and their frequency of occurrence below:
Colours: [(32047, 0), (34515, 1), (59838, 2), (70181, 3), (53419, 4)]
You can equally check the colours with ImageMagick like this:
magick identify -verbose result.png
Sample Output
Image:
Filename: result.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: PseudoClass
Geometry: 500x500+0+0
Units: Undefined
Colorspace: sRGB
Type: Grayscale
Base type: Undefined
Endianness: Undefined
Depth: 8-bit
Channel depth:
Red: 8-bit
Green: 8-bit
Blue: 8-bit
Channel statistics:
Pixels: 250000
Red:
min: 106 (0.415686)
max: 166 (0.65098)
mean: 133.412 (0.523186)
median: 139 (0.545098)
standard deviation: 19.4166 (0.0761436)
kurtosis: -0.979496
skewness: 0.129338
entropy: 0.972589
Green:
min: 106 (0.415686)
max: 166 (0.65098)
mean: 133.412 (0.523186)
median: 139 (0.545098)
standard deviation: 19.4166 (0.0761436)
kurtosis: -0.979496
skewness: 0.129338
entropy: 0.972589
Blue:
min: 106 (0.415686)
max: 166 (0.65098)
mean: 133.412 (0.523186)
median: 139 (0.545098)
standard deviation: 19.4166 (0.0761436)
kurtosis: -0.979496
skewness: 0.129338
entropy: 0.972589
Image statistics:
Overall:
min: 106 (0.415686)
max: 166 (0.65098)
mean: 133.412 (0.523186)
median: 139 (0.545098)
standard deviation: 19.4166 (0.0761436)
kurtosis: -0.979485
skewness: 0.129339
entropy: 0.972589
Colors: 5
Histogram:
53419: (106,106,106) #6A6A6A srgb(106,106,106)
70181: (125,125,125) #7D7D7D grey49
59838: (139,139,139) #8B8B8B srgb(139,139,139)
34515: (153,153,153) #999999 grey60
32047: (166,166,166) #A6A6A6 grey65
Colormap entries: 5
Colormap:
0: (166,166,166,1) #A6A6A6FF grey65
1: (153,153,153,1) #999999FF grey60
2: (139,139,139,1) #8B8B8BFF srgba(139,139,139,1)
3: (125,125,125,1) #7D7D7DFF grey49
4: (106,106,106,1) #6A6A6AFF srgba(106,106,106,1)
Rendering intent: Perceptual
Gamma: 0.454545
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Matte color: grey74
Background color: white
Border color: srgb(223,223,223)
Transparent color: none
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 500x500+0+0
Dispose: Undefined
Iterations: 0
Compression: Zip
Orientation: Undefined
Properties:
date:create: 2022-06-30T13:25:02+00:00
date:modify: 2022-06-30T13:25:02+00:00
png:IHDR.bit-depth-orig: 4
png:IHDR.bit_depth: 4
png:IHDR.color-type-orig: 3
png:IHDR.color_type: 3 (Indexed)
png:IHDR.interlace_method: 0 (Not interlaced)
png:IHDR.width,height: 500, 500
png:PLTE.number_colors: 5
png:sRGB: intent=0 (Perceptual Intent)
signature: ff62d5806f38bc0228513619c9822015bc70ee8466714b0317441e89ff3b815b
Artifacts:
verbose: true
Tainted: False
Filesize: 15193B
Number pixels: 250000
Pixel cache type: Memory
Pixels per second: 90.1415MP
User time: 0.000u
Elapsed time: 0:01.002
Version: ImageMagick 7.1.0-33 Q16-HDRI arm 20040 https://imagemagick.org
Keywords: Python, image processing, quantize, reduce colours.