DEV Community

Cover image for ColorDetection -  Python ColorDetect package
Marvin
Marvin

Posted on • Edited on

ColorDetection - Python ColorDetect package

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. 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.

pip install ColorDetect
Enter fullscreen mode Exit fullscreen mode

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

random_balls.jpg

A program that gets the colors in this specific image.

from colordetect import ColorDetect

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

colors = user_image.get_color_count()

print(colors)
Enter fullscreen mode Exit fullscreen mode

ColorDetect will go, do its thing and return this:

$ 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}
Enter fullscreen mode Exit fullscreen mode

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().

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}
Enter fullscreen mode Exit fullscreen mode

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

user_image.get_color_count(color_format='hex', color_count=8)
Enter fullscreen mode Exit fullscreen mode

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.


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

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

processed.jpg

Perfecto!

we did have something about the crazy people with videos, didn't we?
Now, where is that video...oh, here it is. Our earth.mp4 file.

from colordetect import VideoColor


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

video_colors = my_video.get_video_frames( progress=True)

print(f"{video_colors}")
Enter fullscreen mode Exit fullscreen mode
{'[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} 
Enter fullscreen mode Exit fullscreen mode

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

print(my_video.color_sort(color_count=6))
Enter fullscreen mode Exit fullscreen mode
{'[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}

Enter fullscreen mode Exit fullscreen mode

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.

We can hold off here and let the steam cool off.
Do keep up to date with the package as more features and performance improvements come to light.

Yours,

TheGreencodes

Top comments (0)