예제 #1
0
파일: utils.py 프로젝트: SunTzunami/fury
def numpy_to_vtk_cells(data, is_coords=True):
    """Convert numpy array to a vtk cell array.

    Parameters
    ----------
    data : ndarray
        points coordinate or connectivity array (e.g triangles).
    is_coords : ndarray
        Select the type of array. default: True.

    Returns
    -------
    vtk_cell : vtkCellArray
        connectivity + offset information

    """
    data = np.array(data, dtype=object)
    nb_cells = len(data)

    # Get lines_array in vtk input format
    connectivity = data.flatten() if not is_coords else []
    offset = [0, ]
    current_position = 0

    cell_array = CellArray()

    if VTK_9_PLUS:
        for i in range(nb_cells):
            current_len = len(data[i])
            offset.append(offset[-1] + current_len)

            if is_coords:
                end_position = current_position + current_len
                connectivity += list(range(current_position, end_position))
                current_position = end_position

        connectivity = np.array(connectivity, np.intp)
        offset = np.array(offset, dtype=connectivity.dtype)

        vtk_array_type = numpy_support.get_vtk_array_type(connectivity.dtype)
        cell_array.SetData(
            numpy_support.numpy_to_vtk(offset, deep=True,
                                       array_type=vtk_array_type),
            numpy_support.numpy_to_vtk(connectivity, deep=True,
                                       array_type=vtk_array_type))
    else:
        for i in range(nb_cells):
            current_len = len(data[i])
            end_position = current_position + current_len
            connectivity += [current_len]
            connectivity += list(range(current_position, end_position))
            current_position = end_position

        connectivity = np.array(connectivity)
        cell_array.GetData().DeepCopy(numpy_support.numpy_to_vtk(connectivity))

    cell_array.SetNumberOfCells(nb_cells)
    return cell_array
예제 #2
0
파일: peak.py 프로젝트: guaje/fury
def _points_to_vtk_cells(points, points_per_line=2):
    """

    Returns the VTK cell array for the peaks given the set of points
    coordinates.

    Parameters
    ----------
    points : (N, 3) array or ndarray
        points coordinates array.
    points_per_line : int (1 or 2), optional
        number of points per peak direction.

    Returns
    -------
    cell_array : vtkCellArray
        connectivity + offset information.

    """
    num_pnts = len(points)
    num_cells = num_pnts // points_per_line

    cell_array = CellArray()
    """
    Connectivity is an array that contains the indices of the points that
    need to be connected in the visualization. The indices start from 0.
    """
    connectivity = np.asarray(list(range(0, num_pnts)), dtype=int)
    """
    Offset is an array that contains the indices of the first point of
    each line. The indices start from 0 and given the known geometry of
    this actor the creation of this array requires a 2 points padding
    between indices.
    """
    offset = np.asarray(list(range(0, num_pnts + 1, points_per_line)),
                        dtype=int)

    vtk_array_type = numpy_support.get_vtk_array_type(connectivity.dtype)
    cell_array.SetData(
        numpy_support.numpy_to_vtk(offset,
                                   deep=True,
                                   array_type=vtk_array_type),
        numpy_support.numpy_to_vtk(connectivity,
                                   deep=True,
                                   array_type=vtk_array_type))

    cell_array.SetNumberOfCells(num_cells)
    return cell_array
예제 #3
0
def numpy_to_vtk_image_data(array,
                            spacing=(1.0, 1.0, 1.0),
                            origin=(0.0, 0.0, 0.0),
                            deep=True):
    """Convert numpy array to a vtk image data.

    Parameters
    ----------
    array : ndarray
        pixel coordinate and colors values.
    spacing : (float, float, float) (optional)
        sets the size of voxel (unit of space in each direction x,y,z)
    origin : (float, float, float) (optional)
        sets the origin at the given point
    deep : bool (optional)
        decides the type of copy(ie. deep or shallow)

    Returns
    -------
    vtk_image : vtkImageData

    """
    if array.ndim not in [2, 3]:
        raise IOError("only 2D (L, RGB, RGBA) or 3D image available")

    vtk_image = ImageData()
    depth = 1 if array.ndim == 2 else array.shape[2]

    vtk_image.SetDimensions(array.shape[1], array.shape[0], depth)
    vtk_image.SetExtent(0, array.shape[1] - 1, 0, array.shape[0] - 1, 0, 0)
    vtk_image.SetSpacing(spacing)
    vtk_image.SetOrigin(origin)
    temp_arr = np.flipud(array)
    temp_arr = temp_arr.reshape(array.shape[1] * array.shape[0], depth)
    temp_arr = np.ascontiguousarray(temp_arr, dtype=array.dtype)
    vtk_array_type = numpy_support.get_vtk_array_type(array.dtype)
    uchar_array = numpy_support.numpy_to_vtk(temp_arr,
                                             deep=deep,
                                             array_type=vtk_array_type)
    vtk_image.GetPointData().SetScalars(uchar_array)
    return vtk_image
