コード例 #1
0
ファイル: stack.py プロジェクト: VicidominiLab/miplib
def register_stack_slices(stack):
    """
    An utility to register slices in an image stack. The registration is performed
    by iterating over adjacent layers (0->1, 1->2,...). The shift obtained for each
    layer, is with respect to the image at idx=0.

    :param stack {Image}:  a 3D image stack
    :return: the image shifts with respect to index 0 (in pixels).

    """
    assert isinstance(stack, Image)
    assert stack.ndim == 3

    shifts = np.zeros((stack.shape[0], 2), dtype=np.float)

    for f_idx, m_idx in zip(range(0, stack.shape[0] - 1),
                            range(1, stack.shape[0])):
        fixed = Image(stack[f_idx], stack.spacing[1:])
        moving = Image(stack[m_idx], stack.spacing[1:])

        offset = registration.phase_correlation_registration(fixed,
                                                             moving,
                                                             resample=False)
        shifts[m_idx] = shifts[f_idx] + np.asarray(offset)

    return shifts
コード例 #2
0
def calculate_two_image_frc(image1, image2, args, z_correction=1):
    """
    A simple utility to calculate a regular FRC with a two image input

    :param image: the image as an Image object
    :param args:  the parameters for the FRC calculation. See *miplib.ui.frc_options*
                  for details
    :return:      returns the FRC result as a FourierCorrelationData object
    """
    assert isinstance(image1, Image)
    assert isinstance(image2, Image)

    assert image1.shape == image2.shape

    frc_data = FourierCorrelationDataCollection()

    spacing = image1.spacing

    if not args.disable_hamming:

        image1 = Image(windowing.apply_hamming_window(image1), spacing)
        image2 = Image(windowing.apply_hamming_window(image2), spacing)

    # Run FRC
    iterator = iterators.FourierRingIterator(image1.shape, args.d_bin)
    frc_task = FRC(image1, image2, iterator)
    frc_data[0] = frc_task.execute()

    # Analyze results
    analyzer = fsc_analysis.FourierCorrelationAnalysis(frc_data,
                                                       image1.spacing[0], args)

    return analyzer.execute(z_correction=z_correction)[0]
コード例 #3
0
ファイル: registration.py プロジェクト: hermes-soleil/miplib
def register_stack_slices(stack, reference=0):
    """
    An utility to register slices in an image stack. 
    :param stack {Image}:  a 3D image stack
    :param reference: the index (z) of the image that is to be used as a
    reference for the registration
    :return: a 3D Image with each slice aligned

    """
    assert isinstance(stack, Image)
    assert stack.ndim == 3

    aligned = np.zeros(stack.shape, dtype=np.float32)
    spacing = stack.spacing

    for i in range(stack.shape[0]):
        if i == reference:
            aligned[i] = stack[i]
        else:
            aligned[i] = phase_correlation_registration(
                Image(stack[reference], stack.spacing[1:]), 
                Image(stack[i], stack.spacing[1:]))

    return Image(aligned, spacing)




# endregions
コード例 #4
0
def wiener_deconvolution(image, psf, snr=30, add_pad=0):
    assert isinstance(image, Image)
    assert isinstance(psf, Image)

    image_s = Image(image.copy(), image.spacing)
    orig_shape = image.shape

    if image.ndim != psf.ndim:
        raise ValueError("Image and psf dimensions do not match")

    if psf.spacing != image.spacing:
        psf = imops.zoom_to_spacing(psf, image.spacing)

    if add_pad != 0:
        new_shape = list(i + 2 * add_pad for i in image_s.shape)
        image_s = imops.zero_pad_to_shape(image_s, new_shape)

    if psf.shape != image_s.shape:
        psf = imops.zero_pad_to_shape(psf, image_s.shape)

    psf /= psf.max()

    psf_f = fftn(fftshift(psf))

    wiener = arrayops.safe_divide(
        np.abs(psf_f)**2 / (np.abs(psf_f)**2 + snr), psf_f)

    image_s = fftn(image_s)

    image_s = Image(np.abs(ifftn(image_s * wiener).real), image.spacing)

    return imops.remove_zero_padding(image_s, orig_shape)
コード例 #5
0
ファイル: fusion.py プロジェクト: hermes-soleil/miplib
    def get_result(self, cast_to_8bit=False):
        """
        Show fusion result. This is a temporary solution for now
        calling Fiji through ITK. An internal viewer would be
        preferable.
        """
        if cast_to_8bit:
            result = self.estimate.copy()
            result *= (255.0 / result.max())
            result[result < 0] = 0
            return Image(result, self.voxel_size)

        return Image(self.estimate, self.voxel_size)
