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

Aashish Chaudhary aashish.chaudhary at kitware.com
Tue Dec 14 09:12:26 EST 2010


You are welcome.

Glad that I was able to help.


On Tue, Dec 14, 2010 at 6:02 AM, Rodrigo M. <rodrigo.geof at gmail.com> wrote:

> 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
> >
>



-- 
| Aashish Chaudhary
| R&D Engineer
| Kitware Inc.
| www.kitware.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20101214/2b383f3a/attachment.htm>


More information about the vtkusers mailing list