Welcome to ColorDetect’s documentation!¶
Welcome to ColorDetect’s documentation¶
This site covers ColorDetect’s usage and module documentation.
Getting started¶
Installation¶
$ pip install ColorDetect
For usage , import as:
import colordetect
For more details, proceed to image_color_recognition
ColorDetect¶
Image color recognition¶
Example 1¶
As a walk through some of the capabilities of ColorDetect we will use this sample image.

# Get the most dominant color count from an image
>>> from colordetect import ColorDetect
>>>
>>> my_image = ColorDetect("<image_path>")
>>> my_image.get_color_count(color_format="rgb")
'[2.0, 2.0, 249.0]': 6.2, '[5.0, 211.0, 212.0]': 7.15, '[173.0, 25.0, 98.0]': 17.49, '[146.0, 155.0, 9.0]': 18.62, '[253.0, 253.0, 253.0]': 50.54}
A dictionary, with the RGB value of the color as the key and its percentage occurrence in the image
as the value is returned.
To get a more human readable format, one would call get_color_count()
parsing the parameter
for color_format
as human_readable.
Our line to obtain colors would be replaced by:
>>> my_image.get_color_count()
{'blue': 6.2, 'darkturquoise': 7.15, 'mediumvioletred': 17.49, 'olive': 18.62, 'white': 50.54}
Note
As of the ColorDetect 0.1.7, the percentage changed from being presented as a key to being presented as a value. This attributed to the uniqueness of python dictionary keys. See the change log for more info.
For clarification:
'[2.0, 2.0, 249.0]': 6.2
# this key value pair would imply 6.2 % of the image, has an RGB of [2.0, 2.0, 249.0]
By default, ColorDetect will count the 5 most dominant colors. This can , of course ,be overridden by parsing an argument specifying how many colors most dominant you need from the image, with values decreasing in their percentage presence the higher you go on the color count.
Look up get_color_count for details on the different arguments it accepts including the different color format return values. Now suppose you want to take it a step further and write the result to the image itself.
Warning
Take note of the difference in saving the image to storage from the previous save_color_count<save_color_count> to save_image<save_image>
>>> my_image.write_color_count()
>>> my_image.save_image("<path_to_save_image>", "<name_of_image>")
Just as save_color_count, save_image will accept , as optional parameters, the path and name of the image with color count on it.
By default, these values are .
(For the current directory the script is being run from)
and out.jpg
respectively.
The result.

Depending on the size of the image, you might want to decide whether to write the count to the image or not. As observed, a smaller image gives a crowded appearance.
As a similar example, with colors represented in their hex format,

Additionally, to enable the use of custom text on an image:
>>> from colordetect import ColorDetect
>>> my_image = ColorDetect("<image_path>")
>>> my_image.write_text(text="a random string", font_color=(0,0,0))

To appropriately place the text onto the image and ensure the text does not fade over the object on the image with the same color, a font color can be parsed as an RGB tuple. This defaults to (0,0,0) , which would be black. More customization features over the text, including text margin, font thickness and line spacing (the space between lines of text) can be found on the write_text method documentation.
Whether using write_text
or write_color_count
, the image has to be saved using save_image.
Getting colors from URL:¶
>>> from colordetect import ColorDetect
>>>
>>> my_image = ColorDetect("<image_url>")
>>> my_image.get_color_count()
Example 2¶
We get colors from a random image on unsplash.
Our photo of choice, is one by Ruby Cevallos on Unsplash
>>> from colordetect import ColorDetect
>>>
>>> my_image = ColorDetect("https://images.unsplash.com/photo-1628127437106-0cc010a5fd2d?ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwzfHx8ZW58MHx8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60")
>>> my_image.get_color_count()
{'saddlebrown': 6.17, 'sienna': 12.62, 'rosybrown': 15.62, 'lightgray': 27.67, 'whitesmoke': 37.91}
We may, go ahead and write this color count to the image, and save it.
Video color recognition can be done using VideoColor
Color segmentation¶
Overview¶
Color segmentation is the process by which specific target parts of the image are extracted based on , in this case , their color.
Example¶
Using the below image, extract the vehicle color. We will display both a segmented image and a monochromatic image(which will exclude the vehicle from the monochrome color scale).

