ColorDetection -  Python ColorDetect package
Tags: python, opensource, datascience, tutorial
Published: 2020-09-28 07:04:11

Images. That's it. Images. As a point of practicality, take a fashion designer (as a forum member vividly described to me at one point). You are given an image or have an image at your disposal that simply tickles your curiosity and want to incorporate it in one of your new lines. Let's swerve a little into the genetics section. Given a petri dish image for instance, with pigmented bacteria or similar organisms, and you would like to find the abundance of that organism or organisms in this specific image. Get the gist?

That's why we have [ColorDetect](https://colordetect.readthedocs.io/en/latest/). Letting you knab those colors right from the image, or if you were a tad bit crazy, a video. For an overview, we'll kick it off by installation.

As all Pythonistas have it, create a virtual environment, and install.

```python
pip install ColorDetect
```

For this demonstration, we'll borrow Greyson Joralemon's photo.

![random_balls.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1601131919267/A4U0klzAt.jpeg)

A program that gets the colors in this specific image.

```python
from colordetect import ColorDetect

user_image = ColorDetect('media/random_balls.jpg')

colors = user_image.get_color_count()

print(colors)
```

ColorDetect will go, do its thing and return this:
```bash
$ python get_colors.py

{'[59.0, 70.0, 198.0]': 7.63, '[245.0, 155.0, 186.0]': 9.0, '[232.0, 22.0, 103.0]': 11.98, '[207.0, 143.0, 3.0]': 35.54, '[88.0, 70.0, 34.0]': 35.85}
```
A color description of the image, breaking down the relevant most abundant colors to say, hey, this image has `7.63 %` of it occupied by this **RGB** color: `'[59.0, 70.0, 198.0]'`.

If we wanted the **hex** for this instead, we'd pass that as the parameter to `get_color_count()`.

```python
colors = user_image.get_color_count(color_format='hex')

#colors
# {'#3b46c6': 7.63, '#f59bba': 9.0, '#e81667': 11.99, '#cf8f03': 35.56, '#584622': 35.83}
```

We could, of course, look for more color than just five of the most dominant.

```python
user_image.get_color_count(color_format='hex', color_count=8)
```

Depending on the size or ratio of the image, it may take a moment. A case in point, a low graphic image, say 2MP vs a high definition top of the line camera image. These two images, despite pointing to the same object or scene, have very different pixel ratios.

Let's go ahead, and instead of getting the color as a variable, write this color onto the image.

```python

user_image.write_color_count()
# save the image after writing the color count to it
user_image.save_image('media', 'processed.jpg')
```

We save this image in the media directory with a name `processed.jpg`:


![processed.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1601269610638/hEdMJCh-W.jpeg)

 
Perfecto!

