PickPixel2
VTKExamples/Cxx/Images/PickPixel2
Description¶
This example demonstrates how to continuously retrieve pixel values using the mouse.
This example is a slight modification of the existing example PickPixel. The main difference is the display of the exact pixel coordinates and values instead of interpolated values.
Code¶
PickPixel2.cxx
#include <vtkVersion.h> #include <vtkAssemblyPath.h> #include <vtkCell.h> #include <vtkCommand.h> #include <vtkCornerAnnotation.h> #include <vtkImageActor.h> #include <vtkImageData.h> #include <vtkImageViewer2.h> #include <vtkInteractorStyleImage.h> #include <vtkTIFFReader.h> #include <vtkPointData.h> #include <vtkPropPicker.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkSmartPointer.h> #include <vtkTextProperty.h> #include <vtkImageNoiseSource.h> #include <vtkImageCast.h> #include <vtkMath.h> // Template for image value reading template<typename T> void vtkValueMessageTemplate(vtkImageData* image, int* position, std::string& message) { T* tuple = ((T*)image->GetScalarPointer(position)); int components = image->GetNumberOfScalarComponents(); for (int c = 0; c < components; ++c) { message += vtkVariant(tuple[c]).ToString(); if (c != (components - 1)) { message += ", "; } } message += " )"; } // The mouse motion callback, to pick the image and recover pixel values class vtkImageInteractionCallback : public vtkCommand { public: static vtkImageInteractionCallback *New() { return new vtkImageInteractionCallback; } vtkImageInteractionCallback() { this->Viewer = NULL; this->Picker = NULL; this->Annotation = NULL; } ~vtkImageInteractionCallback() { this->Viewer = NULL; this->Picker = NULL; this->Annotation = NULL; } void SetPicker(vtkPropPicker *picker) { this->Picker = picker; } void SetAnnotation(vtkCornerAnnotation *annotation) { this->Annotation = annotation; } void SetViewer(vtkImageViewer2 *viewer) { this->Viewer = viewer; } virtual void Execute(vtkObject *, unsigned long vtkNotUsed(event), void *) { vtkRenderWindowInteractor *interactor = this->Viewer->GetRenderWindow()->GetInteractor(); vtkRenderer* renderer = this->Viewer->GetRenderer(); vtkImageActor* actor = this->Viewer->GetImageActor(); vtkImageData* image = this->Viewer->GetInput(); vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast( interactor->GetInteractorStyle()); #if VTK_MAJOR_VERSION <= 5 image->Update(); #endif // Pick at the mouse location provided by the interactor this->Picker->Pick(interactor->GetEventPosition()[0], interactor->GetEventPosition()[1], 0.0, renderer); // There could be other props assigned to this picker, so // make sure we picked the image actor vtkAssemblyPath* path = this->Picker->GetPath(); bool validPick = false; if (path) { vtkCollectionSimpleIterator sit; path->InitTraversal(sit); vtkAssemblyNode *node; for (int i = 0; i < path->GetNumberOfItems() && !validPick; ++i) { node = path->GetNextNode(sit); if (actor == vtkImageActor::SafeDownCast(node->GetViewProp())) { validPick = true; } } } if (!validPick) { this->Annotation->SetText(0, "Off Image"); interactor->Render(); // Pass the event further on style->OnMouseMove(); return; } // Get the world coordinates of the pick double pos[3]; this->Picker->GetPickPosition(pos); int image_coordinate[3]; int axis = this->Viewer->GetSliceOrientation(); switch (axis) { case vtkImageViewer2::SLICE_ORIENTATION_XZ: image_coordinate[0] = vtkMath::Round(pos[0]); image_coordinate[1] = this->Viewer->GetSlice(); image_coordinate[2] = vtkMath::Round(pos[2]); break; case vtkImageViewer2::SLICE_ORIENTATION_YZ: image_coordinate[0] = this->Viewer->GetSlice(); image_coordinate[1] = vtkMath::Round(pos[0]); image_coordinate[2] = vtkMath::Round(pos[1]); break; default: // vtkImageViewer2::SLICE_ORIENTATION_XY image_coordinate[0] = vtkMath::Round(pos[0]); image_coordinate[1] = vtkMath::Round(pos[1]); image_coordinate[2] = this->Viewer->GetSlice(); break; } std::string message = "Location: ( "; message += vtkVariant(image_coordinate[0]).ToString(); message += ", "; message += vtkVariant(image_coordinate[1]).ToString(); message += ", "; message += vtkVariant(image_coordinate[2]).ToString(); message += " )\nValue: ( "; switch (image->GetScalarType()) { vtkTemplateMacro((vtkValueMessageTemplate<VTK_TT>(image, image_coordinate, message))); default: return; } this->Annotation->SetText( 0, message.c_str() ); interactor->Render(); style->OnMouseMove(); } private: vtkImageViewer2* Viewer; // Pointer to the viewer vtkPropPicker* Picker; // Pointer to the picker vtkCornerAnnotation* Annotation; // Pointer to the annotation }; int main(int argc, char* argv[]) { vtkSmartPointer<vtkImageViewer2> imageViewer = vtkSmartPointer<vtkImageViewer2>::New(); // Verify input arguments if (argc != 2) { std::cout << argv[0] << " Required parameters: (tif) Filename" << std::endl << "missing..." << std::endl; std::cout << "A noise image will be created!" << std::endl; // create a noise image vtkSmartPointer<vtkImageNoiseSource> noiseSource = vtkSmartPointer<vtkImageNoiseSource>::New(); noiseSource->SetWholeExtent(0, 512, 0, 512, 0, 0); noiseSource->SetMinimum(0.0); noiseSource->SetMaximum(65535.0); // cast noise image to unsigned short vtkSmartPointer<vtkImageCast> imageCast = vtkSmartPointer<vtkImageCast>::New(); imageCast->SetInputConnection(noiseSource->GetOutputPort()); imageCast->SetOutputScalarTypeToUnsignedShort(); imageCast->Update(); // connect to image viewer pipeline imageViewer->SetInputConnection(imageCast->GetOutputPort()); } else { // Parse input argument std::string inputFilename = argv[1]; //Read the image vtkSmartPointer<vtkTIFFReader> tiffReader = vtkSmartPointer<vtkTIFFReader>::New(); if (!tiffReader->CanReadFile(inputFilename.c_str())) { std::cout << argv[0] << ": Error reading file " << inputFilename << std::endl; return EXIT_FAILURE; } tiffReader->SetFileName(inputFilename.c_str()); // connect to image viewer pipeline imageViewer->SetInputConnection(tiffReader->GetOutputPort()); } // Picker to pick pixels vtkSmartPointer<vtkPropPicker> propPicker = vtkSmartPointer<vtkPropPicker>::New(); propPicker->PickFromListOn(); // Give the picker a prop to pick vtkImageActor* imageActor = imageViewer->GetImageActor(); propPicker->AddPickList(imageActor); // disable interpolation, so we can see each pixel imageActor->InterpolateOff(); // Visualize vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); imageViewer->SetupInteractor(renderWindowInteractor); imageViewer->SetSize(600, 600); vtkRenderer* renderer = imageViewer->GetRenderer(); renderer->ResetCamera(); renderer->GradientBackgroundOn(); renderer->SetBackground(0.6, 0.6, 0.5); renderer->SetBackground2(0.3, 0.3, 0.2); // Annotate the image with window/level and mouse over pixel // information vtkSmartPointer<vtkCornerAnnotation> cornerAnnotation = vtkSmartPointer<vtkCornerAnnotation>::New(); cornerAnnotation->SetLinearFontScaleFactor(2); cornerAnnotation->SetNonlinearFontScaleFactor(1); cornerAnnotation->SetMaximumFontSize(20); cornerAnnotation->SetText(0, "Off Image"); cornerAnnotation->SetText(3, "<window>\n<level>"); cornerAnnotation->GetTextProperty()->SetColor(1, 0, 0); imageViewer->GetRenderer()->AddViewProp(cornerAnnotation); // Callback listens to MouseMoveEvents invoked by the interactor's style vtkSmartPointer<vtkImageInteractionCallback> callback = vtkSmartPointer<vtkImageInteractionCallback>::New(); callback->SetViewer(imageViewer); callback->SetAnnotation(cornerAnnotation); callback->SetPicker(propPicker); // InteractorStyleImage allows for the following controls: // 1) middle mouse + move = camera pan // 2) left mouse + move = window/level // 3) right mouse + move = camera zoom // 4) middle mouse wheel scroll = zoom // 5) 'r' = reset window/level // 6) shift + 'r' = reset camera vtkInteractorStyleImage* imageStyle = imageViewer->GetInteractorStyle(); imageStyle->AddObserver(vtkCommand::MouseMoveEvent, callback); renderWindowInteractor->Initialize(); renderWindowInteractor->Start(); return EXIT_SUCCESS; }
CMakeLists.txt¶
cmake_minimum_required(VERSION 2.8) PROJECT(PickPixel2) find_package(VTK REQUIRED) include(${VTK_USE_FILE}) add_executable(PickPixel2 MACOSX_BUNDLE PickPixel2.cxx) target_link_libraries(PickPixel2 ${VTK_LIBRARIES})
Download and Build PickPixel2¶
Danger
The generation of tar files has not been ported to the new VTKExamples. Some tarballs may be missing or out-of-date.
Click here to download PickPixel2 and its CMakeLists.txt file. Once the tarball PickPixel2.tar has been downloaded and extracted,
cd PickPixel2/build
If VTK is installed:
cmake ..
If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:
cmake -DVTK_DIR:PATH=/home/me/vtk_build ..
Build the project:
make
and run it:
./PickPixel2
WINDOWS USERS PLEASE NOTE: Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.