[vtkusers] Res: vtkSeedWidget

Karthik Krishnan karthik.krishnan at kitware.com
Tue Aug 12 09:28:21 EDT 2008



Wagner Sales wrote:
> Hi,
>
> I'm on the same problem (using vtkSeedWidget and points does not 
> disappear after slice change), and after a lot of google search, this 
> message appears ( :) ). But I have some questions:
>
> From Karthik:

I worte the following example code to display an volume, a slice slider, 
and a handle widget on a particular slice.

The Handle Widget should appear on slice 43 and does disappear with the 
slice change. The seed widget is just implemented as a collection of 
handle widgets, so if one works, the other should too. This example 
should get your started.

You are probably missing the 
interactorStyle->AutoAdjustCameraClippingRangeOff().

The AutoAdjustCameraClippingRange ensures that it displays all the props 
in the scene (in so far as possible). You don't want that when you are 
displaying just a slice with an ImageViewer.


--------

#include "vtkImageData.h"
#include "vtkVolume16Reader.h"
#include "vtkImageShiftScale.h"
#include "vtkImageViewer2.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSliderRepresentation.h"
#include "vtkSliderRepresentation2D.h"
#include "vtkSliderWidget.h"
#include "vtkCommand.h"
#include "vtkHandleWidget.h"
#include "vtkImageActorPointPlacer.h"
#include "vtkPointHandleRepresentation3D.h"
#include "vtkInteractorStyleImage.h"
#include "vtkCamera.h"
#include "vtkInteractorEventRecorder.h"
#include "vtkTestUtilities.h"
#include "vtkRenderWindow.h"
#include "vtkRegressionTestImage.h"
#include "vtkProperty.h"

class vtkSliderCallback2 : public vtkCommand
{
public:
  static vtkSliderCallback2 *New()
    { return new vtkSliderCallback2; }
  void SetImageViewer(vtkImageViewer2 *viewer)
    { m_Viewer =  viewer; }
  virtual void Execute(vtkObject *caller, unsigned long , void* )
    {
    vtkSliderWidget *slider = (vtkSliderWidget *)caller;
    vtkSliderRepresentation *sliderRepres = (vtkSliderRepresentation 
*)slider->GetRepresentation();     
    int pos = (int)sliderRepres->GetValue();

    m_Viewer->SetSlice(pos);
    }
protected:
  vtkImageViewer2 *m_Viewer;
};

int main(int argc, char *argv[])
{
  char fname[] = "/home/karthik/Data/VTKData/Data/headsq/quarter";

  vtkVolume16Reader* v16 = vtkVolume16Reader::New();
  v16->SetDataDimensions(64, 64);
  v16->SetDataByteOrderToLittleEndian();
  v16->SetImageRange(1, 93);
  v16->SetDataSpacing(3.2, 3.2, 1.5);
  v16->SetFilePrefix(fname);
  v16->ReleaseDataFlagOn();
  v16->SetDataMask(0x7fff);
  v16->Update();
  
  double range[2];
  v16->GetOutput()->GetScalarRange(range);

  vtkImageShiftScale* shifter = vtkImageShiftScale::New();
  shifter->SetShift(-1.0*range[0]);
  shifter->SetScale(255.0/(range[1]-range[0]));
  shifter->SetOutputScalarTypeToUnsignedChar();
  shifter->SetInputConnection(v16->GetOutputPort());
  shifter->ReleaseDataFlagOff();
  shifter->Update();

 
  vtkImageViewer2 *ImageViewer = vtkImageViewer2::New();
  ImageViewer->SetInput(shifter->GetOutput());
  ImageViewer->SetColorLevel(127);
  ImageViewer->SetColorWindow(255);

  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
  ImageViewer->SetupInteractor(iren);

  ImageViewer->Render();
  ImageViewer->GetRenderer()->ResetCamera();
 
  // Important. If you don't have this, the camera clipping range will 
be adjusted
  // to display both the handle and the image actor almost always. We 
want the
  // clipping range to include just the slice being shown.
  ImageViewer->GetInteractorStyle()->AutoAdjustCameraClippingRangeOff();

  ImageViewer->Render();   
 
  vtkSliderRepresentation2D *SliderRepres = 
vtkSliderRepresentation2D::New();
  int min = ImageViewer->GetSliceMin();
  int max = ImageViewer->GetSliceMax();
  SliderRepres->SetMinimumValue(min);
  SliderRepres->SetMaximumValue(max);
  SliderRepres->SetValue((int)((min + max) / 2));
  SliderRepres->SetTitleText("Slice");
  
SliderRepres->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedDisplay();
  SliderRepres->GetPoint1Coordinate()->SetValue(0.3, 0.05);
  
SliderRepres->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedDisplay();
  SliderRepres->GetPoint2Coordinate()->SetValue(0.7, 0.05);
  SliderRepres->SetSliderLength(0.02);
  SliderRepres->SetSliderWidth(0.03);
  SliderRepres->SetEndCapLength(0.01);
  SliderRepres->SetEndCapWidth(0.03);
  SliderRepres->SetTubeWidth(0.005);
  SliderRepres->SetLabelFormat("%3.0lf");
  SliderRepres->SetTitleHeight(0.02);
  SliderRepres->SetLabelHeight(0.02);

  vtkSliderWidget *SliderWidget = vtkSliderWidget::New();
  SliderWidget->SetInteractor(iren);
  SliderWidget->SetRepresentation(SliderRepres);
  SliderWidget->KeyPressActivationOff();
  SliderWidget->SetAnimationModeToAnimate();
  SliderWidget->SetEnabled(true);
 
  vtkSliderCallback2 *SliderCb = vtkSliderCallback2::New();
  SliderCb->SetImageViewer(ImageViewer);
  SliderWidget->AddObserver(vtkCommand::InteractionEvent, SliderCb); 

  ImageViewer->SetSlice((int)SliderRepres->GetValue());

  vtkHandleWidget *HandleWidget = vtkHandleWidget::New();

  vtkPointHandleRepresentation3D *rep =
    vtkPointHandleRepresentation3D::New();
  HandleWidget->SetRepresentation(rep);
  double bounds[6];
  v16->GetOutput()->GetBounds( bounds );
  double worldPos[] = { (bounds[0] + bounds[1])/2.0, (bounds[2] + 
bounds[3])/2.0, (bounds[4] + bounds[5])/2.0 };
  rep->SetWorldPosition( worldPos );
  rep->GetProperty()->SetColor(0,1,1);
  rep->Delete();

  HandleWidget->SetInteractor(iren);
  HandleWidget->SetEnabled(true);
  HandleWidget->ProcessEventsOn();

  ImageViewer->GetRenderWindow()->SetSize(500, 500);

  // render the image
  //
  iren->Initialize();
  ImageViewer->Render();

  int retVal = vtkRegressionTestImage( ImageViewer->GetRenderWindow() );
  if ( retVal == vtkRegressionTester::DO_INTERACTOR)
    {
    iren->Start();
    }

  SliderRepres->Delete();
  SliderCb->Delete();
  HandleWidget->Delete();
  v16->Delete();
  ImageViewer->Delete();
  shifter->Delete();
  SliderWidget->Delete();
  iren->Delete();
 
  return EXIT_SUCCESS;
}


