Я не знаю, в чем ваша проблема, но используя ваш код, я создаю версию, которая работает для меня
Я использую 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
выполняется только один раз, и ваша версия помещает текст только в один кадр, но спустя несколько миллисекунд основной цикл получает новый кадр и отображает его без текста - так что, наконец, вы не видите текст в кадре.