ITK  5.4.0 Insight Toolkit
Examples/Filtering/FFTImageFilterFourierDomainFiltering.cxx
/*=========================================================================
*
*
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
*
*=========================================================================*/
// Software Guide : BeginLatex
//
// One of the most common image processing operations performed in the
// Fourier Domain is the masking of the spectrum in order to eliminate a
// range of spatial frequencies from the input image. This operation is
// typically performed by taking the input image, computing its Fourier
// transform using a FFT filter, masking the resulting image in the Fourier
// domain with a mask, and finally taking the result of the masking and
// computing its inverse Fourier transform.
//
// This typical process is illustrated in the example below.
//
// \index{itk::Forward\-FFT\-Image\-Filter}
// \index{itk::Vnl\-Forward\-FFT\-Image\-Filter}
// \index{itk::FFTW\-Forward\-FFT\-Image\-Filter}
//
// Software Guide : EndLatex
#include "itkImage.h"
// Software Guide : BeginLatex
//
// We start by including the headers of the FFT filters and the Mask image
// filter. Note that we use two different types of FFT filters here. The first
// one expects as input an image of real pixel type (real in the sense of
// complex numbers) and produces as output a complex image. The second FFT
// filter expects as in put a complex image and produces a real image as
// output.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
// Software Guide : EndCodeSnippet
int
main(int argc, char * argv[])
{
if (argc < 4)
{
std::cerr << "Usage: " << argv[0] << " inputScalarImage inputMaskImage";
std::cerr << " outputFilteredImage" << std::endl;
}
// Software Guide : BeginLatex
//
// The first decision to make is related to the pixel type and dimension of
// the images on which we want to compute the Fourier transform.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
using InputPixelType = float;
constexpr unsigned int Dimension = 2;
using InputImageType = itk::Image<InputPixelType, Dimension>;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Then we select the pixel type to use for the mask image and instantiate
// the image type of the mask.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Both the input image and the mask image can be read from files or could
// be obtained as the output of a preprocessing pipeline. We omit here the
// details of reading the image since the process is quite standard.
//
// Software Guide : EndLatex
// Software Guide : BeginLatex
//
// Now the \doxygen{VnlForwardFFTImageFilter} can be instantiated.
// Like most ITK filters, the FFT filter is instantiated using the full
// image type. By not setting the output image type, we decide to use the
// default one provided by the filter. Using this type we construct one
// instance of the filter.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
auto fftFilter = FFTFilterType::New();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Since our purpose is to perform filtering in the frequency domain by
// altering the weights of the image spectrum, we need a filter that will
// mask the Fourier transform of the input image with a binary image. Note
// that the type of the spectral image is taken here from the traits of the
// FFT filter.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
using SpectralImageType = FFTFilterType::OutputImageType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We connect the inputs to the mask filter by taking the outputs from the
// first FFT filter and from the reader of the Mask image.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// For the purpose of verifying the aspect of the spectrum after being
// filtered with the mask, we can write out the output of the Mask filter to
// a file.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
using SpectralWriterType = itk::ImageFileWriter<SpectralImageType>;
auto spectralWriter = SpectralWriterType::New();
spectralWriter->SetFileName("filteredSpectrum.mhd");
spectralWriter->Update();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The output of the mask filter will contain the \emph{filtered} spectrum
// of the input image. We must then apply an inverse Fourier transform on it
// in order to obtain the filtered version of the input image. For that
// purpose we create another instance of the FFT filter.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
auto fftInverseFilter = IFFTFilterType::New();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The execution of the pipeline can be triggered by invoking the
// \code{Update()} method in this last filter. Since this invocation can
// eventually throw an exception, the call must be placed inside a try/catch
// block.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
try
{
fftInverseFilter->Update();
}
catch (const itk::ExceptionObject & excp)
{
std::cerr << "Error: " << std::endl;
std::cerr << excp << std::endl;
return EXIT_FAILURE;
}
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The result of the filtering can now be saved into an image file, or be
// passed to a subsequent processing pipeline. Here we simply write it out
// to an image file.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
auto writer = WriterType::New();
writer->SetFileName(argv[3]);
writer->SetInput(fftInverseFilter->GetOutput());
// Software Guide : EndCodeSnippet
try
{
writer->Update();
}
catch (const itk::ExceptionObject & excp)
{
std::cerr << "Error writing the real image: " << std::endl;
std::cerr << excp << std::endl;
return EXIT_FAILURE;
}
// Software Guide : BeginLatex
//
// Note that this example is just a minimal illustration of the multiple
// types of processing that are possible in the Fourier domain.
//
// Software Guide : EndLatex
return EXIT_SUCCESS;
}
itkImage.h
itk::VnlInverseFFTImageFilter
VNL-based reverse Fast Fourier Transform.
Definition: itkVnlInverseFFTImageFilter.h:48
Data source that reads image data from a single file.
itk::ImageFileWriter
Writes image data to a single file.
Definition: itkImageFileWriter.h:88
itkRescaleIntensityImageFilter.h
itkImageFileWriter.h
itkVnlForwardFFTImageFilter.h
itk::VnlForwardFFTImageFilter
VNL based forward Fast Fourier Transform.
Definition: itkVnlForwardFFTImageFilter.h:45
itkVnlInverseFFTImageFilter.h
itk::Image
Templated n-dimensional image class.
Definition: itkImage.h:88
New
static Pointer New()
itk::GTest::TypedefsAndConstructors::Dimension2::Dimension
constexpr unsigned int Dimension
Definition: itkGTestTypedefsAndConstructors.h:44