VTK/Examples/Cxx/Images/Gradient
From KitwarePublic
Find the gradient vector of an image at every pixel. Display the original image, the x component of the gradient, the y component of the gradient, and the gradient itself.
- Thanks to Eric Monson.
Gradient.cxx
#include <vtkImageData.h> #include <vtkInteractorStyleImage.h> #include <vtkDoubleArray.h> #include <vtkArrowSource.h> #include <vtkGlyph3DMapper.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkImageMapper3D.h> #include <vtkImageActor.h> #include <vtkPointData.h> #include <vtkImageMathematics.h> #include <vtkImageShiftScale.h> #include <vtkJPEGReader.h> #include <vtkJPEGWriter.h> #include <vtkSmartPointer.h> #include <vtkImageExtractComponents.h> #include <vtkImageRGBToHSV.h> #include <vtkImageGradient.h> #include <vtkImageCast.h> #include <vtkImageCanvasSource2D.h> #include <vtkXMLImageDataWriter.h> int main(int, char *[]) { // Create an image vtkSmartPointer<vtkImageCanvasSource2D> imageSource = vtkSmartPointer<vtkImageCanvasSource2D>::New(); imageSource->SetScalarTypeToUnsignedChar(); imageSource->SetNumberOfScalarComponents(1); imageSource->SetExtent(0, 200, 0, 200, 0, 0); imageSource->SetDrawColor(0, 0, 0); imageSource->FillBox(0, 200, 0, 200); imageSource->SetDrawColor(255, 0, 0); imageSource->FillBox(10, 30, 10, 30); imageSource->Update(); vtkSmartPointer<vtkImageGradient> gradientFilter = vtkSmartPointer<vtkImageGradient>::New(); gradientFilter->SetInputConnection(imageSource->GetOutputPort()); gradientFilter->SetDimensionality(3); gradientFilter->Update(); vtkSmartPointer<vtkXMLImageDataWriter> writer = vtkSmartPointer<vtkXMLImageDataWriter>::New(); writer->SetFileName("test.vti"); writer->SetInputConnection(gradientFilter->GetOutputPort()); writer->Write(); // Extract the x component of the gradient vtkSmartPointer<vtkImageExtractComponents> extractXFilter = vtkSmartPointer<vtkImageExtractComponents>::New(); extractXFilter->SetComponents(0); extractXFilter->SetInputConnection(gradientFilter->GetOutputPort()); extractXFilter->Update(); double xRange[2]; extractXFilter->GetOutput()->GetPointData()->GetScalars()->GetRange(xRange); // Gradient could be negative, so take the absolute value vtkSmartPointer<vtkImageMathematics> imageAbsX = vtkSmartPointer<vtkImageMathematics>::New(); imageAbsX->SetOperationToAbsoluteValue(); imageAbsX->SetInputConnection(extractXFilter->GetOutputPort()); imageAbsX->Update(); // Scale the output (0,255) vtkSmartPointer<vtkImageShiftScale> shiftScaleX = vtkSmartPointer<vtkImageShiftScale>::New(); shiftScaleX->SetOutputScalarTypeToUnsignedChar(); shiftScaleX->SetScale(255 / xRange[1]); shiftScaleX->SetInputConnection(imageAbsX->GetOutputPort()); shiftScaleX->Update(); // Extract the y component of the gradient vtkSmartPointer<vtkImageExtractComponents> extractYFilter = vtkSmartPointer<vtkImageExtractComponents>::New(); extractYFilter->SetComponents(1); extractYFilter->SetInputConnection(gradientFilter->GetOutputPort()); extractYFilter->Update(); double yRange[2]; extractYFilter->GetOutput()->GetPointData()->GetScalars()->GetRange( yRange ); // Gradient could be negative, so take the absolute value vtkSmartPointer<vtkImageMathematics> imageAbsY = vtkSmartPointer<vtkImageMathematics>::New(); imageAbsY->SetOperationToAbsoluteValue(); imageAbsY->SetInputConnection(extractYFilter->GetOutputPort()); imageAbsY->Update(); // Scale the output (0,255) vtkSmartPointer<vtkImageShiftScale> shiftScaleY = vtkSmartPointer<vtkImageShiftScale>::New(); shiftScaleY->SetOutputScalarTypeToUnsignedChar(); shiftScaleY->SetScale(255 / yRange[1]); shiftScaleY->SetInputConnection(imageAbsY->GetOutputPort()); shiftScaleY->Update(); // Visualize // (xmin, ymin, xmax, ymax) double originalViewport[4] = {0.0, 0.0, 0.25, 1.0}; double xGradientViewport[4] = {0.25, 0.0, 0.5, 1.0}; double yGradientViewport[4] = {0.5, 0.0, 0.75, 1.0}; double vectorGradientViewport[4] = {0.75, 0.0, 1.0, 1.0}; // Create a renderer, render window, and interactor vtkSmartPointer<vtkRenderer> originalRenderer = vtkSmartPointer<vtkRenderer>::New(); originalRenderer->SetViewport(originalViewport); vtkSmartPointer<vtkRenderer> xGradientRenderer = vtkSmartPointer<vtkRenderer>::New(); xGradientRenderer->SetViewport(xGradientViewport); vtkSmartPointer<vtkRenderer> yGradientRenderer = vtkSmartPointer<vtkRenderer>::New(); yGradientRenderer->SetViewport(yGradientViewport); vtkSmartPointer<vtkRenderer> vectorGradientRenderer = vtkSmartPointer<vtkRenderer>::New(); vectorGradientRenderer->SetViewport(vectorGradientViewport); vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->SetSize(1200,300); renderWindow->AddRenderer(originalRenderer); renderWindow->AddRenderer(xGradientRenderer); renderWindow->AddRenderer(yGradientRenderer); renderWindow->AddRenderer(vectorGradientRenderer); vtkSmartPointer<vtkImageActor> originalActor = vtkSmartPointer<vtkImageActor>::New(); originalActor->GetMapper()->SetInputConnection(imageSource->GetOutputPort()); vtkSmartPointer<vtkImageActor> xGradientActor = vtkSmartPointer<vtkImageActor>::New(); xGradientActor->GetMapper()->SetInputConnection(shiftScaleX->GetOutputPort()); vtkSmartPointer<vtkImageActor> yGradientActor = vtkSmartPointer<vtkImageActor>::New(); yGradientActor->GetMapper()->SetInputConnection(shiftScaleY->GetOutputPort()); vtkSmartPointer<vtkArrowSource> arrowSource = vtkSmartPointer<vtkArrowSource>::New(); gradientFilter->GetOutput()->GetPointData()->SetActiveVectors("ImageScalarsGradient"); vtkSmartPointer<vtkGlyph3DMapper> vectorGradientMapper = vtkSmartPointer<vtkGlyph3DMapper>::New(); vectorGradientMapper->ScalingOn(); vectorGradientMapper->SetScaleFactor(.01); vectorGradientMapper->SetSourceConnection(arrowSource->GetOutputPort()); vectorGradientMapper->SetInputConnection(gradientFilter->GetOutputPort()); vectorGradientMapper->Update(); vtkSmartPointer<vtkActor> vectorGradientActor = vtkSmartPointer<vtkActor>::New(); vectorGradientActor->SetMapper(vectorGradientMapper); vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); renderWindowInteractor->SetRenderWindow(renderWindow); vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New(); renderWindowInteractor->SetInteractorStyle(style); // Add the actor to the scene originalRenderer->AddActor(originalActor); xGradientRenderer->AddActor(xGradientActor); yGradientRenderer->AddActor(yGradientActor); vectorGradientRenderer->AddActor(originalActor); vectorGradientRenderer->AddActor(vectorGradientActor); // Render and interact renderWindow->Render(); renderWindowInteractor->Start(); return EXIT_SUCCESS; }
CMakeLists.txt
cmake_minimum_required(VERSION 2.6) PROJECT(Gradient) FIND_PACKAGE(VTK REQUIRED) INCLUDE(${VTK_USE_FILE}) ADD_EXECUTABLE(Gradient Gradient.cxx) TARGET_LINK_LIBRARIES(Gradient vtkHybrid)