NonLocalMeansFilter2d
Adaptive filter denoising a two-dimensional image.
Access to parameter description
For an introduction to image filters: see Images Filtering.
This algorithm computes a weighted mean of a large set of pixels (search windows) around the pixel to be denoised (target pixel). The pixel weight in the search window is a function of the similarity between this pixel and the target pixel. A pixel very similar to the target pixel is assigned to a weight close to 1.0. A pixel very different from the target pixel is assigned to a weight close to 0 and has a small influence on the resulting denoised value.
The similarity between a pixel and the target pixel is based on the squared intensity differences between two patches of user-defined size, centered on the current pixel and the target pixel.
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 basic implementation of the previous equation has a complexity of $\mathcal{O}(P^2S^2NM)$ that can be reduced to $\mathcal{O}(S^2NM)$ where $N$ and $M$ are respectively the X and Y 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
See related example
Access to parameter description
For an introduction to image filters: see Images Filtering.
This algorithm computes a weighted mean of a large set of pixels (search windows) around the pixel to be denoised (target pixel). The pixel weight in the search window is a function of the similarity between this pixel and the target pixel. A pixel very similar to the target pixel is assigned to a weight close to 1.0. A pixel very different from the target pixel is assigned to a weight close to 0 and has a small influence on the resulting denoised value.
The similarity between a pixel and the target pixel is based on the squared intensity differences between two patches of user-defined size, centered on the current pixel and the target pixel.
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:
- $ssd(k,n)$ is the similarity criterion (sum of squared differences)
- $\lambda$ is the similarity
- $f(n)$ is the indicator function of the search region
- and $h(n)$ is the indicator function of the patch region.
The basic implementation of the previous equation has a complexity of $\mathcal{O}(P^2S^2NM)$ that can be reduced to $\mathcal{O}(S^2NM)$ where $N$ and $M$ are respectively the X and Y 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
See related example
Function Syntax
This function returns outputImage.
// Function prototype
std::shared_ptr< iolink::ImageView > nonLocalMeansFilter2d( std::shared_ptr< iolink::ImageView > inputImage, uint32_t patchRadius, uint32_t kernelRadius, double similarity, NonLocalMeansFilter2d::KernelShape kernelShape, std::shared_ptr< iolink::ImageView > outputImage = NULL );
This function returns outputImage.
// Function prototype. non_local_means_filter_2d( input_image, patch_radius = 3, kernel_radius = 6, similarity = 0.6, kernel_shape = NonLocalMeansFilter2d.KernelShape.SQUARE, output_image = None )
This function returns outputImage.
// Function prototype. public static IOLink.ImageView NonLocalMeansFilter2d( IOLink.ImageView inputImage, UInt32 patchRadius = 3, UInt32 kernelRadius = 6, double similarity = 0.6, NonLocalMeansFilter2d.KernelShape kernelShape = ImageDev.NonLocalMeansFilter2d.KernelShape.SQUARE, IOLink.ImageView outputImage = null );
Class Syntax
Parameters
Class Name | NonLocalMeansFilter2d |
---|
Parameter Name | Description | Type | Supported Values | Default Value | |||||
---|---|---|---|---|---|---|---|---|---|
inputImage |
The input image. | Image | Grayscale or Multispectral | nullptr | |||||
kernelShape |
The shape of the search window.
|
Enumeration | SQUARE | ||||||
kernelRadius |
The search window half size side length or radius, in pixels.
In case of a square, a value N produces a square of 2N+1 pixels side length. In case of a disk, a value N produces a disk with a 2N+1 pixels 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. Too small values result in simple blurring of the image because there is not enough structural data within the search window area. |
UInt32 | >=1 | 6 | |||||
patchRadius |
The patch box half size side length, in pixels.
The weight of a pixel in the search windows is computed by comparing the neighborhood of this pixel with the neighborhood of the target pixel. This value represents the edge size of the neighborhood volume, in number of pixels (patch neighborhood is a square), 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 | |||||
similarity |
The similarity is used to compute weight w(k,n) assigned to each pixel 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 | |||||
outputImage |
The output image. Its dimensions, type, and calibration are forced to the same values as the input. | Image | nullptr |
Object Examples
std::shared_ptr< iolink::ImageView > polystyrene = ioformat::readImage( std::string( IMAGEDEVDATA_IMAGES_FOLDER ) + "polystyrene.tif" ); NonLocalMeansFilter2d nonLocalMeansFilter2dAlgo; nonLocalMeansFilter2dAlgo.setInputImage( polystyrene ); nonLocalMeansFilter2dAlgo.setPatchRadius( 3 ); nonLocalMeansFilter2dAlgo.setKernelRadius( 3 ); nonLocalMeansFilter2dAlgo.setSimilarity( 0.6 ); nonLocalMeansFilter2dAlgo.setKernelShape( NonLocalMeansFilter2d::KernelShape::SQUARE ); nonLocalMeansFilter2dAlgo.execute(); std::cout << "outputImage:" << nonLocalMeansFilter2dAlgo.outputImage()->toString();
polystyrene = ioformat.read_image(imagedev_data.get_image_path("polystyrene.tif")) non_local_means_filter_2d_algo = imagedev.NonLocalMeansFilter2d() non_local_means_filter_2d_algo.input_image = polystyrene non_local_means_filter_2d_algo.patch_radius = 3 non_local_means_filter_2d_algo.kernel_radius = 3 non_local_means_filter_2d_algo.similarity = 0.6 non_local_means_filter_2d_algo.kernel_shape = imagedev.NonLocalMeansFilter2d.SQUARE non_local_means_filter_2d_algo.execute() print( "output_image:", str( non_local_means_filter_2d_algo.output_image ) )
ImageView polystyrene = ViewIO.ReadImage( @"Data/images/polystyrene.tif" ); NonLocalMeansFilter2d nonLocalMeansFilter2dAlgo = new NonLocalMeansFilter2d { inputImage = polystyrene, patchRadius = 3, kernelRadius = 3, similarity = 0.6, kernelShape = NonLocalMeansFilter2d.KernelShape.SQUARE }; nonLocalMeansFilter2dAlgo.Execute(); Console.WriteLine( "outputImage:" + nonLocalMeansFilter2dAlgo.outputImage.ToString() );
Function Examples
std::shared_ptr< iolink::ImageView > polystyrene = ioformat::readImage( std::string( IMAGEDEVDATA_IMAGES_FOLDER ) + "polystyrene.tif" ); auto result = nonLocalMeansFilter2d( polystyrene, 3, 3, 0.6, NonLocalMeansFilter2d::KernelShape::SQUARE ); std::cout << "outputImage:" << result->toString();
polystyrene = ioformat.read_image(imagedev_data.get_image_path("polystyrene.tif")) result = imagedev.non_local_means_filter_2d( polystyrene, 3, 3, 0.6, imagedev.NonLocalMeansFilter2d.SQUARE ) print( "output_image:", str( result ) )
ImageView polystyrene = ViewIO.ReadImage( @"Data/images/polystyrene.tif" ); IOLink.ImageView result = Processing.NonLocalMeansFilter2d( polystyrene, 3, 3, 0.6, NonLocalMeansFilter2d.KernelShape.SQUARE ); Console.WriteLine( "outputImage:" + result.ToString() );