import cv2 import numpy as np import pandas as pd class Camera(): def __init__(self) -> None: self.colors = [(0, 0, 255), (0, 255, 0), (255, 0, 0)] self.color_names = ["Rot", "Gruen", "Blau"] self.lower_red = np.array([80, 160, 150]) self.upper_red = np.array([255, 255, 255]) self.lower_green = np.array([40, 50, 160]) self.upper_green = np.array([80, 255, 255]) self.lower_blue = np.array([95, 180, 90]) self.upper_blue = np.array([130, 255, 255]) self.video = cv2.VideoCapture(0) self.start_process = False self.correct_field_frame = 0 self.mean_error = [] self.scores = {'score_red': 0, 'score_green': 0, 'score_blue': 0 } def get_frame(self) -> np.ndarray: try: _, self.image = self.video.read(1) except Exception as err: print("Can not capture the video..\n") print(err) return self.image def take_picture(self): path = 'src_folder/Game_Images/' file_name = 'current_score.png' image_path = path+file_name cv2.imwrite(image_path, self.image) def detect_color(self, image): hsv_img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) count_red, count_green, count_blue= 0,0,0 for i, color in enumerate(self.colors): if i == 0: lower = self.lower_red upper = self.upper_red elif i == 1: lower = self.lower_green upper = self.upper_green elif i == 2: lower = self.lower_blue upper = self.upper_blue mask = cv2.inRange(hsv_img, lower, upper) contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for contour in contours: if 100 < cv2.contourArea(contour): x, y, w, h = cv2.boundingRect(contour) cv2.rectangle(image, (x, y), (x + w, y + h), color, 2) cv2.putText(image, self.color_names[i], (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, color, 2) if i == 0: count_red += 1 elif i == 1: count_green += 1 elif i == 2: count_blue += 1 self.scores['score_red'] = count_red self.scores['score_green'] = count_green self.scores['score_blue'] = count_blue def current_score(self, scores: dict): return scores def range_of_interest(self, frame: np.ndarray, correct_field: int): num_windows_in_y = 1 num_windows_in_x = 3 height, width, _ = frame.shape roi_height = height/num_windows_in_y roi_width = width/num_windows_in_x images = [] for x in range(0,num_windows_in_y): for y in range(0,num_windows_in_x): tmp_image=frame[int(x*roi_height):int((x+1)*roi_height), int(y*roi_width):int((y+1)*roi_width)] images.append(tmp_image) correct_field_frame = images[correct_field] return correct_field_frame def reduce_errors(self, mean_error_list: list): for team_color in self.current_score.keys(): df = pd.DataFrame(mean_error_list) total = df[team_color].sum() number_of_rows = len(df.index) error = total/number_of_rows self.current_score[team_color] = round(error) def process(self): my_camera = Camera() square_error = [] while my_camera.start_process: frame = my_camera.get_frame() interested_area = my_camera.range_of_interest(frame, my_camera.correct_field_frame) my_camera.detect_color(interested_area) cv2.line(img=frame, pt1=(frame.shape[1]//3, 0), pt2=(frame.shape[1]//3, frame.shape[0]), color=(0, 0, 0), thickness=2) cv2.line(img=frame, pt1=(2 * frame.shape[1]//3, 0), pt2=(2 * frame.shape[1]//3, frame.shape[0]), color=(0, 0, 0), thickness=2) cv2.imshow("Kamera 1,2 oder 3", frame) print(my_camera.scores) square_error.append(my_camera.scores) if not my_camera.start_process: pass if cv2.waitKey(1) & 0xFF == ord('q'): my_camera.take_picture() print(my_camera.scores) break my_camera.video.release() cv2.destroyAllWindows() # nur zum testen: my_camera.start_process auf True setzen und correct_field_frame zwischen 1 und 3 wählen # if __name__ == "__main__": # my_camera = Camera() # my_camera.process()