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