def normalizeRelativeCoordinates(self, x_shift=None, y_shift=None): """ :param x_shift: The shift to apply to the X axis :type x_shift: int :param y_shift: The shift to apply to the Y axis :type y_shift: int Shift a mapping so that all values of the mapping are shifted by x_shift and y_shift. If x_shift is None, The lowest x value will be 0 and other x values are adapted in consequence. If y_shift is None, The lowest y value will be 0 and other y values are adapted in consequence. """ if x_shift is None and y_shift is None: (x_shift, y_shift) = geom.min_tuple(self._relative_coordinates.keys()) elif x_shift is None: (x_shift, _) = geom.min_tuple(self._relative_coordinates.keys()) elif y_shift is None: (_, y_shift) = geom.min_tuple(self._relative_coordinates.keys()) new_mapping = {} if x_shift != 0 and y_shift != 0: keys = self._relative_coordinates.keys() for key in keys: value = self._relative_coordinates.pop(key) new_mapping[(key[0] - x_shift, key[1] - y_shift)] = value elif x_shift != 0: keys = self._relative_coordinates.keys() for key in keys: value = self._relative_coordinates.pop(key) new_mapping[(key[0] - x_shift, key[1])] = value elif y_shift != 0: keys = self._relative_coordinates.keys() for key in keys: value = self._relative_coordinates.pop(key) new_mapping[(key[0], key[1] - y_shift)] = value else: new_mapping = self._relative_coordinates self._relative_coordinates = new_mapping
def prepareConnection(self, circles, bounds=None): """ :param circles: The circles in which a circle grid will be detected :type circles: list :param bounds: The boundaries of the image in which the circles have been detected :type bounds: list Method to call before self.connectCircles to set the object parameters properly """ self._circles = circles for i in range(len(circles)): self._noise_circles.append(False) if bounds is None: tuple_max = geom.max_tuple(circles) tuple_min = geom.min_tuple(circles) # bounds = (int(tuple_min[1]), int(tuple_min[0]), int(tuple_max[1]) + 1, int(tuple_max[0]) + 1) bounds = (int(tuple_min[0]), int(tuple_min[1]), int(tuple_max[0]) + 1, int(tuple_max[1]) + 1) self._bounds = bounds
def setUp(self): def create_connect4(x_dist=65, y_dist=55, max_x_error=10, max_y_error=8, hor=7, vert=6): connect4 = [] current_x = 0 current_y = 0 for i in range(vert): for j in range(hor): error_x = random.random() * max_x_error error_y = random.random() * max_y_error connect4.append((round(current_x + error_x, 2), round(current_y + error_y, 2))) current_x += x_dist current_y += y_dist current_x = 0 # random.shuffle(gameboard) return connect4 # Almost perfect circle grid (no circle missing, no noise) self.circles_0 = [(0, 0), (5, 0), (5, 8), (10, 4), (10, 8), (10, 0), (0, 4), (0, 8), (5, 4)] # Minimum circles so it can detect a 3x3 grid self.circles_1 = [(25, 40), (50, 20), (50, 0), (0, 40), (25, 20)] # Noise added to self.circles_1. The first element is isolated by noise so it'll be lost by filtering self.circles_2 = [(25, 40), (50, 20), (50, 0), (0, 40), (25, 20), (10, 42), (25, 25), (0, 20)] # Noise removed from self.circles_2. The first element is no more isolated by noise. self.circles_3 = [(5, 8), (10, 4), (10, 0), (0, 8), (5, 4), (5, 5), (0, 4)] # Almost perfect Connect 4 (no circle missing, no noise) self.connect4_0 = [ (331, 165), (267, 225), (5, 226), (73, 59), (8, 166), (202, 61), (3, 3), (197, 276), (198, 226), (71, 281), (135, 222), (268, 1), (1, 115), (391, 59), (71, 170), (332, 222), (267, 62), (139, 58), (329, 5), (130, 171), (69, 228), (199, 114), (329, 276), (397, 227), (327, 112), (398, 6), (267, 282), (391, 165), (260, 115), (134, 278), (9, 56), (5, 278), (329, 58), (391, 281), (199, 6), (196, 171), (266, 172), (139, 7), (65, 5), (393, 111), (132, 115), (67, 110), ] # """"""""Worst case""""""""" # Connect 4 with 3 of the 4 corners missing, some internal circles missing, # some internal noise, some external noise self.connect4_1 = [ (-71, 6), # Noise before first node (-1, 0) (7, -60), # Noise before first node (0, -1) (8, 3), (74, 3), (134, 8), (161, 4), # Noise between (2, 0) and (3, 0) # (200.01, 0.95), (3, 0) missing (263, 2), # (328.74, 5.82), (5, 0) missing # (396.51, 7.67), (6, 0) missing (3, 55), (74, 56), # (134.77, 62.91), (2, 1) missing (202, 57), # (262.29, 62.02), (4, 1) missing (333, 56), (394, 59), (391, 84), # Noise between (6, 1) and (6, 2) # (6.75, 114.49), (0, 2) missing (69, 112), (133, 114), (201, 113), (269, 113), (263, 140), # Noise between (4, 2) and (4, 3) (331, 113), # (399.9, 114.83), (6, 2) missing (0, 172), (1, 193), # Noise between (0, 3) and (0, 4) (100, 151), # Noise in the middle of (1, 2), (2, 2), (1, 3), (2, 3) # (69.1, 172.5), (1, 3) missing (137, 171), (199, 168), (204, 201), # Noise between (3, 3) and (3, 4) # (262.98, 172.59), (4, 3) missing (328, 169), # (395.7, 165.24), (6, 3) missing (10, 225), # (65.64, 225.93), (102, 215), # Noise between (1, 4) and (2, 4) (135, 222), (204, 223), # (267.24, 224.12), (4, 4) missing (334, 226), (391, 225), # (4.83, 282.79), (0, 5) missing (3, 326), # Noise above (0, 5) (69, 275), # (136.19, 280.97), (203.95, 275.62), (2, 5) and (3, 5) missing (265, 280), (260, 320), # Noise above (4, 5) (327, 280), (390, 278), (390, 322), ] # Noise above (6, 5) tuple_min = geom.min_tuple(self.connect4_1) temp = [] for (x, y) in self.connect4_1: x0 = x - tuple_min[0] y0 = y - tuple_min[1] temp.append((x0, y0)) self.connect4_1 = temp self.connect4_model = DefaultModel() self.c4Detector = FrontHolesDetector(self.connect4_model) self.circleGridDetector = CircleGridDetector()