From 5bf5dca1b43373e781c6f27204edf415415da021 Mon Sep 17 00:00:00 2001 From: Will Belcher Date: Thu, 7 Feb 2019 20:50:13 -0500 Subject: [PATCH 1/5] Yay --- ScriptManager/.DS_Store | Bin 6148 -> 6148 bytes ScriptManager/ball.py | 11 ++++++++++- ScriptManager/table.py | 20 ++++++++++++++++++++ ScriptManager/tape3.py | 9 +++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 ScriptManager/table.py diff --git a/ScriptManager/.DS_Store b/ScriptManager/.DS_Store index ebf818c2f7b110c86f6b2911cdb6ff4902ce38bd..2dfcd9289e6c7c34eb6d6a928651a63a64bcd7c8 100644 GIT binary patch delta 102 zcmZoMXfc=|#>B`mu~2NHo}wrV0|Nsi1A_nqgC0WxL#1aB)qu~2NHo}wr_0|Nsi1A_nqLo!1m5N9x?GQ@BG$he%*93;if5D$a} z43)^z4Dp^h`N>H+`AI+(K%I=OKw9HJ7%(tQ=3z8c Date: Thu, 7 Feb 2019 21:02:33 -0500 Subject: [PATCH 2/5] Preton --- ScriptManager/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 ScriptManager/.DS_Store diff --git a/ScriptManager/.DS_Store b/ScriptManager/.DS_Store deleted file mode 100644 index 2dfcd9289e6c7c34eb6d6a928651a63a64bcd7c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%Sr=55UkdK3trZf9{1=$1o7x)3Gv|B572C~sIW2O1N64v7DZ7fW7?eU+VbELQPLR4c);65x12RyW}r=M(zWlP z!4w^TE9+l2?4d03K|K6SmNro02{Sz6j(dH^g3NoC8?N7eSea$75Q#sa-y&-#OVpO70#ZwG1I@>Fcs~vkoqeDFT z5TE%wd66_b$FEX2q&AE?6bJ=|3T)eFsrUam|1#Mme@Kb1P#_feX9~z@ayc1uQ+~Jp z+MeFE70We?n#T3&(C7~y0sPQ& Date: Fri, 8 Feb 2019 13:05:12 -0500 Subject: [PATCH 3/5] quick --- ScriptManager/ball.py | 2 +- ScriptManager/tape3.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ScriptManager/ball.py b/ScriptManager/ball.py index 64e8d25..0a2abb8 100644 --- a/ScriptManager/ball.py +++ b/ScriptManager/ball.py @@ -240,7 +240,7 @@ def connection(stop_message): print("--------------") print("Ball not found") - table.updateNumber("B00B13S") + table.updateNumber("BOOBIES") cv2.imshow('frame',grip.mask_output) rawCap.truncate(0) diff --git a/ScriptManager/tape3.py b/ScriptManager/tape3.py index 8ea8369..07e3a69 100644 --- a/ScriptManager/tape3.py +++ b/ScriptManager/tape3.py @@ -225,7 +225,7 @@ def connection(stop_message): else: - table.updateNumber("B00B13S") + table.updateNumber("BOOBIES") From 515dffd997a937197b94dd1dcba3ccb665f9d983 Mon Sep 17 00:00:00 2001 From: Will Belcher Date: Sat, 16 Feb 2019 10:58:45 -0500 Subject: [PATCH 4/5] listener --- ScriptManager/.DS_Store | Bin 0 -> 6148 bytes ScriptManager/ball.py | 2 +- ScriptManager/listener.py | 23 +++++++++++++++++++++++ ScriptManager/tape3.py | 2 +- 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 ScriptManager/.DS_Store create mode 100644 ScriptManager/listener.py diff --git a/ScriptManager/.DS_Store b/ScriptManager/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..d935ab3f8cde4e88948f6336c8414e76c857e195 GIT binary patch literal 6148 zcmeHKu};H447E!IK`dc{@kR!Ogcw<(stnA00FX8Uq?A@rBv?=u{(*1c_xJ#KK3h@J zq$>hsSH5@WJjZu0QLaZsJbIcQ6Qx9yzy$}}XnIVpi+5~bkxd}SdmPb%Ue3$;BriK` z5Bx?2!}y>+x3><=a^m5$LF`s{Di*%`=pOgAK)K0=C_Mk-C`~UvZizid`54EJFKg? zw^9*9H&?(Fa0UL90@$;~k{v~FT>)3X6{r=E??ZqKW`>nw{B)p+M*!du;b`c~SweDx zVP;q<;tGs46{x9fM-0|<#DnoN!%9)piS6*gR+;UD!m&E;A0nMNQ}osqa0S{5Z0InR z{r_zJ`M;gyBUiu`_*V+>aC|WyVM(^Pb`~dlZGd0F#e`QW)+y-3tr%R{iud8s5D(G; VW`>m_A~63W5M}Vj75GsFz5$;CVwV5_ literal 0 HcmV?d00001 diff --git a/ScriptManager/ball.py b/ScriptManager/ball.py index 0a2abb8..42551bb 100644 --- a/ScriptManager/ball.py +++ b/ScriptManager/ball.py @@ -176,7 +176,7 @@ def __find_lines(input): from table import Table import io -table = Table() +table = Table(1) grip = GripPipeline() diff --git a/ScriptManager/listener.py b/ScriptManager/listener.py new file mode 100644 index 0000000..4b9b8e6 --- /dev/null +++ b/ScriptManager/listener.py @@ -0,0 +1,23 @@ +import time +from networktables import NetworkTables as nt + +nt.initialize(server="10.15.12.2") + +table = nt.getTable("chooser_data") +table2 = nt.getTable("tape_data") +table3 = nt.getTable("ball_data") + +def valueChanged(table, key, value, isNew): + print("Changed:", table, key, value) + +def connectionListener(info, connected): + print("Connected:", info, "Connection:", connected[0],"-",connected[1]) + +nt.addConnectionListener(connectionListener) + +table.addEntryListener(valueChanged) +table2.addEntryListener(valueChanged) +table3.addEntryListener(valueChanged) + +while True: + time.sleep(5) diff --git a/ScriptManager/tape3.py b/ScriptManager/tape3.py index 07e3a69..c5860af 100644 --- a/ScriptManager/tape3.py +++ b/ScriptManager/tape3.py @@ -151,7 +151,7 @@ def find_boxes(contours): from picamera import PiCamera from table import Table -table = Table() +table = Table(0) BlurType = Enum('BlurType', 'Box_Blur Gaussian_Blur Median_Filter Bilateral_Filter') From 5a02b141ae7f991ae1d191e45ad7b024cc4b6404 Mon Sep 17 00:00:00 2001 From: Will Belcher Date: Sat, 16 Feb 2019 11:07:47 -0500 Subject: [PATCH 5/5] working --- ScriptManager/ball.py | 12 +- ScriptManager/scriptmanager.py | 6 +- ScriptManager/table.py | 5 +- ScriptManager/tape3.py | 25 ++-- ScriptManager/tape4.py | 244 +++++++++++++++++++++++++++++++++ 5 files changed, 270 insertions(+), 22 deletions(-) create mode 100644 ScriptManager/tape4.py diff --git a/ScriptManager/ball.py b/ScriptManager/ball.py index 42551bb..1037021 100644 --- a/ScriptManager/ball.py +++ b/ScriptManager/ball.py @@ -230,19 +230,21 @@ def connection(stop_message): cv2.rectangle(grip.mask_output,(x1,y1),(x2,y2),(255,255,255),2) sideX = ((x1-x2)/2)+x2 sideY = ((y1-y2)/2)+y2 + width = x2-x1 cv2.circle(grip.mask_output,(int(sideX),int(sideY)),50,(255,255,255),2) print("Ball found") - + + table.updateNumber((sideX, sideY)) - + table.updateNumber(width, key=1) except Exception as e: print(e) print("--------------") print("Ball not found") - table.updateNumber("BOOBIES") - - cv2.imshow('frame',grip.mask_output) + table.updateNumber("B") + table.updateNumber("B", key=1) + rawCap.truncate(0) ## xraw.seek(0) diff --git a/ScriptManager/scriptmanager.py b/ScriptManager/scriptmanager.py index 3d855cb..caf9aef 100644 --- a/ScriptManager/scriptmanager.py +++ b/ScriptManager/scriptmanager.py @@ -3,10 +3,10 @@ from networktables import NetworkTables as nt import tape3 -import thread_example import ball +import thread_example -ip = "10.31.51.43" +ip = "10.15.12.2" nt.initialize(server=ip) table = nt.getTable("chooser_data") @@ -34,7 +34,7 @@ def valueChanged(table, key, value, isNew): if value != 0: time.sleep(1) - + print("[*]Starting thread: {}".format(value)) t = threading.Thread(target=target_list[value]) t.start() diff --git a/ScriptManager/table.py b/ScriptManager/table.py index ac1ee3d..8c067ae 100644 --- a/ScriptManager/table.py +++ b/ScriptManager/table.py @@ -1,6 +1,7 @@ from networktables import NetworkTables as nt table_list = ["tape_data", "ball_data"] +key_list = ["midpoint", "width"] class Table: @@ -8,11 +9,11 @@ def __init__(self, table_number): nt.initialize(server='10.31.51.43') self.table = nt.getTable(table_list[table_number]) - def updateNumber(self, midpoint): + def updateNumber(self, midpoint, key = 0): table = self.table try: - table.putString('midpoint', str(midpoint)) + table.putString(key_list[key],str(midpoint)) except Exception as e: print(e) diff --git a/ScriptManager/tape3.py b/ScriptManager/tape3.py index c5860af..055abc9 100644 --- a/ScriptManager/tape3.py +++ b/ScriptManager/tape3.py @@ -20,8 +20,8 @@ def __init__(self): self.__hsv_threshold_input = self.blur_output self.__hsv_threshold_hue = [0.0, 180.0] - self.__hsv_threshold_saturation = [0.0, 47.0] - self.__hsv_threshold_value = [252.0, 255.0] + self.__hsv_threshold_saturation = [0.0, 255.0] + self.__hsv_threshold_value = [190.0, 255.0] self.hsv_threshold_output = None @@ -113,9 +113,7 @@ def midpoint(box_list): else: y += y1 - midx, midy = int(x), int(y) - - return (midx, midy) + return (round(x,2),round(y2)) #Defines bounding boxes from contours def find_boxes(contours): @@ -158,7 +156,7 @@ def find_boxes(contours): g = GripPipeline() #Minimum area of a bounding box -size_threshold = 4000 +size_threshold = 250 def main(stop_message): @@ -176,6 +174,7 @@ def connection(stop_message): cam = PiCamera() cam.resolution = (640, 480) cam.framerate = 32 + cam.exposure_mode = 'off' rawCap = PiRGBArray(cam, size=(640, 480)) for frame in cam.capture_continuous(rawCap, format="bgr", use_video_port=True): @@ -219,20 +218,22 @@ def connection(stop_message): #Draws midpoint if one exists if mid != 0: - cv2.circle(frame, (mid[0], mid[1]), 5, (0, 0, 255), -1) - table.updateNumber(mid) + cv2.circle(frame, (int(mid[0]),int(mid[1])), 5, (0, 0, 255), -1) + table.updateNumber((mid[0], mid[1])) + #table.updateNumber(-box_list[0][1][0], key=1) + table.updateNumber(-50, key=1) + print("Midpoint:", mid) - + else: - table.updateNumber("BOOBIES") - + table.updateNumber("B") + table.updateNumber("B", key=1) if box_list != []: print("************************") - cv2.imshow('frame', frame) rawCap.truncate(0) diff --git a/ScriptManager/tape4.py b/ScriptManager/tape4.py new file mode 100644 index 0000000..62fab04 --- /dev/null +++ b/ScriptManager/tape4.py @@ -0,0 +1,244 @@ +import sys +import cv2 +import numpy as np +import math +from enum import Enum + +class GripPipeline: + """ + An OpenCV pipeline generated by GRIP. + """ + + def __init__(self): + """initializes all values to presets or None if need to be set + """ + + self.__blur_type = BlurType.Box_Blur + self.__blur_radius = 6.306306306306296 + + self.blur_output = None + + self.__hsv_threshold_input = self.blur_output + self.__hsv_threshold_hue = [0.0, 180.0] + self.__hsv_threshold_saturation = [0.0, 255.0] + self.__hsv_threshold_value = [190.0, 255.0] + + self.hsv_threshold_output = None + + + + def process(self, source0): + """ + Runs the pipeline and sets all outputs to new values. + """ + # Step Blur0: + self.__blur_input = source0 + (self.blur_output) = self.__blur(self.__blur_input, self.__blur_type, self.__blur_radius) + + # Step HSV_Threshold0: + self.__hsv_threshold_input = self.blur_output + (self.hsv_threshold_output) = self.__hsv_threshold(self.__hsv_threshold_input, self.__hsv_threshold_hue, self.__hsv_threshold_saturation, self.__hsv_threshold_value) + + + @staticmethod + def __blur(src, type, radius): + """Softens an image using one of several filters. + Args: + src: The source mat (numpy.ndarray). + type: The blurType to perform represented as an int. + radius: The radius for the blur as a float. + Returns: + A numpy.ndarray that has been blurred. + """ + if(type is BlurType.Box_Blur): + ksize = int(2 * round(radius) + 1) + return cv2.blur(src, (ksize, ksize)) + elif(type is BlurType.Gaussian_Blur): + ksize = int(6 * round(radius) + 1) + return cv2.GaussianBlur(src, (ksize, ksize), round(radius)) + elif(type is BlurType.Median_Filter): + ksize = int(2 * round(radius) + 1) + return cv2.medianBlur(src, ksize) + else: + return cv2.bilateralFilter(src, -1, round(radius), round(radius)) + + @staticmethod + def __hsv_threshold(input, hue, sat, val): + """Segment an image based on hue, saturation, and value ranges. + Args: + input: A BGR numpy.ndarray. + hue: A list of two numbers the are the min and max hue. + sat: A list of two numbers the are the min and max saturation. + lum: A list of two numbers the are the min and max value. + Returns: + A black and white numpy.ndarray. + """ + out = cv2.cvtColor(input, cv2.COLOR_BGR2HSV) + return cv2.inRange(out, (hue[0], sat[0], val[0]), (hue[1], sat[1], val[1])) + + class Line: + + def __init__(self, x1, y1, x2, y2): + self.x1 = x1 + self.y1 = y1 + self.x2 = x2 + self.y2 = y2 + + def length(self): + return np.sqrt(pow(self.x2 - self.x1, 2) + pow(self.y2 - self.y1, 2)) + + def angle(self): + return np.degrees(np.arctan2(self.y2 - self.y1, self.x2 - self.x1)) + + +#finds the midpoint between the coordinates of the centers of two boxes +def midpoint(box_list): + + if len(box_list) < 2: + return 0 + + x1, y1 = box_list[0][0] + x2, y2 = box_list[1][0] + + x = abs((x1 - x2)/2) + y = abs((y1 - y2)/2) + + if x1 > x2: + x += x2 + else: + x += x1 + + if y1 > y2: + y += y2 + else: + y += y1 + + midx, midy = int(x), int(y) + + return (midx, midy) + +#Defines bounding boxes from contours +def find_boxes(contours): + + box_list=[] + t = 0 + + for cnt in contours: + rect = cv2.minAreaRect(cnt) + + width = rect[1][0] + length = rect[1][1] + + area = math.floor(width * length) + + if t == 2: + break + + if area > size_threshold: + + if width > 2*length or length > 2*width: + + #adds the area as an element + rect = rect + (area,) + box_list.append(rect) + + t+=1 + + return box_list + + +from picamera.array import PiRGBArray +from picamera import PiCamera +from table import Table + + +table = Table(0) + +BlurType = Enum('BlurType', 'Box_Blur Gaussian_Blur Median_Filter Bilateral_Filter') + +g = GripPipeline() + +#Minimum area of a bounding box +size_threshold = 1000 + +def main(): + + cam = PiCamera() + cam.resolution = (640, 480) + cam.framerate = 32 + cam.exposure_mode = "off" + rawCap = PiRGBArray(cam, size=(640, 480)) + + for frame in cam.capture_continuous(rawCap, format="bgr", use_video_port=True): + + box_list=[] + + frame = frame.array + frame2 = frame + #Runs the frame through the grip pipeline + g.process(frame) + threshed_frame = g.hsv_threshold_output + + ret, thresh = cv2.threshold(threshed_frame, 127, 255, cv2.THRESH_BINARY) + im2, contours, heirarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + + try: + box_list = find_boxes(contours) + + except Exception as e: + print(e) + + + for rect in box_list: + + #Converts box into coordinates + box = cv2.boxPoints(rect[:3]) + box = np.int0(box) + + angle = math.floor(rect[2]) + area = rect[3] + + print("Angle:", -angle) + print("Area:", area) + + print("|----------|") + + #Draws bounding boxes + frame = cv2.drawContours(threshed_frame, [box], 0, (255, 255, 255), 2) + + mid = midpoint(box_list) + + #Draws midpoint if one exists + if mid != 0: + + cv2.circle(threshed_frame, (mid[0], mid[1]), 5, (255, 255, 255), -1) + #table.updateNumber(mid) + print("Midpoint:", mid) + + #else: + + #table.updateNumber("B") + + + + if box_list != []: + print("************************") + + + rawCap.truncate(0) + + cv2.imshow("frame", threshed_frame) + cv2.imshow("original", frame2) + + #connection(stop_message) + + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +main() + + + + + +