예제 #1
0
def test_peak_slicer(interactive=False):

    _peak_dirs = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype='f4')
    # peak_dirs.shape = (1, 1, 1) + peak_dirs.shape

    peak_dirs = np.zeros((11, 11, 11, 3, 3))

    peak_values = np.random.rand(11, 11, 11, 3)

    peak_dirs[:, :, :] = _peak_dirs

    scene = window.Scene()
    peak_actor = actor.peak_slicer(peak_dirs)
    scene.add(peak_actor)
    scene.add(actor.axes((11, 11, 11)))
    if interactive:
        window.show(scene)

    scene.clear()
    scene.add(peak_actor)
    scene.add(actor.axes((11, 11, 11)))
    for k in range(11):
        peak_actor.display_extent(0, 10, 0, 10, k, k)

    for j in range(11):
        peak_actor.display_extent(0, 10, j, j, 0, 10)

    for i in range(11):
        peak_actor.display(i, None, None)

    scene.rm_all()

    peak_actor = actor.peak_slicer(
        peak_dirs,
        peak_values,
        mask=None,
        affine=np.diag([3, 2, 1, 1]),
        colors=None,
        opacity=0.8,
        linewidth=3,
        lod=True,
        lod_points=10 ** 4,
        lod_points_size=3)

    scene.add(peak_actor)
    scene.add(actor.axes((11, 11, 11)))
    if interactive:
        window.show(scene)

    report = window.analyze_scene(scene)
    ex = ['vtkLODActor', 'vtkOpenGLActor']
    npt.assert_equal(report.actors_classnames, ex)

    # 6d data
    data_6d = (255 * np.random.rand(5, 5, 5, 5, 5, 5))
    npt.assert_raises(ValueError, actor.peak_slicer, data_6d, data_6d)
예제 #2
0
def test_peak_slicer(interactive=False):

    _peak_dirs = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype='f4')
    # peak_dirs.shape = (1, 1, 1) + peak_dirs.shape

    peak_dirs = np.zeros((11, 11, 11, 3, 3))

    peak_values = np.random.rand(11, 11, 11, 3)

    peak_dirs[:, :, :] = _peak_dirs

    renderer = window.Renderer()
    peak_actor = actor.peak_slicer(peak_dirs)
    renderer.add(peak_actor)
    renderer.add(actor.axes((11, 11, 11)))
    if interactive:
        window.show(renderer)

    renderer.clear()
    renderer.add(peak_actor)
    renderer.add(actor.axes((11, 11, 11)))
    for k in range(11):
        peak_actor.display_extent(0, 10, 0, 10, k, k)

    for j in range(11):
        peak_actor.display_extent(0, 10, j, j, 0, 10)

    for i in range(11):
        peak_actor.display(i, None, None)

    renderer.rm_all()

    peak_actor = actor.peak_slicer(
        peak_dirs,
        peak_values,
        mask=None,
        affine=np.diag([3, 2, 1, 1]),
        colors=None,
        opacity=1,
        linewidth=3,
        lod=True,
        lod_points=10 ** 4,
        lod_points_size=3)

    renderer.add(peak_actor)
    renderer.add(actor.axes((11, 11, 11)))
    if interactive:
        window.show(renderer)

    report = window.analyze_renderer(renderer)
    ex = ['vtkLODActor', 'vtkOpenGLActor', 'vtkOpenGLActor', 'vtkOpenGLActor']
    npt.assert_equal(report.actors_classnames, ex)
예제 #3
0
def create_peaks_slicer(data,
                        orientation,
                        slice_index,
                        peak_values=None,
                        mask=None,
                        color=None,
                        peaks_width=1.0,
                        symmetric=False):
    """
    Create a peaks slicer actor rendering a slice of the fODF peaks
    """
    # Normalize input data
    norm = np.linalg.norm(data, axis=-1)
    data[norm > 0] /= norm[norm > 0].reshape((-1, 1))

    # Instantiate peaks slicer
    peaks_slicer = actor.peak_slicer(data,
                                     peaks_values=peak_values,
                                     mask=mask,
                                     colors=color,
                                     linewidth=peaks_width,
                                     symmetric=symmetric)
    set_display_extent(peaks_slicer, orientation, data.shape, slice_index)

    return peaks_slicer
