I am trying to make a real-time color sensor. Right now I use several pixels in HSV format, take the average of that and check it on an online color picker. The problem is that the colors are not realistic as I see them on the camera.
import cv2
import time
import pandas as pd
import numpy as np
index = ["color", "color_name", "hex", "R", "G", "B"]
csv = pd.read_csv('colors.csv', names=index, header=None)
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 800)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 600)
def get_color_name(R, G, B):
minimum = 10000
for i in range(len(csv)):
d = abs(R - int(csv.loc[i, "R"])) + abs(G - int(csv.loc[i, "G"])) + abs(B - int(csv.loc[i, "B"]))
if d <= minimum:
minimum = d
cname = csv.loc[i, "color_name"]
return cname
while True:
_, frame = cap.read()
hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
height, width, _ = frame.shape
# x a visszintes
zone_width = 30
zone_height = 10
frame_center = (frame.shape[0] / 2, frame.shape[1] / 2)
y1 = int(frame_center[0] - zone_height)
y2 = int(frame_center[0] + zone_height)
x1= int(frame_center[1] - zone_width)
x2 = int(frame_center[1] + zone_width)
selection = hsv_frame[y1:y2, x1:x2]
cv2.line(frame, (int(frame_center[1]), int(y1)), (int(frame_center[1]), int(y2)), (0,0,255),1)
cv2.line(frame, (int(x1), int(frame_center[0])), (int(x2), int(frame_center[0])), (0,255,0),1)
average_color_row = np.average(selection, axis=0)
average_color = np.average(average_color_row, axis=0)
print(round(average_color[0])," |0-179| ", round(average_color[1])," |0-255| ", round(average_color[2]), " |0-255|")
#cv2.circle(frame, (int(width / 2),int(height / 2)), 5, (255, 0, 0), 3)
cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 0, 0), 2)
cv2.imshow("Frame", frame)
key = cv2.waitKey(1)
if key == 27:
break
time.sleep(0.1)
cap.release()
cv2.destroyAllWindows()
Can anybody help me?