система распознавания цвета с python opencv - PullRequest
0 голосов
/ 19 сентября 2019

я пытаюсь сделать систему обнаружения цвета с помощью Python OpenCV, это то, что я сделал до сих пор.Я все еще новичок в Python, поэтому, пожалуйста, помогите мне, спасибо

В основном, что должно произойти, это то, что, когда пользователь открывает это приложение, камера открывается, и когда он щелкает в любом месте окна, он скажет название цвета

from tkinter import *
from tkinter import ttk
import cv2
import numpy as np
import webcolors

def click_event(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        blue = cap[y, x, 0]
        green = cap[y, x, 1]
        red = cap[y, x, 2]
        font = cv2.FONT_HERSHEY_SIMPLEX

        #colourcode = str(blue) + ", " + str(green) + ", " + str(red)
        colourcode2 = (red, green, blue)

        cv2.imshow('frame', frame)

        def closest_colour(requested_colour):
            min_colours = {}
            for key, name in webcolors.css3_hex_to_names.items():
                r_c, g_c, b_c = webcolors.hex_to_rgb(key)
                rd = (r_c - requested_colour[0]) ** 2
                gd = (g_c - requested_colour[1]) ** 2
                bd = (b_c - requested_colour[2]) ** 2
                min_colours[(rd + gd + bd)] = name
            return min_colours[min(min_colours.keys())]

        def get_colour_name(requested_colour):
            try:
                closest_name = actual_name = webcolors.rgb_to_name(requested_colour)
            except ValueError:
                closest_name = closest_colour(requested_colour)
                actual_name = None
            return actual_name, closest_name


        #print(colourcode2)
        requested_colour = colourcode2
        actual_name, closest_name = get_colour_name(requested_colour)

        #print("colour name:", closest_name)
        cv2.putText(img, closest_name, (0, 50), font, 1, 255, 2)

cap = cv2.VideoCapture(0);
while True:
    ret, frame = cap.read()

    cv2.imshow('frame', frame)

    if cv2.waitKey(40) == 27:
        break



cv2.waitKey(0)
cv2.destroyAllWindows()

1 Ответ

0 голосов
/ 19 сентября 2019

Я не знаю, в чем ваша проблема, но используя ваш код, я создаю версию, которая работает для меня

Я использую cv2.setMouseCallback, чтобы назначить вашу функцию щелчком мыши.Он получает пиксель от frame, а не cap.Пиксель - это список / кортеж (B, G, R), поэтому я чту его list[::-1].После того, как я получил название цвета, я назначаю его внешней / глобальной переменной, а не помещаю во фрейм.В основном цикле я использую это имя, чтобы поставить на кадр, прежде чем он отобразит его.

Я также использую EVENT_LBUTTONUP для удаления текста, когда я отпускаю кнопку мыши.

 elif event == cv2.EVENT_LBUTTONUP:
      closest_name = ''

Если вы удалитеЕсли вы отпустите кнопку выше, он будет содержать текст.

import cv2
import webcolors

# --- functions ---

def closest_colour(requested_colour):
    min_colours = {}
    for key, name in webcolors.css3_hex_to_names.items():
        r_c, g_c, b_c = webcolors.hex_to_rgb(key)
        rd = (r_c - requested_colour[0]) ** 2
        gd = (g_c - requested_colour[1]) ** 2
        bd = (b_c - requested_colour[2]) ** 2
        min_colours[(rd + gd + bd)] = name
    return min_colours[min(min_colours.keys())]

def get_colour_name(requested_colour):
    try:
        closest_name = actual_name = webcolors.rgb_to_name(requested_colour)
    except ValueError:
        closest_name = closest_colour(requested_colour)
        actual_name = None
    return actual_name, closest_name

def click_event(event, x, y, flags, param):
    global closest_name # inform function to assign to global/external variable instead of creating local one

    if event == cv2.EVENT_LBUTTONDOWN:
        #B, G, R = frame[x, y]
        #colour = (R, G, B)  # reverse values
        colour = frame[y,x][::-1] # reverse values
        actual_name, closest_name = get_colour_name(colour)
        print(actual_name, closest_name)

    elif event == cv2.EVENT_LBUTTONUP:
        closest_name = ''

# --- main ---

font = cv2.FONT_HERSHEY_SIMPLEX

closest_name = '' # create global variable at start

cap = cv2.VideoCapture(0);

cv2.namedWindow('frame')
cv2.setMouseCallback('frame', click_event)

while True:
    ret, frame = cap.read()

    if closest_name:
        #print(closest_name)
        cv2.putText(frame, closest_name, (10, 30), font, 1, (255,255,255), 2)

    cv2.imshow('frame', frame)

    if cv2.waitKey(40) == 27:
        break

cv2.waitKey(0)
cv2.destroyAllWindows()

cap.release()

Во всех графических интерфейсах пользователя при нажатии кнопки создается единственное событие EVENT_LBUTTONDOWN - оно не генерирует его снова и сновакогда вы держите кнопку нажатой.Таким образом, функция click_event выполняется только один раз, и ваша версия помещает текст только в один кадр, но спустя несколько миллисекунд основной цикл получает новый кадр и отображает его без текста - так что, наконец, вы не видите текст в кадре.

...