For this, we import ColorDetect as below:
>>> import cv2
>>> from colordetect import ColorDetect
>>> my_car = ColorDetect('car.jpg')
>>> monochromatic, gray, segmented, mask = my_car.get_segmented_image(lower_bound=(0, 70, 0), upper_bound=(80, 255, 255))
>>> cv2.imshow('Segmented', segmented)
>>> cv2.imshow('monochromatic', monochromatic)
>>> cv2.wait(0)
The lower and upper bounds act as a range of colors from which to look from. as a result, our segmented image would appear as below:

get_segmented_image()
accepts more parameters such as erode_iterations,dilate_iterations, use_grab_cut, which is set True
by default and gc_iterations . You may increase or decrease these values depending on the clarity needed off the image.
Our monochromatic image:

Video color recognition¶
Full video color detection¶
To show how video color recognition works, the following video of planet earth will be used.
>>> from colordetect import VideoColor
>>> my_video = VideoColor("<video_path>")
>>> my_video.get_video_frames()
{'[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.72, '[0.0, 0.0, 0.0]': 68.83, '[143.0, 170.0, 186.0]': 0.85, '[76.0, 89.0, 100.0]': 2.11, '[26.0, 32.0, 52.0]': 11.07, '[8.0, 11.0, 27.0]': 15.71, '[135.0, 163.0, 181.0]': 0.95, '[76.0, 88.0, 98.0]': 2.05, '[127.0, 160.0, 180.0]': 0.94, '[71.0, 83.0, 95.0]': 2.38, '[7.0, 11.0, 27.0]': 15.72, '[124.0, 159.0, 181.0]': 0.9, '[69.0, 83.0, 95.0]': 2.28, '[26.0, 32.0, 53.0]': 13.73, '[125.0, 160.0, 182.0]': 0.89, '[68.0, 82.0, 95.0]': 2.27, '[132.0, 166.0, 187.0]': 0.79, '[71.0, 87.0, 100.0]': 2.1, '[25.0, 32.0, 52.0]': 14.18, '[134.0, 167.0, 186.0]': 0.83, '[72.0, 87.0, 100.0]': 2.01, '[26.0, 33.0, 53.0]': 12.11, '[132.0, 165.0, 183.0]': 0.9, '[73.0, 88.0, 99.0]': 2.04, '[8.0, 10.0, 27.0]': 16.76, '[134.0, 166.0, 184.0]': 0.87, '[132.0, 165.0, 185.0]': 0.86, '[74.0, 89.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, 81.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]': 9.51, '[23.0, 29.0, 47.0]': 10.6, '[6.0, 9.0, 26.0]': 19.11, '[67.0, 83.0, 97.0]': 2.0, '[24.0, 29.0, 48.0]': 9.83, '[125.0, 161.0, 183.0]': 0.88, '[67.0, 83.0, 96.0]': 1.96, '[127.0, 162.0, 183.0]': 0.87, '[23.0, 29.0, 46.0]': 8.58, '[5.0, 8.0, 25.0]': 17.77, '[68.0, 84.0, 98.0]': 1.9, '[24.0, 29.0, 46.0]': 6.95, '[125.0, 161.0, 184.0]': 0.85, '[67.0, 84.0, 99.0]': 1.89, '[133.0, 165.0, 186.0]': 0.82, '[67.0, 85.0, 99.0]': 1.84, '[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, '[133.0, 166.0, 186.0]': 0.81, '[73.0, 91.0, 105.0]': 1.69, '[129.0, 163.0, 185.0]': 0.85, '[69.0, 86.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, 163.0, 184.0]': 0.86, '[68.0, 85.0, 98.0]': 2.01, '[21.0, 27.0, 46.0]': 10.62, '[133.0, 165.0, 185.0]': 0.85, '[69.0, 86.0, 99.0]': 1.96, '[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}
Just as image color recognition, a dictionary will be returned. get_video_frames takes optional parameters, that is, frame_color_count, an integer describing how many colors to get per frame grabbed, and color_format, working much the same way as get_color_count, which is to say either RGB, HSV or hex values.
Depending on the video, you may want to display progress of the processing. Thus, an additional, optional parameter, progress=True
may be included.
This is False by default.
Colors are grabbed on a per second basis. Hence , in a video 30 seconds long, a single frame will be used for each second of feed.
Have a look at col_share for details into how you may format the results.
Working with videos and time¶
We can get colors at specific times of the parsed video
>>> from colordetect import VideoColor
>>> my_video = VideoColor("<video_path>")
>>> (image, color_description) = my_video.get_time_frame_color(time=15000)
The result is a tuple with a ColorDetect object and a color description. We can proceed to save the color description onto the image in our preferred color
>>> image.write_color_count(font_color=(255,255,255), save=True)
Locate a file out.jpg in your current working directory.
We could, alternatively, handle the saving ourselves and go as below:
>>> image.write_color_count(font_color=(255,255,255))
>>> image.save_image(location='path/to/directory/of/choice', filename='filenameofchoice.jpg')

col_share¶
Depending on how many colors you have or how many dominant colors you want to narrow down to:
>>> from colordetect import col_share
>>> all_colors = my_video.get_video_frames()
>>> top_colors = col_share.sort_order(object_description=all_colors,key_count=5)
{'[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.11}
The sort gets the top 5 colors, by default, from all the colors obtained from all the frames present. This may be adjusted to suit your needs.
A reverse of the same may be obtained by passing the ascending parameter and setting this to false: ascending=False
.
>>> top_colors = col_share.sort_order(object_description=all_colors,key_count=5, ascending=False)
Miscellaneous¶
Helpful pages.
Developer Notes¶
Here, we dive into ColorDetect’s inner definitions and working. Found a bug or feature request you would like to address? Take a look at the Contribution guidelines and feel free to submit a pull. The project source is hosted on Github
Module ColorDetect¶
Defines ColorDetect class
For example:
>>> from colordetect import ColorDetect
>>> user_image = ColorDetect("<path_to_image>")
# where color_count is the target most dominant colors to be found. Default set to 5
>>> colors = user_image.get_color_count(color_count=5)
>>> colors
# alternatively, save these RGB values to the image
>>> user_image.write_color_count()
>>> user_image.save_image("<storage_path>","<image_file_name>")
# Image processed and saved successfully
- class colordetect.color_detect.ColorDetect(image, resize_h: Optional[int] = None)[source]¶
Bases:
object
Detect and recognize the number of colors in an image
- get_color_count(color_count: int = 5, color_format: str = 'human_readable') dict [source]¶
Count the number of different colors
- color_count: int
The number of most dominant colors to be obtained from the image
- color_format:str
The format to return the color in. Options
hsv - (60°,100%,100%)
rgb - rgb(255, 255, 0) for yellow
hex - #FFFF00 for yellow
human_readable - yellow for yellow
- Returns
color description
- get_segmented_image(lower_bound: tuple, upper_bound: tuple, erode_iterations: int = 3, dilate_iterations: int = 3, use_grab_cut: bool = True, gc_iterations: int = 3) tuple [source]¶
Get image masks from an image
- lower_bound: tuple
A lower color range from which to look from
- upper_bound: tuple
The higher RGB color range from which to look from
- erode_iterations: int
The number of times to perform erosion of the image
- dilate_iterations: int
The number of times dilation is applied.
- use_grab_cut: bool
A boolean indicating whether grabCut will be applied to the image. This is True by default.
- gc_iterations: int
Number of iterations the algorithm should make before returning the result
- Returns
output_image, gray, segmented, mask
- save_image(location: str = '.', file_name: str = 'out.jpg')[source]¶
Save the resultant image file to the local directory
- location: str
The file location of the image
- file_name:str
The name of the new image
- write_color_count(left_margin: int = 10, top_margin: int = 20, font: int = 0, font_color: tuple = (0, 0, 0), font_scale: float = 1.0, font_thickness: float = 1, line_type: int = 1, save: bool = False)[source]¶
Write the number of colors found to the image
- left_margin: int
Text spacing from the left
- top_margin: int
Text spacing from the top
- font: int
Font to use in text. Look up acceptable values from python-opencv
- font_color:
RGB tuple of text font color
- font_scale:
Size of the text to be written
- font_thickness:
Thickness of the text
line_type: int = 1,
- write_text(text: str = '', left_margin: int = 10, top_margin: int = 20, font: int = 0, font_color: tuple = (0, 0, 0), font_scale: float = 1.0, font_thickness: float = 1.0, line_type: int = 1, line_spacing: int = 0)[source]¶
Write text onto an image
Parameters
- text: str
The text to be written onto the image
- line_spacing:int
The spacing between lines
- left_margin: int
Text spacing from the left
- top_margin: int
Text spacing from the top
- font: int
Font to use in text. Look up acceptable values from python-opencv
- font_color:
RGB tuple of text font color
- font_scale:
Size of the text to be written
- font_thickness: float = 1.0
Thickness of the text
- line_type: int = 1,
Space betweeen the lines
- Returns
Module VideoColor¶
Defines VideoColor class
Usage:
>>> from colordetect import VideoColor
>>> user_video = VideoColor("<path_to_video>")
# where frame_color_count is the target most dominant colors to be found. Default set to 5
>>> colors = user_video.get_video_frames(frame_color_count=7)
>>> colors
# alternatively shorten the dictionary to get a specific number of sorted colors from the whole lot
>>> from colordetect import col_share
>>> top_colors = col_share.sort_order(object_description=colors, key_count=8)
- class colordetect.video_color_detect.VideoColor(video)[source]¶
Bases:
object
Detect and recognize the number of colors in a video
- get_time_frame_color(color_count: int = 5, color_format: str = 'rgb', time: int = 1000) tuple [source]¶
Get color from a specific time in the video
Parameters
- time: int
Time to get color from in video in milliseconds
- color_count: int
Number of colors to return at the given time frame
- color_format:str
The format to return the color in. Options
hsv - (60°,100%,100%)
rgb - rgb(255, 255, 0) for yellow
hex - #FFFF00 for yellow
- return
(image, color_description)
- get_video_frames(frame_color_count: int = 5, color_format: str = 'rgb', progress: bool = False) dict [source]¶
Get image frames and their colors from the video
- frame_color_count: int
The number of most dominant colors to be obtained from a single frame
- color_format:str
The format to return the color in. Options
hsv - (60°,100%,100%)
rgb - rgb(255, 255, 0) for yellow
hex - #FFFF00 for yellow
- return
color_description dictionary
Contributing to ColorDetect¶
Thank you for taking your time to look at the ColorDetect project.
Use the following as guidelines to making your contributions and do feel free to propose changes to this document in a pull request. The source code, located at the ColorDetect project page.
Setup¶
This project can be setup with:
python3 -m venv .venv
.venv/bin/activate
pip install -r requirements/requirements-dev.txt
pre-commit install
Issues¶
Check if the issue has been addressed or is in progress and if not , only then do you create a new issue. Remember to give it the appropriate label
Enhancements¶
Describe the enhancement in mind and what you would expect to have resulted from this process. Submit the enhancement with the enhancement tag along with its test
Pull requests¶
Reference the issue or enhancement being referenced in the pull request and submit the pull request to the development branch.
ColorDetect Changelog¶
1.6.0 (22-09-2022)¶
Features¶
Perform color recognition on a video at a specific time
Extract image from video at a specific time
1.5.1 (30-08-2021)¶
Docs¶
Update contribution readme with pre-commit configuration.
Fix¶
Linting of code
1.5.0 (11-08-2021)¶
Features¶
Perform color recognition on images based on URL passed
1.4.6 (07-09-2021)¶
Docs¶
Contribution pre-commit file linting
Bug Fixes¶
Tests passing locally and failing remotely
1.4.5 (06-28-2021)¶
Bug Fixes¶
Documentation update
1.4.3 (06-28-2021)¶
Bug Fixes¶
Video processing percentage display fix
1.4.3 (03-29-2021)¶
Bug Fixes¶
Validate RGB font color input and add tests for it
1.4.2 (03-09-2021)¶
Bug Fixes¶
Input RGB values instead of inverted BGR in writing color count and text
1.4.1 (02-09-2021)¶
Documentation¶
Fix error in image display of masked image
Format documentation to fix side panel and have structure in sections
1.4.0 (02-09-2021)¶
Features¶
Image color segmentation, masking and monochromatic colors on specific image sections
1.3.0 (02-02-2021)¶
Features¶
Add a return of human readable colors.
Documentation¶
Update ColorDetect module documentation to show method params
1.3.0rc (18-01-2021)¶
Features¶
Add a return of human readable colors.
Documentation¶
Update ColorDetect module documentation to show method params
Move to version
1.3.0rc
due to error in1.1.1
packaging
1.1.1 (17-01-2021)¶
Documentation¶
Update setup to show correct package version.
1.1.0 (17-01-2021)¶
Features¶
Enable customization of text input from the user as well as color count being written to the image
Documentation¶
Add contributors to readme and update project documentation with relevant parameter methods
1.0.1 (23-11-2020)¶
Features¶
Add pre-commit hooks for better contribution styling
Documentation¶
Update readme with development guide.
1.0.0 (03-10-2020)¶
Features¶
Creation of col_share module. Split methods non-exclusive to VideoColor and ColorDetect
Documentation¶
Include col_share documentation.
Update readme to reflect col_share.
0.3.1 (17-10-2020)¶
Bug fix¶
Perform check to ensure the color description has content before writing color count.
0.3.0 (26-09-2020)¶
Features¶
Video color detection and recognition
Documentation¶
Include video color detection documentation
Correction in package imports
0.2.0 (13-08-2020)¶
Features¶
Enable input of custom text onto the image
Documentation¶
Add
write_text
method along with other breaking changes to the documentation
0.1.7 (17-04-2020)¶
Features¶
Invert return of recognized colors dictionary. Return the colors as keys and percentages as values to avoid duplicate dictionary keys.
0.1.6 (17-04-2020)¶
Features¶
Add color format return options. Include RGB, hex and hsv
Misc¶
Add tests suite and move test files out of project root.
Add contributions file
Update dev requirements
Improve methods types specification and exception catching.
0.1.5 (11-04-2020)¶
Features¶
Return a whole number for the RGB value instead of float.
Documentation¶
Add changelog to the documentation.
0.1.4 (5-04-2020)¶
Features¶
Allow recognition of non pre-defined color sets
Allow a plain dictionary to be obtained with color recognition from the image before writing onto it.
Format display of percentage and RGB values
Bugfixes¶
Update CI config file with correct requirements path.
Correct test running instructions on README.
Improved Documentation¶
Publish package documentation ColorDetect
Misc¶
Add versioning to readme and edit dev requirements.
0.1.3 (22-03-2020)¶
Features¶
Change image reading from command-line to ColorDetect object initialization.
Bug fixes¶
Fix image reading.
Misc¶
Split dev and base requirements.
0.1.2 (22-03-2020)¶
Features¶
Include project license
0.1.1 (22-03-2020)¶
Initial release