From c1b1b8fec9a6e551e4d8a507792fd29fc13ff157 Mon Sep 17 00:00:00 2001 From: Mann Patel <130435633+MannPatel0@users.noreply.github.com> Date: Wed, 1 Jan 2025 01:48:15 -0700 Subject: [PATCH] computer vision --- .DS_Store | Bin 8196 -> 8196 bytes Computer Vision/1.py | 160 --------- Computer Vision/main1.py | 144 -------- Computer Vision/main2.py | 320 ------------------ {Computer Vision => ComputerVision}/.DS_Store | Bin 6148 -> 6148 bytes .../Image_Processing.py | 35 +- .../Video_Processing.py | 7 +- .../Image_Processing.cpython-311.pyc | Bin 0 -> 9190 bytes .../Video_Processing.cpython-311.pyc | Bin 0 -> 9512 bytes .../__pycache__/final.cpython-311.pyc | Bin 0 -> 600 bytes .../__pycache__/main1.cpython-311.pyc | Bin .../__pycache__/main2.cpython-311.pyc | Bin 0 -> 9338 bytes .../robocup_ssl_env.cpython-311.pyc | Bin 0 -> 1321 bytes ComputerVision/robocup_ssl_env.py | 298 ++++++++++++++++ ComputerVision/train_rl_model.py | 33 ++ main.py | 14 + 16 files changed, 368 insertions(+), 643 deletions(-) delete mode 100644 Computer Vision/1.py delete mode 100644 Computer Vision/main1.py delete mode 100644 Computer Vision/main2.py rename {Computer Vision => ComputerVision}/.DS_Store (79%) rename Computer Vision/2.py => ComputerVision/Image_Processing.py (85%) rename Computer Vision/3.py => ComputerVision/Video_Processing.py (96%) create mode 100644 ComputerVision/__pycache__/Image_Processing.cpython-311.pyc create mode 100644 ComputerVision/__pycache__/Video_Processing.cpython-311.pyc create mode 100644 ComputerVision/__pycache__/final.cpython-311.pyc rename {Computer Vision => ComputerVision}/__pycache__/main1.cpython-311.pyc (100%) create mode 100644 ComputerVision/__pycache__/main2.cpython-311.pyc create mode 100644 ComputerVision/__pycache__/robocup_ssl_env.cpython-311.pyc create mode 100644 ComputerVision/robocup_ssl_env.py create mode 100644 ComputerVision/train_rl_model.py create mode 100644 main.py diff --git a/.DS_Store b/.DS_Store index 830c7655b9933b77d46f5c9b668e1c607b33faee..cf0a2381b106df69b26678f42fef5be1db2113f2 100644 GIT binary patch delta 287 zcmZp1XmOa}FD%Hwz`)4BAi%&-=9!b9oRpKFw6Sm+`@{zR&Fma39F`z?Rt7zWGKN%! zJcJscC{PPSDG=-Z2Lm7rMdjoh0>>xw3p8*e>7E=TWG%?Y;LMQEkjqd2)LjBJwP^Ax zA#E(8FN7{*5j`g?k10AyL>W_XvKdy<91$!AOr9rFvDt~|DD!4^iEk_$E7+L-uxYuLV2eSugGlNjY(;Og$Rb6hri%U{Y zeiBfg(zc7qEtARYx8#vrV%0HUxuVDdCUYhiu{XP|d;fgUbp zC; 220 and green < 50 and red < 50: - return 'Blue' - if blue < 50 and green > 200 and red > 200: - return 'Yellow' - if blue > 200 and green < 50 and red > 200: - return 'Purple' - if blue < 50 and green > 220 and red < 50: - return 'Green' - if blue < 50 and green < 200 and red > 180: - return 'Orange' - return 'Unidentified' - - -def IdentifyCircles(img, circle): - global ball - - x, y = int(circle[0]), int(circle[1]) - blue, green, red = img[y, x, 0], img[y, x, 1], img[y, x, 2] - color = Color_Detection(blue, green, red) - - # Debugging statements - print(f"Circle at ({x}, {y}) with BGR ({blue}, {green}, {red}) detected as {color}") - - if color == 'Blue' or color == 'Yellow': - robotList.append(Robot([x, y], color)) - elif color == 'Green' or color == 'Purple': - robotMarks.append([x, y, color]) - print('ROBOT FOUND') - elif color == 'Orange': - ball.pos = [x, y] - print(f"Ball found at ({x}, {y})") - - -def assignIDmarks(): - if robotList is not None: - for idx, robot in enumerate(robotList): - distances = [] - - for i, mark in enumerate(robotMarks): - mark_dist = distance.euclidean(mark[:2], robot.pos) - distances.append((i, mark_dist)) - distances.sort(key=lambda x: x[1]) - closest_marks_indices = [i for i, _ in distances[:4]] - robot.circles = [robotMarks[i] for i in closest_marks_indices] - robot.ID = idx + 1 - - -def detect_circles(image): - gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) - blurred = cv2.GaussianBlur(gray, (9, 9), 0) - circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, 1, minDist=20, param1=50, param2=14, minRadius=15, - maxRadius=50) - return [circles] - - -def annotate_image(img): - for robot in robotList: - team_color = "B" if robot.team == 'Blue' else "Y" - cv2.putText(img, f'{team_color}', (robot.pos[0] + 20, robot.pos[1] - 40), cv2.FONT_HERSHEY_SIMPLEX, .75, - (255, 255, 255), 2, cv2.LINE_AA) - cv2.putText(img, f'ID{robot.ID}', (robot.pos[0] + 20, robot.pos[1] - 20), cv2.FONT_HERSHEY_SIMPLEX, .75, - (255, 255, 255), 2, cv2.LINE_AA) - cv2.putText(img, f'{robot.pos}', (robot.pos[0] + 20, robot.pos[1]), cv2.FONT_HERSHEY_SIMPLEX, .75, - (255, 255, 255), 2, cv2.LINE_AA) - - if ball.pos: - cv2.putText(img, f'Ball {ball.pos}', (ball.pos[0] + 20, ball.pos[1] + 20), cv2.FONT_HERSHEY_SIMPLEX, 1, - (255, 255, 255), 2, cv2.LINE_AA) - cv2.circle(img, (ball.pos[0], ball.pos[1]), 10, (0, 165, 255), -1) # Orange color for the ball - - -# Main function -def main(): - global robotList, robotMarks - global ball - - while True: - # Initialize globals - robotList = [] - robotMarks = [] - ball = Ball() # Ensure ball is always an instance of Ball - - # Load and process the image - imgpath = "Assets/Images/BotsAndBall.png" - img = cv2.imread(imgpath) - if img is None: - print(f"Failed to load image at path: {imgpath}") - return - - cv2.imshow("Original Image", img) - - # Detect circles in the image - circles = detect_circles(img) - - if circles is not None: - circles = np.uint8(np.around(circles)) - for circle in circles[0, :]: - IdentifyCircles(img, circle) - cv2.circle(img, (circle[0], circle[1]), circle[2], (0, 255, 0), 2) - cv2.circle(img, (circle[0], circle[1]), 2, (0, 0, 255), 3) - - assignIDmarks() - - for robot in robotList: - print(f'There is a {robot.team} robot with these ID circles:') - for mark in robot.circles: - print(mark) - - if ball.pos: - print(f'Ball found at {ball.pos}') - - for robot in robotList: - if robot.pos: - cv2.circle(img, (robot.pos[0], robot.pos[1]), 10, (0, 0, 0), 5) - for mark in robot.circles: - cv2.circle(img, (mark[0], mark[1]), 10, (0, 0, 0), 5) - - else: - print("No circles detected") - - annotate_image(img) - cv2.imshow("Annotated Image", img) - cv2.waitKey(0) - cv2.destroyAllWindows() - - -if __name__ == "__main__": - main() diff --git a/Computer Vision/main1.py b/Computer Vision/main1.py deleted file mode 100644 index bc70e8c..0000000 --- a/Computer Vision/main1.py +++ /dev/null @@ -1,144 +0,0 @@ -import cv2 -import numpy as np -from scipy.spatial import distance as dist - -# Initialize empty lists for robots and ID markings -robotList = [] -robotMarks = [] - -class Robot: - def __init__(self, pos=None, team='-no team!-', ID='-no ID!-'): - self.pos = pos if pos is not None else [] - self.team = team - self.ID = ID - self.circles = [] # ID markings [x, y, color] - - def add_marking(self, circle=None): - if circle is None: - circle = [0, 0, [0, 0, 0]] - self.circles.append(circle) - -class Ball: - def __init__(self, pos=None): - self.pos = pos if pos is not None else [] - -# Initialize the ball with default position -ball = Ball() - -def Color_Detection(blue, green, red): - if blue > 220 and green < 50 and red < 50: - return 'Blue' - elif blue < 50 and green > 200 and red > 200: - return 'Yellow' - elif blue > 200 and green < 50 and red > 200: - return 'Purple' - elif blue < 50 and green > 220 and red < 50: - return 'Green' - elif blue < 50 and green < 200 and red > 220: - return 'Orange' - return f'Unidentified Color R:{red}, G:{green}, B:{blue}' - -def IdentifyCircles(img, circle): - global ball - - x, y = int(circle[0]), int(circle[1]) - blue, green, red = img[y, x, 0], img[y, x, 1], img[y, x, 2] - color = Color_Detection(blue, green, red) - - if color == 'Blue' or color == 'Yellow': - robotList.append(Robot([x, y], color)) - elif color == 'Green' or color == 'Purple': - robotMarks.append([x, y, color]) - elif color == 'Orange': - ball = Ball([x, y]) - -def assignIDmarks(): - if robotList is not None: - for idx, robot in enumerate(robotList): - distances = [] - - for i, mark in enumerate(robotMarks): - mark_dist = dist.euclidean(mark[:2], robot.pos) - distances.append((i, mark_dist)) - distances.sort(key=lambda x: x[1]) - closest_marks_indices = [i for i, _ in distances[:4]] - robot.circles = [robotMarks[i] for i in closest_marks_indices] - robot.ID = idx + 1 - -def detect_circles(image): - gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) - blurred = cv2.GaussianBlur(gray, (9, 9), 0) - circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, 1, minDist=20, param1=50, param2=14, minRadius=15, maxRadius=50) - return circles - -def annotate_image(img): - for robot in robotList: - team_color = "B" if robot.team == 'Blue' else "Y" - cv2.putText(img, f'{team_color}', (robot.pos[0] + 20, robot.pos[1] - 40), cv2.FONT_HERSHEY_SIMPLEX, .75, (255, 255, 255), 2, cv2.LINE_AA) - cv2.putText(img, f'\nID{robot.ID}', (robot.pos[0] + 20, robot.pos[1] - 20), cv2.FONT_HERSHEY_SIMPLEX, .75, (255, 255, 255), 2, cv2.LINE_AA) - cv2.putText(img, f'{robot.pos }', (robot.pos[0] + 20, robot.pos[1]), cv2.FONT_HERSHEY_SIMPLEX, .75, (255, 255, 255), 2, cv2.LINE_AA) - - if ball: - cv2.putText(img, f'Ball {ball.pos}', (ball.pos[0] + 20, ball.pos[1] + 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA) - -# Main function -def main(): - global robotList, robotMarks, ball - - # Initialize globals - robotList = [] - robotMarks = [] - ball = None - - # Load and process the video - video_path = "/Users/mannpatel/Desktop/Robocup/Assets/Video/Test2.mp4" - cap = cv2.VideoCapture(video_path) - - while cap.isOpened(): - ret, frame = cap.read() - if not ret: - break - - # Reset robot and mark lists for each frame - robotList = [] - robotMarks = [] - - # Detect circles in the frame - circles = detect_circles(frame) - - if circles is not None: - circles = np.uint16(np.around(circles)) - for circle in circles[0, :]: - IdentifyCircles(frame, circle) - cv2.circle(frame, (circle[0], circle[1]), circle[2], (0, 255, 0), 2) - cv2.circle(frame, (circle[0], circle[1]), 2, (0, 0, 255), 3) - - assignIDmarks() - - # for robot in robotList: - # print(f'There is a {robot.team} robot with these ID circles:') - # for mark in robot.circles: - # print(mark) - - if ball: - print(f'Ball found at {ball.pos}') - - for robot in robotList: - cv2.circle(frame, (robot.pos[0], robot.pos[1]), 10, (0, 0, 0), 5) - for mark in robot.circles: - cv2.circle(frame, (mark[0], mark[1]), 10, (0, 0, 0), 5) - - else: - print("No circles detected") - - annotate_image(frame) - cv2.imshow("Annotated Video", frame) - - if cv2.waitKey(1) & 0xFF == ord('q'): - break - - cap.release() - cv2.destroyAllWindows() - -if __name__ == "__main__": - main() diff --git a/Computer Vision/main2.py b/Computer Vision/main2.py deleted file mode 100644 index bd3ffdc..0000000 --- a/Computer Vision/main2.py +++ /dev/null @@ -1,320 +0,0 @@ -# import cv2 -# import numpy as np -# from scipy.spatial import distance as dist, distance -# -# class Robot: -# def __init__(self, pos=None, team='-no team!-', ID='-no ID!-'): -# self.pos = pos if pos is not None else [] -# self.team = team -# self.ID = ID -# self.circles = [] -# -# def add_marking(self, circle=None): -# if circle is None: -# circle = [0, 0, [0, 0, 0]] -# self.circles.append(circle) -# -# class Ball: -# def __init__(self, pos=None): -# self.pos = pos if pos is not None else [] -# -# ball = Ball() -# robotList = [] -# robotMarks = [] -# -# def Color_Detection(blue, green, red): -# if blue >= 220 and green <= 50 and red <= 50: -# return 'Blue' -# if blue <= 50 and green >= 200 and red >= 200: -# return 'Yellow' -# if blue >= 200 and green <= 50 and red >= 200: -# return 'Purple' -# if blue <= 50 and green >= 220 and red <= 50: -# return 'Green' -# if blue <= 50 and green <= 200 and red >= 180: -# return 'Orange' -# return 'Unidentified' -# -# -# def IdentifyCircles(img, circle): -# global ball -# -# x, y = int(circle[0]), int(circle[1]) -# blue, green, red = img[y, x, 0], img[y, x, 1], img[y, x, 2] -# color = Color_Detection(blue, green, red) -# -# if color == 'Blue' or color == 'Yellow': -# robotList.append(Robot([x, y], color)) -# elif color == 'Green' or color == 'Purple': -# robotMarks.append([x, y, color]) -# print('ROBOT FOUND') -# elif color == 'Orange': -# ball.pos = [x, y] -# print(f"Ball found at ({x}, {y})") -# -# -# def assignIDmarks(): -# if robotList is not None: -# for idx, robot in enumerate(robotList): -# distances = [] -# -# for i, mark in enumerate(robotMarks): -# mark_dist = distance.euclidean(mark[:2], robot.pos) -# distances.append((i, mark_dist)) -# distances.sort(key=lambda x: x[1]) -# closest_marks_indices = [i for i, _ in distances[:4]] -# robot.circles = [robotMarks[i] for i in closest_marks_indices] -# robot.ID = idx + 1 -# -# -# def detect_circles(image): -# gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) -# blurred = cv2.GaussianBlur(gray, (9, 9), 0) -# circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, 1, minDist=20, param1=50, param2=14, minRadius=15, -# maxRadius=50) -# return circles -# -# -# def annotate_image(img): -# for robot in robotList: -# team_color = "B" if robot.team == 'Blue' else "Y" -# sting = f'Team: {team_color} | ID: {robot.ID} | POS: {robot.pos}' -# cv2.putText(img, sting, (robot.pos[0] + 20, robot.pos[1] - 40), cv2.FONT_HERSHEY_SIMPLEX, .75, -# (255, 255, 255), 2, cv2.LINE_AA) -# -# if ball.pos: -# cv2.putText(img, f'Ball {ball.pos}', (ball.pos[0] + 20, ball.pos[1] + 20), cv2.FONT_HERSHEY_SIMPLEX, 1, -# (255, 255, 255), 2, cv2.LINE_AA) -# -# # Main function -# def main(): -# global robotList, robotMarks -# global ball -# -# while True: -# # Initialize globals -# robotList = [] -# robotMarks = [] -# ball = Ball() # Ensure ball is always an instance of Ball -# -# # Load and process the image -# imgpath = "/Users/mannpatel/Desktop/Project/Computer Vision/Test2.jpeg" -# img = cv2.imread(imgpath) -# if img is None: -# print(f"Failed to load image at path: {imgpath}") -# return -# -# cv2.imshow("Original Image", img) -# -# # Detect circles in the image -# circles = detect_circles(img) -# -# if circles is not None: -# circles = np.uint16(np.around(circles)) -# for circle in circles[0, :]: -# IdentifyCircles(img, circle) -# cv2.circle(img, (circle[0], circle[1]), circle[2], (0, 255, 0), 2) -# cv2.circle(img, (circle[0], circle[1]), 2, (0, 0, 255), 3) -# assignIDmarks() -# -# for robot in robotList: -# print(f'There is a {robot.team} robot with these ID circles:') -# for mark in robot.circles: -# print(mark) -# -# if ball.pos: -# print(f'Ball found at {ball.pos}') -# -# for robot in robotList: -# if robot.pos: -# cv2.circle(img, (robot.pos[0], robot.pos[1]), 10, (0, 0, 0), 5) -# for mark in robot.circles: -# cv2.circle(img, (mark[0], mark[1]), 10, (0, 0, 0), 5) -# -# else: -# print("No circles detected") -# -# annotate_image(img) -# cv2.imshow("Annotated Image", img) -# cv2.waitKey(0) -# cv2.destroyAllWindows() -# -# -# if __name__ == "__main__": -# main() -import cv2 -import numpy as np -from scipy.spatial import distance as dist, distance - - -class Robot: - def __init__(self, pos=None, team='-no team!-', ID='-no ID!-'): - self.pos = pos if pos is not None else [] - self.team = team - self.ID = ID - self.circles = [] - - def add_marking(self, circle=None): - if circle is None: - circle = [0, 0, [0, 0, 0]] - self.circles.append(circle) - - -class Ball: - def __init__(self, pos=None): - self.pos = pos if pos is not None else [] - - -# Initialize the ball with default position -ball = Ball() -# Initialize empty lists for robots and ID markings -robotList = [] -robotMarks = [] - -def Color_Detection(blue, green, red): - if blue >= 220 and green <= 50 and red <= 50: - return 'Blue' - if blue <= 50 and green >= 200 and red >= 200: - return 'Yellow' - if blue >= 200 and green <= 50 and red >= 200: - return 'Purple' - if blue <= 50 and green >= 220 and red <= 50: - return 'Green' - if blue <= 50 and green <= 200 and red >= 220: - return 'Orange' - return 'Unidentified' - -# def Color_Detection(blue, green, red): -# if blue == 246 and green == 0 and red == 0: -# return 'Blue' -# if blue <= 0 and green >= 250 and red > 350: -# return 'Yellow' -# if blue == 247 and green == 51 and red == 235: -# return 'Purple' -# if blue == 77 and green == 252 and red == 118: -# return 'Green' -# if blue == 50 and green == 113 and red == 228: -# return 'Orange' -# return 'Unidentified' - - -def IdentifyCircles(img, circle): - global ball - - x, y = int(circle[0]), int(circle[1]) - blue, green, red = img[y, x, 0], img[y, x, 1], img[y, x, 2] - color = Color_Detection(blue, green, red) - - # Debugging statements - print(f"Circle at ({x}, {y}) with BGR ({blue}, {green}, {red}) detected as {color}") - - if color == 'Blue' or color == 'Yellow': - robotList.append(Robot([x, y], color)) - elif color == 'Green' or color == 'Purple': - robotMarks.append([x, y, color]) - print('ROBOT FOUND') - elif color == 'Orange': - ball.pos = [x, y] - print(f"Ball found at ({x}, {y})") - - -def assignIDmarks(): - if robotList is not None: - for idx, robot in enumerate(robotList): - distances = [] - - for i, mark in enumerate(robotMarks): - mark_dist = distance.euclidean(mark[:2], robot.pos) - distances.append((i, mark_dist)) - distances.sort(key=lambda x: x[1]) - closest_marks_indices = [i for i, _ in distances[:4]] - robot.circles = [robotMarks[i] for i in closest_marks_indices] - robot.ID = idx + 1 - - -def detect_circles(image): - gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) - blurred = cv2.GaussianBlur(gray, (9, 9), 0) - circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, 1, minDist=20, param1=50, param2=14, minRadius=15, - maxRadius=50) - return circles - - -def annotate_image(img): - for robot in robotList: - team_color = "B" if robot.team == 'Blue' else "Y" - cv2.putText(img, f'{team_color}', (robot.pos[0] + 20, robot.pos[1] - 40), cv2.FONT_HERSHEY_SIMPLEX, .75, - (255, 255, 255), 2, cv2.LINE_AA) - cv2.putText(img, f'ID{robot.ID}', (robot.pos[0] + 20, robot.pos[1] - 20), cv2.FONT_HERSHEY_SIMPLEX, .75, - (255, 255, 255), 2, cv2.LINE_AA) - cv2.putText(img, f'{robot.pos}', (robot.pos[0] + 20, robot.pos[1]), cv2.FONT_HERSHEY_SIMPLEX, .75, - (255, 255, 255), 2, cv2.LINE_AA) - - if ball.pos: - cv2.putText(img, f'Ball {ball.pos}', (ball.pos[0] + 20, ball.pos[1] + 20), cv2.FONT_HERSHEY_SIMPLEX, 1, - (255, 255, 255), 2, cv2.LINE_AA) - cv2.circle(img, (ball.pos[0], ball.pos[1]), 10, (0, 165, 255), -1) # Orange color for the ball - - -# Main function -def main(): - global robotList, robotMarks - global ball - - # Initialize globals - robotList = [] - robotMarks = [] - ball = Ball() # Ensure ball is always an instance of Ball - - # Load and process the image - imgpath = "/Users/mannpatel/Desktop/Robocup/Computer Vision/Template1.png" - img = cv2.imread(imgpath) - if img is None: - print(f"Failed to load image at path: {imgpath}") - return - - cv2.imshow("Original Image", img) - - # Detect circles in the image - circles = detect_circles(img) - - if circles is not None: - circles = np.uint16(np.around(circles)) - for circle in circles[0, :]: - IdentifyCircles(img, circle) - cv2.circle(img, (circle[0], circle[1]), circle[2], (0, 255, 0), 2) - cv2.circle(img, (circle[0], circle[1]), 2, (0, 0, 255), 3) - - assignIDmarks() - - for robot in robotList: - print(f'There is a {robot.team} robot with these ID {robot.ID}') - for mark in robot.circles: - print(mark) - - if ball.pos: - print(f'Ball found at {ball.pos}') - - for robot in robotList: - if robot.pos: - cv2.circle(img, (robot.pos[0], robot.pos[1]), 10, (0, 0, 0), 5) - for mark in robot.circles: - cv2.circle(img, (mark[0], mark[1]), 10, (0, 0, 0), 5) - - else: - print("No circles detected") - - annotate_image(img) - cv2.imshow("Annotated Image", img) - - # Use cv2.waitKey() to display the window until a key is pressed - while True: - key = cv2.waitKey(1) & 0xFF - if key == ord('q'): - break - - cv2.destroyAllWindows() - - -if __name__ == "__main__": - main() diff --git a/Computer Vision/.DS_Store b/ComputerVision/.DS_Store similarity index 79% rename from Computer Vision/.DS_Store rename to ComputerVision/.DS_Store index 11140deda619fcf2cd6193e658c4dad6d44da63b..4f23566b68587b4c95d7fa32db8a6143294ad5fb 100644 GIT binary patch delta 147 zcmZoMXfc=|#>B!ku~2NI-d)B;EKHNRnL-qW89W(s84?-N8B!VI83GuJ81fmCf$U-+ z%w))8NS}O&Np*5Nlfh(pW|7IinZ5vZgaKtzfNJt_=tyEx-TaOD3FBsV4t@@xm76~@ Ye`lV|FXG6-$iTqF00f&OMAk3^0Fxyn<^TWy delta 97 zcmZoMXfc=|#>B)qu~2NI-d)DY+$v+_&IAB&ODi4#F2vm2pAa{ST;w9tYHQKqY@UT diff --git a/Computer Vision/2.py b/ComputerVision/Image_Processing.py similarity index 85% rename from Computer Vision/2.py rename to ComputerVision/Image_Processing.py index 2307b9b..ff9f431 100644 --- a/Computer Vision/2.py +++ b/ComputerVision/Image_Processing.py @@ -2,9 +2,8 @@ import cv2 import numpy as np from scipy.spatial import distance as dist, distance - class Robot: - def __init__(self, pos=None, team='-no team!-', ID='-no ID!-'): + def __init__(self, pos=None , team=None , ID=None): self.pos = pos if pos is not None else [] self.team = team self.ID = ID @@ -28,18 +27,31 @@ robotList = [] robotMarks = [] def Color_Detection(blue, green, red): - if blue > 220 and green < 50 and red < 50: + if blue >= 220 and green <= 50 and red <= 50: return 'Blue' - if blue < 50 and green > 200 and red > 200: + if blue <= 50 and green >= 200 and red >= 200: return 'Yellow' - if blue > 200 and green < 50 and red > 200: + if blue >= 200 and green <= 50 and red >= 200: return 'Purple' - if blue < 50 and green > 220 and red < 50: + if blue <= 50 and green >= 220 and red <= 50: return 'Green' - if blue <= 50 and green <= 200 and red >= 180: + if blue <= 50 and green <= 200 and red >= 220: return 'Orange' return 'Unidentified' +# def Color_Detection(blue, green, red): +# if blue == 246 and green == 0 and red == 0: +# return 'Blue' +# if blue <= 0 and green >= 250 and red > 350: +# return 'Yellow' +# if blue == 247 and green == 51 and red == 235: +# return 'Purple' +# if blue == 77 and green == 252 and red == 118: +# return 'Green' +# if blue == 50 and green == 113 and red == 228: +# return 'Orange' +# return 'Unidentified' + def IdentifyCircles(img, circle): global ball @@ -48,9 +60,6 @@ def IdentifyCircles(img, circle): blue, green, red = img[y, x, 0], img[y, x, 1], img[y, x, 2] color = Color_Detection(blue, green, red) - # Debugging statements - print(f"Circle at ({x}, {y}) with BGR ({blue}, {green}, {red}) detected as {color}") - if color == 'Blue' or color == 'Yellow': robotList.append(Robot([x, y], color)) elif color == 'Green' or color == 'Purple': @@ -131,7 +140,7 @@ def main(): assignIDmarks() for robot in robotList: - print(f'There is a {robot.team} robot with these ID circles:') + print(f'There is a {robot.team} robot with these ID {robot.ID}') for mark in robot.circles: print(mark) @@ -157,7 +166,3 @@ def main(): break cv2.destroyAllWindows() - - -if __name__ == "__main__": - main() diff --git a/Computer Vision/3.py b/ComputerVision/Video_Processing.py similarity index 96% rename from Computer Vision/3.py rename to ComputerVision/Video_Processing.py index b8a9c16..c10edb5 100644 --- a/Computer Vision/3.py +++ b/ComputerVision/Video_Processing.py @@ -73,8 +73,7 @@ def assignIDmarks(): def detect_circles(image): gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (9, 9), 0) - circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, 1, minDist=20, param1=50, param2=14, minRadius=1, - maxRadius=99) + circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, 1, minDist=20, param1=50, param2=14, minRadius=20, maxRadius=59) return circles @@ -100,8 +99,8 @@ def main(): global ball # Open the video file - video_path = "Assets/Images/BotsAndBall.png" - cap = cv2.VideoCapture(1) + video_path = "Assets/Video/Test2.mp4" + cap = cv2.VideoCapture(video_path) if not cap.isOpened(): print(f"Failed to open video file: {video_path}") diff --git a/ComputerVision/__pycache__/Image_Processing.cpython-311.pyc b/ComputerVision/__pycache__/Image_Processing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3f87a44b07221268876779e17cebff55936c2850 GIT binary patch literal 9190 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 HCdB(+oZZ9S literal 0 HcmV?d00001 diff --git a/ComputerVision/__pycache__/final.cpython-311.pyc b/ComputerVision/__pycache__/final.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1342f667665f1ae1cdd1813383177ea1d62b4f02 GIT binary patch literal 600 zcmZuvF-yZh6uxUtsm3~q;1-Y$aWJho2#Uojn5l!JgIjD;i6psjcTrj`bZ~HRaC1=* z!K(OYS}6ztCnpD?(5;j2LR%1hm;3JfF7LjV$K@%LnM4rZ`Nv8R)=w#hks6TR43HaS zBO80@0NJSvbbxKVi*)5nrj*Kq#AF!*RABZV0B(@L$!-ER7DG?a$0ObZ_Bv7+{hwv0 z=0;Za-@eMdtoSF+Q4^}aj=tcx!q5@)KuWcY#f~E1354dkTztv=+N|k#9@Wn3i<(JK zHH$e~l|}`f#A6|I0}(5{%3}g2PvY?kWxgeJ9FxHE9WD*De$m+D4&#Pz1wm*D$1}EQ zIVr=9ZC9Alp|L{`VJkE?sUJqdVcNdST^bk_H?X|Luo@HJas#G<-#AQO1ZbcSGI3eB z+q^Z~B-M8Pcdnk vc)uVvCAs_+`sp>F+L7n1vuTjB6|Mtx6^wB=jj-C7l%q=&ywpX1A+h=andN=k literal 0 HcmV?d00001 diff --git a/Computer Vision/__pycache__/main1.cpython-311.pyc b/ComputerVision/__pycache__/main1.cpython-311.pyc similarity index 100% rename from Computer Vision/__pycache__/main1.cpython-311.pyc rename to ComputerVision/__pycache__/main1.cpython-311.pyc diff --git a/ComputerVision/__pycache__/main2.cpython-311.pyc b/ComputerVision/__pycache__/main2.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..634b1533aee8f379f70d1c9de274749e004ec0ae GIT binary patch literal 9338 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 YwnmjfZ4Hg)sR6!niUz*j2*`f?FEwSZX#fBK literal 0 HcmV?d00001 diff --git a/ComputerVision/__pycache__/robocup_ssl_env.cpython-311.pyc b/ComputerVision/__pycache__/robocup_ssl_env.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96fec68b74ebd94a435e507d93fec80436868f0c GIT binary patch literal 1321 zcma)4y>Ht_6hE4xNQ#ymH@4EmwE;UVYA@2@EieKU&KDB5G2%7@kwT@&vwaYcBM2I8gyS(;5iiXzC=N4W$fXX)b|-^cyl=iQrpK8JwT z?YFysPa*U!QBqR=6F&SSA@l+{$dO!RO2DVwDJq+?l-Oi9LlsjQ$r(3GRa2GF6vFBW zxSyu6kg0)9!P*JLI)!~sBc$wr-N~M*Co-JDJ||PhdUsS^YDu}Ho#_|j0MUc8V&5(@Pl z>{mI+mbZt6R1s>xutV%nWGy=+z9-ZQR1jhgUeKb*GW^tH zj>tH^hed{XyMAKx9L$7byD*&J(Fe$jK0PS^#4+P#YI$A&5!~`E7z@Q-$jf(0c&}b9 zC-a6$l{bAF)L}l435S&B3w@M=gHPH9bWnHkP4*4MPOgKm!+$7Ck`$vWy>!KBxi`6D zbfY)9VzkzqT*E9<=OWtl+kPa2BIP2zbG=z;7oq~F`gBL`Ja~DzYxT6%zP38hRwE^W zWe<&(@$zV$~QTNx2pmW}lN^$+Ox~ts{T@6Um2qOK%!&BN~0|It=e$ D)>BEN literal 0 HcmV?d00001 diff --git a/ComputerVision/robocup_ssl_env.py b/ComputerVision/robocup_ssl_env.py new file mode 100644 index 0000000..aaede1b --- /dev/null +++ b/ComputerVision/robocup_ssl_env.py @@ -0,0 +1,298 @@ +# import pygame +# import numpy as np + +# # Constants based on the image provided +# FIELD_WIDTH = 13.4 # meters +# FIELD_HEIGHT = 10.4 # meters +# GOAL_WIDTH = 1.8 # meters +# GOAL_HEIGHT = 1.8 # meters +# GOAL_DEPTH = 0.7 # meters +# SCALE = 50 # pixels per meter +# FPS = 60 + +# # Colors +# WHITE = (255, 255, 255) +# BLACK = (0, 0, 0) +# BLUE = (0, 0, 255) +# GREEN = (0, 255, 0) +# RED = (255, 0, 0) +# ORANGE = (255, 165, 0) + +# class RoboCupSSLEnv: +# def __init__(self): +# pygame.init() +# self.screen = pygame.display.set_mode((int(FIELD_WIDTH * SCALE), int(FIELD_HEIGHT * SCALE))) +# pygame.display.set_caption("RoboCup SSL Environment") +# self.clock = pygame.time.Clock() + +# self.total_reward = 0 +# self._reset_positions() + +# def _reset_positions(self): +# self.robot_pos = np.array([6.7, 5.2]) +# self.robot_angle = 0 +# self.ball_pos = np.array([6.7, 3.2]) +# self.ball_in_possession = False + +# def reset(self): +# self.total_reward = 0 +# self._reset_positions() +# return self._get_obs() + +# def _get_obs(self): +# return np.array([ +# self.robot_pos[0], self.robot_pos[1], self.robot_angle, +# self.ball_pos[0], self.ball_pos[1], int(self.ball_in_possession) +# ]) + +# def step(self, action): +# if action == 0: # Turn left +# self.robot_angle -= np.pi / 18 # Turn 10 degrees +# elif action == 1: # Turn right +# self.robot_angle += np.pi / 18 # Turn 10 degrees +# elif action == 2: # Move forward +# self.robot_pos[0] += 0.1 * np.cos(self.robot_angle) +# self.robot_pos[1] += 0.1 * np.sin(self.robot_angle) +# elif action == 3: # Move backward +# self.robot_pos[0] -= 0.1 * np.cos(self.robot_angle) +# self.robot_pos[1] -= 0.1 * np.sin(self.robot_angle) +# elif action == 4: # Kick +# if self.ball_in_possession: +# self.ball_pos = self.robot_pos + 2 * np.array([np.cos(self.robot_angle), np.sin(self.robot_angle)]) +# self.ball_in_possession = False + +# # Ball possession +# if not self.ball_in_possession and np.linalg.norm(self.robot_pos - self.ball_pos) < 0.2: +# self.ball_in_possession = True + +# # Move ball with robot if in possession +# if self.ball_in_possession: +# self.ball_pos = self.robot_pos + np.array([0.2 * np.cos(self.robot_angle), 0.2 * np.sin(self.robot_angle)]) + +# # Collision with field boundaries +# self.robot_pos = np.clip(self.robot_pos, [0, 0], [FIELD_WIDTH, FIELD_HEIGHT]) +# self.ball_pos = np.clip(self.ball_pos, [0, 0], [FIELD_WIDTH, FIELD_HEIGHT]) + +# # Check for goal on the right side +# reward = 0 +# done = False +# if self.ball_pos[0] >= FIELD_WIDTH and (FIELD_HEIGHT / 2 - GOAL_HEIGHT / 2) <= self.ball_pos[1] <= (FIELD_HEIGHT / 2 + GOAL_HEIGHT / 2): +# reward += 1 # Scored a goal +# self.total_reward += reward +# print("---> Goal! Total Reward:", self.total_reward) +# self._reset_positions() # Reset player and ball positions + +# return self._get_obs(), reward, done, {} + +# def handle_keys(self): +# keys = pygame.key.get_pressed() +# if keys[pygame.K_LEFT]: +# return 0 # Turn left +# elif keys[pygame.K_RIGHT]: +# return 1 # Turn right +# elif keys[pygame.K_UP]: +# return 2 # Move forward +# elif keys[pygame.K_DOWN]: +# return 3 # Move backward +# elif keys[pygame.K_SPACE]: +# return 4 # Kick +# return -1 # No action + +# def render(self): +# self.screen.fill(BLACK) # Clear screen + +# # Draw field +# pygame.draw.rect(self.screen, GREEN, pygame.Rect(0, 0, FIELD_WIDTH * SCALE, FIELD_HEIGHT * SCALE)) + +# # Draw center line +# pygame.draw.line(self.screen, WHITE, (FIELD_WIDTH * SCALE / 2, 0), (FIELD_WIDTH * SCALE / 2, FIELD_HEIGHT * SCALE), 2) + +# # Draw center circle +# pygame.draw.circle(self.screen, WHITE, (int(FIELD_WIDTH * SCALE / 2), int(FIELD_HEIGHT * SCALE / 2)), int(1.0 * SCALE), 2) + +# # Draw goals +# # Left goal +# pygame.draw.rect(self.screen, WHITE, pygame.Rect(0, (FIELD_HEIGHT / 2 - GOAL_HEIGHT / 2) * SCALE, GOAL_DEPTH * SCALE, GOAL_HEIGHT * SCALE), 2) +# pygame.draw.rect(self.screen, WHITE, pygame.Rect(0, (FIELD_HEIGHT / 2 - GOAL_HEIGHT / 2) * SCALE, GOAL_WIDTH * SCALE, GOAL_HEIGHT * SCALE), 2) + +# # Right goal +# pygame.draw.rect(self.screen, RED, pygame.Rect((FIELD_WIDTH - GOAL_DEPTH) * SCALE, (FIELD_HEIGHT / 2 - GOAL_HEIGHT / 2) * SCALE, GOAL_DEPTH * SCALE, GOAL_HEIGHT * SCALE), 2) +# pygame.draw.rect(self.screen, RED, pygame.Rect((FIELD_WIDTH - GOAL_WIDTH) * SCALE, (FIELD_HEIGHT / 2 - GOAL_HEIGHT / 2) * SCALE, GOAL_WIDTH * SCALE, GOAL_HEIGHT * SCALE), 2) + +# # Draw robot +# robot_center = (int(self.robot_pos[0] * SCALE), int(self.robot_pos[1] * SCALE)) +# pygame.draw.circle(self.screen, BLUE, robot_center, 10) + +# # Draw direction arrow +# robot_arrow_end = (robot_center[0] + int(20 * np.cos(self.robot_angle)), robot_center[1] + int(20 * np.sin(self.robot_angle))) +# pygame.draw.line(self.screen, BLUE, robot_center, robot_arrow_end, 3) + +# # Draw ball +# ball_center = (int(self.ball_pos[0] * SCALE), int(self.ball_pos[1] * SCALE)) +# pygame.draw.circle(self.screen, ORANGE, ball_center, 8) + +# pygame.display.flip() +# self.clock.tick(FPS) + +# def close(self): +# pygame.quit() + +# # Usage +# env = RoboCupSSLEnv() +# obs = env.reset() +# done = False + +# while not done: +# for event in pygame.event.get(): +# if event.type == pygame.QUIT: +# done = True + +# action = env.handle_keys() +# if action != -1: +# obs, reward, done, info = env.step(action) +# env.render() + +# if env.total_reward >= 25: +# done = True + +# env.close() +import gym +from gym import spaces +import pygame +import numpy as np + +# Constants based on the image provided +FIELD_WIDTH = 13.4 # meters +FIELD_HEIGHT = 10.4 # meters +GOAL_WIDTH = 1.8 # meters +GOAL_HEIGHT = 1.8 # meters +GOAL_DEPTH = 0.7 # meters +SCALE = 50 # pixels per meter +FPS = 60 + +# Colors +WHITE = (255, 255, 255) +BLACK = (0, 0, 0) +BLUE = (0, 0, 255) +GREEN = (0, 255, 0) +RED = (255, 0, 0) +ORANGE = (255, 165, 0) + +class RoboCupSSLEnv(gym.Env): + metadata = {'render.modes': ['human']} + + def __init__(self): + super(RoboCupSSLEnv, self).__init__() + + # Define action and observation space + # They must be gym.spaces objects + self.action_space = spaces.Discrete(5) # 5 possible actions + self.observation_space = spaces.Box( + low=np.array([0, 0, -np.pi, 0, 0, 0]), + high=np.array([FIELD_WIDTH, FIELD_HEIGHT, np.pi, FIELD_WIDTH, FIELD_HEIGHT, 1]), + dtype=np.float32 + ) + + self.total_reward = 0 + self._reset_positions() + + def _reset_positions(self): + self.robot_pos = np.array([6.7, 5.2]) + self.robot_angle = 0 + self.ball_pos = np.array([6.7, 3.2]) + self.ball_in_possession = False + + def reset(self): + self.total_reward = 0 + self._reset_positions() + return self._get_obs() + + def _get_obs(self): + return np.array([ + self.robot_pos[0], self.robot_pos[1], self.robot_angle, + self.ball_pos[0], self.ball_pos[1], int(self.ball_in_possession) + ]) + + def step(self, action): + if action == 0: # Turn left + self.robot_angle -= np.pi / 18 # Turn 10 degrees + elif action == 1: # Turn right + self.robot_angle += np.pi / 18 # Turn 10 degrees + elif action == 2: # Move forward + self.robot_pos[0] += 0.1 * np.cos(self.robot_angle) + self.robot_pos[1] += 0.1 * np.sin(self.robot_angle) + elif action == 3: # Move backward + self.robot_pos[0] -= 0.1 * np.cos(self.robot_angle) + self.robot_pos[1] -= 0.1 * np.sin(self.robot_angle) + elif action == 4: # Kick + if self.ball_in_possession: + self.ball_pos = self.robot_pos + 2 * np.array([np.cos(self.robot_angle), np.sin(self.robot_angle)]) + self.ball_in_possession = False + + # Ball possession + if not self.ball_in_possession and np.linalg.norm(self.robot_pos - self.ball_pos) < 0.2: + self.ball_in_possession = True + + # Move ball with robot if in possession + if self.ball_in_possession: + self.ball_pos = self.robot_pos + np.array([0.2 * np.cos(self.robot_angle), 0.2 * np.sin(self.robot_angle)]) + + # Collision with field boundaries + self.robot_pos = np.clip(self.robot_pos, [0, 0], [FIELD_WIDTH, FIELD_HEIGHT]) + self.ball_pos = np.clip(self.ball_pos, [0, 0], [FIELD_WIDTH, FIELD_HEIGHT]) + + # Check for goal on the right side + reward = 0 + done = False + if self.ball_pos[0] >= FIELD_WIDTH and (FIELD_HEIGHT / 2 - GOAL_HEIGHT / 2) <= self.ball_pos[1] <= (FIELD_HEIGHT / 2 + GOAL_HEIGHT / 2): + reward += 1 # Scored a goal + self.total_reward += reward + print("---> Goal! Total Reward:", self.total_reward) + self._reset_positions() # Reset player and ball positions + + return self._get_obs(), reward, done, {} + + def render(self, mode='human'): + if not hasattr(self, 'screen'): + pygame.init() + self.screen = pygame.display.set_mode((int(FIELD_WIDTH * SCALE), int(FIELD_HEIGHT * SCALE))) + pygame.display.set_caption("RoboCup SSL Environment") + self.clock = pygame.time.Clock() + + self.screen.fill(BLACK) # Clear screen + + # Draw field + pygame.draw.rect(self.screen, GREEN, pygame.Rect(0, 0, FIELD_WIDTH * SCALE, FIELD_HEIGHT * SCALE)) + + # Draw center line + pygame.draw.line(self.screen, WHITE, (FIELD_WIDTH * SCALE / 2, 0), (FIELD_WIDTH * SCALE / 2, FIELD_HEIGHT * SCALE), 2) + + # Draw center circle + pygame.draw.circle(self.screen, WHITE, (int(FIELD_WIDTH * SCALE / 2), int(FIELD_HEIGHT * SCALE / 2)), int(1.0 * SCALE), 2) + + # Draw goals + # Left goal + pygame.draw.rect(self.screen, WHITE, pygame.Rect(0, (FIELD_HEIGHT / 2 - GOAL_HEIGHT / 2) * SCALE, GOAL_DEPTH * SCALE, GOAL_HEIGHT * SCALE), 2) + pygame.draw.rect(self.screen, WHITE, pygame.Rect(0, (FIELD_HEIGHT / 2 - GOAL_HEIGHT / 2) * SCALE, GOAL_WIDTH * SCALE, GOAL_HEIGHT * SCALE), 2) + + # Right goal + pygame.draw.rect(self.screen, RED, pygame.Rect((FIELD_WIDTH - GOAL_DEPTH) * SCALE, (FIELD_HEIGHT / 2 - GOAL_HEIGHT / 2) * SCALE, GOAL_DEPTH * SCALE, GOAL_HEIGHT * SCALE), 2) + pygame.draw.rect(self.screen, RED, pygame.Rect((FIELD_WIDTH - GOAL_WIDTH) * SCALE, (FIELD_HEIGHT / 2 - GOAL_HEIGHT / 2) * SCALE, GOAL_WIDTH * SCALE, GOAL_HEIGHT * SCALE), 2) + + # Draw robot + robot_center = (int(self.robot_pos[0] * SCALE), int(self.robot_pos[1] * SCALE)) + pygame.draw.circle(self.screen, BLUE, robot_center, 10) + + # Draw direction arrow + robot_arrow_end = (robot_center[0] + int(20 * np.cos(self.robot_angle)), robot_center[1] + int(20 * np.sin(self.robot_angle))) + pygame.draw.line(self.screen, GREEN, robot_center, robot_arrow_end, 3) + + # Draw ball + ball_center = (int(self.ball_pos[0] * SCALE), int(self.ball_pos[1] * SCALE)) + pygame.draw.circle(self.screen, ORANGE, ball_center, 8) + + pygame.display.flip() + self.clock.tick(FPS) + + def close(self): + pygame.quit() diff --git a/ComputerVision/train_rl_model.py b/ComputerVision/train_rl_model.py new file mode 100644 index 0000000..823434b --- /dev/null +++ b/ComputerVision/train_rl_model.py @@ -0,0 +1,33 @@ +import gymnasium as gym +from stable_baselines3 import PPO +from stable_baselines3.common.env_checker import check_env +from robocup_ssl_env import RoboCupSSLEnv + +# Create environment +env = RoboCupSSLEnv() + +# Check if the environment follows the Gym interface +check_env(venv) + +# Instantiate the agent +model = PPO('MlpPolicy', env, verbose=1) + +# Train the agent +model.learn(total_timesteps=10000) + +# Save the model +model.save("ppo_robocup_ssl") + +# To reload the trained model +# model = PPO.load("ppo_robocup_ssl") + +# Evaluate the trained agent +obs = env.reset() +for _ in range(1000): + action, _states = model.predict(obs, deterministic=True) + obs, reward, done, info = env.step(action) + env.render() + if done: + obs = env.reset() + +env.close() diff --git a/main.py b/main.py new file mode 100644 index 0000000..909c5b6 --- /dev/null +++ b/main.py @@ -0,0 +1,14 @@ +import ComputerVision.Image_Processing as file1 +import ComputerVision.Video_Processing as file2 +import sys + + +if sys.argv[1] == "file1": + if __name__ == '__main__': + file1.main() + +elif sys.argv[1] == "file2": + if __name__ == '__main__': + file2.main() +else: + print("Invalid argument")