예제 #4
0
파일: io.py 프로젝트: m-agour/fury
def load_image(filename, as_vtktype=False, use_pillow=True):
    """Load an image.

    Parameters
    ----------
    filename: str
        should be png, bmp, jpeg or jpg files
    as_vtktype: bool, optional
        if True, return vtk output otherwise an ndarray. Default False.
    use_pillow: bool, optional
        Use pillow python library to load the files. Default True

    Returns
    -------
    image: ndarray or vtk output
        desired image array

    """
    is_url = filename.lower().startswith('http://') \
        or filename.lower().startswith('https://')

    if is_url:
        image_name = os.path.basename(filename)

        if len(image_name.split('.')) < 2:
            raise IOError(f'{filename} is not a valid image URL')

        urlretrieve(filename, image_name)
        filename = image_name

    if use_pillow:
        with Image.open(filename) as pil_image:
            if pil_image.mode in ['RGBA', 'RGB', 'L']:
                image = np.asarray(pil_image)
            elif pil_image.mode.startswith('I;16'):
                raw = pil_image.tobytes('raw', pil_image.mode)
                dtype = '>u2' if pil_image.mode.endswith('B') else '<u2'
                image = np.frombuffer(raw, dtype=dtype)
                image.reshape(pil_image.size[::-1]).astype('=u2')
            else:
                try:
                    image = pil_image.convert('RGBA')
                except ValueError:
                    raise RuntimeError('Unknown image mode {}'.format(
                        pil_image.mode))
                image = np.asarray(pil_image)
            image = np.flipud(image)

        if as_vtktype:
            if image.ndim not in [2, 3]:
                raise IOError("only 2D (L, RGB, RGBA) or 3D image available")

            vtk_image = ImageData()
            depth = 1 if image.ndim == 2 else image.shape[2]

            # width, height
            vtk_image.SetDimensions(image.shape[1], image.shape[0], depth)
            vtk_image.SetExtent(0, image.shape[1] - 1, 0, image.shape[0] - 1,
                                0, 0)
            vtk_image.SetSpacing(1.0, 1.0, 1.0)
            vtk_image.SetOrigin(0.0, 0.0, 0.0)

            image = image.reshape(image.shape[1] * image.shape[0], depth)
            image = np.ascontiguousarray(image, dtype=image.dtype)
            vtk_array_type = numpy_support.get_vtk_array_type(image.dtype)
            uchar_array = numpy_support.numpy_to_vtk(image,
                                                     deep=True,
                                                     array_type=vtk_array_type)
            vtk_image.GetPointData().SetScalars(uchar_array)
            image = vtk_image

        if is_url:
            os.remove(filename)
        return image

    d_reader = {
        ".png": PNGReader,
        ".bmp": BMPReader,
        ".jpeg": JPEGReader,
        ".jpg": JPEGReader,
        ".tiff": TIFFReader,
        ".tif": TIFFReader
    }

    extension = os.path.splitext(os.path.basename(filename).lower())[1]

    if extension.lower() not in d_reader.keys():
        raise IOError(
            "Impossible to read the file {0}: Unknown extension {1}".format(
                filename, extension))

    reader = d_reader.get(extension)()
    reader.SetFileName(filename)
    reader.Update()
    reader.GetOutput().GetPointData().GetArray(0).SetName("original")

    if not as_vtktype:
        w, h, _ = reader.GetOutput().GetDimensions()
        vtk_array = reader.GetOutput().GetPointData().GetScalars()

        components = vtk_array.GetNumberOfComponents()
        image = numpy_support.vtk_to_numpy(vtk_array).reshape(h, w, components)

    if is_url:
        os.remove(filename)
    return reader.GetOutput() if as_vtktype else image
