def img2binList(img, lenWidth, GRID_SIZE=50, verbose=0): global DISTANCECOSTMAP gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, gray = cv2.threshold(gray, 112, 255, cv2.THRESH_BINARY_INV) if verbose: cv2.imshow("img", gray) cv2.waitKey(0) cnts = cv2.findContours(gray.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts) locs = [] height, width = gray.shape tmp = np.zeros((height, width), np.uint8) idxLargest = 0 areaLargest = 0 # loop over the contours for (i, c) in enumerate(cnts): # compute the bounding box of the contour, then use the # bounding box coordinates to derive the aspect ratio (x, y, w, h) = cv2.boundingRect(c) if w * h > areaLargest: idxLargest = i areaLargest = w * h cv2.rectangle(tmp, (x, y), (x + w, y + h), (255, 0, 0), 2) if verbose: # print("found largest contour outline") cv2.imshow("img", tmp) cv2.waitKey(0) # print("cropping image as largest contour") (x, y, w, h) = cv2.boundingRect(cnts[idxLargest]) gray = gray[y:y + h, x:x + w] if verbose: cv2.imshow("img", gray) cv2.waitKey(0) mapWidth = (int)(lenWidth // GRID_SIZE) mapHeight = (int)((h / w) * lenWidth // GRID_SIZE) print("the map will be created by the size: " + str(mapWidth) + " X " + str(mapHeight)) resized_gray = imutils.resize(gray, width=mapWidth) # resize the map for convolution _, resized_gray = cv2.threshold(resized_gray, 1, 255, cv2.THRESH_BINARY) if verbose: cv2.imshow("img", resized_gray) cv2.waitKey(0) maze = convert2list(resized_gray) my_maze = np.array(maze) solution = pyfmm.march(my_maze == 1, batch_size=100000)[0] # NOTE : white area means walkable area DISTANCECOSTMAP = solution # cv2.destroyAllWindows() return maze
def test_fmm_infpick(self): # Given my_mesh = np.zeros((5, 5), dtype=np.bool) my_mesh[2, 2] = True # When exact = pyfmm.march(my_mesh, batch_size=np.inf)[0] # Then if self.do_plot: plt.imshow(exact, interpolation='None') plt.colorbar() plt.show() self.assertFalse(np.argwhere(np.isnan(exact))) self.assertAlmostEqual(exact[2, 2], 0) self.assertAlmostEqual(exact[0, 2], 2.0) self.assertAlmostEqual(exact[2, 0], 2.0)
def test_fmm_npick(self): # Given my_mesh = np.zeros((5, 5), dtype=np.bool) my_mesh[2, 2] = True # When solution = pyfmm.march(my_mesh, batch_size=5)[0] # Then if self.do_plot: plt.imshow(solution, interpolation='None') plt.colorbar() plt.show() self.assertFalse(np.any(np.isnan(solution))) self.assertAlmostEqual(solution[2, 2], 0) self.assertAlmostEqual(solution[0, 2], 2.0) self.assertAlmostEqual(solution[2, 0], 2.0)
def test_fmm_L_shape(self): # Given my_mesh = np.zeros((200, 200), dtype=np.bool) my_mesh[75:125, 75] = True my_mesh[75, 75:125] = True # When solution = pyfmm.march(my_mesh, batch_size=100)[0] #solution = pyfmm.pyfmm(my_mesh, n_min_pick_size=20) TODO: investigate why some values are undefined (inf or nan) # Then if self.do_plot: plt.imshow(solution, interpolation='None') plt.colorbar() plt.show() self.assertFalse(np.any(np.isinf(solution))) self.assertFalse(np.any(np.isnan(solution))) self.assertTrue(np.max(solution) < 160)
def test_fmm_race_to_middle(self): # Given my_mesh = np.zeros((20, 200), dtype=np.bool) my_mesh[:, 0] = True my_mesh[:, -1] = True speed_map = np.ones((20, 200)) speed_map[:, 100:] = 2.0 # When solution = pyfmm.march(my_mesh, speed=speed_map, batch_size=20)[0] # Then if self.do_plot: plt.imshow(solution, interpolation='None') plt.colorbar() plt.show() self.assertFalse(np.any(np.isinf(solution))) self.assertFalse(np.any(np.isnan(solution))) self.assertTrue(np.max(solution) < 75)
def test_fmm_plateau(self): # Given my_mesh = np.zeros((20, 200), dtype=np.bool) my_mesh[:, 0] = True speed_map = np.ones((20, 200)) speed_map[:, 100:] = 0.0 # When solution, certain_values = pyfmm.march(my_mesh, speed=speed_map, batch_size=20) # Then if self.do_plot: plt.imshow(solution, interpolation='None') plt.colorbar() plt.show() self.assertLessEqual(np.sum(np.isinf(solution)), 2000) self.assertLessEqual(np.sum(certain_values), 2000)
def test_fmm_known_values(self): # Given xx = np.outer(np.arange(0, 20, 1), np.ones((20, ))) yy = np.outer(np.ones((20, )), np.arange(0, 20, 1)) true_solution = np.abs(np.sqrt(np.square(xx) + np.square(yy)) - 10) known_values = true_solution < 1.0 # When computed_solution, _discard = pyfmm.march(known_values, true_solution, batch_size=1) # Then if self.do_plot: plt.imshow(computed_solution - true_solution, interpolation='None') plt.colorbar() plt.title('test_fmm_known_values') plt.show() self.assertLess(np.max(np.abs(computed_solution - true_solution)), 0.7)
def test_fmm_circle(self): # Given n = 200 my_mesh = np.zeros((n, n), dtype=np.bool) xx = np.array(100 + 50 * np.cos(np.linspace(0, 2 * np.pi, 100)), dtype=np.int) yy = np.array(100 + 50 * np.sin(np.linspace(0, 2 * np.pi, 100)), dtype=np.int) my_mesh[xx, yy] = True # When solution = pyfmm.march(my_mesh, batch_size=10)[0] # Then if self.do_plot: plt.imshow(solution, interpolation='None') plt.colorbar() plt.show() self.assertFalse(np.any(np.isinf(solution))) self.assertAlmostEqual(solution[n / 2, n / 2], 50.0, places=-1) self.assertAlmostEqual(solution[0, 0], 1.4142 * 100 - 50, places=-1)
import matplotlib.pyplot as plt import pyfmm my_image = plt.imread('irregular_boundary.png') solution = pyfmm.march(my_image[:, :, 0] == 0, batch_size=10)[0] plt.imshow(solution, interpolation='None') plt.colorbar() plt.title('Irregular boundary') plt.show()
import numpy as np import matplotlib.pyplot as plt import pyfmm # Double speed, 50/50 my_mesh = np.zeros((20, 200), dtype=np.bool) my_mesh[:, 0] = True my_mesh[:, -1] = True speed_map = np.ones((20, 200)) speed_map[:, 100:] = 2.0 solution_a = pyfmm.march(my_mesh, speed=speed_map, batch_size=5)[0] solution_b = pyfmm.march(my_mesh, speed=speed_map, batch_size=np.inf)[0] plt.subplot(3, 2, 1) plt.imshow(speed_map, interpolation='None') plt.colorbar(orientation='horizontal') plt.title('Speed map (50/50)') plt.subplot(3, 2, 3) plt.imshow(solution_a, interpolation='None') plt.colorbar(orientation='horizontal') plt.title('Accurate solution (50/50)') plt.subplot(3, 2, 5) plt.imshow(solution_b, interpolation='None') plt.colorbar(orientation='horizontal') plt.title('Inaccurate solution (50/50)') # 10x speed, 90/10
import pyfmm import matplotlib.pyplot as plt import numpy as np from time import perf_counter # Define a boundary resembling a circle n = 300 my_mesh = np.zeros((n, n), dtype=np.bool) xx = np.array(100 + 50 * np.cos(np.linspace(0, 2 * np.pi, 100)), dtype=np.int) yy = np.array(100 + 50 * np.sin(np.linspace(0, 2 * np.pi, 100)), dtype=np.int) my_mesh[xx, yy] = True # Compute solution tmp = perf_counter() solution_n1 = pyfmm.march(my_mesh, batch_size=1) t1 = perf_counter() - tmp tmp = perf_counter() solution_n20 = pyfmm.march(my_mesh, batch_size=20) t2 = perf_counter() - tmp tmp = perf_counter() solution_n100 = pyfmm.march(my_mesh, batch_size=100) t3 = perf_counter() - tmp tmp = perf_counter() solution_ninf = pyfmm.march(my_mesh, batch_size=np.inf) t4 = perf_counter() - tmp print("Timings (s):") print("\tbatch_size = 1: %2.3f" % t1) print("\tbatch_size = 20: %2.3f" % t2) print("\tbatch_size = 100: %2.3f" % t3) print("\tbatch_size = inf: %2.3f" % t4)