HTH
--
karthik


> What is the output display bounds of the result of vtkImageReslice. I
> presume you are passing it through to vtkImageActor. If the display
> bounds, as you scroll through slices do change, the seeds should
> appear and disappear automatically.
> Since the ImageActor doesn't have a SetBounds() method and 
> ImageReslice doesn't have a GetBounds() method, how to do this? .
>
> Another question:
> When I call a the following on my callback, on Execute(vtkObject*,  
> unsigned long, void*) method:
> if( event == vtkCommand::PlacePointEvent)
>   {
>     std::cout << "A point are placed!"<< std::endl;
>     cout << "Point placed, total of:" << 
> this->SeedRepresentation->GetNumberOfSeeds() << "\n";
>     double vc[3];
>     double wc[3];
>     
> this->SeedRepresentation->GetSeedWorldPosition(this->SeedRepresentation->GetNumberOfSeeds() 
> - 1, vc);
>     
> this->SeedRepresentation->GetSeedDisplayPosition(this->SeedRepresentation->GetNumberOfSeeds() 
> - 1, wc);
>     std::cout << "Printing the word coordinate: " << vc[0] << ", " << 
> vc[1] << ", " << vc[2] << std::endl;
>     std::cout << "Printing the display coordinate: " << wc[0] << ", " 
> << wc[1] << ", " << wc[2] << std::endl;
>    }
> The output never show a valid Z value. If are in display coordinate, 
> are every times 0 ( which I think are correct, since I'm are using a 
> 2D viewer ).
> But and in world coordinate? My access of this value of course are 
> wrong. Can someone help me with these?
>
> Sorry by the newbie question and thanks in advance,
>
> Wagner Sales
>
>
> ----- Mensagem original ----
> De: Ken Urish <ken.urish at gmail.com>
> Para: Karthik Krishnan <karthik.krishnan at kitware.com>; vtkusers at vtk.org
> Enviadas: Terça-feira, 29 de Abril de 2008 13:44:07
> Assunto: Re: [vtkusers] vtkSeedWidget
>
> Karthik
>
> Yes I am passing vtkImageReslice through an actor.
> No, I am not declaring any bounds on the reslice. I am using the
> example based off the ImageReslice test file. I assume I should set
> the bounds in the Reslice callback (below). Could you offer me what
> command to use? I dont see object that looks like it will set bounds?
> I really appreciate your help with this, I was up most of last night
> trying to power through it.
> Thanks, Ken
>
> //------------------------------------------------------------------------------
> // IMAGE RESLICE CALLBACK
> // The mouse motion callback, to turn "Slicing" on and off
> //-------------------------------------------------------------------------------
> class vtkImageInteractionCallback : public vtkCommand
> {
> public:
>
>   static vtkImageInteractionCallback *New() {
>     return new vtkImageInteractionCallback; };
>
>   vtkImageInteractionCallback() {
>     this->Slicing = 0;
>     this->ImageReslice = 0;
>     this->Interactor = 0; };
>
>   void SetImageReslice(vtkImageReslice *reslice) {
>     this->ImageReslice = reslice; };
>
>   vtkImageReslice *GetImageReslice() {
>     return this->ImageReslice; };
>
>   void SetInteractor(vtkRenderWindowInteractor *interactor) {
>     this->Interactor = interactor; };
>
>   vtkRenderWindowInteractor *GetInteractor() {
>     return this->Interactor; };
>
>   virtual void Execute(vtkObject *, unsigned long event, void *)
>     {
>     vtkRenderWindowInteractor *interactor = this->GetInteractor();
>
>     int lastPos[2];
>     interactor->GetLastEventPosition(lastPos);
>     int currPos[2];
>     interactor->GetEventPosition(currPos);
>
>     if (event == vtkCommand::LeftButtonPressEvent)
>       {
>       this->Slicing = 1;
>       }
>     else if (event == vtkCommand::LeftButtonReleaseEvent)
>       {
>       this->Slicing = 0;
>       }
>     else if (event == vtkCommand::MouseMoveEvent)
>       {
>       if (this->Slicing)
>         {
>         vtkImageReslice *reslice = this->ImageReslice;
>
>         // Increment slice position by deltaY of mouse
>         int deltaY = (lastPos[1] - currPos[1]);
>
>         reslice->GetOutput()->UpdateInformation();
>         double sliceSpacing = reslice->GetOutput()->GetSpacing()[2];
>         vtkMatrix4x4 *matrix = reslice->GetResliceAxes();
>         // move the center point that we are slicing through
>         double point[4];
>         double center[4];
>         point[0] = 0.0;
>         point[1] = 0.0;
>         point[2] = sliceSpacing * deltaY;
>         point[3] = 1.0;
>         std::cout<<point[2]<<std::endl;
>         matrix->MultiplyPoint(point, center);
>         matrix->SetElement(0, 3, center[0]);
>         matrix->SetElement(1, 3, center[1]);
>         matrix->SetElement(2, 3, center[2]);
>         interactor->Render();
>         }
>       else
>         {
>         vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast(
>           interactor->GetInteractorStyle());
>         if (style)
>           {
>           style->OnMouseMove();
>           }
>         }
>       }
>     };
>
>
> On Tue, Apr 29, 2008 at 8:31 AM, Karthik Krishnan
> <karthik.krishnan at kitware.com <mailto:karthik.krishnan at kitware.com>> 
> wrote:
> > The Seed widget uses a vtkHandleWidget internally for each seed, with
> >  the default representation being the 3D vtkPointHandleRepresentation3D
> >  class. The resulting primitives exist in world coordinates (and not on
> >  the overlay plane). So they should disappear when you move to the next
> >  slice.
> >
> >  What is the output display bounds of the result of vtkImageReslice. I
> >  presume you are passing it through to vtkImageActor. If the display
> >  bounds, as you scroll through slices do change, the seeds should
> >  appear and disappear automatically.
> >
> >  HTH
> >  --
> >  karthik
> >
> >
> >
> >  On Tue, Apr 29, 2008 at 9:30 AM, Ken Urish <ken.urish at gmail.com 
> <mailto:ken.urish at gmail.com>> wrote:
> >  > Hey all,
> >  >
> >  >  Im using vtkSeedWidget on a 3D image that I am viewing through
> >  >  ImageReslice. When I place my seed points on a 2D slice, how can I
> >  >  have the seed points disappear when I move to the next slice? Im
> >  >  moving through ~100 slices and I dont want them building up. Is this
> >  >  even possible? I appreciate the help.
> >  >
> >  >  Thanks
> >  >  --Ken--
> >  >  _______________________________________________
> >  >  This is the private VTK discussion list.
> >  >  Please keep messages on-topic. Check the FAQ at: 
> http://www.vtk.org/Wiki/VTK_FAQ
> >  >  Follow this link to subscribe/unsubscribe:
> >  >  http://www.vtk.org/mailman/listinfo/vtkusers
> >
> _______________________________________________
> This is the private VTK discussion list.
> Please keep messages on-topic. Check the FAQ at: 
> http://www.vtk.org/Wiki/VTK_FAQ
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtkusers
>
> ------------------------------------------------------------------------
> Novos endereços, o Yahoo! que você conhece. Crie um email novo 
> <http://br.rd.yahoo.com/mail/taglines/mail/*http://br.new.mail.yahoo.com/addresses> 
> com a sua cara @ymail.com ou @rocketmail.com.

-- 
Karthik Krishnan
R & D Engineer,
Kitware Inc,
Ph: +1 518 3713971 x119
Fax: +1 518 3714573




More information about the vtkusers mailing list