From 46deaabcdd6230b1ad85c033b0580dc41a84c4cd Mon Sep 17 00:00:00 2001 From: Owen Beck Date: Thu, 7 Dec 2023 17:32:13 -0500 Subject: [PATCH 1/2] Apriltag code is written but requires tuning. --- VisionCode/Main.py | 48 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/VisionCode/Main.py b/VisionCode/Main.py index 8ae59f76..6f191987 100644 --- a/VisionCode/Main.py +++ b/VisionCode/Main.py @@ -53,12 +53,13 @@ # Resize image to smaller size img = cv2.resize(img, (imgSizeX, imgSizeY)) + # + # GAME PIECE DETECTION + # + # Create HSV version of img (used for game piece detection) imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) - # Create a grayscale version of img (used for apriltag detection) - imgGrayscale = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) - # Create object mask objectMask = cv2.inRange(imgHSV, (hueMin, saturationMin, valueMin), (hueMax, saturationMax, valueMax)) objectMask = cv2.medianBlur(objectMask, 25) @@ -67,7 +68,7 @@ # Find object contours objectCnts = cv2.findContours(objectMask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) - # Report the closest object to RioComms + # Find the contours of visible objects objectCntsAreas = [] for i in objectCnts[0]: @@ -76,21 +77,52 @@ objectCntsAreas.append(M["m00"]) if len(objectCntsAreas) > 0: + # Find the largest (and theoretically closest) object maxValue = max(objectCntsAreas) maxObjectCntsIndex = objectCntsAreas.index(maxValue) + # Find pixel position of object M = cv2.moments(objectCnts[0][maxObjectCntsIndex]) - cX = int((M["m10"] / M["m00"])) - cY = int((M["m01"] / M["m00"])) + cX = int((M["m10"] / M["m00"])) - (imgSizeX / 2) + cY = int((M["m01"] / M["m00"])) - (imgSizeY / 2) - rioComms.send("objects", "Object X", cX - (imgSizeX / 2)) - rioComms.send("objects", "Object Y", cY - (imgSizeY / 2)) + # Send pixel position of object to network tables if an object is visible + rioComms.send("objects", "Object X", cX) + rioComms.send("objects", "Object Y", cY) rioComms.send("objects", "Object Visible", 1) else: + # Send zeroes to network tables if no object is visible rioComms.send("objects", "Object X", 0) rioComms.send("objects", "Object Y", 0) rioComms.send("objects", "Object Visible", 0) + # + # APRILTAG DETECTION + # + + # Create grayscale version of img (used for apriltag detection) + imgGrayscale = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + + # Detect apriltags + apriltags = at_detector.detect(imgGrayscale) + + # Remove apriltags that might not be identified correctly + # HAMMING = 0 WAS USED FOR 16h5, WITH 36h11 WE SHOULD BE ABLE TO INCREASE THIS TO 7+ + apriltags = [x for x in apriltags if x.hamming == 0] + + for i in range(len(apriltags)): + # Convert returned apriltag center into a readable form + centerXY = ast.literal_eval((re.sub(" +", " ", ((str(apriltags[i].center).replace("[", "")).replace("]", "")).strip())).replace(" ", ", ")) + + # Calculate pixel position of apriltag center + centerXY = list(centerXY) + centerXY[0] -= (imgSizeX / 2) + centerXY[1] -= (imgSizeY / 2) + + # Send apriltag position to network tables + rioComms.send("apriltags", "Tag " + str(apriltags[i].tag_id) + " X", centerXY[0]) + rioComms.send("apriltags", "Tag " + str(apriltags[i].tag_id) + " Y", centerXY[1]) + From f47221c86e6a27d4804890489ab1cfeb80f78678 Mon Sep 17 00:00:00 2001 From: Owen Beck Date: Sun, 7 Jan 2024 20:47:39 -0500 Subject: [PATCH 2/2] Vision display preparations. --- VisionCode/Main.py | 13 ++++++++++--- VisionCode/__pycache__/RioComms.cpython-37.pyc | Bin 0 -> 900 bytes 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 VisionCode/__pycache__/RioComms.cpython-37.pyc diff --git a/VisionCode/Main.py b/VisionCode/Main.py index 6f191987..0cf8d323 100644 --- a/VisionCode/Main.py +++ b/VisionCode/Main.py @@ -28,7 +28,7 @@ ) # Video capture is 640 pixels by 480 pixels -cap = cv2.VideoCapture(0) +cap = cv2.VideoCapture(1) # Desired image size (should be small) imgSizeX = 200 @@ -48,7 +48,7 @@ exit() # Read current frame from the camera - img = cap.read() + _, img = cap.read() # Resize image to smaller size img = cv2.resize(img, (imgSizeX, imgSizeY)) @@ -61,9 +61,11 @@ imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # Create object mask + kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, ksize=(25, 25)) objectMask = cv2.inRange(imgHSV, (hueMin, saturationMin, valueMin), (hueMax, saturationMax, valueMax)) objectMask = cv2.medianBlur(objectMask, 25) - objectMask = cv2.erode(objectMask, 25) + objectMask = cv2.erode(objectMask, kernel) + objectMask = cv2.dilate(objectMask, kernel) # Find object contours objectCnts = cv2.findContours(objectMask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) @@ -126,3 +128,8 @@ rioComms.send("apriltags", "Tag " + str(apriltags[i].tag_id) + " X", centerXY[0]) rioComms.send("apriltags", "Tag " + str(apriltags[i].tag_id) + " Y", centerXY[1]) + cv2.imshow("image", img) + cv2.imshow("image HSV", imgHSV) + cv2.imshow("object mask", objectMask) + + cv2.waitKey(5) diff --git a/VisionCode/__pycache__/RioComms.cpython-37.pyc b/VisionCode/__pycache__/RioComms.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b2f9b778ed9a4511f6b8c2b7b06688ea7640279 GIT binary patch literal 900 zcmZuwJCD;q5Z+xs;)Iw-LqS1B<0AY3gy6sk8f2t9I3&xG)>>=L0EzQ$l{?$No4VoB-*Ez&PQwBo$35 zC2t64+_@y&`NmSl-7^w-zu*mts0kC%ereR=eK9SCo}qSs7zigo`VlZeQpyQTrjJt2ms&P;+;EZYVLx83O_1l9GS4xKMn+1B^~gqB>v$gzc);FD-=+tcB)Ym=^; zLgk*qU}o6jJd&ak##xB9@m59I3FBF{t$WJ`_!xRpbKHv^*b&`?2e4>64itxR3@8la z08$O%Q91;q|KU@ZP2EDSd!ksyZd~AIU zHRrh*<$2Zcu0(m9=byWx+*(wC(QhNefH#uawAc`Z`-Y@Z70|#BJgbA&r(wNac-u*B WCt+>J0-50H7Q{37*NDb-9J9acrpIOg literal 0 HcmV?d00001