Compute and Display Gradient of Image#

Warning

Fix Problem Contains problems not fixed from original wiki.

Synopsis#

Compute and display the gradient of an image.

Results#

Note

Help Wanted Implementation of Results for sphinx examples containing this message. Reconfiguration of CMakeList.txt may be necessary. Write An Example <https://itk.org/ITKExamples/Documentation/Contribute/WriteANewExample.html>

Code#

C++#

#include "itkImage.h"
#include "itkCovariantVector.h"
#include "itkImageFileReader.h"
#include "itkGradientImageFilter.h"

#include <itkImageToVTKImageFilter.h>

#include "vtkPointData.h"
#include "vtkFloatArray.h"
#include "vtkImageData.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderWindow.h"
#include "vtkSmartPointer.h"
#include "vtkImageActor.h"
#include "vtkActor.h"
#include "vtkInteractorStyleImage.h"
#include "vtkRenderer.h"
#include "vtkGlyph3DMapper.h"
#include "vtkArrowSource.h"

static void
VectorImageToVTKImage(itk::Image<itk::CovariantVector<float, 2>, 2>::Pointer vectorImage, vtkImageData * VTKImage);

int
main(int argc, char * argv[])
{
  // Verify command line arguments
  if (argc < 2)
  {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << "inputImageFile" << std::endl;
    return EXIT_FAILURE;
  }

  // Parse command line arguments
  std::string inputFileName = argv[1];

  // Setup types
  using FloatImageType = itk::Image<float, 2>;
  using UnsignedCharImageType = itk::Image<unsigned char, 2>;

  const auto input = itk::ReadImage<UnsignedCharImageType>(inputFileName);

  // Create and setup a gradient filter
  using GradientFilterType = itk::GradientImageFilter<UnsignedCharImageType, float>;
  auto gradientFilter = GradientFilterType::New();
  gradientFilter->SetInput(input);
  gradientFilter->Update();

  // Visualize original image
  using ConnectorType = itk::ImageToVTKImageFilter<UnsignedCharImageType>;
  auto originalConnector = ConnectorType::New();
  originalConnector->SetInput(input);

  vtkSmartPointer<vtkImageActor> originalActor = vtkSmartPointer<vtkImageActor>::New();
  originalActor->SetInput(originalConnector->GetOutput());

  // Visualize gradient
  vtkSmartPointer<vtkImageData> gradientImage = vtkSmartPointer<vtkImageData>::New();
  VectorImageToVTKImage(gradientFilter->GetOutput(), gradientImage);

  vtkSmartPointer<vtkArrowSource> arrowSource = vtkSmartPointer<vtkArrowSource>::New();

  vtkSmartPointer<vtkGlyph3DMapper> gradientMapper = vtkSmartPointer<vtkGlyph3DMapper>::New();
  gradientMapper->ScalingOn();
  gradientMapper->SetScaleFactor(.05);
  gradientMapper->SetSourceConnection(arrowSource->GetOutputPort());
  gradientMapper->SetInputConnection(gradientImage->GetProducerPort());
  gradientMapper->Update();

  vtkSmartPointer<vtkActor> gradientActor = vtkSmartPointer<vtkActor>::New();
  gradientActor->SetMapper(gradientMapper);

  // Visualize
  // Define viewport ranges
  // (xmin, ymin, xmax, ymax)
  double leftViewport[4] = { 0.0, 0.0, 0.5, 1.0 };
  double rightViewport[4] = { 0.5, 0.0, 1.0, 1.0 };

  // Setup both renderers
  vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->SetSize(600, 300);

  vtkSmartPointer<vtkRenderer> leftRenderer = vtkSmartPointer<vtkRenderer>::New();
  renderWindow->AddRenderer(leftRenderer);
  leftRenderer->SetViewport(leftViewport);

  vtkSmartPointer<vtkRenderer> rightRenderer = vtkSmartPointer<vtkRenderer>::New();
  renderWindow->AddRenderer(rightRenderer);
  rightRenderer->SetViewport(rightViewport);
  rightRenderer->SetBackground(1, 0, 0);

  leftRenderer->AddActor(originalActor);
  rightRenderer->AddActor(gradientActor);

  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();

  vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();
  renderWindowInteractor->SetInteractorStyle(style);

  renderWindowInteractor->SetRenderWindow(renderWindow);
  renderWindowInteractor->Initialize();

  renderWindowInteractor->Start();

  return EXIT_SUCCESS;
}

void
VectorImageToVTKImage(itk::Image<itk::CovariantVector<float, 2>, 2>::Pointer vectorImage, vtkImageData * VTKImage)
{
  itk::Image<itk::CovariantVector<float, 2>, 2>::RegionType region = vectorImage->GetLargestPossibleRegion();
  itk::Image<itk::CovariantVector<float, 2>, 2>::SizeType   imageSize = region.GetSize();
  VTKImage->SetExtent(0, imageSize[0] - 1, 0, imageSize[1] - 1, 0, 0);

  vtkSmartPointer<vtkFloatArray> vectors = vtkSmartPointer<vtkFloatArray>::New();
  vectors->SetNumberOfComponents(3);
  vectors->SetNumberOfTuples(imageSize[0] * imageSize[1]);
  vectors->SetName("GradientVectors");

  int counter = 0;
  for (unsigned int j = 0; j < imageSize[1]; ++j)
  {
    for (unsigned int i = 0; i < imageSize[0]; ++i)
    {
      itk::Image<itk::CovariantVector<float, 2>, 2>::IndexType index;
      index[0] = i;
      index[1] = j;

      itk::Image<itk::CovariantVector<float, 2>, 2>::PixelType pixel = vectorImage->GetPixel(index);

      float v[2];
      v[0] = pixel[0];
      v[1] = pixel[1];
      v[2] = 0;
      vectors->InsertTupleValue(counter, v);
      counter++;
    }
  }
  // std::cout << region << std::endl;

  VTKImage->GetPointData()->SetVectors(vectors);
}

Classes demonstrated#

template<typename TInputImage, typename TOperatorValueType = float, typename TOutputValueType = float, typename TOutputImageType = Image<CovariantVector<TOutputValueType, TInputImage::ImageDimension>, TInputImage::ImageDimension>>
class GradientImageFilter : public itk::ImageToImageFilter<TInputImage, TOutputImageType>

Computes the gradient of an image using directional derivatives.

Computes the gradient of an image using directional derivatives. The directional derivative at each pixel location is computed by convolution with a first-order derivative operator.

The second template parameter defines the value type used in the derivative operator (defaults to float). The third template parameter defines the value type used for output image (defaults to float). The output image is defined as a covariant vector image whose value type is specified as this third template parameter.

See

Image

See

Neighborhood

See

NeighborhoodOperator

See

NeighborhoodIterator

ITK Sphinx Examples:

See itk::GradientImageFilter for additional documentation.