Ejemplo n.º 1
0
    def __rasterize(self, points, data_roi, voxel_size, dtype, settings, mask_array=None):
        '''Rasterize 'points' into an array with the given 'voxel_size'''

        mask = mask_array.data if mask_array is not None else None

        logger.debug("Rasterizing points in %s", points.spec.roi)

        # prepare output array
        rasterized_points = np.zeros(data_roi.get_shape(), dtype=dtype)

        # Fast rasterization currently only implemented for mode ball without
        # inner radius set
        use_fast_rasterization = (
            settings.mode == 'ball' and
            settings.inner_radius_fraction is None
        )

        if use_fast_rasterization:

            dims = len(rasterized_points.shape)

            # get structuring element for mode ball
            ball_kernel = create_ball_kernel(settings.radius, voxel_size)
            radius_voxel = Coordinate(np.array(ball_kernel.shape)/2)
            data_roi_base = Roi(
                    offset=Coordinate((0,)*dims),
                    shape=Coordinate(rasterized_points.shape))
            kernel_roi_base = Roi(
                    offset=Coordinate((0,)*dims),
                    shape=Coordinate(ball_kernel.shape))

        # Rasterize volume either with single voxel or with defined struct elememt
        for point in points.data.values():

            # get the voxel coordinate, 'Coordinate' ensures integer
            v = Coordinate(point.location/voxel_size)

            # get the voxel coordinate relative to output array start
            v -= data_roi.get_begin()

            # skip points outside of mask
            if mask is not None and not mask[v]:
                continue

            logger.debug(
                "Rasterizing point %s at %s",
                point.location,
                point.location/voxel_size - data_roi.get_begin())

            if use_fast_rasterization:

                # Calculate where to crop the kernel mask and the rasterized array
                shifted_kernel = kernel_roi_base.shift(v - radius_voxel)
                shifted_data = data_roi_base.shift(-(v - radius_voxel))
                arr_crop = data_roi_base.intersect(shifted_kernel)
                kernel_crop = kernel_roi_base.intersect(shifted_data)
                arr_crop_ind = arr_crop.get_bounding_box()
                kernel_crop_ind = kernel_crop.get_bounding_box()

                rasterized_points[arr_crop_ind] = np.logical_or(
                    ball_kernel[kernel_crop_ind],
                    rasterized_points[arr_crop_ind])

            else:

                rasterized_points[v] = 1

        # grow points
        if not use_fast_rasterization:

            if settings.mode == 'ball':

                enlarge_binary_map(
                    rasterized_points,
                    settings.radius,
                    voxel_size,
                    1.0 - settings.inner_radius_fraction,
                    in_place=True)

            else:

                sigmas = settings.radius/voxel_size

                gaussian_filter(
                    rasterized_points,
                    sigmas,
                    output=rasterized_points,
                    mode='constant')

                # renormalize to have 1 be the highest value
                max_value = np.max(rasterized_points)
                if max_value > 0:
                    rasterized_points /= max_value

        if mask_array is not None:
            # use more efficient bitwise operation when possible
            if settings.mode == 'ball':
                rasterized_points &= mask
            else:
                rasterized_points *= mask

        return rasterized_points
Ejemplo n.º 2
0
    def __rasterize(self, graph, data_roi, voxel_size, dtype, settings, mask_array=None):
        '''Rasterize 'graph' into an array with the given 'voxel_size'''

        mask = mask_array.data if mask_array is not None else None

        logger.debug("Rasterizing graph in %s", graph.spec.roi)

        # prepare output array
        rasterized_graph = np.zeros(data_roi.get_shape(), dtype=dtype)

        # Fast rasterization currently only implemented for mode ball without
        # inner radius set
        use_fast_rasterization = (
            settings.mode == "ball"
            and settings.inner_radius_fraction is None
            and len(list(graph.edges)) == 0
        )

        if use_fast_rasterization:

            dims = len(rasterized_graph.shape)

            # get structuring element for mode ball
            ball_kernel = create_ball_kernel(settings.radius, voxel_size)
            radius_voxel = Coordinate(np.array(ball_kernel.shape)/2)
            data_roi_base = Roi(
                    offset=Coordinate((0,)*dims),
                    shape=Coordinate(rasterized_graph.shape))
            kernel_roi_base = Roi(
                    offset=Coordinate((0,)*dims),
                    shape=Coordinate(ball_kernel.shape))

        # Rasterize volume either with single voxel or with defined struct elememt
        for node in graph.nodes:

            # get the voxel coordinate, 'Coordinate' ensures integer
            v = Coordinate(node.location/voxel_size)

            # get the voxel coordinate relative to output array start
            v -= data_roi.get_begin()

            # skip graph outside of mask
            if mask is not None and not mask[v]:
                continue

            logger.debug(
                "Rasterizing node %s at %s",
                node.location,
                node.location/voxel_size - data_roi.get_begin())

            if use_fast_rasterization:

                # Calculate where to crop the kernel mask and the rasterized array
                shifted_kernel = kernel_roi_base.shift(v - radius_voxel)
                shifted_data = data_roi_base.shift(-(v - radius_voxel))
                arr_crop = data_roi_base.intersect(shifted_kernel)
                kernel_crop = kernel_roi_base.intersect(shifted_data)
                arr_crop_ind = arr_crop.get_bounding_box()
                kernel_crop_ind = kernel_crop.get_bounding_box()

                rasterized_graph[arr_crop_ind] = np.logical_or(
                    ball_kernel[kernel_crop_ind], rasterized_graph[arr_crop_ind]
                )

            else:

                if settings.color_attr is not None:
                    c = graph.nodes[node].get(settings.color_attr)
                    if c is None:
                        logger.debug(f"Skipping node: {node}")
                        continue
                    elif np.isclose(c, 1) and not np.isclose(settings.fg_value, 1):
                        logger.warning(
                            f"Node {node} is being colored with color {c} according to "
                            f"attribute {settings.color_attr} "
                            f"but color 1 will be replaced with fg_value: {settings.fg_value}"
                            )
                else:
                    c = 1
                rasterized_graph[v] = c
        if settings.edges:
            for e in graph.edges:
                if settings.color_attr is not None:
                    c = graph.edges[e].get(settings.color_attr)
                    if c is None:
                        continue
                    elif np.isclose(c, 1) and not np.isclose(settings.fg_value, 1):
                        logger.warning(
                            f"Edge {e} is being colored with color {c} according to "
                            f"attribute {settings.color_attr} "
                            f"but color 1 will be replaced with fg_value: {settings.fg_value}"
                            )

                u = graph.node(e.u)
                v = graph.node(e.v)
                u_coord = Coordinate(u.location / voxel_size)
                v_coord = Coordinate(v.location / voxel_size)
                line = draw.line_nd(u_coord, v_coord, endpoint=True)
                rasterized_graph[line] = 1

        # grow graph
        if not use_fast_rasterization:

            if settings.mode == "ball":

                enlarge_binary_map(
                    rasterized_graph,
                    settings.radius,
                    voxel_size,
                    settings.inner_radius_fraction,
                    in_place=True)

            else:

                sigmas = settings.radius/voxel_size

                gaussian_filter(
                    rasterized_graph, sigmas, output=rasterized_graph, mode="constant"
                )

                # renormalize to have 1 be the highest value
                max_value = np.max(rasterized_graph)
                if max_value > 0:
                    rasterized_graph /= max_value

        if mask_array is not None:
            # use more efficient bitwise operation when possible
            if settings.mode == "ball":
                rasterized_graph &= mask
            else:
                rasterized_graph *= mask

        return rasterized_graph