Skip to content

Instantly share code, notes, and snippets.

@leobm
Last active March 2, 2019 12:57
Show Gist options
  • Save leobm/91cec2a57d3e02c178ef902cfcb362e3 to your computer and use it in GitHub Desktop.
Save leobm/91cec2a57d3e02c178ef902cfcb362e3 to your computer and use it in GitHub Desktop.
software that can name colors
# Use the tool
# python detect_color.py --image source.png
#
# Install the opencv and numpy packages before
# python -m pip install numpy
# python -m pip install opencv-python
# python -m pip install scikit-learn
# import the necessary packages
import numpy as np
import cv2
from sklearn.cluster import KMeans
threshold_RGB = 120
threshold_area = 2000
def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
# initialize the dimensions of the image to be resized and
# grab the image size
dim = None
(h, w) = image.shape[:2]
# if both the width and height are None, then return the
# original image
if width is None and height is None:
return image
# check to see if the width is None
if width is None:
# calculate the ratio of the height and construct the
# dimensions
r = height / float(h)
dim = (int(w * r), height)
# otherwise, the height is None
else:
# calculate the ratio of the width and construct the
# dimensions
r = width / float(w)
dim = (width, int(h * r))
# resize the image
resized = cv2.resize(image, dim, interpolation = inter)
# return the resized image
return resized
def name_color(masked_image, output, rgb):
r, g , b, color_name = rgb
font = cv2.FONT_HERSHEY_SIMPLEX
font_scale = 0.55
font_margin = 5
font_thickness = 1
font_color = (255, 255, 255)
gray = cv2.cvtColor(masked_image, cv2.COLOR_RGB2GRAY)
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)
#cv2.imshow("thresh",thresh)
# find contours and get the external one
contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
if contours is not None:
# contours = np.array(contours, dtype=np.float32)
for cnt in contours[0]:
area = cv2.contourArea(cnt)
if area > threshold_area:
# compute the center of the contour
M = cv2.moments(cnt)
if M["m00"] != 0:
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])
cv2.circle(output, (cx, cy), 3, (255, 255, 255), -1)
text_size = cv2.getTextSize(color_name, font, font_scale, font_thickness)
text_width = text_size[0][0]
text_height = text_size[0][1]
cv2.putText(output, color_name, (cx - int(text_width/2), cy), font, 0.5, (0,0,0), 4)
cv2.putText(output, color_name, (cx - int(text_width/2), cy), font, 0.5, font_color, 2)
x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(output, (x,y),(x + w, y + h), (b, g, r), 2)
return output
def main(args):
# load the image
original = cv2.imread(args["image"])
original_resized =image_resize(original, height = 400)
n_colors = 6
arr = original_resized.reshape((-1, 3))
kmeans = KMeans(n_clusters=n_colors, random_state=42).fit(arr)
labels = kmeans.labels_
centers = kmeans.cluster_centers_
less_colors = centers[labels].reshape(original_resized.shape).astype('uint8')
rgbs = [
(255, 255, 0, 'yellow'),
(255, 0, 0, 'red'),
(0, 255, 0, 'green'),
(0, 0, 255, 'blue'),
]
output = original_resized.copy()
# loop over the boundaries
for rgb in rgbs:
r, g , b, color_name = rgb
# create NumPy arrays from the boundaries
lowerBGR = np.array([b - threshold_RGB, g - threshold_RGB, r - threshold_RGB])
upperBGR = np.array([b + threshold_RGB, g + threshold_RGB, r + threshold_RGB])
# find the colors within the specified boundaries and apply
# the mask
mask = cv2.inRange(less_colors, lowerBGR, upperBGR)
masked_image = cv2.bitwise_and(less_colors, less_colors, mask = mask)
#cv2.imshow("masked_image:"+color_name, masked_image)
#cv2.waitKey(0)
output = name_color(masked_image, output, rgb)
cv2.imshow("images", np.hstack([original_resized, output]))
cv2.waitKey(0)
if __name__ == '__main__':
import argparse
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", help = "path to the image")
args = vars(ap.parse_args())
main(args)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment