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))
CodePudding user response:
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