def k_diagonal_interchange(self, p: Pixel, p_1: Pixel, elem: B4W4_Elements) -> int or None: compute_elbows_set = elem.compute_set_elbows(p, p_1) array_interchange = [] if elem.binary_image.is_cut_vertex(p_1): for p_i in compute_elbows_set: n_w = elem.binary_image.get_pixel_directional( p_i, [Direction.N, Direction.W]) array_interchange.append((p_i.get_coords(), n_w.get_coords())) else: compute_elbows_set.remove(p) for p_i in compute_elbows_set: s_e = elem.binary_image.get_pixel_directional( p_i, [Direction.S, Direction.E]) array_interchange.append((p_i.get_coords(), s_e.get_coords())) nb_interchange = elem.binary_image.multiple_swap_pixels( array_interchange) if nb_interchange is not None: elem.array_interchange = [ *elem.array_interchange, *array_interchange ] elem.update_elements() return nb_interchange
def first_condition(self, elem: B4W4_Elements) -> int: nb_interchange = 0 n_w = elem.binary_image.get_pixel_directional( elem.top_pixel, [Direction.N, Direction.W]) n_n_w = elem.binary_image.get_pixel_directional( elem.top_pixel, [Direction.N, Direction.N, Direction.W]) while n_n_w.color == PixelColor.BLACK: if not (n_w.color == PixelColor.WHITE and n_n_w.color == PixelColor.BLACK): return nb_interchange else: k_diag, p_1 = self.lemme_5(n_n_w, elem) if p_1 is not None: nb_interchange += self.k_diagonal_interchange( n_n_w, p_1, elem) if elem.binary_image.get_pixel( n_n_w.x, n_n_w.y).color == PixelColor.BLACK: n = elem.binary_image.get_pixel_adjacent( elem.top_pixel, Direction.N) elem.array_interchange.append( (n_n_w.get_coords(), n.get_coords())) elem.binary_image.swap_pixels(n_n_w.get_coords(), n.get_coords()) nb_interchange += 1 elem.all_elbows = elem.compute_all_elbows() elem.top_pixel = elem.compute_top_pixel() n_w = elem.binary_image.get_pixel_directional( elem.top_pixel, [Direction.N, Direction.W]) n_n_w = elem.binary_image.get_pixel_directional( elem.top_pixel, [Direction.N, Direction.N, Direction.W]) return nb_interchange
def __init__(self, binaryImageStart: BinaryImage, binaryImageFinal: BinaryImage): if binaryImageStart.size != binaryImageFinal.size: print("Size of images must be the same !") exit() self.imageElementsStart = B4W4_Elements( binaryImageStart) # starting image self.imageElementsFinal = B4W4_Elements( binaryImageFinal) # final image self.array_interchange = [] # array of all interchange self.interchange = 0 # Number of swap
def test_compute_height(self): binary_image = BinaryImage.create_img_from_array( IMG_ALGO_B4W4_ELEMENTS, BLACK_CONNEXITY, WHITE_CONNEXITY) algo = B4W4_Elements(binary_image) self.assertEqual(2, algo.height, "height should be -1") binary_image = BinaryImage.create_img_from_array( IMG_TEST_CASE_1, BLACK_CONNEXITY, WHITE_CONNEXITY) algo = B4W4_Elements(binary_image) self.assertEqual(None, algo.height, "height should be 0 in vertical image")
def test_compute_anchor(self): binary_image = BinaryImage.create_img_from_array(IMG_ALGO_B4W4_ELEMENTS, BLACK_CONNEXITY, WHITE_CONNEXITY) algo = B4W4_Elements(binary_image) self.assertEqual(algo.binary_image.get_pixel(2, 4), algo.compute_anchor(), "Anchor should be (2, 4)") binary_image = BinaryImage.create_img_from_array(IMG_TEST_CASE_1, BLACK_CONNEXITY, WHITE_CONNEXITY) algo = B4W4_Elements(binary_image) self.assertEqual(None, algo.compute_anchor(), "Anchor should be None on vertical image")
def test_compute_top_pixel(self): binary_image = BinaryImage.create_img_from_array(IMG_ALGO_B4W4_ELEMENTS, BLACK_CONNEXITY, WHITE_CONNEXITY) algo = B4W4_Elements(binary_image) self.assertEqual(algo.binary_image.get_pixel(5, 5), algo.compute_top_pixel(), "Anchor should be (5, 5)")
def test_lemme_6_p_cut_into_not_cut(self): img_depart = [[0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 1, 0, 0, 0], [0, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0], [0, 0, 0, 1, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0]] img_soluce = [[0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [0, 1, 0, 1, 1, 0, 0, 0], [0, 1, 1, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 1, 1, 0], [0, 0, 0, 1, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0]] binary_image = BinaryImage.create_img_from_array(img_depart, BLACK_CONNEXITY, WHITE_CONNEXITY) solver = B4W4_Elements(binary_image) solver.lemme_6() self.assertEqual(img_soluce, binary_image.convert_pixels_to_img(), "In case of lemma_6, if the lead elbow = p is cut vertex we're applying a k-diag interchange" "on p. In this case p should not be cut vertex at the end of the interchanges") self.assertEqual(2, len(solver.array_interchange), "The number interchange should be 2")
def test_lemme_6_case_1_k_0_NWp_and_NNWp_white_but_NNWWp_black_and_NWW_white(self): img_depart = [[0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 1, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0]] img_soluce = [[0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 1, 0, 1, 1, 0], [0, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0]] binary_image = BinaryImage.create_img_from_array(img_depart, BLACK_CONNEXITY, WHITE_CONNEXITY) solver = B4W4_Elements(binary_image) solver.lemme_6() self.assertEqual(img_soluce, binary_image.convert_pixels_to_img(), "In case of lemma_6, if the lead elbow = p is not cut vertex and k=0 and NW(p) is black" "then the interchange is <p, N(p)>") self.assertEqual(2, len(solver.array_interchange), "The number interchange should be 2")
def test_lemme_6_case_1_k_superior_0(self): img_depart = [[0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]] img_soluce = [[0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 1, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]] binary_image = BinaryImage.create_img_from_array(img_depart, BLACK_CONNEXITY, WHITE_CONNEXITY) solver = B4W4_Elements(binary_image) solver.lemme_6() self.assertEqual(img_soluce, binary_image.convert_pixels_to_img(), "In case of lemma_6, if the lead elbow = p is not cut vertex and k>0 we'll slide p upward the" "east side of the frontier. The interchanges are is <p, NE(p)>, <NiE(p), Ni+1E(p)>" "<NkE(p), Nk+1E(p)>") self.assertEqual(5, len(solver.array_interchange), "The number interchange should be 5")
def test_first_condition_cut_NWp1_cut(self): img_depart = [[0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 0, 0, 0], [0, 1, 0, 0, 1, 0, 0], [0, 1, 1, 1, 1, 0, 0], [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0]] img_soluce = [[0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 0, 0], [0, 1, 1, 1, 0, 1, 0], [0, 0, 0, 1, 0, 1, 0], [0, 0, 0, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0]] binary_image = BinaryImage.create_img_from_array(img_depart, BLACK_CONNEXITY, WHITE_CONNEXITY) solver = B4W4_Elements(binary_image) solver.first_condition() self.assertEqual(img_soluce, binary_image.convert_pixels_to_img(), "In case of NNW(t) black and NW(t) white you need to apply a k-vertical interchange on NNW(t)." "Here it's a 3 times a 1-diagonal interchange where p1 is cut vertex the first time" "then not cut vertex twice. Note : the top pixel change once after the second interchange") self.assertEqual(3, len(solver.array_interchange), "The number interchange should be 3")
def test_first_condition_not_cut_1(self): img_depart = [[0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 0, 0], [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 1, 0], [0, 1, 1, 1, 1, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0]] img_soluce = [[0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 0, 0], [0, 1, 0, 0, 1, 0], [0, 1, 0, 0, 1, 0], [0, 1, 1, 1, 1, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0]] binary_image = BinaryImage.create_img_from_array(img_depart, BLACK_CONNEXITY, WHITE_CONNEXITY) solver = B4W4_Elements(binary_image) solver.first_condition() self.assertEqual(img_soluce, binary_image.convert_pixels_to_img(), "In case of NNW(t) black and NW(t) white you need to apply a k-vertical interchange on NNW(t)." "Here it's a 1-diagonal interchange where p1 is not cut vertex.") self.assertEqual(1, len(solver.array_interchange), "The number interchange should be 1")
def test_is_elbow(self): binary_image = BinaryImage.create_img_from_array(IMG_ALGO_B4W4_ELEMENTS, BLACK_CONNEXITY, WHITE_CONNEXITY) algo = B4W4_Elements(binary_image) for pixel in algo.binary_image.get_black_pixels(): self.assertEqual(pixel in algo.compute_all_elbows(), algo.is_elbow(pixel))
def test_compute_frontier(self): binary_image = BinaryImage.create_img_from_array(IMG_ALGO_B4W4_ELEMENTS, BLACK_CONNEXITY, WHITE_CONNEXITY) algo = B4W4_Elements(binary_image) frontier_test = [algo.binary_image.get_pixel(1, 5), algo.binary_image.get_pixel(2, 5), algo.binary_image.get_pixel(4, 5), algo.binary_image.get_pixel(5, 5)] frontier_algo, temp = algo.compute_frontier() self.assertEqual(frontier_test, frontier_algo, "Pixels that should be in frontier [(1, 5), (2, 5), (4, 5), (5, 5)]")
def test_compute_all_elbows(self): binary_image = BinaryImage.create_img_from_array(IMG_ALGO_B4W4_ELEMENTS, BLACK_CONNEXITY, WHITE_CONNEXITY) algo = B4W4_Elements(binary_image) elbows_test = [algo.binary_image.get_pixel(1, 1), algo.binary_image.get_pixel(1, 5), algo.binary_image.get_pixel(2, 2), algo.binary_image.get_pixel(4, 5), algo.binary_image.get_pixel(6, 3)] elbows_algo = algo.compute_all_elbows() self.assertEqual(elbows_test, elbows_algo, "Pixels that should be in frontier [(1, 1), (1, 5), (2, 2), (4, 5), (6, 3)]")
def lemme_6(self, elem: B4W4_Elements) -> int: nb_interchange = self.first_condition(elem) array_interchange = [] if not elem.binary_image.is_cut_vertex(elem.lead_elbow): p = copy.copy(elem.lead_elbow) k = elem.top_pixel.x - p.x if k > 0: n_e = elem.binary_image.get_pixel_directional( p, [Direction.N, Direction.E]) array_interchange.append((p.get_coords(), n_e.get_coords())) for i in range(k - 1): p = elem.binary_image.pixels[ elem.binary_image.pixels.index(n_e)] n_e = elem.binary_image.get_pixel_adjacent(p, Direction.N) array_interchange.append( (p.get_coords(), n_e.get_coords())) n_e = elem.binary_image.pixels[elem.binary_image.pixels.index( n_e)] n = elem.binary_image.get_pixel_directional( n_e, [Direction.N, Direction.W]) array_interchange.append((n_e.get_coords(), n.get_coords())) nb_interchange = elem.binary_image.multiple_swap_pixels( array_interchange) elif k == 0: n = elem.binary_image.get_pixel_directional(p, [Direction.N]) n_w = elem.binary_image.get_pixel_directional( p, [Direction.N, Direction.W]) n_n_w = elem.binary_image.get_pixel_directional( p, [Direction.N, Direction.N, Direction.W]) n_w_w = elem.binary_image.get_pixel_directional( p, [Direction.N, Direction.W, Direction.W]) q = n_n_w_w = elem.binary_image.get_pixel_directional( p, [Direction.N, Direction.N, Direction.W, Direction.W]) if n_w.color == PixelColor.BLACK: elem.binary_image.swap_pixels(p.get_coords(), n.get_coords()) array_interchange.append((p.get_coords(), n.get_coords())) nb_interchange += 1 elif n_w.color == PixelColor.WHITE and n_n_w.color == PixelColor.WHITE and \ not (n_n_w_w.color == PixelColor.BLACK and n_w_w.color == PixelColor.WHITE): elem.binary_image.swap_pixels(p.get_coords(), n_w.get_coords()) array_interchange.append( (p.get_coords(), n_w.get_coords())) nb_interchange += 1 elif n_n_w_w.color == PixelColor.BLACK and n_w_w.color == PixelColor.WHITE: k_diag, p_1 = self.lemme_5(n_n_w_w, elem) if p_1 is not None: nb_interchange += self.k_diagonal_interchange( n_n_w_w, p_1, elem) if elem.binary_image.get_pixel( q.x, q.y).color == PixelColor.WHITE: elem.binary_image.swap_pixels(p.get_coords(), n_w.get_coords()) array_interchange.append( (p.get_coords(), n_w.get_coords())) nb_interchange += 1 else: s_e_q = elem.binary_image.get_pixel_directional( q, [Direction.S, Direction.E]) array_interchange.append( (q.get_coords(), s_e_q.get_coords())) array_interchange.append( (p.get_coords(), n.get_coords())) nb_interchange += elem.binary_image.multiple_swap_pixels( array_interchange) else: p = copy.copy(elem.lead_elbow) k_diag, p_1 = self.lemme_5(p, elem) nb_interchange += self.k_diagonal_interchange(p, p_1, elem) if nb_interchange is not None: elem.array_interchange = [ *elem.array_interchange, *array_interchange ] elem.update_elements() elem.binary_image.expand_image() elem.binary_image.reduce_image() return nb_interchange