Denoising
This example shows how to denoise a grayscale image with three different algorithms available in ImageDev.
The first denoising algorithm applied in this example is BoxFilter2d. This linear filter computes a moving
average on a square window with a user-defined size. It is fast to apply but softens the objects edges and
adds blur to the input image.
The second denoising algorithm is MedianFilter2d. This non-linear filter replaces each pixel by the median value of its neighborhood. It is slower to compute than a box filter but preserves the edges better. It is especially efficient for removing impulse noise.
At last, a NonLocalMeansFilter2d algorithm is applied. This adaptive filter performs a weighted averaging of each pixel with similar pixels of its neighborhood. It is very slow to compute but preserves edges very efficiently.
Figure 1. Denoising filters (a) the initial image, (b) the box filter result,
(c) the median filter result, and (d) the non-local means filter result
Each filter result is saved in the project directory. As expected, the box filter generates blur, the median filter preserves edges better, and the non-local means filter preserves also the internal structure of nuclei.
See also
The second denoising algorithm is MedianFilter2d. This non-linear filter replaces each pixel by the median value of its neighborhood. It is slower to compute than a box filter but preserves the edges better. It is especially efficient for removing impulse noise.
At last, a NonLocalMeansFilter2d algorithm is applied. This adaptive filter performs a weighted averaging of each pixel with similar pixels of its neighborhood. It is very slow to compute but preserves edges very efficiently.
![]() (a) |
![]() (b) |
![]() (c) |
![]() (d) |
Each filter result is saved in the project directory. As expected, the box filter generates blur, the median filter preserves edges better, and the non-local means filter preserves also the internal structure of nuclei.
#include <ImageDev/ImageDev.h>
#include <ioformat/IOFormat.h>
#include <string.h>
using namespace imagedev;
int
main( int argc, char* argv[] )
{
int status = 0;
try
{
// ImageDev library initialization
if ( imagedev::isInitialized() == false )
imagedev::init();
// Open a tif file to denoise
auto imageInput = ioformat::readImage( std::string( IMAGEDEVDATA_IMAGES_FOLDER ) + "mnu.tif" );
// Apply an average filter
std::cout << "Applying a box filter... " << std::endl;
auto imageOutput = boxFilter2d( imageInput, 7, 7, BoxFilter2d::AutoScale::YES );
ioformat::writeView( imageOutput, "T03_01_box.png" );
// Apply a median filter processing
std::cout << "Applying a median filter... " << std::endl;
imageOutput =
medianFilter2d( imageInput, 3, MedianFilter2d::KernelMode::SQUARE, MedianFilter2d::SearchMode::AUTOMATIC );
ioformat::writeView( imageOutput, "T03_01_median.png" );
// Apply a non-local means filter processing
std::cout << "Applying a non-local means filter... " << std::endl;
imageOutput = nonLocalMeansFilter2d( imageInput, 3, 3, 0.6, NonLocalMeansFilter2d::SQUARE );
ioformat::writeView( imageOutput, "T03_01_nlm.png" );
std::cout << "This example ran successfully." << std::endl;
}
catch ( const imagedev::Exception& error )
{
// Print potential exception in the standard output
std::cerr << "ImageDev exception: " << error.what() << std::endl;
status = -1;
}
// ImageDev library finalization
imagedev::finish();
// Check if we must ask for an enter key to close the program
if ( !( ( argc == 2 ) && strcmp( argv[1], "--no-stop-at-end" ) == 0 ) )
std::cout << "Press Enter key to close this window." << std::endl, getchar();
return status;
}
using System;
using ImageDev;
using IOLink;
using IOFormat;
namespace T03_01_Denoising
{
class Program
{
static void Main(string[] args)
{
int status = 0;
try
{
// Initialize the ImageDev library if not done
if (Initialization.IsInitialized() == false)
Initialization.Init();
// Open a tif file to denoise
ImageView imageInput = ViewIO.ReadImage("Data/images/mnu.tif") as ImageView;
// Apply an average filter
Console.WriteLine("Applying a box filter...");
ImageView imageOutput = Processing.BoxFilter2d(imageInput, 7, 7) as ImageView;
IOFormat.ViewIO.WriteView(imageOutput, "T03_01_box.png");
// Apply a median filter processing
Console.WriteLine("Applying a median filter... ");
imageOutput = Processing.MedianFilter2d(imageInput, 3, MedianFilter2d.KernelMode.SQUARE);
IOFormat.ViewIO.WriteView(imageOutput, "T03_01_median.png");
// Apply a non-local means filter processing
Console.WriteLine("Applying a non-local means filter... ");
imageOutput = Processing.NonLocalMeansFilter2d(imageInput, 3, 3);
IOFormat.ViewIO.WriteView(imageOutput, "T03_01_nlm.png");
}
catch (Exception error)
{
// Print potential exception in the standard output
System.Console.WriteLine("HelloImageDev exception: " + error.ToString());
status = -1;
}
// ImageDev library finalization
Initialization.Finish();
// Check if we must ask for an enter key to close the program
if (!((args.Length >= 1) && (args[0] == "--no-stop-at-end")))
{
System.Console.WriteLine("Press Enter key to close this window.");
System.Console.ReadKey();
}
System.Environment.Exit(status);
}
}
}
import imagedev
import imagedev_data
import ioformat
# Initialize the ImageDev library if not done
if (imagedev.is_initialized() == False): imagedev.init()
# Open a tif file to denoise
image_input = ioformat.read_image(imagedev_data.get_image_path("mnu.tif"))
# Apply an average filter
print("Applying a box filter...")
image_output = imagedev.box_filter_2d(image_input, 7, 7)
ioformat.write_view(image_output, "T03_01_box.png")
# Apply a median filter processing
print("Applying a median filter...")
image_output = imagedev.median_filter_2d(image_input, 3, imagedev.MedianFilter2d.SQUARE)
ioformat.write_view(image_output, "T03_01_median.png")
# Apply a non-local means filter processing
print("Applying a non-local means filter...")
image_output = imagedev.non_local_means_filter_2d(image_input, 3, 3)
ioformat.write_view(image_output, "T03_01_nlm.png")
# ImageDev library finalization
imagedev.finish() See also