예제 #4
0
def create_peaks_slicer(data,
                        orientation,
                        slice_index,
                        peak_values=None,
                        mask=None,
                        color=None,
                        peaks_width=1.0,
                        symmetric=False):
    """
    Create a peaks slicer actor rendering a slice of the fODF peaks

    Parameters
    ----------
    data : np.ndarray
        Peaks data.
    orientation : str
        Name of the axis to visualize. Choices are axial, coronal and sagittal.
    slice_index : int
        Index of the slice to visualize along the chosen orientation.
    peak_values : np.ndarray, optional
        Peaks values. Defaults to None.
    mask : np.ndarray, optional
        Only the data inside the mask will be displayed. Defaults to None.
    color : tuple (3,), optional
        Color used for peaks. If None, a RGB colormap is used. Defaults to
        None.
    peaks_width : float, optional
        Width of peaks segments. Defaults to 1.0.
    symmetric : bool, optional
        If True, peaks are drawn for both peaks_dirs and -peaks_dirs. Else,
        peaks are only drawn for directions given by peaks_dirs. Defaults to
        False.

    Returns
    -------
    slicer_actor : actor.peak_slicer
        Fury object containing the peaks information.
    """
    # Normalize input data
    norm = np.linalg.norm(data, axis=-1)
    data[norm > 0] /= norm[norm > 0].reshape((-1, 1))

    # Instantiate peaks slicer
    peaks_slicer = actor.peak_slicer(data,
                                     peaks_values=peak_values,
                                     mask=mask,
                                     colors=color,
                                     linewidth=peaks_width,
                                     symmetric=symmetric)
    set_display_extent(peaks_slicer, orientation, data.shape, slice_index)

    return peaks_slicer
예제 #5
0
def plot_peak_slice(odf_4d,
                    sphere,
                    background_data,
                    out_file,
                    axis,
                    slicenum,
                    mask_data,
                    tile_size=1200,
                    normalize_peaks=True):
    from fury import actor, window
    view_up = [(0., 0., 1.), (0., 0., 1.), (0., -1., 0.)]

    # Make a slice mask to reduce memory
    new_shape = list(odf_4d.shape)
    new_shape[axis] = 1
    image_shape = new_shape[:3]
    midpoint = (new_shape[0] / 2., new_shape[1] / 2., new_shape[2] / 2.)

    if axis == 0:
        odf_slice = odf_4d[slicenum, :, :, :].reshape(new_shape)
        image_slice = background_data[slicenum, :, :].reshape(image_shape)
        mask_slice = mask_data[slicenum, :, :].reshape(image_shape)
        camera_dist = max(midpoint[1], midpoint[2]) * np.pi
    elif axis == 1:
        odf_slice = odf_4d[:, slicenum, :, :].reshape(new_shape)
        image_slice = background_data[:, slicenum, :].reshape(image_shape)
        mask_slice = mask_data[:, slicenum, :].reshape(image_shape)
        camera_dist = max(midpoint[0], midpoint[2]) * np.pi
    elif axis == 2:
        odf_slice = odf_4d[:, :, slicenum, :].reshape(new_shape)
        image_slice = background_data[:, :, slicenum].reshape(image_shape)
        mask_slice = mask_data[:, :, slicenum].reshape(image_shape)
        camera_dist = max(midpoint[0], midpoint[1]) * np.pi
    position = list(midpoint)
    position[axis] += camera_dist

    # Find the actual peaks
    peak_dirs, peak_values = peaks_from_odfs(odf_slice,
                                             sphere,
                                             relative_peak_threshold=.1,
                                             min_separation_angle=15,
                                             mask=mask_slice,
                                             normalize_peaks=normalize_peaks,
                                             npeaks=3)
    if normalize_peaks:
        peak_values = peak_values / peak_values.max() * np.pi
    peak_actor = actor.peak_slicer(peak_dirs, peak_values, colors=None)
    image_actor = actor.slicer(image_slice,
                               opacity=0.6,
                               interpolation='nearest')
    image_size = (tile_size, tile_size)
    scene = window.Scene()
    scene.add(image_actor)
    scene.add(peak_actor)

    xfov_min, xfov_max = 0, new_shape[0] - 1
    yfov_min, yfov_max = 0, new_shape[1] - 1
    zfov_min, zfov_max = 0, new_shape[2] - 1
    peak_actor.display_extent(xfov_min, xfov_max, yfov_min, yfov_max, zfov_min,
                              zfov_max)
    image_actor.display_extent(xfov_min, xfov_max, yfov_min, yfov_max,
                               zfov_min, zfov_max)
    scene.set_camera(focal_point=tuple(midpoint),
                     position=tuple(position),
                     view_up=view_up[axis])
    window.record(scene,
                  out_path=out_file,
                  reset_camera=False,
                  size=image_size)
    scene.clear()
