From 8e32a5f038d132ca3da8ea359b8aeafea4ec9e27 Mon Sep 17 00:00:00 2001 From: Jan Gutsche Date: Thu, 13 May 2021 18:20:47 +0200 Subject: [PATCH 1/3] Format generate_maps --- .../generate_maps.py | 84 ++++++++++++------- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/humanoid_league_map_generator/generate_maps.py b/humanoid_league_map_generator/generate_maps.py index b5a8db2..aca4c3c 100755 --- a/humanoid_league_map_generator/generate_maps.py +++ b/humanoid_league_map_generator/generate_maps.py @@ -1,19 +1,22 @@ #!/usr/bin/env python3 +import argparse +import math +import os + import cv2 import numpy as np from scipy import ndimage -import math -import os -import argparse # Generates .png files for localization # Default color scheme: black on white background # Scale: 1 px = 1 cm. parser = argparse.ArgumentParser(description="Generate maps for localization") -parser.add_argument('output', help="output folder where the models should be saved") -parser.add_argument('-p', '--package', dest="package", help="ros package where the models maps be saved") +parser.add_argument('output', + help="output folder where the models should be saved") +parser.add_argument('-p', '--package', dest="package", + help="ros package where the models maps be saved") args = parser.parse_args() lines = True @@ -45,6 +48,7 @@ if args.package: import rospkg + # Path to store generated models path = os.path.join(rospkg.RosPack().get_path(args.package), args.output) else: @@ -64,36 +68,52 @@ color = (255, 255, 255) # white # Size of complete turf field (field with outside borders) -image_size = (field_width + border_strip_width * 2, field_length + border_strip_width * 2, 3) +image_size = (field_width + border_strip_width * 2, + field_length + border_strip_width * 2, + 3) # Calculate important points on the field field_outline_start = (border_strip_width, border_strip_width) -field_outline_end = (field_length + border_strip_width, field_width + border_strip_width) - -middle_line_start = (field_length // 2 + border_strip_width, border_strip_width) -middle_line_end = (field_length // 2 + border_strip_width, field_width + border_strip_width) - -middle_point = (field_length // 2 + border_strip_width, field_width // 2 + border_strip_width) - -penalty_mark_left = (penalty_mark_distance + border_strip_width, field_width // 2 + border_strip_width) -penalty_mark_right = (image_size[1] - border_strip_width - penalty_mark_distance, field_width // 2 + border_strip_width) - -goal_area_left_start = (border_strip_width, border_strip_width + field_width // 2 - goal_area_width // 2) -goal_area_left_end = ( -border_strip_width + goal_area_length, field_width // 2 + border_strip_width + goal_area_width // 2) - -goal_area_right_start = (image_size[1] - goal_area_left_start[0], goal_area_left_start[1]) -goal_area_right_end = (image_size[1] - goal_area_left_end[0], goal_area_left_end[1]) - -penalty_area_left_start = (border_strip_width, border_strip_width + field_width // 2 - penalty_area_width // 2) -penalty_area_left_end = ( -border_strip_width + penalty_area_length, field_width // 2 + border_strip_width + penalty_area_width // 2) - -penalty_area_right_start = (image_size[1] - penalty_area_left_start[0], penalty_area_left_start[1]) -penalty_area_right_end = (image_size[1] - penalty_area_left_end[0], penalty_area_left_end[1]) - -goalpost_left_1 = (border_strip_width, border_strip_width + field_width // 2 + goal_width // 2) -goalpost_left_2 = (border_strip_width, border_strip_width + field_width // 2 - goal_width // 2) +field_outline_end = (field_length + border_strip_width, + field_width + border_strip_width) + +middle_line_start = (field_length // 2 + border_strip_width, + border_strip_width) +middle_line_end = (field_length // 2 + border_strip_width, + field_width + border_strip_width) + +middle_point = (field_length // 2 + border_strip_width, + field_width // 2 + border_strip_width) + +penalty_mark_left = (penalty_mark_distance + border_strip_width, + field_width // 2 + border_strip_width) +penalty_mark_right = (image_size[1] - border_strip_width - penalty_mark_distance, + field_width // 2 + border_strip_width) + +goal_area_left_start = (border_strip_width, + border_strip_width + field_width // 2 - goal_area_width // 2) +goal_area_left_end = (border_strip_width + goal_area_length, + field_width // 2 + border_strip_width + goal_area_width // 2) + +goal_area_right_start = (image_size[1] - goal_area_left_start[0], + goal_area_left_start[1]) +goal_area_right_end = (image_size[1] - goal_area_left_end[0], + goal_area_left_end[1]) + +penalty_area_left_start = (border_strip_width, + border_strip_width + field_width // 2 - penalty_area_width // 2) +penalty_area_left_end = (border_strip_width + penalty_area_length, + field_width // 2 + border_strip_width + penalty_area_width // 2) + +penalty_area_right_start = (image_size[1] - penalty_area_left_start[0], + penalty_area_left_start[1]) +penalty_area_right_end = (image_size[1] - penalty_area_left_end[0], + penalty_area_left_end[1]) + +goalpost_left_1 = (border_strip_width, + border_strip_width + field_width // 2 + goal_width // 2) +goalpost_left_2 = (border_strip_width, + border_strip_width + field_width // 2 - goal_width // 2) goalpost_right_1 = (image_size[1] - goalpost_left_1[0], goalpost_left_1[1]) goalpost_right_2 = (image_size[1] - goalpost_left_2[0], goalpost_left_2[1]) From ec747274f16da63ad2e64a30cfad10b9586f2893 Mon Sep 17 00:00:00 2001 From: Jan Gutsche Date: Thu, 13 May 2021 19:32:36 +0200 Subject: [PATCH 2/3] generate_maps: Draw goal back area --- .../generate_maps.py | 61 +++++++++++++------ 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/humanoid_league_map_generator/generate_maps.py b/humanoid_league_map_generator/generate_maps.py index aca4c3c..9a3e120 100755 --- a/humanoid_league_map_generator/generate_maps.py +++ b/humanoid_league_map_generator/generate_maps.py @@ -17,8 +17,12 @@ help="output folder where the models should be saved") parser.add_argument('-p', '--package', dest="package", help="ros package where the models maps be saved") +parser.add_argument('--no_blur', action='store_true', + help="disable blurring for debug purposes") args = parser.parse_args() +do_apply_blur = not args.no_blur + lines = True posts = False fieldboundary = False @@ -30,21 +34,23 @@ tcrossings_blobs = False crosses_blobs = False -penalty_mark = False -center_point = False +penalty_mark = True +center_point = True +goal_back = True # Draw goal back area -# 2019 field WM +# V-HL21 Rules +line_width = 5 field_length = 900 field_width = 600 +goal_depth = 60 goal_width = 260 goal_area_length = 100 goal_area_width = 300 -penalty_area_length = 200 -penalty_area_width = 500 penalty_mark_distance = 150 center_circle_diameter = 150 border_strip_width = 100 -line_width = 5 +penalty_area_length = 200 +penalty_area_width = 500 if args.package: import rospkg @@ -57,9 +63,6 @@ if not os.path.exists(path): os.mkdir(path) -# Invert image image to get black on white background -invert = True - # Choose mark style # mark_type = 'point' mark_type = 'cross' @@ -118,18 +121,31 @@ goalpost_right_1 = (image_size[1] - goalpost_left_1[0], goalpost_left_1[1]) goalpost_right_2 = (image_size[1] - goalpost_left_2[0], goalpost_left_2[1]) +goal_back_corner_left_1 = (goalpost_left_1[0] - goal_depth, + goalpost_left_1[1]) +goal_back_corner_left_2 = (goalpost_left_2[0] - goal_depth, + goalpost_left_2[1]) + +goal_back_corner_right_1 = (goalpost_right_1[0] + goal_depth, + goalpost_right_1[1]) +goal_back_corner_right_2 = (goalpost_right_2[0] + goal_depth, + goalpost_right_2[1]) -def drawCross(img, point, width=5, length=10): - # Might need some fine tuning - vertical_start = (point[0] - width, point[1] - length) - vertical_end = (point[0] + width, point[1] + length) - horizontal_start = (point[0] - length, point[1] - width) - horizontal_end = (point[0] + length, point[1] + width) + +def drawCross(img, point, width=5, length=15): + half_width = width // 2 + width % 2 + vertical_start = (point[0] - half_width, point[1] - length) + vertical_end = (point[0] + half_width, point[1] + length) + horizontal_start = (point[0] - length, point[1] - half_width) + horizontal_end = (point[0] + length, point[1] + half_width) img = cv2.rectangle(img, vertical_start, vertical_end, color, -1) img = cv2.rectangle(img, horizontal_start, horizontal_end, color, -1) def blurDistance(image, b=5): + if not do_apply_blur: # Skip blur + return image + # Calc distances distance_map = 255 - ndimage.morphology.distance_transform_edt(255 - image) # todo weniger hin und her rechnen @@ -154,6 +170,9 @@ def blurDistance(image, b=5): def blurGaussian(image): + if not do_apply_blur: # Skip blur + return image + out_img = cv2.GaussianBlur(image, (99, 99), cv2.BORDER_DEFAULT) out_img = cv2.normalize(out_img, None, alpha=0, beta=100, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F) out_img = 100 - out_img @@ -165,7 +184,6 @@ def blurGaussian(image): ################################################################################ if lines: - # Create black image in correct size for lines img_lines = np.zeros(image_size, np.uint8) @@ -183,7 +201,7 @@ def blurGaussian(image): if mark_type == 'point': img_lines = cv2.circle(img_lines, middle_point, line_width * 2, color, -1) else: - drawCross(img_lines, middle_point) + drawCross(img_lines, middle_point, line_width) # Draw penalty marks if penalty_mark: @@ -191,8 +209,8 @@ def blurGaussian(image): img_lines = cv2.circle(img_lines, penalty_mark_left, line_width * 2, color, -1) img_lines = cv2.circle(img_lines, penalty_mark_right, line_width * 2, color, -1) else: - drawCross(img_lines, penalty_mark_left) - drawCross(img_lines, penalty_mark_right) + drawCross(img_lines, penalty_mark_left, line_width) + drawCross(img_lines, penalty_mark_right, line_width) # Draw goal area img_lines = cv2.rectangle(img_lines, goal_area_left_start, goal_area_left_end, color, line_width) @@ -202,6 +220,11 @@ def blurGaussian(image): img_lines = cv2.rectangle(img_lines, penalty_area_left_start, penalty_area_left_end, color, line_width) img_lines = cv2.rectangle(img_lines, penalty_area_right_start, penalty_area_right_end, color, line_width) + # Draw goal back area + if goal_back: + img_lines = cv2.rectangle(img_lines, goalpost_left_1, goal_back_corner_left_2, color, line_width) + img_lines = cv2.rectangle(img_lines, goalpost_right_1, goal_back_corner_right_2, color, line_width) + # blur and write cv2.imwrite(os.path.join(path, 'lines.png'), blurDistance(img_lines, 5)) From 4b7f4aa023f0e6180c20e444b1aa53dfa04bb452 Mon Sep 17 00:00:00 2001 From: Jan Gutsche Date: Thu, 13 May 2021 23:24:49 +0200 Subject: [PATCH 3/3] generate_maps: Variable blur --- .../generate_maps.py | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/humanoid_league_map_generator/generate_maps.py b/humanoid_league_map_generator/generate_maps.py index 9a3e120..498d12f 100755 --- a/humanoid_league_map_generator/generate_maps.py +++ b/humanoid_league_map_generator/generate_maps.py @@ -17,12 +17,10 @@ help="output folder where the models should be saved") parser.add_argument('-p', '--package', dest="package", help="ros package where the models maps be saved") -parser.add_argument('--no_blur', action='store_true', - help="disable blurring for debug purposes") +parser.add_argument('-b', '--blur', type=float, default=1.0, + help="amount of applied blurring (between 0 and 1)") args = parser.parse_args() -do_apply_blur = not args.no_blur - lines = True posts = False fieldboundary = False @@ -142,12 +140,12 @@ def drawCross(img, point, width=5, length=15): img = cv2.rectangle(img, horizontal_start, horizontal_end, color, -1) -def blurDistance(image, b=5): - if not do_apply_blur: # Skip blur - return image +def blurDistance(image, blur_factor=args.blur): + if blur_factor <= 0: # Skip blur + return (255 - image) // 2.55 # Calc distances - distance_map = 255 - ndimage.morphology.distance_transform_edt(255 - image) # todo weniger hin und her rechnen + distance_map = 255 - ndimage.morphology.distance_transform_edt(255 - image) # Maximum field distance maximum_size = math.sqrt(image.shape[0] ** 2 + image.shape[1] ** 2) @@ -156,7 +154,7 @@ def blurDistance(image, b=5): distance_map = (distance_map / maximum_size) # Magic value please change it - beta = b + beta = (1 - blur_factor) * 10 # Activation function distance_map = distance_map ** (2 * beta) @@ -169,11 +167,12 @@ def blurDistance(image, b=5): return out_img -def blurGaussian(image): - if not do_apply_blur: # Skip blur - return image +def blurGaussian(image, blur_factor=args.blur): + if blur_factor <= 0: # Skip blur + return (255 - image) // 2.55 - out_img = cv2.GaussianBlur(image, (99, 99), cv2.BORDER_DEFAULT) + sigma = blur_factor * 50 + out_img = cv2.GaussianBlur(image, (99, 99), sigma, borderType=cv2.BORDER_DEFAULT) out_img = cv2.normalize(out_img, None, alpha=0, beta=100, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F) out_img = 100 - out_img return out_img @@ -226,7 +225,7 @@ def blurGaussian(image): img_lines = cv2.rectangle(img_lines, goalpost_right_1, goal_back_corner_right_2, color, line_width) # blur and write - cv2.imwrite(os.path.join(path, 'lines.png'), blurDistance(img_lines, 5)) + cv2.imwrite(os.path.join(path, 'lines.png'), blurDistance(img_lines)) ############################################################################# # goalposts @@ -258,7 +257,7 @@ def blurGaussian(image): line_width) # blur and write - cv2.imwrite(os.path.join(path, 'fieldboundary.png'), blurDistance(img_fieldboundary, 5)) # TODO oder gaussian? + cv2.imwrite(os.path.join(path, 'fieldboundary.png'), blurDistance(img_fieldboundary)) # TODO oder gaussian? ############################################################################ # features