[vtkusers] Rubber band zoom and pick on 2d image
rodrigo
rodrigo.geof at gmail.com
Tue Dec 7 16:14:24 EST 2010
Hello, I'm new to vtk, what I want to do is to zoom on a 2D image using a
Rubber band box, and to have my mouse coordinates showed up.
I tried to modify one of the wiki examples, but I couldn't make the mouse
coordinates be showed up and have the rubber band at the same time. Besides
that, I have no idea on how to make the rubber band zoom my image. I really
want to use the coordinates grabbed by the rubber box to zoom the image.
Here is my code:
#include <vtk-5.2/vtkAssemblyPath.h>
#include <vtk-5.2/vtkCell.h>
#include <vtk-5.2/vtkCommand.h>
#include <vtk-5.2/vtkCornerAnnotation.h>
#include <vtk-5.2/vtkImageActor.h>
#include <vtk-5.2/vtkImageData.h>
#include <vtk-5.2/vtkImageViewer2.h>
#include <vtk-5.2/vtkInteractorStyleImage.h>
#include <vtk-5.2/vtkJPEGReader.h>
#include <vtk-5.2/vtkPointData.h>
#include <vtk-5.2/vtkPropPicker.h>
#include <vtk-5.2/vtkRenderer.h>
#include <vtk-5.2/vtkRenderWindow.h>
#include <vtk-5.2/vtkRenderWindowInteractor.h>
#include <vtk-5.2/vtkSmartPointer.h>
#include <vtk-5.2/vtkTextProperty.h>
#include <vtkInteractorStyleRubberBand2D.h>
#include <vtkCallbackCommand.h>
// The mouse motion callback, to pick the image and recover pixel values
class vtkImageInteractionCallback1 : public vtkCommand
{
public:
static vtkImageInteractionCallback1 *New()
{
return new vtkImageInteractionCallback1;
}
vtkImageInteractionCallback1()
{
this->Viewer = 0;
this->Picker = 0;
this->Annotation = 0;
this->PointData = vtkPointData::New();
}
~vtkImageInteractionCallback1()
{
this->Viewer = 0;
this->Picker = 0;
this->Annotation = 0;
this->PointData->Delete();
}
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 *)
{
//this->Viewer;
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());
image->Update();
// 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 );
// Fixes some numerical problems with the picking
double *bounds = actor->GetDisplayBounds();
int axis = this->Viewer->GetSliceOrientation();
pos[axis] = bounds[2*axis];
vtkPointData* pd = image->GetPointData();
if( !pd )
{
return;
}
this->PointData->InterpolateAllocate( pd, 1, 1 );
// Use tolerance as a function of size of source data
double tol2 = image->GetLength();
tol2 = tol2 ? tol2*tol2 / 1000.0 : 0.001;
// Find the cell that contains pos
int subId;
double pcoords[3], weights[8];
vtkCell* cell = image->FindAndGetCell(
pos, NULL, -1, tol2, subId, pcoords, weights );
if( cell )
{
// Interpolate the point data
this->PointData->InterpolatePoint( pd, 0, cell->PointIds, weights );
int components =
this->PointData->GetScalars()->GetNumberOfComponents();
double* tuple = this->PointData->GetScalars()->GetTuple( 0 );
std::string message = "Location: ( ";
message += vtkVariant( pos[0] ).ToString();
message += ", ";
message += vtkVariant( pos[1] ).ToString();
message += ", ";
message += vtkVariant( pos[2] ).ToString();
message += " )\nValue: ( ";
for( int c = 0; c < components; ++c )
{
message += vtkVariant( tuple[ c ] ).ToString();
if( c != components - 1 )
{
message += ", ";
}
}
message += " )";
this->Annotation->SetText( 0, message.c_str() );
interactor->Render();
style->OnMouseMove();
}
}
private:
// Pointer to the viewer
vtkImageViewer2 *Viewer;
// Pointer to the picker
vtkPropPicker *Picker;
// Pointer to the annotation
vtkCornerAnnotation *Annotation;
// Interpolator
vtkPointData* PointData;
};
void SelectionChangedCallbackFunction ( vtkObject* vtkNotUsed(caller),
long unsigned int vtkNotUsed(eventId), void* vtkNotUsed(clientData),
void* callData )
{
std::cout << "SelectionChanged callback" << std::endl;
unsigned int* rect = reinterpret_cast<unsigned int*> ( callData );
unsigned int pos1X = rect[0];
unsigned int pos1Y = rect[1];
unsigned int pos2X = rect[2];
unsigned int pos2Y = rect[3];
std::cout << "Start x: " << pos1X << " Start y: " << pos1Y
<< " End x: " << pos2X << " End y: " << pos2Y << std::endl;
}
int main ( int argc, char* argv[] )
{
//Verify input arguments
if ( argc != 2 )
{
std::cout << "Usage: " << argv[0]
<< " Filename(jpeg)" << std::endl;
return EXIT_FAILURE;
}
//Parse input argument
std::string inputFilename = argv[1];
//Read the image
vtkSmartPointer<vtkJPEGReader> jpegReader =
vtkSmartPointer<vtkJPEGReader>::New();
if( !jpegReader->CanReadFile( inputFilename.c_str() ) )
{
std::cout << argv[0] << ": Error reading file "
<< inputFilename << endl << "Exiting..." << endl;
return EXIT_FAILURE;
}
jpegReader->SetFileName ( inputFilename.c_str() );
// Picker to pick pixels
vtkSmartPointer<vtkPropPicker> propPicker =
vtkSmartPointer<vtkPropPicker>::New();
propPicker->PickFromListOn();
// Give the picker a prop to pick
vtkSmartPointer<vtkImageViewer2> imageViewer =
vtkSmartPointer<vtkImageViewer2>::New();
propPicker->AddPickList( imageViewer->GetImageActor() );
// Visualize
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
imageViewer->SetInputConnection( jpegReader->GetOutputPort() );
imageViewer->SetupInteractor( renderWindowInteractor );
imageViewer->SetSize( 600, 600 );
vtkRenderer* renderer = imageViewer->GetRenderer();
renderer->ResetCamera();
renderer->GradientBackgroundOn();
renderer->SetBackground(0,0,0);
renderer->SetBackground2(1,1,1);
// 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<vtkImageInteractionCallback1> callback =
vtkSmartPointer<vtkImageInteractionCallback1>::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 );
vtkSmartPointer<vtkCallbackCommand> selectionChangedCallback =
vtkSmartPointer<vtkCallbackCommand>::New();
selectionChangedCallback->SetCallback ( SelectionChangedCallbackFunction );
vtkSmartPointer<vtkInteractorStyleRubberBand2D> style =
vtkSmartPointer<vtkInteractorStyleRubberBand2D>::New();
style->AddObserver ( vtkCommand::SelectionChangedEvent,
selectionChangedCallback );
renderWindowInteractor->SetInteractorStyle( style );
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
--
View this message in context: http://vtk.1045678.n5.nabble.com/Rubber-band-zoom-and-pick-on-2d-image-tp3296495p3296495.html
Sent from the VTK - Users mailing list archive at Nabble.com.
More information about the vtkusers
mailing list