#import necessary packages import numpy as np import cv2 import serial import time #set constant variables ball_detected = False video = cv2.VideoCapture(1) width = 960 height = 540 num = "3" positionX = 0 #intialize microcontroller serial communication arduino = serial.Serial(port='COM12', baudrate=115200, timeout=.1) #function defining serial communication def write_read(x): arduino.write(bytes(x, 'utf-8')) time.sleep(0.05) data = arduino.readline() return data #program loop while True: (grabbed, frame) = video.read() if not grabbed: break frame = cv2.resize(frame, (width, height)) #apply blur to average local values and use HSV for color detection [red] blur = cv2.GaussianBlur(frame, (21, 21), 0) hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV) lower = [149, 163, 150] upper = [255, 255, 255] lower = np.array(lower, dtype="uint8") upper = np.array(upper, dtype="uint8") mask = cv2.inRange(hsv, lower, upper) #outline detected color/object with circular contour contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) detections = [] for cnt in contours: area = cv2.contourArea(cnt) if area > 100: (x, y), radius = cv2.minEnclosingCircle(cnt) center = (int(x), int(y)) radius = int(radius) positionX = x cv2.circle(frame, center, radius, (0,255,0), 2) #create visual mask and count number of pixels in mask output = cv2.bitwise_and(frame, hsv, mask=mask) no_red = cv2.countNonZero(mask) print(no_red) #send serial messages based on number of pixels detected if int(no_red) > 1000: ball_detected = True else: ball_detected = False cv2.imshow("output", output) if ball_detected: if positionX < (width/2)-40: num = "3" elif positionX > (width/2)+40: num = "4" else: if int(no_red) < 45250: num = "1" else: num = "2" write_read(num) time.sleep(1) num = "5" write_read(num) else: value = write_read("3") #close program if cv2.waitKey(1) & 0xFF == ord('q'): break cv2.destroyAllWindows() video.release()