Color detection and tell which color is appearing

Asked

Viewed 1,110 times

0

How could it be done so that when the predominant color in the video appears a message telling which is the predominant color?

Example: appears an object in the capture of red video there would appear a message saying that the predominant color is red, this code detects the colors green, red and yellow.

import cv2
import numpy as np


captura = cv2.VideoCapture(0)

while (1):

    _, imagen = captura.read()
    hsv = cv2.cvtColor(imagen, cv2.COLOR_BGR2HSV)

    lower_green = np.array([49, 50, 50])
    upper_green = np.array([107, 255, 255])


    lower_red1 = np.array([0, 65, 75], dtype=np.uint8)
    upper_red1 = np.array([12, 255, 255], dtype=np.uint8)
    lower_red2 = np.array([240, 65, 75], dtype=np.uint8)
    upper_red2 = np.array([256, 255, 255], dtype=np.uint8)

    lower_yellow = np.array([16, 76, 72], dtype=np.uint8)
    upper_yellow = np.array([30, 255, 210], dtype=np.uint8)

    mask_green = cv2.inRange(hsv, lower_green, upper_green)

    mask_red1 = cv2.inRange(hsv, lower_red1, upper_red1)
    mask_red2 = cv2.inRange(hsv, lower_red2, upper_red2)

    mask_yellow = cv2.inRange(hsv, lower_yellow, upper_yellow)

    kernel = np.ones((6, 6), np.uint8)

    mask_green = cv2.morphologyEx(mask_green, cv2.MORPH_CLOSE, kernel)
    mask_green = cv2.morphologyEx(mask_green, cv2.MORPH_OPEN, kernel)

    mask_yellow = cv2.morphologyEx(mask_yellow, cv2.MORPH_CLOSE, kernel)
    mask_yellow = cv2.morphologyEx(mask_yellow, cv2.MORPH_OPEN, kernel)

    mask_red1 = cv2.morphologyEx(mask_red1, cv2.MORPH_OPEN, kernel)
    mask_red1 = cv2.morphologyEx(mask_red1, cv2.MORPH_OPEN, kernel)

    mask_red2 = cv2.morphologyEx(mask_red2, cv2.MORPH_OPEN, kernel)
    mask_red2 = cv2.morphologyEx(mask_red2, cv2.MORPH_OPEN, kernel)


    mask1 = cv2.add(mask_red1, mask_red2)
    mask2 = cv2.add(mask_green,mask_yellow)


    cv2.imshow('red', mask1)
    cv2.imshow('green', mask2)
    cv2.imshow('Camara', imagen)

    tecla = cv2.waitKey(5) & 0xFF
    if tecla == 27:
        break

cv2.destroyAllWindows()

1 answer

1


Solution

  • Create two subplots in matplotlib, one is webcam the other a rectangle with the dominant color
  • Use the FuncAnimation to animate the graph in matplot, updating it every 200 ms
  • Use the Opencv K-Means Clustering to get the dominant color RGB parameters or use the unique_count_app()
  • Create a rectangle with the dominant color RGB

Code

import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation


#https://stackoverflow.com/a/44604435/7690982
def grab_frame(cap):
    ret,frame = cap.read()
    return cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)

def atualizar(i):
    img = grab_frame(captura)
    im1.set_data(img)
    im2.set_data(retangulo(img))

def close(event):
    if event.key == 'q':
        plt.close(event.canvas.figure)

#https://stackoverflow.com/q/50899692/7690982
def unique_count_app(a):
    colors, count = np.unique(a.reshape(-1,a.shape[-1]), axis=0, return_counts=True)
    return colors[count.argmax()]

def retangulo(img):
    r, g, b = contar_kmeans(img)
    h, w, c = img.shape
    rect = np.zeros((h, w, 3), np.uint8)
    rect[0:h, 0:w] = (r,g,b)
    return rect

#https://stackoverflow.com/a/50900494/7690982
def contar_kmeans(img):
    data = np.reshape(img, (-1,3))
    data = np.float32(data)
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
    flags = cv2.KMEANS_RANDOM_CENTERS
    compactness, labels, centers = cv2.kmeans(data, 1, None, criteria, 10, flags)
    return centers[0]

#Inicialização
captura = cv2.VideoCapture(0)
imagem = grab_frame(captura)

#Cria os dois subplots
ax1 = plt.subplot(1,2,1)
ax2 = plt.subplot(1,2,2)

#Cria duas imagens nos subplots
im1 = ax1.imshow(imagem)
im2 = ax2.imshow(retangulo(imagem))

#Animação e atualização
ani = FuncAnimation(plt.gcf(), atualizar, interval=200)

#Fechar
cid = plt.gcf().canvas.mpl_connect("key_press_event", close)
#Mostrar o gráfico
plt.show()

Results

Verde

Vermelho

Azul

  • As I could do in case the predominant color is red, from a print saying that the color and red, if possible just give me a way to do the research, thank you very much

  • Search for color spaces (colorspaces), where you have 3 RGB channels, and can convert to other types of spaces. [255,0,0] is red, [0,255,0] green and [0,0,255] blue. So which channel has the highest value is the dominant channel. Or you could create other types of colors and various ranges for each one. For example that color palette

  • I’m unable to do the programming, could help me?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.