ImageDev

NonLocalMeansFilter3d

Adaptive filter denoising a three-dimensional image.

Access to parameter description

For an introduction to image filters: Images Filtering.

This algorithm computes a weighted mean of a large set of voxels (search windows) around the voxel to be denoised (target voxel). The voxel weight in the search window is a function of the similarity between this voxel and the target voxel. A voxel very similar to the target voxel is assigned to a weight close to 1.0. A voxel very different from the target voxel is assigned to a weight close to 0 and has a small influence on the resulting denoised value.

The similarity between a voxel and the target voxel is based on the squared intensity differences between two patches of user-defined size, centered on the current voxel and the target voxel.

Images are often corrupted by noise because of the acquisition process. For an image $y$ defined on $\Omega$, which is the image domain, the noise added by acquisition is assimilated to an additive white gaussian noise: $$ y[k] = x[k] + e[k], \forall k \in \Omega $$ where $$ e[k] \sim \mathcal{N}(0, \sigma), \forall k \in \Omega $$
The denoised image $z$ is an estimation of $x$ as follows: $$ z[k] = \frac{\sum_{n\in\mathbb{Z}^3} w[k,n]\cdot y[k+n]}{\sum_{n\in\mathbb{Z}^3} w[k,n]} $$ with $$ w[k,n] = f(n)\exp\left(-\frac{ssd(k,n)}{\lambda}\right) $$ where: The algorithm looks for matchings within the search window area, around each voxel.

The basic implementation of the previous equation has a complexity of $\mathcal{O}(P^3S^3NMQ)$ that can be reduced to $\mathcal{O}(S^3NMQ)$ where $N$, $M$ and $Q$ are, respectively, the X, Y, and Z dimensions of the input image, $P$ is the patch size, and $S$ is the search window size.

Reference:
A.Buades, B. Coll, J.M.Morel. "A Non-Local Algorithm for Image Denoising". Proceedings of the 2005 IEEE Computer Society Conference on Computer Vision and Pattern Recognition (CVPR), vol. 2, pp. 60-65, 2005.

See also

Function Syntax

This function returns outputImage.
// Function prototype
std::shared_ptr< iolink::ImageView > nonLocalMeansFilter3d( std::shared_ptr< iolink::ImageView > inputImage, uint32_t patchRadius, uint32_t kernelRadius, double similarity, NonLocalMeansFilter3d::KernelShape kernelShape, std::shared_ptr< iolink::ImageView > outputImage = NULL );
This function returns outputImage.
// Function prototype.
non_local_means_filter_3d( input_image,
                           patch_radius = 3,
                           kernel_radius = 6,
                           similarity = 0.6,
                           kernel_shape = NonLocalMeansFilter3d.KernelShape.CUBE,
                           output_image = None )
This function returns outputImage.
// Function prototype.
public static IOLink.ImageView
NonLocalMeansFilter3d( IOLink.ImageView inputImage,
                       UInt32 patchRadius = 3,
                       UInt32 kernelRadius = 6,
                       double similarity = 0.6,
                       NonLocalMeansFilter3d.KernelShape kernelShape = ImageDev.NonLocalMeansFilter3d.KernelShape.CUBE,
                       IOLink.ImageView outputImage = null );

Class Syntax

Parameters

Class Name NonLocalMeansFilter3d

