def compute_weights(self): ''' Computes all weights of G and of G_tilde and returns them as a tuple (w, w_tilde). ''' self.w = np.zeros([len(self.images), self.num_columns, self.K]) # node weights self.w_tilde = np.zeros_like(self.w) # fill in node weights for t in range(len(self.images)): for i in range(self.num_columns): from_x = int(self.centers[t][0] + self.col_vectors[i, 0] * self.min_radius[0]) from_y = int(self.centers[t][1] + self.col_vectors[i, 1] * self.min_radius[1]) to_x = int(self.centers[t][0] + self.col_vectors[i, 0] * self.max_radius[0]) to_y = int(self.centers[t][1] + self.col_vectors[i, 1] * self.max_radius[1]) coords = bham.bresenhamline(np.array([[from_x, from_y]]), np.array([[to_x, to_y]])) num_pixels = len(coords) for k in range(self.K): start = int(k * float(num_pixels) / self.K) end = max(start + 1, start + num_pixels / self.K) self.w[t, i, k] = -1 * self.compute_weight_at( t, coords[start:end]) for i in range(self.num_columns): self.w_tilde[t, i, 0] = self.w[t, i, 0] for k in range(1, self.K): self.w_tilde[t, i, k] = self.w[t, i, k] - self.w[t, i, k - 1]
def do_wave(BC, wave_origin, t0=0.0): assert (type(wave_origin) is tuple) #will save heartach later ##set speed of sound speed_sound = N * 340 #get dimensionality of space dims = len(wave_origin) #generate the time grid and set it to the initial time time_grid = np.ones_like(BC, dtype=float) * t0 #generate basis with zero around the origin basis = [ np.arange(-wave_origin[i], BC.shape[i] - wave_origin[i]) for i in range(dims) ] #create a mesh m_grid = np.meshgrid(*basis[::-1]) #stack it to another dimension m_grid_ar = np.stack(m_grid) #get disntance dists = np.linalg.norm(m_grid_ar, axis=0) #and use speed of sound to add on time_grid = time_grid + (dists / speed_sound) ##now we worry about what get hit visited = np.zeros_like(BC, dtype=np.bool_) #generate the rays that land in boundary #get coordinates of all the boundary edge_idx = [] edge_idx.append([(0, i) for i in range(BC.shape[1])]) #top edge_idx.append([(i, BC.shape[1]) for i in range(0, BC.shape[1])]) #right edge_idx.append([(BC.shape[0], i) for i in range(BC.shape[1])]) #bottom edge_idx.append([(i, -1) for i in range(BC.shape[1])]) #left edge_idx = [x for y in edge_idx for x in y] #loop through all the points for idx in edge_idx: #simplify the rise over run sp = np.array(wave_origin)[np.newaxis, :] idx = np.array(idx)[np.newaxis, :] #init the move list #it contains the id of the basis vector to take move_list = bresenhamline(sp, idx) move_list = [tuple(move_list[s, :]) for s in range(move_list.shape[0])] for cur_pos in move_list: try: visited[cur_pos] = True except: break if BC[cur_pos]: #hit a boundary!!! break visited[wave_origin] = True return visited, time_grid
def compute_weights(image, center, K, max_radii, col_vectors, inverse_order=False, min_radii=[0, 0, 0]): ''' Computes all weights of G and of G_tilde and returns them as a tuple (w, w_tilde). Parameters: - image the image data (3d numpy array) - center tupel with center coordinates (x, y, z) - K number of nodes along each col_vector - max_radii tupel containing number of pixels in (x, y, z) directions - col_vectors vectors pointing on the unit sphere in all directions to be sampled - inverse_order if true, the computed weights will be sorted such that they go from the outside to the inside of the given image (along same vectors) - min_radii defines the min_radii to start sampling the col_vectors at ''' num_columns = len(col_vectors) w = np.zeros([num_columns, K]) # node weights w_tilde = np.zeros([num_columns, K]) # fill in node weights for i in range(num_columns): from_x = int(center[0] + col_vectors[i, 0] * min_radii[0]) from_y = int(center[1] + col_vectors[i, 1] * min_radii[1]) from_z = int(center[2] + col_vectors[i, 2] * min_radii[2]) to_x = int(center[0] + col_vectors[i, 0] * max_radii[0]) to_y = int(center[1] + col_vectors[i, 1] * max_radii[1]) to_z = int(center[2] + col_vectors[i, 2] * max_radii[2]) coords = bham.bresenhamline(np.array([[from_x, from_y, from_z]]), np.array([[to_x, to_y, to_z]])) num_pixels = len(coords) for k in range(K): start = int(k * float(num_pixels) / K) end = max(start + 1, start + num_pixels / K) w[i, k] = -1 * compute_weight(image, coords[start:end]) if inverse_order: w = w[:, ::-1] for i in range(num_columns): w_tilde[i, 0] = w[i, 0] for k in range(1, K): w_tilde[i, k] = w[i, k] - w[i, k - 1] return w, w_tilde
def get_column_flowvectors(self, oid, frame, column_id): ''' Returns all flowvector for one column of the net surface graph. The length of the returned list of 2-tupel (flow-vectors x,y) corresponds to the number of pixels along the bresenham line from this objects seedpoint and the point the net surface flow found the outline. ''' flow = self.flows[frame] point_c = self.object_seedpoints[oid][frame] point_b = self.netsurfs[oid][frame].get_surface_point(column_id) coords = bham.bresenhamline(np.array([point_c]), np.array([point_b])) vectors = [] for c in coords: fx, fy = flow[c[1], c[0]].T vectors.append((fx, fy)) return vectors
def _process_ray(i, j, xray_img, ct_img3d, board_m, light_pos, light_pos_m): # Calculate the voxels along the line segment connecting the light source with the sensor board pixel px3d_m = board_m.pixel_to_3d_hg([i, j]) # TODO efficiency: intersect with the CT volume before running Bresenham to avoid making redundant calculations voxel_list = bresenhamline(light_pos_m[np.newaxis, :3], px3d_m[:3], max_iter=-1) # (assuming the entire CT volume is between the light source and the board) valid_voxels = np.logical_and(voxel_list >= 0, voxel_list < ct_img3d.shape).all(axis=1) voxel_list = voxel_list[valid_voxels].astype(np.int) # Calculate the distance the ray travels per voxel px3d = board_m.pixel_to_3d_hg([i, j]) ray_direction_m = px3d_m[:3] - light_pos_m[:3] ray_direction = px3d[:3] - light_pos principal_dimension = np.argmax(np.abs(ray_direction_m)) # The distance is 1/cos(angle between the line segment and the principal direction) distance_per_voxel = np.abs(norm(ray_direction) / ray_direction[principal_dimension]) # Sum the voxels along the line segment voxel_values = ct_img3d[tuple(voxel_list.T)] # index into the CT volume xray_img[i, j] = np.sum(voxel_values) * distance_per_voxel
def compute_weights(self, inverse_order=False): ''' Computes all weights of G and of G_tilde and returns them as a tuple (w, w_tilde). ''' assert not self.image is None self.w = np.zeros([self.num_columns, self.K]) # node weights self.w_tilde = np.zeros([self.num_columns, self.K]) # fill in node weights for i in range(self.num_columns): from_x = int(self.center[0] + self.col_vectors[i, 0] * self.min_radii[0]) from_y = int(self.center[1] + self.col_vectors[i, 1] * self.min_radii[1]) from_z = int(self.center[2] + self.col_vectors[i, 2] * self.min_radii[2]) to_x = int(self.center[0] + self.col_vectors[i, 0] * self.max_radii[0]) to_y = int(self.center[1] + self.col_vectors[i, 1] * self.max_radii[1]) to_z = int(self.center[2] + self.col_vectors[i, 2] * self.max_radii[2]) coords = bham.bresenhamline(np.array([[from_x, from_y, from_z]]), np.array([[to_x, to_y, to_z]])) num_pixels = len(coords) for k in range(self.K): start = int(k * float(num_pixels) / self.K) end = max(start + 1, start + num_pixels / self.K) self.w[i, k] = -1 * self.compute_weight_at(coords[start:end]) if inverse_order: self.w = self.w[:, ::-1] for i in range(self.num_columns): self.w_tilde[i, 0] = self.w[i, 0] for k in range(1, self.K): self.w_tilde[i, k] = self.w[i, k] - self.w[i, k - 1]
centers = [ndimage.center_of_mass(labels==i) for i in range(1, num_maxima+1)] radii = [data[center] for center in centers] return np.array(centers), np.array(radii) def rasterize(): pass solid_nodes, solid_edges = map(np.array, load_pdb('CHA')) solid_nodes -= solid_nodes.min(axis=0) solid_nodes *= 4 coord_pair = solid_nodes[solid_edges] discretized = [] for a, b in coord_pair: point_list = bresenham.bresenhamline(np.atleast_2d(a), b, -1).astype(int).tolist() discretized.extend([tuple(point) for point in point_list]) array = np.array(discretized) size = array.max(axis=0) - array.min(axis=0) + 1 canvas = np.ones(size, dtype=bool) offset = array.min(axis=0) for idx, _ in np.ndenumerate(canvas): if idx in discretized: canvas[idx] = 0 # mpl_tools.visualize(canvas) centers, radii = extract_spheres(canvas)
def calcWork(v, w, currentsGrid_u, currentsGrid_v, targetSpeed_mps, geotransform=None, timeIn=0, interval=3600, pixelsize_m=1, distMeas="haversine"): ''' This function calculates the work applied by a vehicle between two points, given rasters with u, v force components v: start point (row, col) in force rasters w: end point (row, col) in force rasters currentsGrid_u: 3D Raster of forces u components. [time index, row, column] = u currentsGrid_v: 3D Raster of forces v components. [time index, row, column] = v ''' elapsed = float(timeIn) (index, rem) = divmod(elapsed, interval) index = min(floor(index), currentsGrid_u.shape[0] - 2) if v != w: # Heading vecs = (w[1] - v[1], w[0] - v[0]) dotprod = vecs[0] * 1 + vecs[1] * 0 maga = pow(vecs[0] * vecs[0] + vecs[1] * vecs[1], 0.5) heading_rad = 0.0 if (maga != 0): costheta = dotprod / maga heading_rad = acos(costheta) # Distance rows = currentsGrid_u.shape[0] if distMeas == "haversine": v_latlon = grid2world(v[0], v[1], geotransform, rows) w_latlon = grid2world(w[0], w[1], geotransform, rows) hdist = haversine.haversine(v_latlon, w_latlon) * 1000 elif distMeas == "euclidean-scaled": hdist = pow( (pow(v[0] - w[0], 2) + pow(v[1] - w[1], 2)), 0.5) * pixelsize_m elif distMeas == "euclidean": hdist = pow((pow(v[0] - w[0], 2) + pow(v[1] - w[1], 2)), 0.5) # Work work = 0 print(v, w) b = list(bresenham.bresenhamline(np.array([v]), np.array([w]))) hdist_ = hdist / len(b) for p in b[:]: xA = targetSpeed_mps * cos(heading_rad) yA = targetSpeed_mps * sin(heading_rad) # Interpolate between nearest time's currents if currentsGrid_u.shape[0] > 1: ua_ = currentsGrid_u[index, p[0], p[1]] * cos( currentsGrid_v[index, p[0], p[1]]) va_ = currentsGrid_u[index, p[0], p[1]] * sin( currentsGrid_v[index, p[0], p[1]]) try: ub_ = currentsGrid_u[index + 1, p[0], p[1]] * cos( currentsGrid_v[index + 1, p[0], p[1]]) vb_ = currentsGrid_u[index + 1, p[0], p[1]] * sin( currentsGrid_v[index + 1, p[0], p[1]]) except: ub_ = currentsGrid_u[index, p[0], p[1]] * cos( currentsGrid_v[index + 1, p[0], p[1]]) vb_ = currentsGrid_u[index, p[0], p[1]] * sin( currentsGrid_v[index + 1, p[0], p[1]]) u_ = ua_ * (1 - (rem / interval)) + ub_ * ((rem / interval)) v_ = va_ * (1 - (rem / interval)) + vb_ * ((rem / interval)) uv_ = np.array([u_, v_]) cmag = np.sqrt(uv_.dot(uv_)) cdir = atan2(v_, u_) # Convert to knots for sanity check #knots = cmag * 1.94384 #print(knots) else: # Static currents -> can't interpolate in time cmag = currentsGrid_u[0, p[0], p[1]] cdir = currentsGrid_v[0, p[0], p[1]] xB = cmag * cos(cdir) yB = cmag * sin(cdir) # Calculate applied force, # given desired and environment forces dV = (xB - xA, yB - yA) magaDV = pow(dV[0] * dV[0] + dV[1] * dV[1], 0.5) dirDV = 0.0 dotprod = dV[0] * 1 + dV[1] * 0 if magaDV != 0: costheta = dotprod / magaDV dirDV = acos(costheta) work += magaDV * hdist_ # Update time elapsed += hdist_ / targetSpeed_mps (index, rem) = divmod(elapsed, interval) index = min(floor(index), currentsGrid_u.shape[0] - 2) else: work = 0 return work, elapsed
return np.array(centers), np.array(radii) def rasterize(): pass solid_nodes, solid_edges = map(np.array, load_pdb('CHA')) solid_nodes -= solid_nodes.min(axis=0) solid_nodes *= 4 coord_pair = solid_nodes[solid_edges] discretized = [] for a, b in coord_pair: point_list = bresenham.bresenhamline(np.atleast_2d(a), b, -1).astype(int).tolist() discretized.extend([tuple(point) for point in point_list]) array = np.array(discretized) size = array.max(axis=0) - array.min(axis=0) + 1 canvas = np.ones(size, dtype=bool) offset = array.min(axis=0) for idx, _ in np.ndenumerate(canvas): if idx in discretized: canvas[idx] = 0 # mpl_tools.visualize(canvas) centers, radii = extract_spheres(canvas)
def calcWork(path, n, regionGrid, targetSpeed_mps=1, currentsGrid_u=None, currentsGrid_v=None, currentsTransform=None, regionTransform=None, rewardGrid=None, timeIn=0, interval=3600, pixelsize_m=1): ''' This function calculates cost to move vehicle along path ''' # Initialize costs: distance, obstacles, work, reward costs = np.zeros(4) # Get all cells along path cells_ = np.array([ bresenham.bresenhamline(np.array([path[i]]), np.array([path[i + 1]])) for i, p in enumerate(path[:-1]) ]) # Number of cells in each path segment lens = np.array([len(c) for c in cells_]) cells = np.vstack(cells_) # Obstacle penalty costs[1] = np.sum((grid[cells[:, 0], cells[:, 1]])) # Reward if rewardGrid is not None: costs[3] = np.sum((rewardGrid[cells[:, 0], cells[:, 1]])) # Points in (lon, lat) lonlat = np.vstack( (regionTransform[1] * path[:, 1] + regionTransform[2] * path[:, 0] + regionTransform[0], regionTransform[4] * path[:, 1] + regionTransform[5] * path[:, 0] + regionTransform[3])).T # Haversine distances, converted from km to meters hdists = haversine_np(lonlat[:-1][:, 0], lonlat[:-1][:, 1], lonlat[1:][:, 0], lonlat[1:][:, 1]) * 1000 # Distance penalty costs[0] = sum(hdists) # If no water currents, return now if currentsGrid_u is None: costs[2] = costs[0] return costs[2], costs[0], costs[1], costs[3] # Calculate headings vecs = np.flip(path[1:] - path[:-1], axis=1) dotprod = vecs[:, 0] maga = np.sqrt(vecs[:, 0] * vecs[:, 0] + vecs[:, 1] * vecs[:, 1]) costheta = vecs[:, 0] / maga # Should check if div by 0? heading_rad = np.arccos(costheta) # Approx distance of each cell hdists_ = hdists / lens # Expand path-length variables to cell-length hdists_e = np.hstack( [np.zeros(c.shape[0]) + hdists_[i] for i, c in enumerate(cells_)]) # Estimate elapsed time to reach each cell ela = [(hdists_e[i] / targetSpeed_mps) * i for i in range(cells.shape[0])] # Vehicle target velocities xA = targetSpeed_mps * np.cos(heading_rad) yA = targetSpeed_mps * np.sin(heading_rad) xA = np.hstack( [np.zeros(c.shape[0]) + xA[i] for i, c in enumerate(cells_)]) yA = np.hstack( [np.zeros(c.shape[0]) + yA[i] for i, c in enumerate(cells_)]) # Calculate indices for accessing water current grids rem_idx = np.divmod(ela, interval) p = np.array(cells[:]).astype("int") idx_1 = np.minimum(rem_idx[0], currentsGrid_u.shape[0] - 2).astype("int") idx_2 = idx_1 + 1 # Interpolate all needed water currents uv_ = np.array( ( (currentsGrid_u[idx_1, p[:, 0], p[:, 1]] * np.cos(currentsGrid_v[idx_1, p[:, 0], p[:, 1]])) \ * (1 - (rem_idx[1] / interval)) + \ (currentsGrid_u[idx_2, p[:, 0], p[:, 1]]) * np.cos((currentsGrid_v[idx_2, p[:, 0], p[:, 1]])) \ * (rem_idx[1] / interval), (currentsGrid_u[idx_1, p[:, 0], p[:, 1]]) * np.sin((currentsGrid_v[idx_1, p[:, 0], p[:, 1]])) \ * (1 - (rem_idx[1] / interval)) + \ (currentsGrid_u[idx_2, p[:, 0], p[:, 1]]) * np.sin((currentsGrid_v[idx_2, p[:, 0], p[:, 1]])) \ * (rem_idx[1] / interval) ) ).T # Calculate applied force required by vehicle to maintain target velocity cmag = np.sqrt(np.sum(uv_ * uv_, axis=1)) cdir = np.arctan2(uv_[:, 1], uv_[:, 0]) xB = cmag * np.cos(cdir) yB = cmag * np.sin(cdir) dV = np.array((xB - xA, yB - yA)).T magaDV = np.power(dV[:, 0] * dV[:, 0] + dV[:, 1] * dV[:, 1], 0.5) dotprod = dV[:, 0] costheta = dotprod / magaDV # Prob need to check for div by 0 ?? dwork = magaDV * hdists_e # Work penalty costs[2] = np.sum(dwork) return costs[2], costs[0], costs[1], costs[3]