예제 #6
0
def main():
    parser = _build_arg_parser()
    args = parser.parse_args()
    required = [args.dwi, args.bval, args.bvec, args.target_template]
    assert_inputs_exist(parser, required)

    output_filenames = []
    for axis_name in ['sagittal', 'coronal', 'axial']:
        if args.output_suffix:
            output_filenames.append(os.path.join(args.output_dir,
                                                 '{0}_{1}.png'.format(
                                                     axis_name,
                                                     args.output_suffix)))
        else:
            output_filenames.append(os.path.join(args.output_dir,
                                                 '{0}.png'.format(axis_name)))

    assert_outputs_exist(parser, args, output_filenames)

    if args.output_dir and not os.path.isdir(args.output_dir):
        os.mkdir(args.output_dir)

    # Get the relevant slices from the template
    target_template_img = nib.load(args.target_template)
    zooms = 1 / float(target_template_img.header.get_zooms()[0])

    x_slice = int(target_template_img.shape[0] / 2 + zooms*30)
    y_slice = int(target_template_img.shape[1] / 2)
    z_slice = int(target_template_img.shape[2] / 2)
    slices_choice = (x_slice, y_slice, z_slice)

    FA, evals, evecs = prepare_data_for_actors(args.dwi, args.bval, args.bvec,
                                               args.target_template,
                                               slices_choice,
                                               shells=args.shells)

    # Create actors from each dataset for Dipy
    volume_actor = actor.slicer(FA,
                                affine=nib.load(args.target_template).affine,
                                opacity=0.3,
                                interpolation='nearest')
    peaks_actor = actor.peak_slicer(evecs,
                                    affine=nib.load(
                                        args.target_template).affine,
                                    peaks_values=evals,
                                    colors=None, linewidth=1)

    # Take a snapshot of each dataset, camera setting are fixed for the
    # known template, won't work with another.
    display_slices(volume_actor, slices_choice,
                   output_filenames[0], 'sagittal',
                   view_position=tuple([x for x in (-125, 10, 10)]),
                   focal_point=tuple([x for x in (0, -10, 10)]),
                   peaks_actor=peaks_actor)
    display_slices(volume_actor, slices_choice,
                   output_filenames[1], 'coronal',
                   view_position=tuple([x for x in (0, 150, 30)]),
                   focal_point=tuple([x for x in (0, 0, 30)]),
                   peaks_actor=peaks_actor)
    display_slices(volume_actor, slices_choice,
                   output_filenames[2], 'axial',
                   view_position=tuple([x for x in (0, 25, 150)]),
                   focal_point=tuple([x for x in (0, 25, 0)]),
                   peaks_actor=peaks_actor)