Parameter Name Description Type Supported Values Default Value
input
inputImage
The input image. Image Grayscale or Multispectral nullptr
input
kernelShape
The shape of the search window. The shape of the window search area can be used to improve the run time. For example, choosing a ball shape reduces the computation time by 50%.
CUBE The shape is a cube.
BALL The shape is a sphere.
Enumeration CUBE
input
kernelRadius
The search window half size side length or radius, in voxels.
In the case of a cube, a value N produces a cube of 2N+1 voxels side length. In the case of a ball, a value N produces a ball with a 2N+1 voxels diameter. The larger the search window, the better the results usually are. But the size of the search window also affects the run time significantly. This value has to be set to a large enough value so that similar structures can be found within the search window area. Values that are too small result in simple blurring of the image because there is not enough structural data within the search window area.
UInt32 >=1 6
input
patchRadius
The patch box half size side length, in voxels.
The weight of a voxel in the search windows is computed by comparing the neighborhood of this voxel with the neighborhood of the target voxel. This value represents the edge size of the neighborhood volume, in number of voxels (patch neighborhood is a cube), and affects the quality of the result. If this value is either much smaller, or much larger than the finest structures of the image, the algorithm shows few or no effect at all. This parameter has almost no effect on the computation time.
UInt32 Any value 3
input
similarity
The similarity is used to compute weight w(k,n) assigned to each voxel in the search window.
The squared similarity is proportional to the standard deviation of the assumed gaussian noise of the input image. The larger this value, the more the resulting image is smoothed. The similarity has no effect on the computation time.
Float64 >=0.001 0.6
output
outputImage
The output image. Its dimensions, type, and calibration are forced to the same values as the input. Image nullptr

Object Examples

auto foam = readVipImage( std::string( IMAGEDEVDATA_IMAGES_FOLDER ) + "foam.vip" );

NonLocalMeansFilter3d nonLocalMeansFilter3dAlgo;
nonLocalMeansFilter3dAlgo.setInputImage( foam );
nonLocalMeansFilter3dAlgo.setPatchRadius( 3 );
nonLocalMeansFilter3dAlgo.setKernelRadius( 3 );
nonLocalMeansFilter3dAlgo.setSimilarity( 0.6 );
nonLocalMeansFilter3dAlgo.setKernelShape( NonLocalMeansFilter3d::KernelShape::CUBE );
nonLocalMeansFilter3dAlgo.execute();

std::cout << "outputImage:" << nonLocalMeansFilter3dAlgo.outputImage()->toString();
foam = imagedev.read_vip_image(imagedev_data.get_image_path("foam.vip"))

non_local_means_filter_3d_algo = imagedev.NonLocalMeansFilter3d()
non_local_means_filter_3d_algo.input_image = foam
non_local_means_filter_3d_algo.patch_radius = 3
non_local_means_filter_3d_algo.kernel_radius = 3
non_local_means_filter_3d_algo.similarity = 0.6
non_local_means_filter_3d_algo.kernel_shape = imagedev.NonLocalMeansFilter3d.CUBE
non_local_means_filter_3d_algo.execute()

print( "output_image:", str( non_local_means_filter_3d_algo.output_image ) )
ImageView foam = Data.ReadVipImage( @"Data/images/foam.vip" );

NonLocalMeansFilter3d nonLocalMeansFilter3dAlgo = new NonLocalMeansFilter3d
{
    inputImage = foam,
    patchRadius = 3,
    kernelRadius = 3,
    similarity = 0.6,
    kernelShape = NonLocalMeansFilter3d.KernelShape.CUBE
};
nonLocalMeansFilter3dAlgo.Execute();

Console.WriteLine( "outputImage:" + nonLocalMeansFilter3dAlgo.outputImage.ToString() );

Function Examples

auto foam = readVipImage( std::string( IMAGEDEVDATA_IMAGES_FOLDER ) + "foam.vip" );

auto result = nonLocalMeansFilter3d( foam, 3, 3, 0.6, NonLocalMeansFilter3d::KernelShape::CUBE );

std::cout << "outputImage:" << result->toString();
foam = imagedev.read_vip_image(imagedev_data.get_image_path("foam.vip"))

result = imagedev.non_local_means_filter_3d( foam, 3, 3, 0.6, imagedev.NonLocalMeansFilter3d.CUBE )

print( "output_image:", str( result ) )
ImageView foam = Data.ReadVipImage( @"Data/images/foam.vip" );

IOLink.ImageView result = Processing.NonLocalMeansFilter3d( foam, 3, 3, 0.6, NonLocalMeansFilter3d.KernelShape.CUBE );

Console.WriteLine( "outputImage:" + result.ToString() );