From 8c5586770887ebb5d0035a3b11edea1ea093e191 Mon Sep 17 00:00:00 2001 From: zoeyzhao57 Date: Sat, 11 Feb 2023 14:14:48 -0800 Subject: [PATCH 1/7] updated seesaw algorithm to normalize the bars --- algorithms/SeesawAlgorithm.py | 61 +++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/algorithms/SeesawAlgorithm.py b/algorithms/SeesawAlgorithm.py index 5bb3e98..f30d0b7 100644 --- a/algorithms/SeesawAlgorithm.py +++ b/algorithms/SeesawAlgorithm.py @@ -29,10 +29,10 @@ def process_frame(self, frame, show): points = np.array(points) both_points = np.array(both_points) - """get best fit line for left points and right points""" - [vx, vy, x, y] = cv.fitLine(points, cv.DIST_L2, 0, 0.01, 0.01) - black_frame = cv.line(black_frame, (int(x - vx * self.WIDTH), int(y - vy * self.HEIGHT)), - (int(x + vx * self.WIDTH), int(y + vy * self.HEIGHT)), (0, 0, 255), 9) + # """get best fit line for left points and right points""" + # [vx, vy, x, y] = cv.fitLine(points, cv.DIST_L2, 0, 0.01, 0.01) + # black_frame = cv.line(black_frame, (int(x - vx * self.WIDTH), int(y - vy * self.HEIGHT)), + # (int(x + vx * self.WIDTH), int(y + vy * self.HEIGHT)), (0, 0, 255), 9) """get best fit line for middle points""" [vx, vy, x, y] = cv.fitLine(both_points, cv.DIST_L2, 0, 0.01, 0.01) @@ -62,42 +62,63 @@ def plot_points(self, frame): square_low = 0 square_high = bar_height - left_array = [] - right_array = [] - points = [] both_points = [] + xs = [] + + normalized = False + black_frame = frame """draw rectangle and point for every square, add points to array""" while square_low < self.HEIGHT: + normalized = False seg_left = left[int(square_low) + 1:int(square_high), 0:half_width] seg_right = right[int(square_low) + 1:int(square_high), 0:half_width] - x1 = half_width - int(np.sum(seg_left == 255) / bar_height) - x2 = half_width + int(np.sum(seg_right == 255) / bar_height) + left_x = int(np.sum(seg_left == 255) / bar_height) + right_x = int(np.sum(seg_right == 255) / bar_height) + + if left_x > half_width/2 or right_x > half_width/2: + normalized = True + + xs.append([left_x, right_x]) + + x1 = half_width - left_x + x2 = half_width + right_x black_frame = cv.rectangle(black_frame, (half_width, square_low), ( - x1, int(square_high)), (255, 255, 255), 3) + x1, int(square_high)), (255, 255, 0), 3) black_frame = cv.rectangle(black_frame, (half_width, square_low), ( - x2, int(square_high)), (255, 255, 255), 3) - - point_left = [int((x1 + half_width) / 2), int((square_high + square_low) / 2)] - point_right = [int((x2 + half_width) / 2), int((square_high + square_low) / 2)] - points.append(point_right) - points.append(point_left) + x2, int(square_high)), (255, 255, 0), 3) both_point = [int((x1 + x2) / 2), int((square_high + square_low) / 2)] both_points.append(both_point) - black_frame = cv.circle(black_frame, point_right, radius=0, color=(0, 0, 255), thickness=10) - black_frame = cv.circle(black_frame, point_left, radius=0, color=(0, 0, 255), thickness=10) black_frame = cv.circle(black_frame, both_point, radius=0, color=(0, 255, 255), thickness=10) square_high += bar_height square_low += bar_height - left_array.append(np.sum(seg_left == 255)) - right_array.append(np.sum(seg_right == 255)) + + if normalized is False: + for points in xs: + points[0] *= 2 + points[1] *= 2 + + square_low = 0 + square_high = bar_height + + for points in xs: + x1 = half_width - points[0] + x2 = half_width + points[1] + + black_frame = cv.rectangle(black_frame, (half_width, square_low), ( + x1, int(square_high)), (255, 255, 255), 3) + black_frame = cv.rectangle(black_frame, (half_width, square_low), ( + x2, int(square_high)), (255, 255, 255), 3) + + square_high += bar_height + square_low += bar_height return black_frame, points, both_points From 14eff03fb1cd3ec0a16cee9ca3d03ee075a65d16 Mon Sep 17 00:00:00 2001 From: zoeyzhao57 Date: Sat, 11 Feb 2023 22:16:02 +0000 Subject: [PATCH 2/7] autopep8 action fixes --- algorithms/SeesawAlgorithm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algorithms/SeesawAlgorithm.py b/algorithms/SeesawAlgorithm.py index f30d0b7..f3b973e 100644 --- a/algorithms/SeesawAlgorithm.py +++ b/algorithms/SeesawAlgorithm.py @@ -79,7 +79,7 @@ def plot_points(self, frame): left_x = int(np.sum(seg_left == 255) / bar_height) right_x = int(np.sum(seg_right == 255) / bar_height) - if left_x > half_width/2 or right_x > half_width/2: + if left_x > half_width / 2 or right_x > half_width / 2: normalized = True xs.append([left_x, right_x]) From aba8e182d9622e5665e9867fe61f793bc0637941 Mon Sep 17 00:00:00 2001 From: zoeyzhao57 <113090188+zoeyzhao57@users.noreply.github.com> Date: Sat, 18 Feb 2023 13:28:40 -0800 Subject: [PATCH 3/7] Update SeesawAlgorithm.py --- algorithms/SeesawAlgorithm.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/algorithms/SeesawAlgorithm.py b/algorithms/SeesawAlgorithm.py index f3b973e..c5f38e3 100644 --- a/algorithms/SeesawAlgorithm.py +++ b/algorithms/SeesawAlgorithm.py @@ -29,11 +29,6 @@ def process_frame(self, frame, show): points = np.array(points) both_points = np.array(both_points) - # """get best fit line for left points and right points""" - # [vx, vy, x, y] = cv.fitLine(points, cv.DIST_L2, 0, 0.01, 0.01) - # black_frame = cv.line(black_frame, (int(x - vx * self.WIDTH), int(y - vy * self.HEIGHT)), - # (int(x + vx * self.WIDTH), int(y + vy * self.HEIGHT)), (0, 0, 255), 9) - """get best fit line for middle points""" [vx, vy, x, y] = cv.fitLine(both_points, cv.DIST_L2, 0, 0.01, 0.01) x1 = int(x - vx * self.WIDTH) @@ -95,7 +90,7 @@ def plot_points(self, frame): both_point = [int((x1 + x2) / 2), int((square_high + square_low) / 2)] both_points.append(both_point) - black_frame = cv.circle(black_frame, both_point, radius=0, color=(0, 255, 255), thickness=10) + black_frame = cv.circle(black_frame, both_point, radius=0, color=(0, 0, 255), thickness=15) square_high += bar_height square_low += bar_height From 975de89b68d5915a048846f7f3247d34cc677cb9 Mon Sep 17 00:00:00 2001 From: zoeyzhao57 Date: Sat, 18 Feb 2023 17:18:33 -0800 Subject: [PATCH 4/7] fixed normalization --- algorithms/SeesawAlgorithm.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/algorithms/SeesawAlgorithm.py b/algorithms/SeesawAlgorithm.py index c5f38e3..d6b4c4e 100644 --- a/algorithms/SeesawAlgorithm.py +++ b/algorithms/SeesawAlgorithm.py @@ -62,6 +62,7 @@ def plot_points(self, frame): xs = [] normalized = False + isnull = True black_frame = frame @@ -77,6 +78,9 @@ def plot_points(self, frame): if left_x > half_width / 2 or right_x > half_width / 2: normalized = True + if left_x != 0 or right_x != 0: + isnull = False + xs.append([left_x, right_x]) x1 = half_width - left_x @@ -95,11 +99,17 @@ def plot_points(self, frame): square_high += bar_height square_low += bar_height - if normalized is False: + if isnull: + normalized = True + + while normalized is False: for points in xs: points[0] *= 2 points[1] *= 2 + if points[0] > half_width / 2 or points[1] > half_width / 2: + normalized = True + square_low = 0 square_high = bar_height From 26de49910b2cc2337245195cdee1487f2e80be38 Mon Sep 17 00:00:00 2001 From: zoeyzhao57 Date: Fri, 3 Mar 2023 22:35:06 -0800 Subject: [PATCH 5/7] fixed normalization --- algorithms/SeesawAlgorithm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algorithms/SeesawAlgorithm.py b/algorithms/SeesawAlgorithm.py index d6b4c4e..f1b240f 100644 --- a/algorithms/SeesawAlgorithm.py +++ b/algorithms/SeesawAlgorithm.py @@ -47,7 +47,7 @@ def process_frame(self, frame, show): def plot_points(self, frame): """This value needs to be changed to change the height of the bars""" - bar_height = int(90) + bar_height = int(30) mask = self.create_binary_mask(frame) half_width = int(self.WIDTH / 2) From 2fd52ba6e7b3bc4d59b632f5c2e6358c03311f86 Mon Sep 17 00:00:00 2001 From: zoeyzhao57 Date: Fri, 3 Mar 2023 23:48:58 -0800 Subject: [PATCH 6/7] fixed normalization --- algorithms/SeesawAlgorithm.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/algorithms/SeesawAlgorithm.py b/algorithms/SeesawAlgorithm.py index f1b240f..3c0302b 100644 --- a/algorithms/SeesawAlgorithm.py +++ b/algorithms/SeesawAlgorithm.py @@ -104,8 +104,8 @@ def plot_points(self, frame): while normalized is False: for points in xs: - points[0] *= 2 - points[1] *= 2 + points[0] = float(1.5*points[0]) + points[1] = float(1.5*points[1]) if points[0] > half_width / 2 or points[1] > half_width / 2: normalized = True @@ -114,8 +114,8 @@ def plot_points(self, frame): square_high = bar_height for points in xs: - x1 = half_width - points[0] - x2 = half_width + points[1] + x1 = int(half_width - points[0]) + x2 = int(half_width + points[1]) black_frame = cv.rectangle(black_frame, (half_width, square_low), ( x1, int(square_high)), (255, 255, 255), 3) From ebd599dea0d425d89213900737939dcaab99fdcb Mon Sep 17 00:00:00 2001 From: zoeyzhao57 Date: Sat, 4 Mar 2023 01:56:12 -0800 Subject: [PATCH 7/7] fixed normalization --- algorithms/SeesawAlgorithm.py | 70 +++++++++++++++++++++++++++-------- config/algorithm/seesaw.yaml | 7 ++-- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/algorithms/SeesawAlgorithm.py b/algorithms/SeesawAlgorithm.py index 3c0302b..3da0a3c 100644 --- a/algorithms/SeesawAlgorithm.py +++ b/algorithms/SeesawAlgorithm.py @@ -8,7 +8,10 @@ class SeesawAlgorithm(Algorithm): def __init__(self, config): - + """ + Sets seesaw algorithm configurations + :param config: config params + """ # masking range for green self.LOW_GREEN = np.array(config.lower_hsv_threshold) self.HIGH_GREEN = np.array(config.upper_hsv_threshold) @@ -23,13 +26,25 @@ def __init__(self, config): self.HEIGHT = int(config.frame_length) self.WIDTH = int(config.frame_width) + # visual parameters + self.BAR_HEIGHT = config.bar_height + self.NORM_FACTOR = config.normalization_factor + def process_frame(self, frame, show): + """ + Divides screen into horizontal strips and draw bars according to the amount + of green present on each strip. Draw the best fit line based on the centre of each bar, + then calculate the angle between the best fit line and a horizontal line. + :param frame: current frame (mat) + :param show: show/hide frames on screen for debugging + :type show: bool + :return: processed frame (mat), angle [-90, 90] + """ - black_frame, points, both_points = self.plot_points(frame) - points = np.array(points) + black_frame, both_points = self.plot_points(frame) both_points = np.array(both_points) - """get best fit line for middle points""" + """get best fit line for centre points""" [vx, vy, x, y] = cv.fitLine(both_points, cv.DIST_L2, 0, 0.01, 0.01) x1 = int(x - vx * self.WIDTH) x2 = int(x + vx * self.WIDTH) @@ -37,18 +52,36 @@ def process_frame(self, frame, show): y2 = int(y + vy * self.HEIGHT) black_frame = cv.line(black_frame, (x1, y1), (x2, y2), (0, 255, 255), 9) - """calculate angle""" + # calculate angle if y1 - y2 != 0: angle = round(math.degrees(math.atan(int(x2 - x1) / int(y1 - y2))), 2) else: angle = None + # alternative way of calculating angle + ''' + angle = 0 + for point in both_points: + if point[0] > self.WIDTH / 2: + angle += 1 + elif point[0] < self.WIDTH / 2: + angle -= 1 + angle = angle/(len(both_points))*90 + ''' + return black_frame, angle def plot_points(self, frame): - """This value needs to be changed to change the height of the bars""" - bar_height = int(30) + """ + Divides screen into equally sized rectangles on the left and right side + and draw bars according to the amount of green present on each strip. + Calculates the centre point of each horizontal strip. + :param frame: current frame (mat) + :return: processed frame (mat), list of centre points + """ + # initializing parameters + bar_height = int(self.BAR_HEIGHT) mask = self.create_binary_mask(frame) half_width = int(self.WIDTH / 2) @@ -58,7 +91,6 @@ def plot_points(self, frame): square_low = 0 square_high = bar_height both_points = [] - xs = [] normalized = False @@ -66,9 +98,11 @@ def plot_points(self, frame): black_frame = frame - """draw rectangle and point for every square, add points to array""" while square_low < self.HEIGHT: + + # for each area, calculates the amount of green present normalized = False + seg_left = left[int(square_low) + 1:int(square_high), 0:half_width] seg_right = right[int(square_low) + 1:int(square_high), 0:half_width] @@ -83,14 +117,16 @@ def plot_points(self, frame): xs.append([left_x, right_x]) + # draw bars based on the amount of green present x1 = half_width - left_x x2 = half_width + right_x - black_frame = cv.rectangle(black_frame, (half_width, square_low), ( - x1, int(square_high)), (255, 255, 0), 3) - black_frame = cv.rectangle(black_frame, (half_width, square_low), ( - x2, int(square_high)), (255, 255, 0), 3) + black_frame = cv.rectangle(black_frame, (half_width, square_low), + (x1, int(square_high)), (255, 255, 0), 3) + black_frame = cv.rectangle(black_frame, (half_width, square_low), + (x2, int(square_high)), (255, 255, 0), 3) + # draw centre points of the bars, add points to a list both_point = [int((x1 + x2) / 2), int((square_high + square_low) / 2)] both_points.append(both_point) @@ -99,17 +135,19 @@ def plot_points(self, frame): square_high += bar_height square_low += bar_height + # normalize the lengths of the bars if isnull: normalized = True while normalized is False: for points in xs: - points[0] = float(1.5*points[0]) - points[1] = float(1.5*points[1]) + points[0] = float(self.NORM_FACTOR * points[0]) + points[1] = float(self.NORM_FACTOR * points[1]) if points[0] > half_width / 2 or points[1] > half_width / 2: normalized = True + # draw normalized bars square_low = 0 square_high = bar_height @@ -125,7 +163,7 @@ def plot_points(self, frame): square_high += bar_height square_low += bar_height - return black_frame, points, both_points + return black_frame, both_points def create_binary_mask(self, frame): """ diff --git a/config/algorithm/seesaw.yaml b/config/algorithm/seesaw.yaml index 40027f4..9eebc45 100644 --- a/config/algorithm/seesaw.yaml +++ b/config/algorithm/seesaw.yaml @@ -4,8 +4,8 @@ gauss_kernel_size: 3,3 dilate_kernel_size: (5,5) sigma_x: 0 -contour_color: 0,129,255 -bar_height: 90 +bar_height: 30 +normalization_factor: 1.5 #### size of frame frame_width: 1280 @@ -13,5 +13,4 @@ frame_length: 720 #### hsv thresholds for crop video lower_hsv_threshold: [35, 80, 80] -upper_hsv_threshold: [80, 255, 255] - +upper_hsv_threshold: [80, 255, 255] \ No newline at end of file