예제 #7
0
def screenshot_fa_peaks(fa, peaks, directory='.'):
    """
    Compute 3 view screenshot with peaks on FA.

    Parameters
    ----------
    fa : string
        FA filename.
    peaks : string
        Peak filename.
    directory : string
        Directory to save the mosaic.

    Returns
    -------
    name : string
        Path of the mosaic
    """
    slice_name = ['sagittal', 'coronal', 'axial']
    data = nib.load(fa).get_data()
    evecs_data = nib.load(peaks).get_data()

    evecs = np.zeros(data.shape + (1, 3))
    evecs[:, :, :, 0, :] = evecs_data[...]

    middle = [data.shape[0] // 2 + 4, data.shape[1] // 2,
              data.shape[2] // 2]

    slice_display = [(middle[0], None, None), (None, middle[1], None),
                     (None, None, middle[2])]

    concat = []
    for j, slice_name in enumerate(slice_name):
        image_name = os.path.basename(str(peaks)).split(".")[0]
        name = os.path.join(directory, image_name + '.png')
        slice_actor = actor.slicer(data, interpolation='nearest', opacity=0.3)
        peak_actor = actor.peak_slicer(evecs, colors=None)

        peak_actor.GetProperty().SetLineWidth(2.5)

        slice_actor.display(slice_display[j][0], slice_display[j][1],
                            slice_display[j][2])
        peak_actor.display(slice_display[j][0], slice_display[j][1],
                           slice_display[j][2])

        renderer = window.ren()

        renderer.add(slice_actor)
        renderer.add(peak_actor)

        center = slice_actor.GetCenter()
        pos = None
        viewup = None
        if slice_name == "sagittal":
            pos = (center[0] - 350, center[1], center[2])
            viewup = (0, 0, -1)
        elif slice_name == "coronal":
            pos = (center[0], center[1] + 350, center[2])
            viewup = (0, 0, -1)
        elif slice_name == "axial":
            pos = (center[0], center[1], center[2] + 350)
            viewup = (0, -1, 1)

        camera = renderer.GetActiveCamera()
        camera.SetViewUp(viewup)

        camera.SetPosition(pos)
        camera.SetFocalPoint(center)

        img = renderer_to_arr(renderer, (1080, 1080))
        if len(concat) == 0:
            concat = img
        else:
            concat = np.hstack((concat, img))

    imgs_comb = Image.fromarray(concat)
    imgs_comb.save(name)

    return name
예제 #8
0
    def render(
        self,
        tractogram: Tractogram = None,
        filename: str = None
    ):
        """ Render the streamlines, either directly or through a file
        Might render from "outside" the environment, like for comet

        Parameters:
        -----------
        tractogram: Tractogram, optional
            Object containing the streamlines and seeds
        path: str, optional
            If set, save the image at the specified location instead
            of displaying directly
        """
        from fury import window, actor
        # Might be rendering from outside the environment
        if tractogram is None:
            tractogram = Tractogram(
                streamlines=self.streamlines[:, :self.length],
                data_per_streamline={
                    'seeds': self.starting_points
                })

        # Reshape peaks for displaying
        X, Y, Z, M = self.peaks.data.shape
        peaks = np.reshape(self.peaks.data, (X, Y, Z, 5, M//5))

        # Setup scene and actors
        scene = window.Scene()

        stream_actor = actor.streamtube(tractogram.streamlines)
        peak_actor = actor.peak_slicer(peaks,
                                       np.ones((X, Y, Z, M)),
                                       colors=(0.2, 0.2, 1.),
                                       opacity=0.5)
        dot_actor = actor.dots(tractogram.data_per_streamline['seeds'],
                               color=(1, 1, 1),
                               opacity=1,
                               dot_size=2.5)
        scene.add(stream_actor)
        scene.add(peak_actor)
        scene.add(dot_actor)
        scene.reset_camera_tight(0.95)

        # Save or display scene
        if filename is not None:
            directory = os.path.dirname(pjoin(self.experiment_path, 'render'))
            if not os.path.exists(directory):
                os.makedirs(directory)
            dest = pjoin(directory, filename)
            window.snapshot(
                scene,
                fname=dest,
                offscreen=True,
                size=(800, 800))
        else:
            showm = window.ShowManager(scene, reset_camera=True)
            showm.initialize()
            showm.start()