Find the color NAME of "most" pixels in a region

I would appreciate help on this question:

I would like to load an image into OpenMV, create a rectangular region, then get the CLOSEST color NAME of the pixels in that region. I would like to use color names from the following page:

https://condor.depaul.edu/sjost/it236/documents/colorNames.htm

For example, the name of the closest color in the region shown in the image is “Royal Blue”. Of course the region may have small parts of other colors (black,red, brown, etc.), but I need the color name representing most pixels in the picture.

How can this be done?

Thanks in advance.

Closest color:

import math

list_of_color_names = ["AliceBlue"]
list_of_color_rgb_tuples = [(240, 248, 255)]

def closest_color(r, g, b):
    closest_color_diff = 1000000
    closest_color_name = "Uknown"
    for i in range(len(list_of_color_rgb_tuples)):
        red_diff = r - list_of_color_rgb_tuples[i][0]
        green_diff = g - list_of_color_rgb_tuples[i][1]
        blue_diff = b - list_of_color_rgb_tuples[i][2]
        diff = math.sqrt((red_diff*red_diff)+(green_diff*green_diff)+(blue_diff*blue_diff))
        if diff < closest_color_diff:
            closest_color_diff =  diff
            closest_color_name = list_of_color_names[i]
    return closest_color_name

Then just use the color conversion methods to take the results of get_statistics which are in the LAB color space and convert those to RGB and then feed the RGB value into the function above.

Thank you very much for your prompt help.

I am looking at the Color tracking example as I am still learning Python. I can see the statement:

 print(img.get_statistics())

Can you please show me how to

"

…use the color conversion methods to take the results of get_statistics which are in the LAB color space and convert those to RGB and then feed the RGB value into the function

"?

image.lab_to_rgb(img.get_statistics())

Thanks in advance.

See the return type of get_stats():

https://docs.openmv.io/library/omv.image.html?highlight=get_stats#id9

So:

stats = img.get_statistics()
r, g, b = image.lab_to_rgb((stats.l_mean(), stats.a_mean(), stats.b_mean()))

Thanks a million.

Please accommodate one last question. I made the change in the code below but there is a compile error. May I ask you for one last request to check it out? I am sure it is a simple Python language error.

Thanks in advance.

# Image Statistics Info Example
#
# This script computes the statistics of the image and prints it out.

import sensor, image, time
import math