we did have something about the crazy people with videos, didn't we?
Now, where is that video...oh, [here it is](https://github.com/TheGreenCodes/ColorDetectPreview/blob/master/media/earth.mp4). Our *earth.mp4* file.

```python
from colordetect import VideoColor


my_video = VideoColor('media/earth.mp4')

video_colors = my_video.get_video_frames( progress=True)

print(f"{video_colors}")
```

```
{'[137.0, 165.0, 182.0]': 0.92, '[71.0, 84.0, 95.0]': 2.16, '[24.0, 30.0, 50.0]': 11.17, '[7.0, 10.0, 26.0]': 17.59, '[0.0, 0.0, 0.0]': 68.83, '[143.0, 170.0, 187.0]': 0.84, '[76.0, 89.0, 101.0]': 2.09, '[26.0, 32.0, 52.0]': 11.18, '[8.0, 11.0, 28.0]': 16.69, '[135.0, 163.0, 181.0]': 0.95, '[76.0, 88.0, 98.0]': 2.05, '[8.0, 11.0, 27.0]': 15.43, '[127.0, 160.0, 179.0]': 0.94, '[71.0, 83.0, 94.0]': 2.38, '[7.0, 11.0, 27.0]': 15.72, '[124.0, 160.0, 181.0]': 0.9, '[69.0, 84.0, 96.0]': 2.26, '[26.0, 32.0, 53.0]': 13.12, '[125.0, 160.0, 182.0]': 0.89, '[68.0, 82.0, 95.0]': 2.27, '[132.0, 166.0, 186.0]': 0.79, '[71.0, 87.0, 100.0]': 2.1, '[25.0, 32.0, 52.0]': 14.18, '[132.0, 164.0, 183.0]': 0.89, '[70.0, 85.0, 97.0]': 2.08, '[132.0, 165.0, 183.0]': 0.9, '[73.0, 88.0, 99.0]': 2.06, '[26.0, 33.0, 53.0]': 12.11, '[8.0, 10.0, 27.0]': 16.76, '[134.0, 166.0, 184.0]': 0.88, '[132.0, 165.0, 185.0]': 0.86, '[74.0, 88.0, 100.0]': 2.0, '[26.0, 33.0, 52.0]': 10.65, '[7.0, 10.0, 27.0]': 16.93, '[124.0, 157.0, 178.0]': 0.99, '[68.0, 82.0, 93.0]': 2.14, '[25.0, 31.0, 50.0]': 10.66, '[124.0, 160.0, 182.0]': 0.88, '[67.0, 82.0, 94.0]': 2.19, '[25.0, 31.0, 49.0]': 10.68, '[124.0, 160.0, 183.0]': 0.85, '[67.0, 83.0, 95.0]': 2.0, '[25.0, 30.0, 49.0]': 11.04, '[123.0, 160.0, 182.0]': 0.87, '[24.0, 29.0, 47.0]': 11.15, '[23.0, 29.0, 47.0]': 10.6, '[6.0, 9.0, 26.0]': 19.34, '[67.0, 83.0, 97.0]': 2.0, '[24.0, 29.0, 48.0]': 9.31, '[125.0, 161.0, 184.0]': 0.85, '[67.0, 84.0, 97.0]': 1.98, '[127.0, 162.0, 183.0]': 0.87, '[67.0, 83.0, 96.0]': 1.96, '[23.0, 29.0, 46.0]': 8.58, '[5.0, 8.0, 25.0]': 17.77, '[125.0, 161.0, 183.0]': 0.88, '[68.0, 84.0, 98.0]': 1.9, '[24.0, 29.0, 46.0]': 6.95, '[67.0, 84.0, 99.0]': 1.89, '[133.0, 166.0, 186.0]': 0.81, '[67.0, 86.0, 99.0]': 1.85, '[23.0, 28.0, 45.0]': 6.83, '[5.0, 8.0, 24.0]': 22.22, '[135.0, 165.0, 186.0]': 0.85, '[69.0, 86.0, 100.0]': 1.79, '[22.0, 27.0, 43.0]': 7.22, '[5.0, 7.0, 24.0]': 22.48, '[73.0, 91.0, 105.0]': 1.69, '[129.0, 163.0, 185.0]': 0.85, '[69.0, 85.0, 98.0]': 1.9, '[21.0, 27.0, 44.0]': 7.25, '[4.0, 7.0, 24.0]': 21.7, '[68.0, 86.0, 101.0]': 1.9, '[22.0, 27.0, 45.0]': 7.91, '[126.0, 160.0, 181.0]': 0.94, '[66.0, 83.0, 96.0]': 1.91, '[22.0, 27.0, 46.0]': 9.19, '[129.0, 164.0, 185.0]': 0.84, '[69.0, 86.0, 99.0]': 1.96, '[21.0, 27.0, 46.0]': 10.65, '[133.0, 165.0, 185.0]': 0.85, '[23.0, 29.0, 48.0]': 10.61, '[7.0, 9.0, 26.0]': 17.7, '[135.0, 165.0, 185.0]': 0.85, '[73.0, 88.0, 100.0]': 1.96, '[24.0, 29.0, 50.0]': 11.34, '[139.0, 164.0, 177.0]': 0.92} 
```

We may find the colors are too much for our use case. So let's shorten this:

```python
print(my_video.color_sort(color_count=6))
```

```
{'[0.0, 0.0, 0.0]': 68.83, '[5.0, 7.0, 24.0]': 22.48, '[5.0, 8.0, 24.0]': 22.22, '[4.0, 7.0, 24.0]': 21.7, '[6.0, 9.0, 26.0]': 19.34, '[5.0, 8.0, 25.0]': 17.77}

```
This will return the top 6 most dominant colors from the whole video, having taken a frame for every second. Looks much better! Unless you want to use all the colors, that is.

I'll iterate on this. This all depends on the quality of the input media file, and length if it is a video in this case. take it this way, a video 5 minutes long, showing a wide variety of colors from all sorts of crayons vs a short video as just shown. Remember, the process is per frame of every second. I'm certain this will be addressed in a future [release](https://colordetect.readthedocs.io/en/latest/contributing.html#contributing).

We can hold off here and let the steam cool off.
Do keep up to date with the [package](https://github.com/MarvinKweyu/ColorDetect) as more features and performance improvements come to light. 

Yours, 

[TheGreencodes](https://thegreencodes.com/)