예제 #5
0
파일: io.py 프로젝트: m-agour/fury
def save_image(arr,
               filename,
               compression_quality=75,
               compression_type='deflation',
               use_pillow=True):
    """Save a 2d or 3d image.

    Expect an image with the following shape: (H, W) or (H, W, 1) or
    (H, W, 3) or (H, W, 4).

    Parameters
    ----------
    arr : ndarray
        array to save
    filename : string
        should be png, bmp, jpeg or jpg files
    compression_quality : int, optional
        compression_quality for jpeg data.
        0 = Low quality, 100 = High quality
    compression_type : str, optional
        compression type for tiff file
        select between: None, lzw, deflation (default)
    use_pillow : bool, optional
        Use imageio python library to save the files.

    """
    if arr.ndim > 3:
        raise IOError("Image Dimensions should be <=3")

    d_writer = {
        ".png": PNGWriter,
        ".bmp": BMPWriter,
        ".jpeg": JPEGWriter,
        ".jpg": JPEGWriter,
        ".tiff": TIFFWriter,
        ".tif": TIFFWriter,
    }

    extension = os.path.splitext(os.path.basename(filename).lower())[1]

    if extension.lower() not in d_writer.keys():
        raise IOError(
            "Impossible to save the file {0}: Unknown extension {1}".format(
                filename, extension))

    if use_pillow:
        arr = np.flipud(arr)
        im = Image.fromarray(arr)
        im.save(filename, quality=compression_quality)
        return

    if arr.ndim == 2:
        arr = arr[..., None]

    shape = arr.shape
    if extension.lower() in [
            '.png',
    ]:
        arr = arr.astype(np.uint8)
    arr = arr.reshape((shape[1] * shape[0], shape[2]))
    arr = np.ascontiguousarray(arr, dtype=arr.dtype)
    vtk_array_type = numpy_support.get_vtk_array_type(arr.dtype)
    vtk_array = numpy_support.numpy_to_vtk(num_array=arr,
                                           deep=True,
                                           array_type=vtk_array_type)

    # Todo, look the following link for managing png 16bit
    # https://stackoverflow.com/questions/15667947/vtkpngwriter-printing-out-black-images
    vtk_data = ImageData()
    vtk_data.SetDimensions(shape[1], shape[0], shape[2])
    vtk_data.SetExtent(0, shape[1] - 1, 0, shape[0] - 1, 0, 0)
    vtk_data.SetSpacing(1.0, 1.0, 1.0)
    vtk_data.SetOrigin(0.0, 0.0, 0.0)
    vtk_data.GetPointData().SetScalars(vtk_array)

    writer = d_writer.get(extension)()
    writer.SetFileName(filename)
    writer.SetInputData(vtk_data)
    if extension.lower() in [".jpg", ".jpeg"]:
        writer.ProgressiveOn()
        writer.SetQuality(compression_quality)
    if extension.lower() in [".tif", ".tiff"]:
        compression_type = compression_type or 'nocompression'
        l_compression = ['nocompression', 'packbits', 'jpeg', 'deflate', 'lzw']

        if compression_type.lower() in l_compression:
            comp_id = l_compression.index(compression_type.lower())
            writer.SetCompression(comp_id)
        else:
            writer.SetCompressionToDeflate()
    writer.Write()
예제 #6
0
def _points_to_vtk_cells(points, points_per_line=2):
    """

    Returns the VTK cell array for the peaks given the set of points
    coordinates.

    Parameters
    ----------
    points : (N, 3) array or ndarray
        points coordinates array.
    points_per_line : int (1 or 2), optional
        number of points per peak direction.

    Returns
    -------
    cell_array : vtkCellArray
        connectivity + offset information.

    """
    num_pnts = len(points)
    num_cells = num_pnts // points_per_line

    cell_array = CellArray()

    if VTK_9_PLUS:
        """
        Connectivity is an array that contains the indices of the points that
        need to be connected in the visualization. The indices start from 0.
        """
        connectivity = np.asarray(list(range(0, num_pnts)), dtype=int)
        """
        Offset is an array that contains the indices of the first point of
        each line. The indices start from 0 and given the known geometry of
        this actor the creation of this array requires a 2 points padding
        between indices.
        """
        offset = np.asarray(list(range(0, num_pnts + 1, points_per_line)),
                            dtype=int)

        vtk_array_type = numpy_support.get_vtk_array_type(connectivity.dtype)
        cell_array.SetData(
            numpy_support.numpy_to_vtk(offset,
                                       deep=True,
                                       array_type=vtk_array_type),
            numpy_support.numpy_to_vtk(connectivity,
                                       deep=True,
                                       array_type=vtk_array_type))
    else:
        connectivity = np.array([], dtype=int)
        i_pos = 0
        while i_pos < num_pnts:
            e_pos = i_pos + points_per_line
            """
            In old versions of VTK (<9.0) the connectivity array should include
            the length of each line and immediately after the indices of the
            points in each line.
            """
            connectivity = np.append(connectivity,
                                     [points_per_line, i_pos, e_pos - 1])
            i_pos = e_pos

        cell_array.GetData().DeepCopy(numpy_support.numpy_to_vtk(connectivity))

    cell_array.SetNumberOfCells(num_cells)
    return cell_array