コード例 #6
0
def noisy(image, noise_type):
    """
    Parameters
    ----------
    image :
        Input image data. Will be converted to float.
    noise_type : str
        One of the following strings, selecting the type of noise to add:

        'gauss'     Gaussian-distributed additive noise.
        'poisson'   Poisson-distributed noise generated from the data.
        's&p'       Replaces random pixels with 0  or 1.
        'speckle'   Multiplicative noise using out = image + n*image,where
                    n is uniform noise with specified mean & variance.
    """
    assert isinstance(image, Image)
    assert image.ndim < 4
    spacing = image.spacing

    if noise_type == "gauss":
        mean = 0
        var = 0.1
        sigma = var**0.5
        gauss = np.random.normal(mean, sigma, image.shape)
        gauss = gauss.reshape(image.shape)
        return Image(image + gauss, spacing)
    elif noise_type == "s&p":
        s_vs_p = 0.5
        amount = 0.004
        out = np.copy(image)
        # Salt mode
        num_salt = np.ceil(amount * image.size * s_vs_p)
        coords = [
            np.random.randint(0, i - 1, int(num_salt)) for i in image.shape
        ]
        out[coords] = 1

        # Pepper mode
        num_pepper = np.ceil(amount * image.size * (1. - s_vs_p))
        coords = [
            np.random.randint(0, i - 1, int(num_pepper)) for i in image.shape
        ]
        out[coords] = 0
        return Image(out, spacing)
    elif noise_type == "poisson":
        vals = 2**np.ceil(np.log2(len(np.unique(image))))
        return Image(np.random.poisson(image * vals) / float(vals), spacing)
    elif noise_type == "speckle":
        gauss = np.random.standard_normal(image.shape).reshape(image.shape)
        return Image(image + image * gauss, spacing)
コード例 #7
0
ファイル: wiener_cuda.py プロジェクト: VicidominiLab/miplib
def wiener_deconvolution(image, psf, snr=30, add_pad=0):
    """ A GPU accelerated implementation of a linear Wiener filter. Some effort is made
    to allow processing even relatively large images, but some kind of block-based processing
     (as in the RL implementation) may be required in some cases."""
    assert isinstance(image, Image)
    assert isinstance(psf, Image)

    image_s = Image(image.copy(), image.spacing)
    orig_shape = image.shape

    if image.ndim != psf.ndim:
        raise ValueError("Image and psf dimensions do not match")

    if psf.spacing != image.spacing:
        psf = imops.zoom_to_spacing(psf, image.spacing)

    if add_pad != 0:
        new_shape = list(i + 2 * add_pad for i in image_s.shape)
        image_s = imops.zero_pad_to_shape(image_s, new_shape)

    if psf.shape != image_s.shape:
        psf = imops.zero_pad_to_shape(psf, image_s.shape)

    psf /= psf.max()
    psf = fftshift(psf)

    psf_dev = cp.asarray(psf.astype(np.complex64))
    with get_fft_plan(psf_dev):
        psf_dev = fftn(psf_dev, overwrite_x=True)

    below = cp.asnumpy(psf_dev)
    psf_abs = cp.abs(psf_dev)**2
    psf_abs /= (psf_abs + snr)
    above = cp.asnumpy(psf_abs)
    psf_abs = None
    psf_dev = None

    image_dev = cp.asarray(image_s.astype(np.complex64))
    with get_fft_plan(image_dev):
        image_dev = fftn(image_dev, overwrite_x=True)

    wiener_dev = cp.asarray(arrayops.safe_divide(above, below))

    image_dev *= wiener_dev

    result = cp.asnumpy(cp.abs(ifftn(image_dev, overwrite_x=True)).real)
    result = Image(result, image.spacing)

    return imops.remove_zero_padding(result, orig_shape)
コード例 #8
0
def calculate_two_image_sectioned_fsc(image1, image2, args, z_correction=1):
    assert isinstance(image1, Image)
    assert isinstance(image2, Image)

    image1 = Image(windowing.apply_hamming_window(image1), image1.spacing)
    image2 = Image(windowing.apply_hamming_window(image2), image2.spacing)

    iterator = iterators.AxialExcludeHollowConicalFourierShellIterator(
        image1.shape, args.d_bin, args.d_angle, args.d_extract_angle)
    fsc_task = DirectionalFSC(image1, image2, iterator)
    data = fsc_task.execute()

    analyzer = fsc_analysis.FourierCorrelationAnalysis(data, image1.spacing[0],
                                                       args)
    return analyzer.execute(z_correction=z_correction)
