Last active
March 2, 2019 12:57
-
-
Save leobm/91cec2a57d3e02c178ef902cfcb362e3 to your computer and use it in GitHub Desktop.
software that can name colors
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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