Home > Software design >  Python color detection from a point with opencv
Python color detection from a point with opencv

Time:09-19

I'm trying to do a sorting machine for color detection with a camera and a raspberry pi. I have succeeded to some extent but not really. I am currently reading the color from the center pixel in BGR format and examining it that way. My question would be how can i read this out of a zone not just a point and make the detection more accurate.

Here's my code:

import cv2
import time
import pandas as pd

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()
    height, width, _ = frame.shape
    
    cx = int(width / 2)
    cy = int(height / 2)
    
    pixel_center = frame[cy, cx]
    
    
    b = int(pixel_center[0])
    g = int(pixel_center[1])
    r = int(pixel_center[2])
    txt = get_color_name(r, g, b)
    
    print(txt)
    print(r, g, b)
    cv2.circle(frame, (cx, cy), 5, (255, 0, 0), 3)
    
    
    cv2.imshow("Frame", frame)
    
    
    key = cv2.waitKey(1)
    if key == 27:
        break
    
    
cap.release()
cv2.destroyAllWindows()

Can anyone help?

CodePudding user response:

Why not try something like this:

The image you captured is now a 2D array, slice it from the center, and read a bunch of points representing a small rectangle in the center. Then, you can average them or get the median, it is up to you.

# capture a video frame here 
height, width, _ = frame.shape
zone_width = 15
zone_height = 15
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 = frame[y1:y2, x1:x2]
r, g, b = get_avg_color()
  • Related