import cv2
import numpy as np
cap = cv2.VideoCapture(0) #src = 0 for default camera
cap.set(3,640) #id=3 for width
cap.set(4,480) #id=4 for height
cap.set(10,150)#id=10 for brightness of camera

myColors = [[5,107,0,19,255,255],[133,56,0,159,156,255],[57,76,0,100,255,255],[90,48,0,118,255,255]]
myColorValues = [[51,153,255], #in the form BGR not RGB
                 [255,0,255],
                 [0,255,0],
                 [255,0,0]]
myPoints = [] ##[x,y,colorId]
def findColor(img,myColors,myColorValues) :
    imgHSV = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    count=0
    newPoints = []
    for color in myColors:
        lower = np.array(color[:3])
        upper = np.array(color[3:6])
        mask = cv2.inRange(imgHSV, lower, upper)
        x,y = getContour(mask)
        cv2.circle(imgResult,(x,y),10,myColorValues[count],cv2.FILLED)
        if(x!=0 and y!=0):
            newPoints.append([x,y,count])
        count = count + 1
    return newPoints

def getContour(img) :  #for setting contours i.e. boundaries
    x,y,w,h = 0,0,0,0
    contours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) #finding the edges of a substance
    for cnt in contours:
        area = cv2.contourArea(cnt) #finding area of a contour
        if area>500:  #filtering contours
            #cv2.drawContours(imgResult, cnt, -1, (255, 0, 0), 3) #drawing contours
            peri = cv2.arcLength(cnt,True) #finding perimeter of theshape
            approx = cv2.approxPolyDP(cnt,0.02*peri,True) #finding boundary points
            x , y , w , h = cv2.boundingRect(approx)
    return x+w //2,y

def drawOnCanvas(myPoints,myColorValues):
    for point in myPoints:
        cv2.circle(imgResult, (point[0],point[1]), 10, myColorValues[point[2]], cv2.FILLED)


while True:
    success,img= cap.read()
    imgResult = img.copy()
    newPoints = findColor(img, myColors,myColorValues)
    if len(newPoints) !=0:
        for newP in newPoints:
            myPoints.append(newP)
    if len(myPoints) !=0:
        drawOnCanvas(myPoints, myColorValues)
    cv2.imshow("Result",imgResult)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break