[Fun Project] Label Random Colors Based on Hue
28 February 2023
I drew a square and filled it with random colors. With help from the hue, I labeled the color of that square.
Have you ever wondered how computers can recognize and interpret colors? It can use complex algorithms and training to identify color (like this example) or use hue.
Hue is part of the HSV (Hue, Saturation, and Value) model that defines the color portion [link]. It is often expressed as a degree between 0 to 360 or as a number between 0 to 1.0 on the HSV color wheel. We can determine whether something is blue, green, yellow, or any other color by looking at its position on the wheel. For example, if a particular hue falls between 0 and 8 degrees, we can guess it is a red shade.
For this project, I categorized the hue based on this reference. They use 16 color labels, e.g., red, red-orange, yellow-green, and blue. For the hue range, I refer to the hue value on their table.
For example, the highest hue for green color is 138, so I start the following color (green-cyan) from 139. Please refer to the color wheel below for a better illustration.
However, while using hue is practical, we must admit that the categorization is limited. By leaving the “value” out, we lose the brightness data from the color system; we do not have the white and black category since both colors can be composed of various hues.
Compared to eye observation, the hue interpretation is sometimes inaccurate. Utilizing a single parameter and lacking learning for the hue range may cause this imperfection.
Program Blocks
This project was done in Python using the turtle to draw graphics into the screen and the colorsys library to convert RGB to HSV color system, and broken down into five steps.
- Set up the screen for displaying a square and its label.
- Create a square and fill it with a random color.
- Convert the color to the HSV color system and label it based on the hue category on the hue color wheel.
- Create text that shows a color label.
- Until we terminate it, loop the program to keep changing the square’s color and showing the label.
Three files were created:
- main.py as the main file
- square.py to hold the Square class that defines a square and has a function to change color, and
- color_guessr.py to hold ColorGuessr class that categorizes the color and prints the label
Set Up the Screen
First, I created a new screen, 600px-by-600px in size.
main.py
from turtle import Screen
screen = Screen()
screen.setup(600, 600) # width = 600px, height = 600px
screen.tracer(0) # automatic screen updates are off
Create a Square
I created a square using the turtle library. I prepared the square in a class named Square that inherited the properties of the turtle library. I stretched the size of the square to make it bigger using the “shapesize” function.
My turtle had a color mode of 1.0. Hence, to initialize the square color to white (the color with the highest value), I set the red, green, and blue spectrum in the RGB color system to 1.
Next, to change the color, I utilized the random library. Whenever we call it, the change_color() function generates a random value for each red, green, and blue spectrum.
square.py
import random
from turtle import Turtle
class Square(Turtle):
def __init__(self):
super().__init__()
self.shape("square")
self.shapesize(stretch_wid=10, stretch_len=10)
self.goto(0, 40)
self.color_r = 1
self.color_g = 1
self.color_b = 1
self.color(self.color_r, self.color_g, self.color_b)
def change_color(self):
self.color_r = random.random()
self.color_g = random.random()
self.color_b = random.random()
self.color(self.color_r, self.color_g, self.color_b)
main.py
from square import Square
...
# Create a square
square = Square()
...
# Change square's color
square.change_color()
Define Color Label
This block was pretty straightforward. Using the colorsys library, I converted the RGB to the HSV color system. Then, I took the first item in the HSV color system to get the hue. Since the color was in 1.0 color mode, to get a maximum hue degree of a full rotation, I multiplied the hue by 360. Last, the hue was segmented based on the range illustrated in the color wheel.
color_guessr.py
import colorsys
...
def guess_color(self, r, g, b):
self.color_r = r
self.color_g = g
self.color_b = b
# Convert RGB to HSV
color_hsv = colorsys.rgb_to_hsv(self.color_r, self.color_g, self.color_b)
# Get the hue from HSV
hue = color_hsv[0] * 360
# Categorize the hue, label the color
if hue < 8:
self.guess = "red"
elif hue < 21:
self.guess = "red-orange"
elif hue < 40:
self.guess = "orange & brown"
elif hue < 52:
self.guess = "orange-yellow"
elif hue < 61:
self.guess = "yellow"
elif hue < 81:
self.guess = "yellow-green"
elif hue < 139:
self.guess = "green"
elif hue < 169:
self.guess = "green-cyan"
elif hue < 200:
self.guess = "cyan"
elif hue < 220:
self.guess = "cyan-blue"
elif hue < 246:
self.guess = "blue"
elif hue < 276:
self.guess = "blue-magenta"
elif hue < 316:
self.guess = "magenta"
elif hue < 341:
self.guess = "magenta-pink"
elif hue < 351:
self.guess = "pink"
elif hue < 356:
self.guess = "pink-red"
else:
self.guess = "red"
Show Color Label
Like the Square class, ColorGuessr class inherits the properties from the turtle library. In the initialization, I hid the icon for the turtle but wrote the color label at the turtle position. Then, I set the turtle’s position below the square with help from the goto() function.
I created two functions inside the ColorGuessr class: guess_color() to define the color label (see the previous block) and print_guess(). The print_guess() function prints the label with a font color matching the square color.
The clear() function is inherited from the turtle library and is crucial to erase the label from the previous color before printing a new one.
color_guessr.py
from turtle import Turtle
import colorsys
class ColorGuessr(Turtle):
def __init__(self):
super().__init__()
self.guess = "undefined"
self.penup()
self.hideturtle()
self.color_r = 1
self.color_g = 1
self.color_b = 1
self.goto(self.xcor(), self.ycor() - 120)
# Define color label
def guess_color(self, r, g, b):
...
self.print_guess()
def print_guess(self):
self.clear()
self.color(self.color_r, self.color_g, self.color_b)
self.write((self.guess).capitalize(), font=("Arial", 40, "bold"), align="center")
Loop the Program
Finally, after creating the objects for both Square and ColorGuessr class, I concluded the main file by looping our objective: changing the square’s color with a random color and labeling that color.
Inside the loop, we also have time.sleep() function that controls how long we will wait before executing another loop.
main.py
from turtle import Screen
from square import Square
from color_guessr import ColorGuessr
import time
SLEEP_TIME = 1 # 1 second
# Set up screen
screen = Screen()
screen.setup(600, 600)
screen.title("?? What COLOR ??")
screen.tracer(0)
# Create a square
square = Square()
# Create a color guesser
guess = ColorGuessr()
while True:
time.sleep(SLEEP_TIME)
screen.update()
# Change square's color
square.change_color()
# Print the square color
guess.guess_color(square.color_r, square.color_g, square.color_b)
screen.exitonclick()
Complete Code and References
Complete code: GIT
References:
- https://medium.com/analytics-vidhya/building-rgb-color-classifier-part-1-af58e3bcfef7
- https://www.lifewire.com/what-is-hsv-in-design-1078068
- http://www.workwithcolor.com/pink-red-color-hue-range-01.htm
- https://docs.python.org/3/library/turtle.html
- https://docs.python.org/3/library/colorsys.html#module-colorsys
P.S. Want a more tangible way to play with color? Try a Reverse Coloring Book*; create lines for watercolor objects.
*As an Amazon Associate, I earn from qualifying purchases.