[vtkusers] Rubber band zoom and pick on 2d image

Rodrigo M. rodrigo.geof at gmail.com
Tue Dec 14 06:02:52 EST 2010


Hi Aashish,

Thanks a lot, this is exactly what I was looking for. =)

2010/12/14 Aashish Chaudhary <aashish.chaudhary at kitware.com>:
> Hi Rodrigo,
> If you have not found the answer this might help:
> On the style you can query GetStartPosition() and GetEndPosition()
> Convert these positions to world coordinate using vtkViewPort functions
> something like this:
>
> double startWorldPosition[4], endWorldPosition[4];
>
>   this->MainRenderer->SetViewPoint(
>
>     (startPosition[0] - halfWidth) / halfWidth,
>
>     (startPosition[1] - halfHeight) / halfHeight,
>
>     1);
>
>   this->MainRenderer->ViewToWorld();
>
>   this->MainRenderer->GetWorldPoint(startWorldPosition);
>
>   this->MainRenderer->SetViewPoint(
>
>     (endPosition[0] - halfWidth) / halfWidth,
>
>     (endPosition[1] - halfHeight) / halfHeight,
>
>     1);
>
>   this->MainRenderer->ViewToWorld();
>
>   this->MainRenderer->GetWorldPoint(endWorldPosition);
>
>   int targetExtents[4] = {
>
>     startWorldPosition[0] < endWorldPosition[0] ? startWorldPosition[0] :
> endWorldPosition[0],
>
>     startWorldPosition[0] > endWorldPosition[0] ? startWorldPosition[0] :
> endWorldPosition[0],
>
>     startWorldPosition[1] < endWorldPosition[1] ? startWorldPosition[1] :
> endWorldPosition[1],
>
>     startWorldPosition[1] > endWorldPosition[1] ? startWorldPosition[1] :
> endWorldPosition[1]};
>
> Once you get target extents you can set camera center to center of these
> extents something like this:
>
>
>     camera->SetPosition(newCenter[0], newCenter[1], 1);
>
>     camera->SetFocalPoint(newCenter[0], newCenter[1], 0);
>
>     camera->SetViewUp(0, 1, 0); // just to make sure
>
>     camera->SetParallelScale((newExtents[3] - newExtents[2]) / 2.0);
>
> Hope this helps.
> On Tue, Dec 7, 2010 at 4:14 PM, rodrigo <rodrigo.geof at gmail.com> wrote:
>>
>> 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.
>> _______________________________________________
>> Powered by www.kitware.com
>>
>> Visit other Kitware open-source projects at
>> http://www.kitware.com/opensource/opensource.html
>>
>> Please keep messages on-topic and check the VTK FAQ at:
>> http://www.vtk.org/Wiki/VTK_FAQ
>>
>> Follow this link to subscribe/unsubscribe:
>> http://www.vtk.org/mailman/listinfo/vtkusers
>
>
>
> --
> | Aashish Chaudhary
> | R&D Engineer
> | Kitware Inc.
> | www.kitware.com
>



More information about the vtkusers mailing list