Esempio n. 1
0
    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]
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
 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
Esempio n. 5
0
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
Esempio n. 6
0
    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)
Esempio n. 8
0
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
Esempio n. 9
0
    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)
Esempio n. 10
0
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]