Basic Image Manipulation

[CG]Maxime
4,102 views

Open Source Your Knowledge, Become a Contributor

Technology knowledge has to be shared and made accessible for free. Join the movement.

Create Content

Luminosity

Changing the luminosity of a picture in a RGB mode can be done by adding a constant to each color component. However, this is a very simplified algorithm: the perceived luminosity has not an easy definition and there are several ways to estimate the luminosity of a pixel. Note that it is also possible to change from RGB to HSL to modify the luminosity easily.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from PIL import Image, ImageDraw
# Square distance between 2 colors
def distance2(color1, color2):
r1, g1, b1 = color1
r2, g2, b2 = color2
return (r1 - r2) ** 2 + (g1 - g2) ** 2 + (b1 - b2) ** 2
# Change this:
luminosity = 80
# Load image:
input_image = Image.open("input.png")
input_pixels = input_image.load()
# Create output image
output_image = Image.new("RGB", input_image.size)
draw = ImageDraw.Draw(output_image)
# Generate image
for x in range(output_image.width):
for y in range(output_image.height):
r, g, b = input_pixels[x, y]
r = int(r + luminosity)
g = int(g + luminosity)
b = int(b + luminosity)
draw.point((x, y), (r, g, b))
output_image.save("output.png")
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Contrast

The contrast is the difference in brightness (or color) that makes the objects in a picture distinguishable. The intensity histogram of an image is the distribution of pixel luminance for an image. In order to improve the contrast, we can use a linear normalization of the intensity histogram:

IN=(IImin)255ImaxImin, where IN is the normalized pixel intensity, Imin and Imax are the minimum and maximum intensity (before normalization).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from PIL import Image, ImageDraw
# Square distance between 2 colors
def distance2(color1, color2):
r1, g1, b1 = color1
r2, g2, b2 = color2
return (r1 - r2) ** 2 + (g1 - g2) ** 2 + (b1 - b2) ** 2
# Change this:
luminosity = 80
# Load image:
input_image = Image.open("input.png")
input_pixels = input_image.load()
# Create output image
output_image = Image.new("RGB", input_image.size)
draw = ImageDraw.Draw(output_image)
# Find minimum and maximum luminosity
imin = 255
imax = 0
for x in range(input_image.width):
for y in range(input_image.height):
r, g, b = input_pixels[x, y]
i = (r + g + b) / 3
imin = min(imin, i)
imax = max(imax, i)
# Generate image
for x in range(output_image.width):
for y in range(output_image.height):
r, g, b = input_pixels[x, y]
# Current luminosity
i = (r + g + b) / 3
# New luminosity
ip = 255 * (i - imin) / (imax - imin)
r = int(r * ip / i)
g = int(g * ip / i)
b = int(b * ip / i)
draw.point((x, y), (r, g, b))
output_image.save("output.png")
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Colorize

In the previous example, we saw how to adjust the color of the pixels. This can be used to change the color balance for instance. In the next example, we detect the pixels whose color is close to blue (0, 0, 255) by computing a distance, and we reduce the value of the red and blue components and increase the green component.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from PIL import Image, ImageDraw
# Square distance between 2 colors
def distance2(color1, color2):
r1, g1, b1 = color1
r2, g2, b2 = color2
return (r1 - r2) ** 2 + (g1 - g2) ** 2 + (b1 - b2) ** 2
color_to_change = (0, 0, 255)
threshold = 220
# Load image:
input_image = Image.open("input.png")
input_pixels = input_image.load()
# Create output image
output_image = Image.new("RGB", input_image.size)
draw = ImageDraw.Draw(output_image)
# Generate image
for x in range(output_image.width):
for y in range(output_image.height):
r, g, b = input_pixels[x, y]
if distance2(color_to_change, input_pixels[x, y]) < threshold ** 2:
r = int(r * .5)
g = int(g * 1.25)
b = int(b * .5)
draw.point((x, y), (r, g, b))
output_image.save("output.png")
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Open Source Your Knowledge: become a Contributor and help others learn. Create New Content