コード例 #9
0
    def __getitem__(self, item):
        gate, detector = item

        self.data.set_active_image(detector, gate, self.scale, self.kind)
        spacing = self.data.get_voxel_size()

        return Image(self.data[:], spacing)
コード例 #10
0
def butterworth_fft_filter(image, threshold, n=3):
    """Create low-pass 2D Butterworth filter.
    :Parameters:
       size : tuple
           size of the filter
       cutoff : float
           relative cutoff frequency of the filter (0 - 1.0)
       n : int, optional
           order of the filter, the higher n is the sharper
           the transition is.
    :Returns:
       numpy.ndarray
         filter kernel in 2D centered
   """
    if not 0 < threshold <= 1.0:
        raise ValueError('Cutoff frequency must be between 0 and 1.0')

    if not isinstance(n, int):
        raise ValueError('n must be an integer >= 1')

    assert isinstance(image, Image)

    spacing = image.spacing

    # Create Fourier grid
    r = indexers.SimplePolarIndexer(image.shape).r

    threshold *= image.shape[0]

    butter = 1.0 / (1.0 + (r / threshold) ** (2 * n))  # The filter

    fft_image = np.fft.fftshift(np.fft.fftn(image))
    fft_image *= butter

    return Image(np.abs(np.fft.ifftn(fft_image).real), spacing)
コード例 #11
0
ファイル: fftutils.py プロジェクト: hermes-soleil/miplib
def ideal_fft_filter(image, threshold, kind='low'):
    """
    An ideal high/low pass frequency domain noise filter.
    :param image: an Image object
    :param threshold: threshold value [0,1], where 1 corresponds
    to the maximum frequency.
    :param kind: filter type 'low' for low-pass, 'high' for high pass
    :return: returns the filtered Image.
    """
    assert isinstance(image, Image)

    spacing = image.spacing

    fft_image = np.fft.fftshift(np.fft.fftn(image))

    if kind == 'low':
        indexer = indexers.PolarLowPassIndexer(image.shape)
    elif kind == 'high':
        indexer = indexers.PolarHighPassIndexer(image.shape)
    else:
        raise ValueError("Unknown filter kind: {}".format(kind))

    r_max = floor(min(image.shape) / 2)

    fft_image *= indexer[threshold * r_max]

    return Image(np.abs(np.fft.ifftn(fft_image).real), spacing)
コード例 #12
0
def translate_image(image, shift):
    """
    Apply a circular shift to an image

    :param image: An Image object
    :param shift: The shift as a single numeric value
    :return: returns the translated image.
    """
    fft_image = np.fft.fftshift(np.fft.fft2(image))

    shape = fft_image.shape
    axes = (np.arange(-np.floor(i / 2.0), np.ceil(i / 2.0)) for i in shape)
    axes = (i / (2 * i.max()) for i in axes)
    y, x = np.meshgrid(*axes)

    xx = np.zeros(fft_image.shape, dtype=np.complex64)
    xx.real[:] = np.cos(2 * np.pi * shift * x)
    xx.imag[:] = np.sin(-2 * np.pi * shift * x)

    yy = np.zeros(fft_image.shape, dtype=np.complex64)
    yy.real[:] = np.cos(2 * np.pi * shift * y)
    yy.imag[:] = np.sin(-2 * np.pi * shift * y)

    multiplier = xx * yy

    result = np.abs(np.fft.ifftn(fft_image * multiplier).real)

    return Image(result, image.spacing)
コード例 #13
0
def flip_image(image):

    assert isinstance(image, Image)

    indexer = (np.s_[::-1], ) * image.ndim

    return Image(image[indexer], image.spacing)
コード例 #14
0
def read_airyscan_data(image_path, time_points=1, detectors=32):
    """ Read an Airyscan image. 
    
    Arguments:
        image_path {string} -- Path to the file
    
    Keyword Arguments:
        time_points {int} -- Number of time points (if a time series) (default: {1})
        detectors {int} -- Number of detectors (default: {32})
    
    Returns:
        ArrayDetectorData -- Returns the Airyscan image in the internal format for ISM
        processing.
    """
    # Open file
    data = pims.bioformats.BioformatsReader(image_path)
    
    # Get metadata
    spacing = [data.metadata.PixelsPhysicalSizeY(0), data.metadata.PixelsPhysicalSizeX(0)]
    
    # Initialize data container
    container = ArrayDetectorData(detectors, time_points)

    # Split time points
    data.bundle_axes = ['t', 'y', 'x']
    data = np.stack(np.split(data[0], time_points))

    # Save to data container
    for i in range(time_points):
        for j in range(detectors):
            container[i, j] = Image(data[i, j, :, :], spacing)
            
    return container
コード例 #15
0
def __bioformats(filename, series=0, channel=0, return_itk=False):
    """
    Read an image using the Bioformats importer. Good for most microscopy formats.

    :param filename:
    :param series:
    :param return_itk:
    :return:
    """
    assert pims.bioformats.available(), "Please install jpype in order to use " \
                                        "the bioformats reader."
    image = pims.bioformats.BioformatsReader(filename, series=series)

    # Get Pixel/Voxel size information
    if 'z' not in image.axes:
        spacing = (image.metadata.PixelsPhysicalSizeY(0),
                   image.metadata.PixelsPhysicalSizeX(0))
    else:
        spacing = (image.metadata.PixelsPhysicalSizeZ(0),
                   image.metadata.PixelsPhysicalSizeY(0),
                   image.metadata.PixelsPhysicalSizeX(0))

    # Get color channel
    if 'c' in image.sizes:
        image.iter_axes = 'c'
        assert len(image) > channel
        image = image[channel]
    else:
        image = image[0]

    if return_itk:
        return itkutils.convert_from_numpy(image, spacing)
    else:
        return Image(image, spacing)
コード例 #16
0
def gaussian_fft_filter(image, threshold):
    """
    Create low-pass 2D Gaussian filter.
    :Parameters:
       size : tuple
           size of the filter
       cutoff : float
           relative cutoff frequency of the filter (0 - 1.0)
       n : int, optional
           order of the filter, the higher n is the sharper
           the transition is.
    :Returns:
       numpy.ndarray:  filter kernel in 2D centered
   """
    if not 0 < threshold <= 1.0:
        raise ValueError('Cutoff frequency must be between 0 and 1.0')

    assert isinstance(image, Image)

    spacing = image.spacing

    # Create Fourier grid
    r = indexers.SimplePolarIndexer(image.shape).r

    r /= image.shape[0]

    gauss = np.exp(-(r**2/(2*(threshold**2))))
    fft_image = np.fft.fftshift(np.fft.fftn(image))
    fft_image *= gauss

    return Image(np.abs(np.fft.ifftn(fft_image).real), spacing)
コード例 #17
0
def shift(data, transforms):
    """
    Resamples all the images in an ArrayDetectorData structure with the supplied transforms,
    and saves the result in a new ArrayDetectorData structure

    :param data: ArrayDetectorData object with images
    :param transforms: A list of transforms (Simple ITK), one for each image
    :return: ArrayDetectorDAta object with shifted images
    """

    assert isinstance(transforms, list) and len(transforms) == data.ndetectors

    shifted = ArrayDetectorData(data.ndetectors, data.ngates)
    reference = Image(np.zeros(data[0, 0].shape, dtype=np.float64),
                      data[0, 0].spacing)

    for gate in range(data.ngates):
        for i in range(data.ndetectors):
            image = itk.resample_image(
                itk.convert_to_itk_image(data[gate, i]),
                transforms[i],
                reference=itk.convert_to_itk_image(reference))

            shifted[gate, i] = itk.convert_from_itk_image(image)

    return shifted
コード例 #18
0
ファイル: psfgen.py プロジェクト: hermes-soleil/miplib
    def xy(self):
        """Return a z slice of the PSF with rotational symmetries applied."""
        data = mirror_symmetry(_psf.zr2zxy(self.data))
        spacing = (self.spacing[1], self.spacing[1])

        center = self.shape[0] - 1
        return Image(data[center], spacing)
コード例 #19
0
ファイル: registration.py プロジェクト: VicidominiLab/miplib
def phase_correlation_registration(fixed_image,
                                   moving_image,
                                   subpixel=100,
                                   verbose=False,
                                   resample=True):
    """
    A simple Phase Correlation based image registration method.
    :param verbose:  enable print functions
    :param subpixel: resampling factor; registration will be perfromed to
                     1/subpixel accuracy
    :param fixed_image: the reference image as MIPLIB Image object
    :param moving_image: the moving image as MIPLIB Image object
    :return: returns the SimpleITK transform
    """
    assert isinstance(fixed_image, Image)
    assert isinstance(moving_image, Image)

    shift, error, diffphase = register_translation(fixed_image, moving_image,
                                                   subpixel)

    scaled_shifts = list(
        -offset * spacing
        for offset, spacing in zip(shift, fixed_image.spacing))
    if verbose:
        print(("Detected offset (y, x): {}".format(scaled_shifts)))

    if resample:
        resampled = np.abs(
            np.fft.ifftn(fourier_shift(np.fft.fftn(moving_image), shift)).real)

        return Image(resampled, fixed_image.spacing)
    else:
        return scaled_shifts
コード例 #20
0
    def get_result(self):
        """
        Show fusion result. This is a temporary solution for now
        calling Fiji through ITK. An internal viewer would be
        preferable.
        """

        return Image(self.estimate, self.image_spacing)
コード例 #21
0
def calculate_one_image_sectioned_fsc(image, args, z_correction=1):
    """ A function to calculate one-image sectioned FSC. I assume here that prior to calling the function,
    the image is going to be in a correct shape, resampled to isotropic spacing and zero padded. If the image
    dimensions are wrong (not a cube) the function will return an error.
    
    :param image: a 3D image, with isotropic spacing and cubic shape
    :type image: Image
    :param options: options for the FSC calculation
    :type options: argparse options
    :param z_correction: correction, for anisotropic sampling. It is the ratio of axial vs. lateral spacing, defaults to 1
    :type z_correction: float, optional
    :return: the resolution measurement results organized by rotation angle
    :rtype: FourierCorrelationDataCollection object
    """
    assert isinstance(image, Image)
    assert all(s == image.shape[0] for s in image.shape)

    image1, image2 = imops.checkerboard_split(image)

    image1 = Image(windowing.apply_hamming_window(image1), image1.spacing)
    image2 = Image(windowing.apply_hamming_window(image2), image2.spacing)

    iterator = iterators.AxialExcludeHollowConicalFourierShellIterator(
        image1.shape, args.d_bin, args.d_angle, args.d_extract_angle)
    fsc_task = DirectionalFSC(image1, image2, iterator)

    data = fsc_task.execute()

    analyzer = fsc_analysis.FourierCorrelationAnalysis(data, image1.spacing[0],
                                                       args)
    result = analyzer.execute(z_correction=z_correction)

    def func(x, a, b, c, d):
        return a * np.exp(c * (x - b)) + d

    params = [0.95988146, 0.97979108, 13.90441896, 0.55146136]

    for angle, dataset in result:
        point = dataset.resolution["resolution-point"][1]

        cut_off_correction = func(point, *params)
        dataset.resolution["spacing"] /= cut_off_correction
        dataset.resolution["resolution"] /= cut_off_correction

    return result
コード例 #22
0
def rescale_to_8_bit(image):
    """
    Converts an Image into 8-bit (typically for saving)
    :param image: an Image object
    :return: a 8-bit version of the Image
    """
    assert isinstance(image, Image)
    return Image((image * (255.0 / image.max())).astype(np.uint8),
                 image.spacing)
コード例 #23
0
def shift_and_sum(data,
                  transforms,
                  photosensor=0,
                  detectors=None,
                  supersampling=1.0):
    """
    Adaptive ISM pixel reassignment. Please use one of the functions above to figure out
    the shifts first, if you haven't already.

    :param supersampling: Insert a number != 1, if you want to rescale the result image to
    a different size. This might make sense, if you the original sampling has been sampled
    sparsely
    :param data: ArrayDetectorData object with all the individual images
    :param transforms: ITK spatial transformation that are to be used for the resampling
    :param photosensor: The photosensor index, if more than one
    :param detectors: a list of detectors to be included in the reconstruction. If None given (default),
    all the images will be used
    :return: reconstruction result Image
    """
    assert isinstance(data, ArrayDetectorData)
    assert isinstance(transforms, list) and len(transforms) == data.ndetectors

    if supersampling != 1.0:
        new_shape = list(
            int(i * supersampling) for i in data[photosensor, 0].shape)
        new_spacing = list(i / supersampling
                           for i in data[photosensor, 0].spacing)
        output = Image(np.zeros(new_shape, dtype=np.float64), new_spacing)
    else:
        output = Image(np.zeros(data[photosensor, 0].shape, dtype=np.float64),
                       data[photosensor, 0].spacing)

    if detectors is None:
        detectors = list(range(data.ndetectors))

    for i in detectors:
        image = itk.resample_image(itk.convert_to_itk_image(data[photosensor,
                                                                 i]),
                                   transforms[i],
                                   reference=itk.convert_to_itk_image(output))

        output += itk.convert_from_itk_image(image)

    return output
コード例 #24
0
ファイル: filters.py プロジェクト: hermes-soleil/miplib
    def run_mean_smoothing(self, return_result=False):
        """
        Mean smoothing is used to create a mask for the entropy calculation
        """

        assert len(self.kernel_size) == len(self.dimensions)
        self.data_temp = ndimage.uniform_filter(self.data[:], size=self.kernel_size)

        if return_result:
            return Image(self.data_temp, self.spacing)
コード例 #25
0
ファイル: psfgen.py プロジェクト: hermes-soleil/miplib
    def volume(self):
        """Return a 3D volume of the PSF with all symmetries applied.

        The shape of the returned array is
            (2*self.shape[0]-1, 2*self.shape[1]-1, 2*self.shape[1]-1)

        """
        data = mirror_symmetry(_psf.zr2zxy(self.data))
        spacing = (self.spacing[0], self.spacing[1], self.spacing[1])

        return Image(data, spacing)
コード例 #26
0
ファイル: utils.py プロジェクト: hermes-soleil/miplib
def average_of_all(data_structure,
                   channel=0,
                   scale=100,
                   image_type="original"):
    assert isinstance(data_structure, ImageData)
    n_views = data_structure.get_number_of_images(image_type)
    data_structure.set_active_image(0, channel, scale, image_type)
    pixel_size = data_structure.get_voxel_size()

    result = sum_of_all(data_structure, channel, scale, image_type)

    return Image(result / n_views, pixel_size)
コード例 #27
0
def remove_zero_padding(image, shape):
    """

    :param image: The zero padded image
    :param shape: The original image size (before padding)
    :return:
    """

    assert isinstance(image, Image)
    assert len(shape) == image.ndim

    return Image(ndarray.contract_to_shape(image, shape), image.spacing)
コード例 #28
0
def zoom_to_spacing(image, spacing, order=3, verbose=False):

    assert isinstance(image, Image)
    assert image.ndim == len(spacing)

    zoom = tuple(i / j for i, j in zip(image.spacing, spacing))
    if verbose:
        print("The zoom is ", zoom)

    array = interpolation.zoom(image, zoom, order=order)

    return Image(array, spacing)
コード例 #29
0
def read_carma_mat(filename):
    """
    A simple implementation for the carma file import in Python
    :param filename: Path to the Carma .mat file
    :return: Returns a 2D nested list of miplib Image objects. The first dimension
             of the list corresponds to the Photosensors count and second, to the
             Detectors count
    """
    assert filename.endswith(".mat")
    #measurement = "meas_" + filename.split('/')[-1].split('.')[0]
    data = loadmat(filename)

    # Find measurement name (in case someone renamed the file)
    for key in list(data.keys()):
        if 'meas_' in key:
            data = data[key]
            break

    # Get necessary metadata
    spacing = list(data['PixelSize'][0][0][0][::-1])
    shape = list(data['Size'][0][0][0][::-1])

    detectors = int(data['DetectorsCount'][0][0][0])
    photosensors = len(data["PhotosensorsTime"][0][0][0])

    # Initialize data container
    container = ArrayDetectorData(detectors, photosensors)

    # Read images
    for i in range(photosensors):
        for j in range(detectors):
            name = 'pixel_d{}_p{}'.format(j, i)
            if shape[0] == 1:
                container[i, j] = Image(
                    np.transpose(data[name][0][0])[0], spacing[1:])
            else:
                container[i, j] = Image(np.transpose(data[name][0][0]),
                                        spacing)

    return container
コード例 #30
0
    def get_8bit_result(self, denoise=False):
        """
        Returns the current estimate (the fusion result) as an 8-bit uint, rescaled
        to the full 0-255 range.
        """
        if denoise:
            image = medfilt(self.estimate)
        else:
            image = self.estimate

        image *= (255.0 / image.max())
        image[image < 0] = 0
        return Image(image.astype(numpy.uint8), self.image_spacing)