sensor.reset()
sensor.set_pixformat(sensor.RGB565) # or RGB565.
sensor.set_framesize(sensor.VGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking
clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot()
    print(img.get_statistics())
#-----------------------------------------------------------------------------------
    stats = img.get_statistics()
    r, g, b = image.lab_to_rgb((stats.l_mean(), stats.a_mean(), stats.b_mean()))
    colorName = closest_color(r, g, b)
    print(colorName)
#-----------------------------------------------------------------------------------
    print(clock.fps())

def closest_color(r, g, b):
    closest_color_diff = 1000000
    closest_color_name = "Uknown"
    for i in range(len(list_of_color_rgb_tuples)):
        red_diff = r - list_of_color_rgb_tuples[i][0]
        green_diff = g - list_of_color_rgb_tuples[i][1]
        blue_diff = b - list_of_color_rgb_tuples[i][2]
        diff = math.sqrt((red_diff*red_diff)+(green_diff*green_diff)+(blue_diff*blue_diff))
        if diff < closest_color_diff:
            closest_color_diff =  diff
            closest_color_name = list_of_color_names[i]
    return closest_color_name

Hi, the resolution is too high. Make it QVGA. When you do VGA RGB565 on the H7 it silent changes it to BAYER to keep working for imaging only.

I have plans to add bayer image support for some methods like get_stats() however. It’s lower on my todo list. So, it won’t be here anytime soon.

I am using the OpenMV Cam H7 Plus.

It is a Python compile error (most likely a language syntax). Please see attached.

Thanks in advance.

Define the function above the place where you call it.

Thank you.

I got another compile error (please see attached).

Do you mind looking at the very short code attached? It is probably a very simple syntax mistake …

Thanks in advance.
ColorName_1.py (1.66 KB)

Hi Jimme, you need to debug these types of errors yourself. I’ve available for high level help support. You are asking about basic python coding issues.

Anyway, the variable:

list_of_color_rgb_tuples is a list of the words you need to define:

list_of_color_names = [“AliceBlue”]
list_of_color_rgb_tuples = [(240, 248, 255)]

Thank you, and fair enough. I appreciate your time in helping me.

While I get better in Python, I am trying to understand how this code will work:

The code currently gets the r, g, b tuple. OK, so far so good.

But how does it find the color name? Do I have to create an array of all the color names?

list_of_color_names = [“AliceBlue”]
list_of_color_rgb_tuples = [(240, 248, 255)]

list_of_color_names = [“Illuminating emerald”]
list_of_color_rgb_tuples = [(49, 145, 119)]

etc.

But then what happens if the rgb values obtained from the function are not identical to those? For example (235, 245, 255)? How will the closest color be found?

Hi Jimme,

So, it seems like you are attempting something quite a bit out of your skill level. So, I’ll do this. Here’s the code:

import sensor, image, time, math, gc

sensor.reset()
sensor.set_pixformat(sensor.RGB565) # or RGB565.
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking
clock = time.clock()

list_of_color_names = []
list_of_color_rgb_tuples = []

with open("rgb.txt") as f:
    for l in f:
        tokens = l.strip().split()
        print("Loading", tokens)
        list_of_color_names.append(tokens[3])
        list_of_color_rgb_tuples.append(tuple(int(x) for x in tokens[0:3]))
        gc.collect() # prevent heap fragmentation

def closest_color(r, g, b):
    closest_color_diff = 1000000
    closest_color_name = "Uknown"
    for i in range(len(list_of_color_rgb_tuples)):
        red_diff = r - list_of_color_rgb_tuples[i][0]
        green_diff = g - list_of_color_rgb_tuples[i][1]
        blue_diff = b - list_of_color_rgb_tuples[i][2]
        diff = math.sqrt((red_diff*red_diff)+(green_diff*green_diff)+(blue_diff*blue_diff))
        if diff < closest_color_diff:
            closest_color_diff =  diff
            closest_color_name = list_of_color_names[i]
    return closest_color_name

while(True):
    clock.tick()
    img = sensor.snapshot()
    stats = img.get_statistics()
    r, g, b = image.lab_to_rgb((stats.l_mean(), stats.a_mean(), stats.b_mean()))
    colorName = closest_color(r, g, b)
    print(clock.fps(), colorName)

And finally, you need to copy the attached rgb.txt file to the OpenMV Cam disk to get the color names.

This meets your initial question. However, moving forwards… please try to understand exactly what is happening in every line in that script and understand what’s going on.
rgb.txt (31 KB)

If you need to target an area of the image:

Then add the following arguments to get_stats():

roi=[x, y, w, h]

Where x, y, w, h are numbers you can get from the IDE by clicking and dragging on an area in it.

T H A N K Y O U!

Exactly what I needed and will help me learn the system.

I appreciate your excellent service (beyond the call).

Thank you again, the code you sent works like a charm.

Where did the color names in the rgb.txt come from? I noticed that most of them are rather strange names :slight_smile:. For example, 39, 63, 65 gives from rgb.txt a “daintree” color.

However, from this page,

https://www.color-blindness.com/color-name-hue/

it gives a “Gable Green” which is more understandable.

Is there a place where these names are “mapped”?

Thanks again.

I got it from here:

Augmenting rgb.txthttps://people.csail.mit.edu/jaffer/Color/Resene-2010-rgb.txt

Edit the file to add your own color names if you want something else.

Yes, if you want a lot of color names you’ll have do a lot of data entry work. Or search for a better color name file.