def body_tracking(image): """ This function get the head, body and tail by performing geodesic in images with boundaries Is too slow for the pi ~1-3 FPS """ # first we get the geodesic distance # because mice and rats are fluffy the torso is the furthest away distance distance = skfmm.distance(image) # get the highest point bx, by = np.unravel_index(distance.argmax(), distance.shape) # the furthest away point from this is the tail # create a boolen mask mask = ~image.astype(bool) # we mark with 0 the body tail = np.ones_like(image) tail[bx][by] = 0 t = np.ma.MaskedArray(tail, mask) # get the distance from 0 # the highest one is the tip of the tail tail_distance = skfmm.distance(t) # same to get the head, but calculate it from the tip of the tail head = np.ones_like(image) tx, ty = np.unravel_index(tail_distance.argmax(), tail_distance.shape) head[tx][ty] = 0 h = np.ma.MaskedArray(head, mask) head_distance = skfmm.distance(h) # get the exact point hx, hy = np.unravel_index(head_distance.argmax(), head_distance.shape) body_points = (by, bx) tail_points = (ty, tx) head_points = (hy, hx) points = [body_points, tail_points, head_points] return distance, tail_distance, head_distance, points
def test_zero_dx(): try: distance([1, 0, 1, 1], 0) except Exception as ex: assert ValueError.__name__ == ex.__class__.__name__ assert ex.args[0] == "dx must be greater than zero" else: raise Exception("no exception thrown")
def test10(): """ test c error handling """ try: distance([-1, 1], self_test=44) except Exception as ex: assert ValueError.__name__ == ex.__class__.__name__ else: raise Exception("no exception raised")
def test_dx_shape(): try: distance([0, 0, 1, 0, 0], [0, 0, 1, 0, 0]) except Exception as ex: assert ValueError.__name__ == ex.__class__.__name__ assert ex.args[0] == "dx must be of length len(phi.shape)" else: raise Exception("no exception thrown")
def test(): """ simple test two point test""" np.testing.assert_array_equal(distance([-1, 1]), [-0.5, 0.5]) np.testing.assert_allclose(distance([-1, -1, -1, 1, 1, 1]), [-2.5, -1.5, -0.5, 0.5, 1.5, 2.5]) np.testing.assert_allclose(distance([1, 1, 1, -1, -1, -1]), [2.5, 1.5, 0.5, -0.5, -1.5, -2.5])
def test11(): """ check array type test """ try: distance(np.array(["a", "b"])) except Exception as ex: assert ValueError.__name__ == ex.__class__.__name__ assert ex.args[0] == "phi must be a 1 to 12-D array of doubles" else: raise Exception("no exception raised")
def ssmdt(dt, ssmiter): dt = ssm(dt, anisotropic=True, iterations=ssmiter) dt[dt < filters.threshold_otsu(dt)] = 0 dt = skfmm.distance(dt, dx=5e-2) dt = skfmm.distance(np.logical_not(dt), dx=5e-3) dt[dt > 0.04] = 0.04 dt = dt.max() - dt dt[dt <= 0.038] = 0 return dt
def test7(): """ no zero level set test """ try: distance([1, 1], self_test=False) except Exception as ex: assert ValueError.__name__ == ex.__class__.__name__ assert ex.args[ 0] == "the array phi contains no zero contour (no zero level set)" else: raise Exception("no exception thrown")
def findIntersection( self, dw ): lvl0 = 1. - 1./self.patch.ppe tol = max(self.patch.dX) gd0 = lvl0 - dw.get('gDist', self.dwis[0]) gd1 = lvl0 - dw.get('gDist', self.dwis[1]) sh = gd0.shape phi0 = gd0.reshape(self.patch.Nc) phi1 = gd1.reshape(self.patch.Nc) dist0 = skfmm.distance( phi0, self.patch.dX ) dist1 = skfmm.distance( phi1, self.patch.dX ) gmask = (dist0.reshape(sh)<tol)*(dist1.reshape(sh)<tol) gmask = gmask*((dist0.reshape(sh)+dist1.reshape(sh))<tol/2./self.patch.ppe) self.nodes = np.where( gmask == True )[0]
def findIntersection(self, dw): lvl0 = 1. - 1. / self.patch.ppe tol = max(self.patch.dX) gd0 = lvl0 - dw.get('gDist', self.dwis[0]) gd1 = lvl0 - dw.get('gDist', self.dwis[1]) sh = gd0.shape phi0 = gd0.reshape(self.patch.Nc) phi1 = gd1.reshape(self.patch.Nc) dist0 = skfmm.distance(phi0, self.patch.dX) dist1 = skfmm.distance(phi1, self.patch.dX) gmask = (dist0.reshape(sh) < tol) * (dist1.reshape(sh) < tol) gmask = gmask * ((dist0.reshape(sh) + dist1.reshape(sh)) < tol / 2. / self.patch.ppe) self.nodes = np.where(gmask == True)[0]
def _make_dt(self): ''' Make the distance transform according to the speed type ''' self._dt = skfmm.distance(self._bimg, dx=5e-2) # Boundary DT if self._speed == 'ssm': if not self._silence: print('--SSM with GVF...') self._dt = ssm(self._dt, anisotropic=True, iterations=40) img = self._dt > threshold_otsu(self._dt) self._dt = skfmm.distance(img, dx=5e-2) self._dt = skfmm.distance(np.logical_not(self._dt), dx=5e-3) self._dt[self._dt > 0.04] = 0.04 self._dt = self._dt.max() - self._dt
def calc_sdf(x): """ calculates thes signed distance function for a batch of input data Arguments: x -- nbatch x Heiht x Width [ x 1] """ if x.ndim == 2 or x.ndim == 3: # H x W [ x 1 ] optional single channel sdf = skfmm.distance(np.squeeze(0.5 - x)) elif x.ndim == 4: # batched example Nbatch x H x W x 1 sdf = np.zeros(x.shape) for i in range(x.shape[0]): sdf[i, :, :, :] = skfmm.distance(np.squeeze(0.5 - x[i, :, :, :])) else: print("Error, invalid array dimension for calc_sdf", x.shape) return sdf
def glb_sdf(fac_file, fac_num): fac_mtr = grdecl_read(fac_file, 200, 100, 75) fac_mtr[fac_mtr != fac_num] = -1 fac_mtr[fac_mtr == fac_num] = 1 fac_sd = skfmm.distance(fac_mtr) return fac_sd
def getRegressionData(self, mapDim, numContours=15): masked = self.getFaceImage(mapDim) regressionMap = None contours = [] contourLengths = {} try: cellSize = 1 / mapDim regressionMap = skfmm.distance(masked, dx=cellSize) * 2 regmax = np.amax(regressionMap) regressionMap = regressionMap[:, :].copy() regressionMap[np.where( masked == 0)] = regmax # Make the core black for dist in np.linspace(0, regmax, numContours): contours.append([]) contourLengths[dist] = 0 layerContours = measure.find_contours(regressionMap, dist, fully_connected='high') for contour in layerContours: contours[-1].append(contour) contourLengths[dist] += geometry.length(contour) except ValueError: # If there aren't any contours, do nothing pass return (masked, regressionMap, contours, contourLengths)
def set_multi_goal(self, goal_map): traversible_ma = ma.masked_values(self.traversible * 1, 0) traversible_ma[goal_map == 1] = 0 dd = skfmm.distance(traversible_ma, dx=1) dd = ma.filled(dd, np.max(dd) + 1) self.fmm_dist = dd return
def generateRegressionMap(self): """Uses the fast marching method to generate an image of how the grain regresses from the core map. The map is stored under self.regressionMap.""" masked = np.ma.MaskedArray(self.coreMap, self.mask) cellSize = 1 / self.mapDim self.regressionMap = skfmm.distance(masked, dx=cellSize) * 2 self.wallWeb = self.unNormalize(np.amax(self.regressionMap))
def initialize(self, img, dx, seed): from scipy.ndimage import gaussian_filter from scipy.ndimage import label import skfmm smoothed = gaussian_filter(img, self.sigma) thresholded = img > smoothed labels, _ = label(thresholded) if labels[self._seed_to_index(seed)] > 0: seed_ = seed else: nonzero = numpy.array(numpy.nonzero(labels)).T nonzero *= dx dists = numpy.linalg.norm(nonzero - seed, axis=1) seed_ = nonzero[dists.argmin()] mask = labels == labels[self._seed_to_index(seed_)] inds = numpy.indices(img.shape, dtype=float) for i in range(inds.shape[0]): inds[i] -= seed_[i] inds[i] *= dx[i] dist_to_seed = (inds**2).sum(axis=0)**0.5 dist_to_boundary = skfmm.distance(mask, dx) return dist_to_seed < dist_to_boundary[self._seed_to_index(seed_)]
def extend_imbie_masks(res, basins, bedFileName): outFileName = 'imbie/basinNumbers_{}.nc'.format(res) if os.path.exists(outFileName): return ds = xarray.Dataset() print(' Extending IMBIE basins beyond ice fronts...') with xarray.open_dataset(bedFileName) as dsIn: nx = dsIn.sizes['x'] ny = dsIn.sizes['y'] ds['x'] = dsIn.x ds['y'] = dsIn.y minDistance = 1e30 * numpy.ones((ny, nx)) basinNumber = -1 * numpy.zeros((ny, nx), int) for index, basinName in enumerate(basins.keys()): print(' {}'.format(basinName)) imageFileName = 'imbie/basins_{}/{}.png'.format(res, basinName) image = misc.imread(imageFileName) basinFraction = 1. - image[::-1, :, 0] / 255. distance = skfmm.distance(-2. * basinFraction + 1) mask = distance < minDistance basinNumber[mask] = index minDistance[mask] = distance[mask] ds['basinNumber'] = (('y', 'x'), basinNumber) ds.to_netcdf(outFileName)
def phage_randomwalk(space, dt, log, phage, biomass_containers, rate): """Move them, go.""" if phage.n == 0: return biomass_containers = to_list(biomass_containers) step_dt = (2 * space.dl * space.dl) / phage.diffusivity nsteps = dt / step_dt * phage.remainder biomass = to_grid(space, biomass_containers, "mass") distance = -np.array( skfmm.distance(biofilm_edge(space, biomass), dx=space.dl), dtype=float) distance[distance < 0] = 0 # rem = 1 - np.exp(-rate * step_dt * distance ** 2) remove = 1 - np.exp( -rate * 2 * space.dl**2 * distance**2 / phage.P.diffusivity) slows = np.zeros(space.shape) for cntnr in biomass_containers: np.add.at(slows.reshape(-1), cntnr.location, cntnr.slow * cntnr.mass / space.dV) location = np.array(np.unravel_index(phage.location, space.shape)).T if space.dimensions == 2: location, remainder = _rw_stuck_2D(location, nsteps, step_dt, slows, np.array(space.shape), remove) elif space.dimensions == 3: location, remainder = _rw_stuck_3D(location, nsteps, step_dt, slows, np.array(space.shape), remove) remainder[nsteps > 0] = remainder[nsteps > 0] / nsteps[nsteps > 0] phage.location = np.ravel_multi_index(location.T, space.shape) phage.remainder = remainder
def make_sdf(a, thr=None, return_contour=False): """ Make signed distance array """ contour = segmentation.find_boundaries(a) if (contour.sum() == 0): contour[0, :] = 1 contour[-1, :] = 1 contour[:, 0] = 1 contour[:, -1] = 1 a_ls = np.ones(contour.shape) a_ls[contour] = -1 sdf = skfmm.distance(a_ls) sdf += 0.5 # make values outside positive sdf[a] = -sdf[a] if (thr is not None): if (return_contour): return np.clip(sdf, -thr, thr), contour else: return np.clip(sdf, -thr, thr) else: if (return_contour): return sdf, contour else: return sdf
def calc_fmm(self, ped, wait=1): """ :param ped: :param wait: :return: """ p, speed = ped if self.fmm_distance.size == 0: t_grid = np.array(np.ones_like(self.grid), dtype=np.double) mask = np.array(0 * np.ones_like(self.grid), dtype=bool) t_grid[self.target.row, self.target.col] = -1 for i in self.obstacles: mask[i.row][i.col] = True phi = np.ma.MaskedArray(t_grid, mask) self.fmm_distance = skfmm.distance(phi) self.grid[p[0]][p[1]].initial_predicted_time = self.fmm_distance[p[0]][p[1]] / self.speed[p[0]][p[1]] self.tt = skfmm.travel_time(phi, self.speed, self.dx) for z in self.pedestrian_fmm: self.grid[z[0][0]][z[0][1]].initial_predicted_time = self.fmm_distance[z[0][0]][z[0][1]] / z[1] for i in self.obstacles: self.fmm_distance[i.row][i.col] = sys.maxsize d = np.copy(self.fmm_distance) t = np.copy(self.tt) for j in self.pedestrian: d[j.row, j.col] *= ((wait * (1 + (1 / (d[j.row, j.col]) * 10))) + 1 / d[j.row, j.col]) return self.calc_fmm_path(d, t, p, speed)
def ind2mesh(indicator, h0, bbox, pfix=None, maxt=300, maxit=3000, imax=2048, jmax=2048): border = 5.0*h0 xlength, ylength = bbox[1,0]-bbox[0,0]+2*border, bbox[1,1]-bbox[0,1]+2*border dx = xlength/imax dy = ylength/jmax # Wrap indicator function to allow some space arund the bounding box # and transform to 0,0 lower left corner def ind_wrap(a, b): return indicator(a-bbox[0,0]-border, b-bbox[0,1]-border) # Fill mesh with indicator values ind_mesh = numpy.zeros((imax, jmax)) for i, x in enumerate(numpy.linspace(0.0, dx*imax, imax)): for j, y in enumerate(numpy.linspace(0.0, dy*jmax, jmax)): ind_mesh[i,j] = ind_wrap(x,y) # Compute distance values via fast marching phi_mesh = skfmm.distance(ind_mesh, dx=[dx, dy]) # Wrap bilinear interpolation of phi values def phi(p): return bil_interpolate(p, phi_mesh, dx, dy) # Generate mesh via distmesh2d shift_pfix = pfix + border shift_bbox = bbox + border p, t = distmesh2d(phi, h0, shift_bbox, pfix=shift_pfix, maxt=maxt, maxit=maxit) return p-border, t
def compute_shortest_path(centroid_y, centroid_x, radius, n): l = 20 X, Y = np.meshgrid(np.linspace(-l / 2, l / 2, n), np.linspace(-l / 2, l / 2, n)) phi = np.ones((n, n)) phi[np.logical_and(X == -10, Y == -10)] = 0 mask = np.less_equal( np.sqrt((X - (centroid_y - 10))**2 + (Y - (centroid_y - 10))**2), radius) phi = np.ma.MaskedArray(phi, mask) distance = skfmm.distance(phi) distance = distance.T #compute gradient with Sobel method dx = cv2.Sobel(distance, cv2.CV_64F, 0, 1, ksize=1) dy = cv2.Sobel(distance, cv2.CV_64F, 1, 0, ksize=1) path = gradient_descent(0.001, 1000000, distance, dx, dy, X, Y, [9.9, 9.8]) #plot fig = plt.figure(figsize=(10, 8)) plt.contour(X, Y, phi, [0], linewidths=(3), colors='black') plt.contour(X, Y, phi.mask, [0], linewidths=(3), colors='red') plt.contour(X, Y, distance.T, 100) plt.colorbar() plt.plot(*zip(*path)) return fig
def compute_visibility_for_all(obj, h, w, radius=np.inf): image = obj2img(obj, h, w) image = image * 1.0 / image.max() # rescale to [0,1] dx = 1.0 / h phi = distance( (image - .5) * 2 * dx, dx) # do we need to convert to signed distance function? yes notVis = {} # dictionary containing {position: [non visible positions] } # create a grid for circular mask x = np.linspace(0, w - 1, w) y = np.linspace(0, h - 1, h) x, y = np.meshgrid(x, y) for i in range( 0, h ): # for now we have to skip borders until i have time to modify the edge cases for vis2d for j in range(0, w): if phi[i, j] == 0: continue # ignore positions inside obstacles mask = createCircle([i, j], radius, x, y) psi = vis2d(phi, [i, j]) psi = 1 * (psi > 0) * mask I, J = np.where(psi == 0) # subscripts of obstacles occluded = (I * w + J).tolist() notVis[i * w + j] = set(occluded) return notVis
def prop_edt3(cls, vxhit, pose_raw, cube, caminfo): from scipy.ndimage.morphology import distance_transform_edt step = caminfo.hmap_size scale = int(vxhit.shape[0] / step) vol_shape = (step, step, step) if 1 == scale: vxhit_hmap = vxhit else: vxhit_hmap = np.zeros(vol_shape) for i0 in np.mgrid[0:scale, 0:scale, 0:scale].reshape(3, -1).T: vxhit_hmap += vxhit[i0[0]::scale, i0[1]::scale, i0[2]::scale] # print(np.sum(vxhit_hmap) - np.sum(vxhit)) mask = (1e-4 > vxhit_hmap) masked_edt = np.ma.masked_array(distance_transform_edt(vxhit_hmap), mask) # masked_edt = np.ma.masked_array( # vxhit_hmap, # mask) grid = regu_grid() grid.from_cube(cube, step) indices = grid.putit(pose_raw) vol_l = [] for index in indices: # phi = np.zeros_like(masked_edt) # phi[index[0], index[1], index[2]] = 1. phi = masked_edt.copy() phi[index[0], index[1], index[2]] = 0. df = skfmm.distance(phi, dx=1e-1) df_max = np.max(df) df = (df_max - df) / df_max df[mask] = 0. vol_l.append(df) return np.stack(vol_l, axis=3)
def compute_fmm_distance_and_angle(self, mask_value=1000): """ Compute the fmm distance based on the goal array and mask array. """ # Mask the goal array if self.mask_grid_mn is not None: phi = np.ma.MaskedArray(self.goal_grid_mn, self.mask_grid_mn) # mask the obstacle_occupancy_grid invalid else: phi = self.goal_grid_mn # Compute the fmm distance fmm_distance = skfmm.distance(phi, dx=self.fmm_distance_map.map_scale*np.ones(2)) # Return the signed distance from the *zero contour* of the array phi. # in phi, goal: -1, else 1, obstacle being masked # Assign some distance at the mask if self.mask_grid_mn is not None: fmm_distance = fmm_distance.filled(mask_value) # Return a copy of self, with masked values filled with a given value. # **However**, if there are no masked values to fill, self will be # returned instead as an ndarray. # Here, Mask obstacles to be 1000, and goals to be 1, and elsewhere, sign-distance to goals # Compute the fmm angle gradient_y, gradient_x = np.gradient(fmm_distance, self.fmm_distance_map.map_scale) # Return the gradient of an N-dimensional array fmm_angle = np.arctan2(-gradient_y, -gradient_x) # use arctan(y/x) to compute angle # Assign fmm distance map and angle self.fmm_distance_map.voxel_function_mn = tf.constant(fmm_distance, dtype=tf.float32) # Assign the distance map to fmm_distance_map object, used in compute_voxel_function self.fmm_angle_map.voxel_function_mn = tf.constant(fmm_angle, dtype=tf.float32) # Assign the angle to fmm_angle_map object, used in compute_voxel_function
def distances(self,goal): traversible_ma = ma.masked_values(self.traversible*1, 0) goal_x, goal_y = int(goal[0]),int(goal[1]) if goal_y >= traversible_ma.shape[0] or goal_x >= traversible_ma.shape[1] or goal_y < 0 or goal_x < 0: return np.ones_like(traversible_ma)*np.inf traversible_ma[goal_y, goal_x] = 0 return skfmm.distance(traversible_ma, dx=1)
def get_SDMmap(img): #take l_train as input filled_reverted_l_train = 1 - ndimage.binary_fill_holes(img).astype( int) #[1,1,1,0,0,0,1,1,1] filled_reverted_l_train[filled_reverted_l_train == 0] = -1 dis = skfmm.distance(filled_reverted_l_train, dx=1) return dis, np.absolute(dis)
def compute_fmm_distance_and_angle(self, mask_value=1000): """ Compute the fmm distance based on the goal array and mask array. """ # Mask the goal array # If the mask grid was given, mask the goal grid to flip the 1's and 0's if False: #self.mask_grid_mn is not None: (goal_grid_mn seems to be the best here) phi = np.ma.MaskedArray(self.goal_grid_mn, self.mask_grid_mn) else: phi = self.goal_grid_mn # Compute the fmm distance fmm_distance = skfmm.distance(phi, dx=self.fmm_distance_map.map_scale * np.ones(2)) # Assign some distance at the mask if False: #self.mask_grid_mn is not None: # Dont think I want to do this fmm_distance = fmm_distance.filled(mask_value) # Compute the fmm angle gradient_y, gradient_x = np.gradient(fmm_distance, self.fmm_distance_map.map_scale) fmm_angle = np.arctan2(-gradient_y, -gradient_x) # Assign fmm distance map and angle self.fmm_distance_map.voxel_function_mn = tf.constant(fmm_distance, dtype=tf.float32) self.fmm_angle_map.voxel_function_mn = tf.constant(fmm_angle, dtype=tf.float32)
def compute_desired_velocity(self): """ To compute the geodesic distance to the doors in using \ a fast-marching method. The opposite of the gradient of this distance corresponds to the desired velocity which permits to reach the closest door Returns ------- door_distance : numpy array distance to the closest door desired_velocity_X : numpy array opposite of the gradient of the door distance, x component desired_velocity_Y : numpy array opposite of the gradient of the door distance, y component """ mask_red = (self.image_red == 255) \ *(self.image_green == 0) \ *(self.image_blue == 0) ind_red = sp.where(mask_red) phi = sp.ones(self.image_red.shape) phi[ind_red] = 0 phi = sp.ma.MaskedArray(phi, mask=self.mask) self.door_distance = skfmm.distance(phi, dx=self.pixel_size) tmp_dist = self.door_distance.filled(9999) grad = sp.gradient(tmp_dist, edge_order=2) grad_X = -grad[1] / self.pixel_size grad_Y = -grad[0] / self.pixel_size norm = sp.sqrt(grad_X**2 + grad_Y**2) norm = (norm > 0) * norm + (norm == 0) * 0.001 self.desired_velocity_X = grad_X / norm self.desired_velocity_Y = grad_Y / norm return self.door_distance, self.desired_velocity_X, self.desired_velocity_Y
def fac_samples_rbnsd(facies_ndarray_file, samples_size, fac_nums, norm_thresh, i_dim, j_dim, k_dim): ''' This is the function to calcualte signed distance for monte carlo facies samples, The results are Radial Based Normalization of SD (RBN-SD) ## facies_ndarray_file: the file location of facies samples,facies ndarray format: n_samples x grid_dim ## fac_nums: the 1d array of facies type numbers that is used for the signed distance calculation ## norm_thresh: the starting point of the Radial Based Normalization ## i_dim, j_dim, k_dim: x, y, z dimensions of grid model ''' m_dim = i_dim * j_dim * k_dim fac_rbnsd_all = np.zeros( (samples_size, len(fac_nums) * i_dim * j_dim * k_dim)) for facindex in range(len(fac_nums)): facies_array = np.load(facies_ndarray_file) facies_array[facies_array != fac_nums[facindex]] = -1 facies_array[facies_array == fac_nums[facindex]] = 1 for i in tqdm(range(samples_size)): sdf_val = skfmm.distance(facies_array[i].reshape( k_dim, j_dim, i_dim)) sdf_val[sdf_val<=-norm_thresh] =\ -norm_thresh - sdf_val[sdf_val<=-norm_thresh]/min(sdf_val[sdf_val<=-norm_thresh]) sdf_val[sdf_val>norm_thresh] = \ norm_thresh + sdf_val[sdf_val>=norm_thresh]/max(sdf_val[sdf_val>=norm_thresh]) fac_rbnsd_all[i, m_dim * (facindex):m_dim * (facindex + 1)] = sdf_val.flatten() return fac_rbnsd_all
def compute_distance_fmm(geometry: Geometry, grid: Grid, start, mask, speed=None): """ Compute the distance to start in geometry. :param geometry: Geometry to use :param grid: Grid to use :param start: start cells :param mask: masked cells :param speed: speed field :return: distance to start by ffm """ inside = grid.inside_cells phi = inside - 5 * start phi = np.ma.MaskedArray(phi, mask) if speed is None: distance = skfmm.distance(phi, dx=grid.cellsize) else: distance = skfmm.travel_time(phi, speed, dx=grid.cellsize) return distance
def perform_fast_marching(D,start_points): """ Implementation of the fast marching algorithm in 2Ds using the skfmm library D : 2D weight matrix, must be positive start_points : 2 x n array, start_points[:,i] is the ith starting point """ D_temp = np.copy(D) D_temp[start_points[0,:],start_points[1,:]] = 0 return fmm.distance(D_temp) + 1e-15
def _make_dt(self): ''' Make the distance transform according to the speed type ''' if self._speed: self._dt = self.img.astype(float) # The input image self._dt /= self._dt.max() else: self._dt = skfmm.distance(self._bimg, dx=5e-2) # Boundary DT
def make_skdt(imshape, swc, K, a=6): skimg = make_sk_img(imshape, swc) dm = math.floor(K / 2) dt = skfmm.distance(skimg, dx=1) include_region = dt <= 1.5 * dm zeromask = dt >= dm dt = np.exp(a * (1 - dt / dm)) - 1 dt[zeromask] = 0 return dt, include_region
def findIntersection( self, dw ): lvl0 = 1. - np.sqrt(2.)/self.patch.ppe tol0 = max(self.patch.dX)/2. tol = 0. gd0 = lvl0 - dw.get('gDist', self.dwis[0]) gd1 = lvl0 - dw.get('gDist', self.dwis[1]) sh = gd0.shape phi0 = gd0.reshape(self.patch.Nc) phi1 = gd1.reshape(self.patch.Nc) dist0 = skfmm.distance( phi0, self.patch.dX ) dist1 = skfmm.distance( phi1, self.patch.dX ) gmask = (dist0.reshape(sh)<tol0)*(dist1.reshape(sh)<tol0) gmask = gmask*((dist0.reshape(sh)+dist1.reshape(sh))<=tol) #dd0 = dw.get('gDist', self.dwis[0]) #dd1 = dw.get('gDist', self.dwis[1]) #dd0[:] = dist0.reshape(sh) #dd1[:] = dist0.reshape(sh) + dist1.reshape(sh) self.nodes = np.where( gmask == True )[0]
def updatefig(*args): global P, frame for i in xrange(50): P = update_phi(P) P = skfmm.distance(P) #reinitialization im.set_array(P) # if frame % 50: # save_figure(P) frame = frame + 1 return im,
def split_organ_by_two_vessels(data, lab): """ Input of function is ndarray with 2 labeled vessels and data. Output is segmented organ by vessls using minimum distance criterium. """ l1 = 1 l2 = 2 # dist se tady počítá od nul jenom v jedničkách # dist1 = scipy.ndimage.distance_transform_edt( # lab != l1, # sampling=data['voxelsize_mm'] # ) # dist2 = scipy.ndimage.distance_transform_edt( # lab != l2, # sampling=data['voxelsize_mm'] # ) import skfmm dist1 = skfmm.distance( lab != l1, dx=data['voxelsize_mm'] ) dist2 = skfmm.distance( lab != l2, dx=data['voxelsize_mm'] ) # print 'skfmm' # from PyQt4.QtCore import pyqtRemoveInputHook; pyqtRemoveInputHook() # import ipdb; ipdb.set_trace() # from PyQt4.QtCore import pyqtRemoveInputHook # pyqtRemoveInputHook() # import ipdb; ipdb.set_trace() # BREAKPOINT # segm = (dist1 < dist2) * (data['segmentation'] != data['slab']['none']) segm = (((data['segmentation'] != 0) * (dist1 < dist2)).astype('int8') + (data['segmentation'] != 0).astype('int8')) return segm, dist1, dist2
def test0(): "circular level" N = 1500 X, Y = np.meshgrid(np.linspace(-1,1,N),np.linspace(-1,1,N)) r = 0.5 dx = [2./(N-1),2./(N-1)] phi = (X)**2 + (Y)**2-r**2 phi = np.ones_like(phi) phi[0][0]=-1 t0=time.time() d = distance(phi,dx) t1=time.time() print "benchmark time", t1-t0 return d
def state_to_tsdf(state, trunc_dist, mode='accurate', return_all=False): ''' ''' assert mode in ['accurate', 'projective'] # observe from the left depth = _state_to_pixel_depth(state) if mode == 'accurate': # make mask where visible surface is zero mask = _state_to_visibility_mask(state, depth) # fill to make a SDF sdf = skfmm.distance(mask) for i in range(state.shape[0]): if depth[i] == np.inf: sdf[i,:] = np.inf # make region behind surface negative for i in range(state.shape[0]): d = depth[i] if d != np.inf: sdf[i,d+1:] *= -1 # sdf[i,d+1+trunc_dist:] = -trunc_dist elif mode == 'projective': # projective point-to-point metric # fill in sdf by marching away from surface sdf = np.zeros_like(state, dtype=float) for i in range(state.shape[0]): d = depth[i] if d == np.inf: sdf[i,:] = np.inf else: for j in range(state.shape[1]): sdf[i,j] = d - j else: raise NotImplementedError tsdf = np.clip(sdf, -trunc_dist, trunc_dist) if return_all: return tsdf, sdf, depth return tsdf
def get_sdf(img): """ given an image (m,n,3) it returns the signed distance field. """ def flood_fill(mask): """ All entries inside the boundary are +1, outside -1. Starts filling from (0,0) [assumes (0,0) is outside. - Mask is a matrix of 0s and 1s. - Boundary is specified with 1s. Background with 0s. """ def in_range(x,y): nx,ny = mask.shape return (0 <= x < nx) and (0 <= y < ny) seg = np.ones_like(mask, dtype='float64') processed = np.zeros_like(mask, dtype='bool') queue = [(0,0)] while len(queue) != 0: cx,cy = queue.pop() processed[cx,cy] = True ## check if in the background: if mask[cx,cy]==0: seg[cx,cy] = -1 ## add neighbors: for dx,dy in [(-1,0), (1,0), (0,-1), (0,1)]: mx,my = cx+dx, cy+dy if in_range(mx,my) and not processed[mx,my]: queue.append([mx,my]) return seg mask = ((img[:,:,0] != 255) | (img[:,:,1] != 255) | (img[:,:,2] != 255)).astype('float64') seg_mask = flood_fill(mask) sdf = skfmm.distance(seg_mask) return sdf
def detect(self, bimg, simple=False, silent=False): """ Automatic detection of soma volume unless the iterations are given. """ # Smooth iterations smoothing = 1 # A float number controls the weight of internal energy lambda1 = 1 # A float number controls the weight of external energy lambda2 = 1.5 # Manually set the number of iterations required for the soma # The type of iterations is int iterations = -1 bimg = bimg.astype('int') # Segment dt = skfmm.distance(bimg, dx=1.1) # Boundary DT # somaradius : the approximate value of # soma radius estimated from distance transform # the type of somaradius is float64 # somaradius is just a float number somaradius = dt.max() # somapos : the coordinate of estimated soma centroid # the type of somapos is int64 # the shape of somapos is (3,) # somapos is array-like somapos = np.asarray(np.unravel_index(dt.argmax(), dt.shape)) # Soma detection is required if not simple: if not silent: print('Reconstructing Soma with SRET') ratioxz = bimg.shape[0] / bimg.shape[2] ratioyz = bimg.shape[1] / bimg.shape[2] sqrval = (somaradius**0.5 * max(ratioxz, ratioyz)) sqrval = np.floor(min(max(sqrval, 3), (somaradius**0.5) * 6)) startpt = somapos - 3 * sqrval endpt = somapos + 3 * sqrval # # To constrain the soma growth region inside the cubic region # # Python index start from 0 startpt[0] = min(max(0, startpt[0]), bimg.shape[0] - 1) startpt[1] = min(max(0, startpt[1]), bimg.shape[1] - 1) startpt[2] = min(max(0, startpt[2]), bimg.shape[2] - 1) endpt[0] = min(max(0, endpt[0]), bimg.shape[0] - 1) endpt[1] = min(max(0, endpt[1]), bimg.shape[1] - 1) endpt[2] = min(max(0, endpt[2]), bimg.shape[2] - 1) startpt = startpt.astype(int) # Convert type to int for indexing endpt = endpt.astype(int) # # Extract soma region for fast soma detection somaimg = bimg[startpt[0]:endpt[0], startpt[1]:endpt[1], startpt[2]: endpt[2]] centerpt = np.zeros(3) centerpt[0] = somaimg.shape[0] / 2 centerpt[1] = somaimg.shape[1] / 2 centerpt[2] = somaimg.shape[2] / 2 centerpt = np.floor(centerpt) # Morphological ACWE. Initialization of the level-set. macwe = MorphACWE(somaimg, startpt, endpt, smoothing, lambda1, lambda2) macwe.levelset = circle_levelset(somaimg.shape, np.floor(centerpt), sqrval) # -1 means the automatic detection # Positive integers means the number of iterations if iterations == -1: macwe.autoconvg() # automatic soma detection else: # Input the iteration number manually for i in range(iterations): macwe.step() # The following achieves the automatic somtic box extension # The maximum somatic region extension iteration # It is set to 10 avoid infinite loops for i in range(1, 11): # if not silent: # print('The somatic region extension iteration is', i) if macwe.enlrspt is None: break # Copy the values to new variables for the safe purpose startpt = macwe.enlrspt.copy() endpt = macwe.enlrept.copy() startpt[0] = min(max(0, startpt[0]), bimg.shape[0]) startpt[1] = min(max(0, startpt[1]), bimg.shape[1]) startpt[2] = min(max(0, startpt[2]), bimg.shape[2]) endpt[0] = min(max(0, endpt[0]), bimg.shape[0]) endpt[1] = min(max(0, endpt[1]), bimg.shape[1]) endpt[2] = min(max(0, endpt[2]), bimg.shape[2]) somaimg = bimg[startpt[0]:endpt[0], startpt[1]:endpt[1], startpt[2]: endpt[2]] full_soma_mask = np.zeros((bimg.shape[0], bimg.shape[1], bimg.shape[2])) # Put the detected somas into the whole image # It is either true or false full_soma_mask[macwe.startpoint[0]:macwe.endpoint[ 0], macwe.startpoint[1]:macwe.endpoint[1], macwe.startpoint[2]: macwe.endpoint[2]] = macwe._u # The newlevelset is the initial soma volume from previous iteration #(the automatic converge operation) newlevelset = full_soma_mask[startpt[0]:endpt[0], startpt[1]:endpt[1], startpt[2]:endpt[2]] # The previous macwe class is released # To avoid the conflicts with the new initialisation of the macwe class del macwe # Initialisation for the new class macwe = MorphACWE(somaimg, startpt, endpt, smoothing, lambda1, lambda2) del somaimg, full_soma_mask, startpt, endpt # Reuse the soma volume from previous iteration macwe.set_levelset(newlevelset) # Release memory to avoid conflicts with previous newlevelset del newlevelset macwe.autoconvg() # The automatic smoothing operation to remove the interferes with dendrites macwe.autosmooth() # Initialise soma mask image full_soma_mask = np.zeros((bimg.shape[0], bimg.shape[1], bimg.shape[2])) # There are two possible scenarios # The first scenrio is that the automatic box extension is not necessary if macwe.enlrspt is None: startpt = macwe.startpoint.copy() endpt = macwe.endpoint.copy() # The second scenrio is that the automatic box extension operations has been performed else: startpt = macwe.enlrspt.copy() endpt = macwe.enlrept.copy() startpt[0] = min(max(0, startpt[0]), bimg.shape[0]) startpt[1] = min(max(0, startpt[1]), bimg.shape[1]) startpt[2] = min(max(0, startpt[2]), bimg.shape[2]) endpt[0] = min(max(0, endpt[0]), bimg.shape[0]) endpt[1] = min(max(0, endpt[1]), bimg.shape[1]) endpt[2] = min(max(0, endpt[2]), bimg.shape[2]) # The soma mask image contains only two possible values # Each element is either 0 or 40 # Value 40 is assigned for the visualisation purpose. full_soma_mask[startpt[0]:endpt[0], startpt[1]:endpt[1], startpt[2]:endpt[ 2]] = macwe._u > 0 # Calculate the new centroid using the soma volume newsomapos = center_of_mass(full_soma_mask) # Round the float coordinates into integers newsomapos = [math.floor(p) for p in newsomapos] self.centroid = newsomapos self.radius = somaradius self.mask = full_soma_mask else: if not silent: print('Reconstructing Soma with Simple Mask') self.centroid = somapos self.radius = somaradius self.simple_mask(bimg)
def process_data(self, input_id, input_data, output_data): """Process one inference and return data to visualize.""" # assume the only output is a CHW image where C is the number # of classes, H and W are the height and width of the image class_data = output_data[output_data.keys()[0]].astype('float32') # Is this binary segmentation? is_binary = class_data.shape[0] == 2 # retain only the top class for each pixel class_data = np.argmax(class_data, axis=0).astype('uint8') # remember the classes we found found_classes = np.unique(class_data) # convert using color map (assume 8-bit output) if self.map: fill_data = (self.map.to_rgba(class_data) * 255).astype('uint8') else: fill_data = np.ndarray((class_data.shape[0], class_data.shape[1], 4), dtype='uint8') for x in xrange(3): fill_data[:, :, x] = class_data.copy() # Assuming that class 0 is the background mask = np.greater(class_data, 0) fill_data[:, :, 3] = mask * 255 line_data = fill_data.copy() seg_data = fill_data.copy() # Black mask of non-segmented pixels mask_data = np.zeros(fill_data.shape, dtype='uint8') mask_data[:, :, 3] = (1 - mask) * 255 def normalize(array): mn = array.min() mx = array.max() return (array - mn) * 255 / (mx - mn) if (mx - mn) > 0 else array * 255 try: PIL.Image.fromarray(input_data) except TypeError: # If input_data can not be converted to an image, # normalize and convert to uint8 input_data = normalize(input_data).astype('uint8') # Generate outlines around segmented classes if len(found_classes) > 1: # Assuming that class 0 is the background. line_mask = np.zeros(class_data.shape, dtype=bool) max_distance = np.zeros(class_data.shape, dtype=float) + 1 for c in (x for x in found_classes if x != 0): c_mask = np.equal(class_data, c) # Find the signed distance from the zero contour distance = skfmm.distance(c_mask.astype('float32') - 0.5) # Accumulate the mask for all classes line_width = 3 line_mask |= c_mask & np.less(distance, line_width) max_distance = np.maximum(max_distance, distance + 128) line_data[:, :, 3] = line_mask * 255 max_distance = np.maximum(max_distance, np.zeros(max_distance.shape, dtype=float)) max_distance = np.minimum(max_distance, np.zeros(max_distance.shape, dtype=float) + 255) seg_data[:, :, 3] = max_distance # Input image with outlines input_max = input_data.max() input_min = input_data.min() input_range = input_max - input_min if input_range > 255: input_data = (input_data - input_min) * 255.0 / input_range elif input_min < 0: input_data -= input_min input_image = PIL.Image.fromarray(input_data.astype('uint8')) input_image.format = 'png' # Fill image fill_image = PIL.Image.fromarray(fill_data) fill_image.format = 'png' # Fill image line_image = PIL.Image.fromarray(line_data) line_image.format = 'png' # Seg image seg_image = PIL.Image.fromarray(seg_data) seg_image.format = 'png' seg_image.save('seg.png') # Mask image mask_image = PIL.Image.fromarray(mask_data) mask_image.format = 'png' # legend for this instance legend = self.get_legend_for(found_classes, skip_classes=[0]) return { 'input_id': input_id, 'input_image': input_image, 'fill_image': fill_image, 'line_image': line_image, 'seg_image': seg_image, 'mask_image': mask_image, 'legend': legend, 'is_binary': is_binary, 'class_data': class_data, }
def plan_path(start_position, goal_position, image): image = cv2.resize(image, (250, 250)) # pyplot.imshow(image) # pyplot.show() # Make an image of ones img_ones = np.ones_like(image[:, :, 2]) # Find the white lines white_lines = image[:, :, 2] > 200 # cv2.imshow("whites", np.uint8(white_lines) * 255) # cv2.waitKey(0) img_ones[white_lines] = 0 gdt_initial = distance(img_ones) # allow leeway when following lines safe_space = distance(img_ones) > 10 img_ones[safe_space] = 0 gdt_safe = distance(img_ones) # pyplot.imshow(gdt_safe, interpolation = 'nearest') # pyplot.show() target_contour = np.ones_like(image[:, :, 2]) target_contour[goal_position] = 0 masked_array = np.ma.MaskedArray(target_contour, safe_space) gdt_final = distance(masked_array) pyplot.imshow(gdt_final, interpolation = 'nearest') #pyplot.show() current = np.array(start_position) path = [] prev_cost = np.inf best_cost = np.inf _next = current while(not np.allclose(_next, np.array(goal_position))): current = _next #if best_cost == prev_cost: # return None # Failed to find path prev_cost = best_cost for x in [-1, 0, 1]: for y in [-1, 0, 1]: xy = np.array([x, y]) try: summed = current + xy cost = gdt_final[summed[0], summed[1]] except(IndexError): continue if cost < best_cost: best_cost = cost _next = current + xy path.append((_next[1], _next[0])) cv2.line(image, (_next[1], _next[0]), (current[1], current[0]), (0, 255, 0), 2) pyplot.imshow(image, interpolation = 'nearest') #pyplot.show() return path
from filtering.morphology import ssm from rivuletpy.utils.io import * import matplotlib.pyplot as plt import skfmm ITER = 30 img = loadimg('/home/siqi/ncidata/rivuletpy/tests/data/test-crop.tif') bimg = (img > 0).astype('int') dt = skfmm.distance(bimg, dx=1) sdt = ssm(dt, anisotropic=True, iterations=ITER) try: from skimage import filters except ImportError: from skimage import filter as filters s_seg = s > filters.threshold_otsu(s) plt.figure() plt.title('DT') plt.imshow(dt.max(-1)) plt.figure() plt.title('img > 0') plt.imshow((img > 0).max(-1)) plt.figure() plt.title('SSM-DT') plt.imshow(sdt.max(-1))
import numpy as np import pylab as plt from skfmm import distance from skimage import io img=io.imread("rect3013.png") data = img[:,:,0].astype(np.double) data = (data-data.max()/2.0)/data.max() dist = distance(data) plt.contour(dist,20, colors="black", linestyles="solid") plt.contour(dist,[0], colors="black", linewidths=3) plt.gca().set_aspect(1) plt.xticks([]) plt.yticks([]) #plt.gca().set_frame_on(False) plt.show()
import numpy as np import pylab as pl import skfmm X, Y = np.meshgrid(np.linspace(-1,1,200), np.linspace(-1,1,200)) phi = -1*np.ones_like(X) phi[X>-0.5] = 1 phi[np.logical_and(np.abs(Y)<0.25, X>-0.75)] = 1 pl.contour(X, Y, phi,[0], linewidths=(3), colors='black') pl.title('Boundary location: the zero contour of phi') pl.savefig('2d_phi.png') pl.show() d = skfmm.distance(phi, dx=1e-2) pl.title('Distance from the boundary') pl.contour(X, Y, phi,[0], linewidths=(3), colors='black') pl.contour(X, Y, d, 15) pl.colorbar() pl.savefig('2d_phi_distance.png') pl.show() speed = np.ones_like(X) speed[Y>0] = 1.5 t = skfmm.travel_time(phi, speed, dx=1e-2) pl.title('Travel time from the boundary') pl.contour(X, Y, phi,[0], linewidths=(3), colors='black') pl.contour(X, Y, t, 15) pl.colorbar()
def reintegrate(m): import skfmm d = skfmm.distance(m) d /= abs(d).max() return d
def save_figure(P, number=99): with open(str(number)+'p.pickle', 'w') as f: pickle.dump(skfmm.distance(P), f)
import msfm from rivuletpy.utils.io import * import skfmm import os from matplotlib import pyplot as plt dir_path = os.path.dirname(os.path.realpath(__file__)) img = loadimg(os.path.join(dir_path, 'data/test.tif')) dt = skfmm.distance(img > 0, dx=1) # Boundary DT somaradius = dt.max() somapos = np.asarray(np.unravel_index(dt.argmax(), dt.shape)) print('somapos in python', somapos, somapos.dtype) print('dt[soma pos] in python: %f' % dt[somapos[0], somapos[1], somapos[2]]) print('Running MSFM...') T = msfm.run(dt, somapos, False, True) plt.imshow(np.squeeze(T.min(axis=-1))) plt.show()
import skfmm X, Y = np.meshgrid(np.linspace(-1,1,501), np.linspace(-1,1,501)) phi = (X+0.8)**2+(Y+0.8)**2 - 0.01 speed = 1+X**2+Y**2 plt.subplot(221) plt.title("Zero-contour of phi") plt.contour(X, Y, phi, [0], colors='black', linewidths=(3)) plt.gca().set_aspect(1) plt.xticks([]); plt.yticks([]) plt.subplot(222) plt.title("Distance") plt.contour(X, Y, phi, [0], colors='black', linewidths=(3)) plt.contour(X, Y, skfmm.distance(phi, dx=2.0/500), 15) plt.gca().set_aspect(1) plt.xticks([]); plt.yticks([]) plt.subplot(223) plt.title("Distance with x- \nand y- directions periodic") plt.contour(X, Y, phi, [0], colors='black', linewidths=(3)) plt.contour(X, Y, skfmm.distance(phi, dx=2.0/500, periodic=True), 15) plt.gca().set_aspect(1) plt.xticks([]); plt.yticks([]) plt.subplot(224) plt.title("Travel time with y- \ndirection periodic ") plt.contour(X, Y, phi, [0], colors='black', linewidths=(3)) plt.contour(X, Y, skfmm.travel_time(phi, speed, dx=2.0/500, periodic=(1,0)), 15) plt.gca().set_aspect(1)
import numpy as np import pylab as plt import skfmm X, Y = np.meshgrid(np.linspace(-1,1,201), np.linspace(-1,1,201)) phi = -1*np.ones_like(X) phi[X>-0.5] = 1 phi[np.logical_and(np.abs(Y)<0.25, X>-0.75)] = 1 plt.contour(X, Y, phi,[0], linewidths=(3), colors='black') plt.title('Boundary location: the zero contour of phi') plt.savefig('2d_phi.png') plt.show() d = skfmm.distance(phi, dx=1e-2) plt.title('Distance from the boundary') plt.contour(X, Y, phi,[0], linewidths=(3), colors='black') plt.contour(X, Y, d, 15) plt.colorbar() plt.savefig('2d_phi_distance.png') plt.show() speed = np.ones_like(X) speed[Y>0] = 1.5 t = skfmm.travel_time(phi, speed, dx=1e-2) plt.title('Travel time from the boundary') plt.contour(X, Y, phi,[0], linewidths=(3), colors='black') plt.contour(X, Y, t, 15) plt.colorbar() plt.savefig('2d_phi_travel_time.png')
def evolve_contour(lv, roi, deltaT=0.1, alpha1=1, alpha2=1, alpha3=0.1, eps=1 / np.pi, eta=1e-5, n_reinit=10, n_max = 100): """ evolve_contour performs an active contour algorithm on a level set curve, specifically on the zero level of a signed distance function. The zero-level is represented by discrete points on a grid. Each point is evolved in the direction where some energy function decreases most :param lv: 64 x 64 binary array predicted :param roi: 64 x 64 region of interest (gray scale) actual image :param deltaT: the step size in time :param alpha1, alpha2, alpha3: parameters for energy components :param eps: parameter for the function approximating the delta_0 function :return: evolved level set function """ try: # error handling: inputs must be 64 x 64 # if np.shape(lv) != (64, 64) | np.shape(roi)!= (64, 64): # raise TypeError("lv and roi must be 64 x 64") if np.unique(lv).size > 2: raise TypeError("lv must be binary") # Initialize phi as a signed distance function which looks like a ice cream cone. It # computes for each point in the 64 x 64 region of interest its distance to # the closest contour point in the binary image LV. phi = copy.deepcopy(lv) phi[phi == 1] = -1 phi[phi == 0] = 1 phi = 10 * skfmm.distance(phi) # now phi is a signed distance function which is negative inside the contour and # positive outside # we will store the initialization of phi again in an extra variable because # we have to recall it in every evolution step phi0 = copy.deepcopy(phi) # START ENERGY OPTIMIZATION convergence = False cIter = 1 # create imshow object. in each iteration update that figure while not convergence: # 1. compute all finite differences # this will be done by the divergence function, so forget about this step # if cIter == 521: # pdb.set_trace() # 2. compute averages inside and outside contour # 2a. average outside c1 = np.sum(roi * heavyside(phi)) / (phi[phi >= 0].size + 0.00000001) c2 = np.sum(roi * heavyside(-phi)) / (phi[phi < 0].size + 0.00000001) """ # 2. compute averages inside and outside contour # 2a. determine which pixels are inside the contour and which are outside # a pixel at (i,j) is inside the contour if phi(i,j) < 0 # Create a mask which is True if phi<=0 and False else phi_mask = copy.deepcopy(-phi) # now phi is 1 inside contour and -1 outside phi_mask[phi_mask < 0] = 0 # now phi is 1 inside contour and 0 outside phi_mask = np.ma.make_mask(phi_mask) # create mask # 2b. Compute average roi pixel value inside the contour (i.e. where phi <= 0) # Wherever mask == True -> apply_mask_to_roi = 1, wherever mask == False -> apply_mask_to_roi = 0 avg_roi_inside = np.mean(roi[phi_mask]) avg_roi_outside = np.mean(roi[-phi_mask]) c1 = avg_roi_outside c2 = avg_roi_inside """ # pdb.set_trace() # 3. Compute divergence old_phi = copy.deepcopy(phi) div = get_div(phi) # 4. Evolve contour # pdb.set_trace() #force = delta_eps(phi, eps) * (alpha1 * div + (alpha2 * np.power(roi - c2, 2)) # - (alpha2 * np.power(roi - c1, 2)) # - (2 * alpha3 * (phi - phi0))) # pdb.set_trace() force = alpha1 * div + alpha2 * np.power(roi - c2, 2) - alpha2 * np.power(roi - c1, 2) - 2 * alpha3 * (phi - phi0) phi += deltaT * force # 6. stop if phi has converged or maximum number of iterations has been reached if (np.linalg.norm(phi - old_phi, 'fro') < eta) | (cIter == n_max): convergence = True #print("converged") # Draw final level set function contour = copy.deepcopy(phi) contour[contour >= 0] = 0 contour[contour < 0] = 1 elif cIter % n_reinit == 0: # Check if we have to reinitialize phi # reinitialize by figuring out where phi is neg. and where pos -> define intermediate contour as points # where phi is non-positive and reinitialize as signed distance mapping phiSmallerZero = phi <= 0 # is an array of bools with True where phi>=0 and False else intermediate_contour = phiSmallerZero.astype(int) # is a binary array that has 1 where phi<=0 and # and 0 else intermediate_contour[intermediate_contour == 1] = -1 # skfmm.distance wants the inner part of the contour # to be -1... intermediate_contour[intermediate_contour == 0] = 1 # ...and the outer part +1 phi = skfmm.distance(intermediate_contour) # reinitialize phi as signed distance function cIter += 1 #print(cIter) else: cIter += 1 #print("cIter", cIter) # draw contour: update the pixels and then draw the figure # pdb.set_trace() if cIter % n_max == 0: contour = copy.deepcopy(phi) contour[contour > 0] = 0 contour[contour < 0] = 1 contour = contour + roi return contour except: print "Returning LV as evolution failed." return lv
centroids = remove_some(centroids) centroids = np.array(centroids).flatten() centroids = centroids.reshape(len(centroids)/2,2) cx,cy = np.transpose(centroids) plt.imshow(slice2) plt.scatter(x=cx, y=cy, c='g', s=14) plt.show() fmm = np.ones((1024,1024)) for i in xrange(len(centroids)): x1 = int(centroids[i][0]) y1 = int(centroids[i][1]) fmm[y1][x1] = -1 dist_mat = skfmm.distance(fmm) plt.imshow(dist_mat) plt.show() speed = 1 - np.copy(slice2) + 0.1 print np.amax(slice2) print np.amin(slice2) print np.amax(speed) print np.amin(speed) t = skfmm.travel_time(fmm, speed) print np.shape(t) plt.imshow(t) plt.show() plt.plot(t[100]) plt.show() plt.contour(np.flipud(t), 55) plt.colorbar()
def buildmap(image, mapname, settingsfile, visualise): with open(settingsfile, 'r') as f: settings = json.load(f) # Read in map print("Reading and processing map image '{0}'...".format(image)) mapim = imread(image) if mapim.ndim < 3: print("The bitmaps need to be 3 layers!") sys.exit(1) if mapim.shape[2] > 3: mapim = mapim[:, :, 0:3] # ignore alpha # Pad with border pwidth = settings['mapbuilder']['padPixels'] mapim = np.pad(mapim, ((pwidth, pwidth), (pwidth, pwidth), (0, 0)), 'constant', constant_values=0) w, h, d = mapim.shape # Find start (full green pixels) startim = np.logical_and(mapim[:, :, 0] != 255, mapim[:, :, 1] == 255, mapim[:, :, 2] != 255) # Find end (full red pixels) endim = np.logical_and(mapim[:, :, 0] == 255, mapim[:, :, 1] != 255, mapim[:, :, 2] != 255) # Make occupancy grid (black pixels) occmap = np.logical_and(mapim[:, :, 0] == 0, mapim[:, :, 1] == 0, mapim[:, :, 2] == 0) # Calculate distance to walls print("Calculating distance to walls...") distintowall = skfmm.distance(~occmap) distouttowall = skfmm.distance(occmap) distmap = distintowall - distouttowall # Calculate start->end potential field print("Calculating flow field to end...") distfromend = skfmm.distance(np.ma.MaskedArray(~endim, occmap)) dfyi, dfxi = np.gradient(-distfromend) dfyo, dfxo = np.gradient(np.ma.MaskedArray(-distouttowall, ~occmap)) dfy, dfx = norm_layer(combine_layers(dfyi, dfyo), combine_layers(dfxi, dfxo)) distfromend = distfromend.filled(0) + distouttowall # Calculate wall normals print("Calculating wall normals...") blurmap = gaussian_filter((~occmap).astype(float), sigma=settings['mapbuilder']['normalBlur']) dny, dnx = norm_layer(*np.gradient(blurmap)) # plotting if visualise: print("Making plots...") skip = (slice(None, None, 20), slice(None, None, 20)) y, x = np.mgrid[0:w, 0:h] fig = pl.figure() fig.add_subplot(231) pl.imshow(occmap, cmap=pl.cm.gray, interpolation='none') pl.title('Occupancy map') fig.add_subplot(232) pl.imshow(startim, cmap=pl.cm.gray, interpolation='none') pl.title('Start point') fig.add_subplot(233) pl.imshow(endim, cmap=pl.cm.gray, interpolation='none') pl.title('End point') fig.add_subplot(234) pl.quiver(x[skip], y[skip], dnx[skip], dny[skip], color='r', angles='xy') pl.gca().invert_yaxis() pl.imshow(distmap, interpolation='none', cmap=pl.cm.gray) pl.title('Distance to walls, wall normals') fig.add_subplot(235) pl.quiver(x[skip], y[skip], dfx[skip], dfy[skip], color='r', angles='xy') pl.gca().invert_yaxis() pl.imshow(distfromend, interpolation='none', cmap=pl.cm.gray) pl.title('Distance to end, flow to end') fig.add_subplot(236) pl.imshow(mapim, interpolation='none') pl.title('Original map image') # pl.figure() # skip = (slice(None, None, 1), slice(None, None, 1)) # pl.quiver(x[skip], y[skip], dfx[skip], dfy[skip], color='r', # angles='xy') # pl.gca().invert_yaxis() # pl.imshow(distfromend, interpolation='none', cmap=pl.cm.gray) # pl.title('Distance to end, flow to end') pl.show() # Process output names print("Saving results...") mapnamebits = image.partition('.') mapname = mapnamebits[0] if mapname is None else mapname.partition[0] # Save padded map print('\t- padded image') imsave(mapname+'_padded.'+mapnamebits[2], mapim) # Binary layers for engine print('\t- binary layers') save_bool_map(mapname+'_start', startim) save_bool_map(mapname+'_end', endim) save_bool_map(mapname+'_occupancy', occmap) save_float32_map(mapname+'_walldist', distmap) save_float32_map(mapname+'_enddist', distfromend) save_float32_map(mapname+'_wnormx', dnx) save_float32_map(mapname+'_wnormy', dny, vec=True) save_float32_map(mapname+'_flowx', dfx) save_float32_map(mapname+'_flowy', dfy, vec=True) # Easy to read formats for players print('\t- csv layers') save_text_bool_map(mapname+'_start', startim) save_text_bool_map(mapname+'_end', endim) save_text_bool_map(mapname+'_occupancy', occmap) save_text_float32_map(mapname+'_enddist', distfromend) save_text_float32_map(mapname+'_flowx', dfx) save_text_float32_map(mapname+'_flowy', dfy, vec=True) print("Done!")
def smooth_to_sdf(phi): import skfmm return skfmm.distance(phi)
def process_data(self, input_id, input_data, output_data): """ Process one inference and return data to visualize """ # assume the only output is a CHW image where C is the number # of classes, H and W are the height and width of the image class_data = output_data[output_data.keys()[0]].astype("float32") # retain only the top class for each pixel class_data = np.argmax(class_data, axis=0).astype("uint8") # remember the classes we found found_classes = np.unique(class_data) # convert using color map (assume 8-bit output) if self.map: fill_data = (self.map.to_rgba(class_data) * 255).astype("uint8") else: fill_data = np.ndarray((class_data.shape[0], class_data.shape[1], 4), dtype="uint8") for x in xrange(3): fill_data[:, :, x] = class_data.copy() # Assuming that class 0 is the background mask = np.greater(class_data, 0) fill_data[:, :, 3] = mask * 255 # Black mask of non-segmented pixels mask_data = np.zeros(fill_data.shape, dtype="uint8") mask_data[:, :, 3] = (1 - mask) * 255 # Generate outlines around segmented classes if len(found_classes) > 1: # Assuming that class 0 is the background. line_mask = np.zeros(class_data.shape, dtype=bool) for c in (x for x in found_classes if x != 0): c_mask = np.equal(class_data, c) # Find the signed distance from the zero contour distance = skfmm.distance(c_mask.astype("float32") - 0.5) # Accumulate the mask for all classes line_width = 3 line_mask |= c_mask & np.less(distance, line_width) # add the outlines to the input image for x in xrange(3): input_data[:, :, x] = input_data[:, :, x] * (1 - line_mask) + fill_data[:, :, x] * line_mask # Input image with outlines input_max = input_data.max() input_min = input_data.min() input_range = input_max - input_min if input_range > 255: input_data = (input_data - input_min) * 255.0 / input_range elif input_min < 0: input_data -= input_min input_image = PIL.Image.fromarray(input_data.astype("uint8")) input_image.format = "png" # Fill image fill_image = PIL.Image.fromarray(fill_data) fill_image.format = "png" # Mask image mask_image = PIL.Image.fromarray(mask_data) mask_image.format = "png" # legend for this instance legend = self.get_legend_for(found_classes, skip_classes=[0]) return { "input_id": input_id, "input_image": input_image, "fill_image": fill_image, "mask_image": mask_image, "legend": legend, "class_data": class_data, }
# data = scipy.ndimage.interpolation.zoom(data, zoom) ##data = 1/(data + data.min() + 0.001) # data *= 10 # data[-1,:] = -1 data = scipy.ndimage.imread("imagem.jpg", True) plt.imshow(data, interpolation="bilinear", cmap="gray") # marker = [47*zoom,20*zoom] # plt.plot(marker[1], marker[0], 'or') # phi = numpy.ones_like(data) # phi[-1,data.shape[1]/4:3*data.shape[1]/4] = -1 # mapa = skfmm.travel_time(phi, data*50) # print mapa # plt.imshow(mapa, interpolation='nearest', cmap='flag') plt.figure() mapa = skfmm.distance(data) # mapa = skfmm.travel_time(mapa[mapa==mapa.max()], mapa) plt.imshow(mapa, interpolation="nearest", cmap="gray") # path = runalongshortestpath(energymap, marker) # plt.plot(path[:,1], path[:,0], '-', lw=1, ms=2, mew=0, color='yellow') plt.show()
import numpy as np import pylab as plt from skfmm import distance N=1001 x, dx = np.linspace(0, 1, N, retstep=True) X, Y = np.meshgrid(x, x) phi = np.ones_like(X) phi[Y==0] = 0 mask = np.zeros_like(phi, dtype=bool) mask[np.logical_and(X>0.5, Y==0.5)] = True phi = np.ma.MaskedArray(phi,mask) d = distance(phi,dx=dx) #plt.contourf(X,Y,d) #plt.colorbar() #plt.show() exact = np.where(np.logical_not(np.logical_and(Y>0.5, X>0.5)), Y, 0.5+np.sqrt((X-0.5)**2+(Y-0.5)**2)) exact = np.ma.MaskedArray(exact,mask) #plt.matshow(d) #plt.show() #plt.matshow(exact) #plt.show() #plt.matshow(d-exact) #plt.show()