How to calculate RGB values in Python
Tags: python, images, tutorial
Published: 2024-04-01 15:41:00

When managing images, a good exercise is to calculate RGB values in Python.

If you’re asking yourself: “What does RGB mean?”; don’t worry: this was the first question I’ve asked myself before coding for this exercise.

So, before the code, let’s talk about RGB.

## Black and white, RGB, Alpha level: basic information about images
RGB stands for “Red, Blue, Green” and it's a model of “additive colors”: their sum results in the white color. In particular, it's a model used in electronic devices because it is helpful to visualize the pixels of an image.

This means, that when analyzing a colored image, Python — in some ways — gives us three numbers: one for Red, one for Green, and the other for Blue.

Of course, this means that, from a black-and-white image, we can calculate just one value.

On the contrary, the alpha level is transparency, and this means that we can calculate four values (one for R, one for G, one for B, and one for the alpha level).

## RGB values in Python: a preliminary study
All right, let’s use some code here!

Let’s say we have a folder called images.

In this folder, we have three images:
- One in black and white, named `bw.png`.
- One colored, named `daffodil.jpg`.
- One colored with the alpha level, called `eclipse.png`.

We want to calculate the RGB values in Python for each one of these images. 

To do so, we can use the library PIL which can load images, and NumPy to transform the images in NumPy’s arrays.

So, let’s import the libraries:
```python
from PIL import Image
import numpy as np
from tabulate import tabulate
import os
```

Now, before coding, we have to understand some topics.

We’ll use NumPy’s arrays and, first of all, let's remember that the shape of an array can be defined as the number of elements in each dimension. Moreover, the ndim function returns the number of dimensions of an array.

So, let’s calculate the shape and the ndim for each array.

For the black and white image (`bw.png`) we have:
```python
arr = np.array(Image.open(os.path.join(dst_img, "bw.png")))
print(arr.shape)
print(arr.ndim)
```
The result is:

```plaintext
(512, 512)
2
```

So, this image has a height and a width equal to 512 px. It also has 2 dimensions, which is in accord with the fact that is in black and white (it has just two dimensions).

For the RGB image (`daffodil.jpg`) we have:
```python
arr = np.array(Image.open(os.path.join(dst_img, "daffodil.jpg")))
print(arr.shape)
print(arr.ndim)
```

The result is:
```plaintext
(500, 335, 3)
3
```

So, this image has a height equal to 500 px and a width equal to 335 px. It also has 3 dimensions, which is in accord with the fact that is an RGB image.

In the end, for the RGB+alpha (`eclipse.png`) image we have:
```python
arr = np.array(Image.open(os.path.join(dst_img, "eclipse.png")))
print(arr.shape)
print(arr.ndim)
```

The result is:
```plaintext
(256, 256, 4)
3
```

this image has a height and a width equal to 256 px. It also has 3 dimensions, which is in accord with the fact that is an RGB image, but it has 4 channels!

Using NumPy’s mean function, we can calculate the mean value for each color channel. Now, we can create a loop to calculate our values.

Let’s see the whole code and then I’ll explain some details.

## How to calculate RGB values in Python: an exercise
This is the code I’ve used to derive the information we’ve seen before from three images. Of course, this is just one way to do it!

```python
from PIL import Image
import numpy as np
import os

# List files in images folder
dst_img = "images" 

# Iterate over dst_image to get the images as arrays
list_img = os.listdir(dst_img)
for image in sorted(list_img):
[file_name, ext] = os.path.splitext(image) # Split file name from extension
arr = np.array(Image.open(os.path.join(dst_img, image))) # Create arrays for all the images

# Calculate height and width for each image
[h, w] = np.shape(arr)[0:2]

# Calculate the dimension for each array
arr_dim = arr.ndim 

# Calculate the shape for each array
arr_shape = arr.shape 
if arr_dim == 2:
 arr_mean = np.mean(arr)
 print(f'[{file_name}, greyscale={arr_mean:.1f}]')
else:
arr_mean = np.mean(arr, axis=(0,1))
if len(arr_mean) == 3: #RGB CASE
 print(f'[{file_name}, R={arr_mean[0]:.1f}, G={arr_mean[1]:.1f}, B={arr_mean[2]:.1f} ]')
else: #ALPHA CASE
 print(f'[{file_name}, R={arr_mean[0]:.1f}, G={arr_mean[1]:.1f}, B={arr_mean[2]:.1f}, ALPHA={arr_mean[3]:.1f}]')
```

The result is:
```plaintext
[bw, greyscale=21.5]
[daffodil, R=109.3, G=85.6, B=5.0 ]
[eclipse, R=109.0, G=109.5, B=39.8, ALPHA=133.6]
```

### Some code explanations
The importance of coding is to try to generalize so that we can use the code again in the future if needed (with the due changes, of course).

In this case, I’ve decided to differentiate the images by studying the shape and the ndim values derived from NumPy.

In the beginning, I wanted to derive the general information from all the images, and this is why I’ve imported them all using Numpy and the library PIL; I could, then, calculate immediately the file name and the dimensions for each image, because this information can be calculated for each image, preliminary.

Then, I wanted to study the black-and-white image using the if `arr_dim == 2` statement: the black-and-white image, as I said before, has just two dimensions.
Then I wanted to study the RGB and the RGB with the ALPHA channel images.

So, before I wanted to generalize the calculation of the mean values using the `arr_mean = np.mean(arr, axis=(0,1))` code; in this case, I had to use `axis=(0,1)` because those images have 3 dimensions, and the calculation has to be done along the `x` and `y` axis in NumPy.

Then, I’ve differentiated the RGB from the RGB+ALPHA image with `len(arr_mean)`; since the RGB image has 3 channels, `len(arr_mean)` has to be equal to 3; instead, since the RGB+ALPHA has 4 channels, `len(arr_mean)` has to be equal to 4; hence, the underlined code before.

## Conclusions
This article describes what RGB values are and how to calculate RGB values in Python.

The best thing you can do now is to try it with your images.

---

The post "[How to calculate RGB values in Python](https://federicotrotta.com/how-to-calculate-rgb-values-in-python/)" was originally created for my blog.