PIL in Python from easy to hard

To get to the complex processing algorithms, it is worth analyzing standard schemes, with which I suggest starting.

For processing examples, an image with different sets of colors will be used:

image

To start, we need two library modules:

from PIL import Image, ImageDraw 

Set up tools for comfortable future work:

image = Image.open('test.jpg')  # Открываем изображение
draw = ImageDraw.Draw(image)  # Создаем инструмент для рисования
width = image.size[0]  # Определяем ширину
height = image.size[1]  # Определяем высоту
pix = image.load()  # Выгружаем значения пикселей

Let's get started


We will process images in RGB format. PIL also supports working with formats 1, L, P, RGB, RGBA, CMYK, YCbCr, LAB, HSV, I, F.

Pixel values ​​in the image are specified in the format: (x, y), (red, green, blue) , where x, y are the coordinates, and the numerical values ​​of RGB are in the range from 0 to 255. That is, we work with an 8-bit image.

Grayscale


A gray tint appears in the case of equality of all color palettes, so we need to get the arithmetic mean value in all three points:


for x in range(width):
    for y in range(height):
       r = pix[x, y][0] #узнаём значение красного цвета пикселя
       g = pix[x, y][1] #зелёного
       b = pix[x, y][2] #синего
       sr = (r + g + b) // 3 #среднее значение
       draw.point((x, y), (sr, sr, sr)) #рисуем пиксель
image.save("result.jpg", "JPEG") #не забываем сохранить изображение

image
Slight nuance
The human eye perceives a different spectrum of colors in different ways. Nobody will give you the exact formula, since the perception of colors is different for everyone one way or another, but if you are interested, you can read more here and here .


Inversion


Inversion is obtained by subtracting the current color from 255:


for x in range(width):
   for y in range(height):
      r = pix[x, y][0]
      g = pix[x, y][1]
      b = pix[x, y][2]
      draw.point((x, y), (255 - r, 255 - g, 255 - b))

image

Grayscale Inversion


Combining the two previous algorithms, you can write the following code:


for x in range(width):
    for y in range(height):
        r = pix[x, y][0]
        g = pix[x, y][1]
        b = pix[x, y][2]
        sr = (r + g + b) // 3
        draw.point((x, y), (255 - sr, 255 - sr, 255 - sr))

image

Selective Grayscale Inversion


For this algorithm, you need to determine the threshold value, which I will take for 100:

for x in range(width):
    for y in range(height):
        r = pix[x, y][0]
        g = pix[x, y][1]
        b = pix[x, y][2]
        if (r+g+b)>100: #если сумма значений больше 100 , то используем инверисю
            sr = (r + g + b) // 3
            draw.point((x, y), (255-sr, 255-sr, 255-sr))
        else: #иначе обычный оттенок серого
            sr = (r + g + b) // 3
            draw.point((x, y), (sr, sr, sr))

image

Conclusion


In the following articles, I would like to talk about how to more locally approach image filtering by dividing it into areas, as well as show interesting possibilities of DFS in image processing algorithms

Also popular now: