def test_patch_size(self):
     """ Test the patch size normalization according to the image anisotropy.
     """
     for spacing, patch_size in zip(self.spacings, self.patch_sizes):
         half_patch_size, full_patch_size = normalize_patch_size(spacing[0], spacing[1:])
         self.assertEqual(half_patch_size.tolist(), patch_size.tolist())
         self.assertEqual(full_patch_size.tolist(), (2 * patch_size + 1).tolist())
 def test_patch_size(self):
     """ Test the patch size normalization according to the image anisotropy.
     """
     for spacing, patch_size in zip(self.spacings, self.patch_sizes):
         half_patch_size, full_patch_size = normalize_patch_size(
             spacing[0], spacing[1:])
         self.assertEqual(half_patch_size.tolist(), patch_size.tolist())
         self.assertEqual(full_patch_size.tolist(),
                          (2 * patch_size + 1).tolist())
Beispiel #3
0
    def __init__(self, to_denoise_array, spacing, mask_array=None,
                 half_patch_size=1, half_spatial_bandwidth=5,
                 central_point_strategy="weight", blockwise_strategy="blockwise",
                 lower_mean_threshold=0.95, lower_variance_threshold=0.5,
                 beta=1, use_optimized_strategy=True, use_cython=True,
                 nb_of_threads=1):
        """ Initialize the non-local denoising class.
    
        Parameters
        ----------
        array_to_denoise: array
            an input n dimensional array to process containing the image
            intensities.
        spacing: n-uplet
            the image spacing in voxel.
        half_patch_size: int
            the patch size in voxel.
        central_point_strategy: str (default 'weight')
            the way the central patch is considered, one of 'add', 'remove' or
            'weight'.
        blockwise_strategy: str (default 'blockwise')
            the blockwise denoising strategy, one of 'pointwise', 'blockwise' or
            'fastblockwise'.
        lower_mean_threshold: float (default 0.95)
            threshold to select two patches depending on the mean values.
        lower_variance_threshold: float (default 0.5)
            threshold to select two patches depending on the variance values.
        beta: float
            smoothing parameter.
        use_optimized_strategy: bool (default True)
            use the mean and variance to discard some patches in the neighborhood
            based on the mean and variance thresholds.
        use_cython: bool (default True)
            the cython to speed up the denoised patch creation.
        nb_of_threads: int (default 1)
            if cython code, defines the number of threads to use.
        """
      
        # Class parameters
        self.to_denoise_array = numpy.cast[numpy.single](to_denoise_array)
        self.spacing = numpy .asarray(spacing)
        self.mask_array = mask_array
        self.mean_array = None
        self.variance_array = None
        self.central_point_strategy = central_point_strategy
        self.blockwise_strategy = blockwise_strategy
        self.use_optimized_strategy = use_optimized_strategy
        self.lower_mean_threshold = lower_mean_threshold
        self.lower_variance_threshold = lower_variance_threshold
        self.use_cython = use_cython
        self.nb_of_threads = nb_of_threads

        # Intern parameters
        self.shape = self.to_denoise_array.shape
        self.size = self.to_denoise_array.size
        
        # Check that the mask array has a valid shape
        if self.mask_array is not None:
            if self.shape != self.mask_array.shape:
                raise ValueError("Input mask array has invalid shape.")
        else:
            self.mask_array = numpy.ones(self.shape, dtype=numpy.int)
        remaining_voxels = len(numpy.where(self.mask_array > 0)[0])
        logger.info("Remaining voxels to process '%s' percent.",
                    int(remaining_voxels / self.size * 100.))

        # Check that a valid denoising strategy has been selected.
        if self.blockwise_strategy not in self.valid_blockwise_strategies:
            raise ValueError(
                "Wrong denoising strategy '{0}'. Valid options are '{1}'.".format(
                    self.blockwise_strategy, self.valid_blockwise_strategies))

        # Check that a valid central point strategy has been selected.
        if self.central_point_strategy not in self.valid_cental_point_strategies:
            raise ValueError(
                "Wrong central point strategy '{0}'. Valid options are '{1}'.".format(
                    self.central_point_strategy, self.valid_cental_point_strategies))
        
        # Intern parameters
        # > patch size
        self.half_patch_size, self.full_patch_size = normalize_patch_size(
            half_patch_size, self.spacing)

        # > spatial bandwidth: equivalent to the size of the volume search area
        # in non-local means
        (self.half_spatial_bandwidth, 
         self.full_spatial_bandwidth) = normalize_patch_size(
            half_spatial_bandwidth, self.spacing)

        # > compute mean and variance images
        if self.use_optimized_strategy:
            if self.use_cython:
                self.mean_array, self.variance_array = c_patch_mean_variance(
                    self.to_denoise_array, 
                    numpy.cast[numpy.single](self.mask_array),
                    self.full_patch_size)
            else:     
                self.mean_array, self.variance_array = patch_mean_variance(
                    self.to_denoise_array, self.mask_array, self.full_patch_size)

        # > smooth parameter      
        self.range_bandwidth = self._compute_range_bandwidth(beta)