How to get the name of color by RGB values from dataframe?

Question:

I’m creating a program that reads an image and prints its name. I have csv file with about 900 colors with RGB values. How can I compare RGB values of the image in my program and compare them to dataframe to get the name of a color?

from webbrowser import Mozilla
from wsgiref import headers
from matplotlib import image
import numpy as np #needed to work with matrix of an image
import pandas as pd #needed to work with color.csv
import cv2 #needed to work with image
import matplotlib.pyplot as pl #needed to work with plotting
import urllib.request#needed to work with image url

#step 1. Read csv file with name, RGB and HEX values.
#step 2. Set color detection function. Get value of pixels in a NumPy array
#step 3. Compare RGB value of a pixel with dataframe.
#step 4. Save the name and RBG value inside a file. 

#global values
#image from url
def url_to_image(url): #doesn't get file, need to work upon this 
    resp = urllib.request.urlopen(url)
    image = np.asarray(bytearray(resp.read()), dtype='uint8')
    image = cv2.imdecode(image,cv2.COLOR_BGR2RGB)
    return image

#dataframe with 864 colors 
index = ['color', 'color_name', 'hex','R','G','B'] 
csv = pd.read_csv('colors.csv', names = index, header = None)



def getColor(R,G,B): 
    minimum = 10000
    for i in range(len(csv)):
        distance = abs(R-int(csv.loc[i, 'R'])) + abs(G-int(csv.loc[i, 'G'])) + abs(B-int(csv.loc[i,'B']))
        if(distance<=minimum):
            minimum = distance
            color_name = csv.loc[i, 'color_name']
        return color_name

#passes image from open source, don't pass images from sources, which considered my attempt as DDOS atack
img = url_to_image("https://htmlcolorcodes.com/assets/images/colors/purple-color-solid-background-1920x1080.png") 
B,G,R = img[100,100] #BGR value of a pixel in x row and y column
print(getColor(R,G,B))

Asked By: Nighttwinkle

||

Answers:

You can use this function to get the color with the smallest distance to your input R, G, B values. You can also specify a maximum value – if the closest value in the color dataframe is too far, no color name is returned:

def get_color(red, green, blue, max_distance=10_000):
    # Make a copy of the dataframe to avoid changing the original
    df = csv.copy()   
    df["distance"] = (
        (df["R"] - red).abs() + 
        (df["G"] - green).abs() + 
        (df["B"] - blue).abs()
    )
    # Select row with smallest distance
    top_row = df.sort_values("distance").iloc[0]
    
    if top_row.distance <= max_distance:
        return top_row.color_name
    
    return None
Answered By: ozacha
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.