Re: vtkusers Digest, Vol 176, Issue 22

classic Classic list List threaded Threaded
2 messages Options
A Z
Reply | Threaded
Open this post in threaded view
|

Re: vtkusers Digest, Vol 176, Issue 22

A Z
I'm in a situation where I'm in a secure environment,
and I can't use Visual Studio or other sorts of tools
to compile and build the VTK.  Particularly,
this is an issue if I need VTK in 64 bit (for Windows).

The other thing is that high speed internet through
the hardware of the phone network is not all that great
where we are.  We are prepared to download the VTK once,
byt not Visual Studio, who who knows what else
Cygwin might need.  :(

What I think I simply finally and just plain need
is for the VTK to buld the 64 bit Windows .dlls for me,
and offer them for download via an internet site.

Can someone who is part of the VTK team acomplish this for me,
but for other similar members of the public as well?

From: vtkusers <[hidden email]> on behalf of [hidden email] <[hidden email]>
Sent: Thursday, 20 December 2018 4:00 AM
To: [hidden email]
Subject: vtkusers Digest, Vol 176, Issue 22
 
Send vtkusers mailing list submissions to
        [hidden email]

To subscribe or unsubscribe via the World Wide Web, visit
        https://public.kitware.com/mailman/listinfo/vtkusers
or, via email, send a message with subject or body 'help' to
        [hidden email]

You can reach the person managing the list at
        [hidden email]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of vtkusers digest..."


Today's Topics:

   1. Problem with displaying cross-hairs on 2D views when using
      vtkImageResliceMapper -> vtkImageSlice -> vtkImageStack pipeline
      (ochampao)
   2. The SetRate() function of vtkFFMPEGWriter is not working
      (=?ISO-8859-1?B?eWlydWkxMjEw?=)
   3. Re: Visualizing normal vectors (Andaharoo)
   4. Re: Problem with displaying cross-hairs on 2D views when
      using vtkImageResliceMapper -> vtkImageSlice -> vtkImageStack
      pipeline (Andras Lasso)
   5. Re: Visualizing normal vectors (mozendi)
   6. Re: Visualizing normal vectors (Andaharoo)


----------------------------------------------------------------------

Message: 1
Date: Tue, 18 Dec 2018 11:40:46 -0700 (MST)
From: ochampao <[hidden email]>
To: [hidden email]
Subject: [vtkusers] Problem with displaying cross-hairs on 2D views
        when using vtkImageResliceMapper -> vtkImageSlice -> vtkImageStack
        pipeline
Message-ID: <[hidden email]>
Content-Type: text/plain; charset=us-ascii

Hi vtkUsers,

I am developing a four-pane viewer for displaying medical images. The 3
views display slices of the volumes in the 3 standard anatomical views
(axial, coronal, sagittal) whereas the 4th one displays some 3D surface
rendering of the volume. For now, I will only focus on the 2D views.

The 2D views use the following pipeline: vtkImageResliceMapper ->
vtkImageSlice -> vtkImageStack. This allows the application to overlay
slices from multiple volumes simultaneously. The attached code is a minimal
example of the 2D pipeline I use in my application. The slices displayed are
determined by the focal point of the camera in each 2D view.

What I would like to do is display a set of cross-hairs on each of the 2D
views, but I don't know how to achieve this using the pipeline I am
currently using.

I am aware of the classes:
vtkResliceCursorWidget,
vtkResliceCursor,
vtkResliceCursorLineRepresentation,
vtkImagePlaneWidget,
vtkResliceImageViewer

I have tried using these classes (see commented code in attached source
code), but they don't seem compatible with my current pipeline. For example,
when using vtkResliceCursorWidget the cross-hairs are visible and I can
interact with them but slicing stops working. I also see some weird
artefacts around the border of the slice. Also, to use these classes I need
to specify the volume which the reslice cursor will be slicing
(vtkResliceCursor->SetImage(imageData)), but in my case I have multiple
volumes.

I am also aware of and tried using vtkCursor2D/vtkCursor3D. Although they
are close to what I have in mind, they allow very limited customization of
their look.

Essentially what I would like to implement is something that looks like the
cursor of vtkResliceCursorWidget/vtkImagePlaneWidget/vtkResliceImageViewer
but does not handle slicing.

Can someone recommend how can I achieve this, or point me to some
classes/examples? Is their a way of using
vtkResliceCursorWidget/vtkImagePlaneWidget/vtkResliceImageViewer with my
current pipeline, or would I need to change it?

Thanks a lot for your help.
Panos

========================================================
Basic Pipeline Minimal Example
========================================================
#include <vtkCamera.h>
#include <vtkDICOMImageReader.h>
#include <vtkImageChangeInformation.h>
#include <vtkImageData.h>
#include <vtkImageProperty.h>
#include <vtkImageResliceMapper.h>
#include <vtkImageSlice.h>
#include <vtkImageStack.h>
#include <vtkInteractorStyleImage.h>
#include <vtkMath.h>
#include <vtkNIFTIImageReader.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>

#include <vtkResliceCursor.h>
#include <vtkResliceCursorActor.h>
#include <vtkResliceCursorLineRepresentation.h>
#include <vtkResliceCursorPolyDataAlgorithm.h>
#include <vtkResliceCursorWidget.h>

void setupCamera(vtkCamera* camera);
vtkSmartPointer<vtkImageData> loadDicom(const char* filename);
vtkSmartPointer<vtkImageData> loadNifti(const char* filename);

int main(int, char*[])
{
        // Setup renderer
        vtkNew<vtkRenderer> renderer;
        renderer->SetBackground(0.0, 0.0, 0.0);
        renderer->GetActiveCamera()->ParallelProjectionOn();
        renderer->ResetCameraClippingRange();
        renderer->ResetCamera();

        // Setup renderWindow
        vtkNew<vtkRenderWindow> renderWindow;
        renderWindow->AddRenderer(renderer);

        // Setup interaction style
        vtkNew<vtkInteractorStyleImage> interactorStyle;
        interactorStyle->SetInteractionModeToImageSlicing();

        // Setup window interactor
        vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
        renderWindowInteractor->SetRenderWindow(renderWindow);
        renderWindowInteractor->SetInteractorStyle(interactorStyle);

        // Setup camera
        setupCamera(renderer->GetActiveCamera());

        // Load data from DICOM series
//      vtkSmartPointer<vtkImageData> imageData =
//              loadDicom("<path_to_DICOM_series>"");

        // Load data from Nifti file
        vtkSmartPointer<vtkImageData> imageData =
                loadNifti("<path_to_nii_file>");

        // setup slice mapper
        vtkNew<vtkImageResliceMapper> resliceMapper;
        resliceMapper->SetInputData(imageData);
        resliceMapper->SliceFacesCameraOn();
        resliceMapper->SliceAtFocalPointOn();
        resliceMapper->JumpToNearestSliceOn();
        resliceMapper->BorderOff();

        // Set to full window and centered level:
        double window = imageData->GetScalarRange()[1] -
imageData->GetScalarRange()[0];
        double level = imageData->GetScalarRange()[0] + window / 2.0;

        // Setup prop holding the slice
        vtkNew<vtkImageSlice> imageSlice;
        imageSlice->SetMapper(resliceMapper);
        imageSlice->GetProperty()->SetColorWindow(window);
        imageSlice->GetProperty()->SetColorLevel(level);
        imageSlice->GetProperty()->SetLayerNumber(0);
        imageSlice->GetProperty()->SetInterpolationTypeToNearest();
       
        // Setup prop holding the multiple slices
        vtkNew<vtkImageStack> imageStack;
        imageStack->SetActiveLayer(imageSlice->GetProperty()->GetLayerNumber());
        imageStack->AddImage(imageSlice); // add slice

        vtkNew<vtkResliceCursor> resliceCursor;
        resliceCursor->SetCenter(imageData->GetCenter());
        resliceCursor->SetThickMode(0);
        resliceCursor->SetImage(imageData);

        vtkNew<vtkResliceCursorLineRepresentation> cursorRepresentation;
        cursorRepresentation->GetResliceCursorActor()->
           GetCursorAlgorithm()->SetResliceCursor(resliceCursor);
        cursorRepresentation->GetResliceCursorActor()->
            BasicPipeline.cxx
<http://vtk.1045678.n5.nabble.com/file/t341857/BasicPipeline.cxx>
GetCursorAlgorithm()->SetReslicePlaneNormal(2);

        vtkNew<vtkResliceCursorWidget> resliceCursorWidget;
        resliceCursorWidget->SetInteractor(renderWindowInteractor);
        resliceCursorWidget->SetDefaultRenderer(renderer);
        resliceCursorWidget->SetRepresentation(cursorRepresentation);
        resliceCursorWidget->SetManageWindowLevel(false);
        resliceCursorWidget->EnabledOn();
        //resliceCursorWidget->ProcessEventsOff();

        // Add actors to renderer
        renderer->AddViewProp(imageStack);
        renderer->ResetCamera();

        // Start interaction
        renderWindowInteractor->Initialize();
        renderWindow->Render();
        renderWindowInteractor->Start();

        return EXIT_SUCCESS;
}

void setupCamera(vtkCamera* camera)
{
        double viewUp[3] = { 0, 1, 0 };
        double leftToRight[3] = { 1, 0, 0 };

        // compute the view plane normal
        double normal[3];
        vtkMath::Cross(leftToRight, viewUp, normal);

        // get the camera focus
        double focus[3];
        camera->GetFocalPoint(focus);

        // get the camera distance from the focus
        double d = camera->GetDistance();

        // position the camera on view plane normal keeping the focus and the
distance from it fixed
        camera->SetPosition(
                focus[0] + d*normal[0],
                focus[1] + d*normal[1],
                focus[2] + d*normal[2]);

        // make sure focus is the same
        camera->SetFocalPoint(focus);

        // setup view up vector
        camera->SetViewUp(viewUp);
        camera->OrthogonalizeViewUp();
}

vtkSmartPointer<vtkImageData> loadDicom(const char* filename)
{
        vtkNew<vtkDICOMImageReader> reader;
        reader->FileLowerLeftOn();
        reader->SetDirectoryName(filename);
        reader->UpdateInformation();

        vtkNew<vtkImageChangeInformation> imageInfo;
        imageInfo->SetOutputOrigin(0.0, 0.0, 0.0);
        imageInfo->SetOutputSpacing(reader->GetPixelSpacing());
        imageInfo->SetInputConnection(reader->GetOutputPort());
        imageInfo->Update();

        return imageInfo->GetOutput();
}

vtkSmartPointer<vtkImageData> loadNifti(const char* filename)
{
        vtkNew<vtkNIFTIImageReader> niftiiReader;
        niftiiReader->SetFileName(filename);

        vtkNew<vtkImageChangeInformation> imageInfo;
        imageInfo->SetOutputOrigin(0.0, 0.0, 0.0);
        imageInfo->SetInputConnection(niftiiReader->GetOutputPort());
        imageInfo->Update();

        return imageInfo->GetOutput();//data;
}





--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html


------------------------------

Message: 2
Date: Wed, 19 Dec 2018 08:25:13 +0800
From: "=?ISO-8859-1?B?eWlydWkxMjEw?=" <[hidden email]>
To: "=?ISO-8859-1?B?dnRrdXNlcnM=?=" <[hidden email]>
Subject: [vtkusers] The SetRate() function of vtkFFMPEGWriter is not
        working
Message-ID: <[hidden email]>
Content-Type: text/plain; charset="iso-8859-1"

Hello, VTKer


I am using vtkFFMPEGWriter to write a video, no matter the frame rate I set, the output video is still 600 frames/sec.

The code I used has been attached. Can anybody check the problem for me? Thank you so much.


Regards,
YiRui
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20181219/8caa3726/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: [hidden email]
Type: image/jpeg
Size: 5053 bytes
Desc: not available
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20181219/8caa3726/attachment-0001.jpg>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 1.png
Type: application/octet-stream
Size: 5053 bytes
Desc: not available
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20181219/8caa3726/attachment-0003.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: CMakeLists.txt
Type: application/octet-stream
Size: 303 bytes
Desc: not available
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20181219/8caa3726/attachment-0004.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: FFMPEG.cxx
Type: application/octet-stream
Size: 1027 bytes
Desc: not available
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20181219/8caa3726/attachment-0005.obj>

------------------------------

Message: 3
Date: Tue, 18 Dec 2018 18:37:04 -0700 (MST)
From: Andaharoo <[hidden email]>
To: [hidden email]
Subject: Re: [vtkusers] Visualizing normal vectors
Message-ID: <[hidden email]>
Content-Type: text/plain; charset=us-ascii

I'd recommend using vtkOpenGLGlyph3DMapper instead. Much faster, assuming you
have some gpu. Just make sure the normal array/orientation array is in the
input polyData's point data.

IE:
polyData->GetPointData()->AddArray(your normal array)

Then just specify the array the mapper should use with
SetOrientationArray(your arrays name here). It will then search for the
array in the input polydata. I frequently use this to draw thousands of
oriented arrows with VTK.



--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html


------------------------------

Message: 4
Date: Wed, 19 Dec 2018 06:31:31 +0000
From: Andras Lasso <[hidden email]>
To: ochampao <[hidden email]>, "[hidden email]"
        <[hidden email]>
Subject: Re: [vtkusers] Problem with displaying cross-hairs on 2D
        views when using vtkImageResliceMapper -> vtkImageSlice ->
        vtkImageStack pipeline
Message-ID:
        <[hidden email]>
       
Content-Type: text/plain; charset="us-ascii"

It is great that you are interested in medical imaging and has chosen to work with VTK. I would recommend to put your talent and effort into contributing to an existing open-source medical image viewer instead of spending time with redeveloping basic features. You could work on more interesting things, develop new features, and you would very quickly become a useful, valued member of a community.

If you are interested in answers to your question (and your future questions) you can have a look at source code of existing VTK-based open-source medical image viewers, such as 3D Slicer, MITK, medInria, Horos, Ibis, CustusX, CamiTK, Invesalius, etc.

Andras

-----Original Message-----
From: vtkusers <[hidden email]> On Behalf Of ochampao
Sent: Tuesday, December 18, 2018 1:41 PM
To: [hidden email]
Subject: [vtkusers] Problem with displaying cross-hairs on 2D views when using vtkImageResliceMapper -> vtkImageSlice -> vtkImageStack pipeline

Hi vtkUsers,

I am developing a four-pane viewer for displaying medical images. The 3 views display slices of the volumes in the 3 standard anatomical views (axial, coronal, sagittal) whereas the 4th one displays some 3D surface rendering of the volume. For now, I will only focus on the 2D views.

The 2D views use the following pipeline: vtkImageResliceMapper -> vtkImageSlice -> vtkImageStack. This allows the application to overlay slices from multiple volumes simultaneously. The attached code is a minimal example of the 2D pipeline I use in my application. The slices displayed are determined by the focal point of the camera in each 2D view.

What I would like to do is display a set of cross-hairs on each of the 2D views, but I don't know how to achieve this using the pipeline I am currently using.

I am aware of the classes:
vtkResliceCursorWidget,
vtkResliceCursor,
vtkResliceCursorLineRepresentation,
vtkImagePlaneWidget,
vtkResliceImageViewer

I have tried using these classes (see commented code in attached source code), but they don't seem compatible with my current pipeline. For example, when using vtkResliceCursorWidget the cross-hairs are visible and I can interact with them but slicing stops working. I also see some weird artefacts around the border of the slice. Also, to use these classes I need to specify the volume which the reslice cursor will be slicing (vtkResliceCursor->SetImage(imageData)), but in my case I have multiple volumes.

I am also aware of and tried using vtkCursor2D/vtkCursor3D. Although they are close to what I have in mind, they allow very limited customization of their look.

Essentially what I would like to implement is something that looks like the cursor of vtkResliceCursorWidget/vtkImagePlaneWidget/vtkResliceImageViewer
but does not handle slicing.

Can someone recommend how can I achieve this, or point me to some classes/examples? Is their a way of using vtkResliceCursorWidget/vtkImagePlaneWidget/vtkResliceImageViewer with my current pipeline, or would I need to change it?

Thanks a lot for your help.
Panos

========================================================
Basic Pipeline Minimal Example
========================================================
#include <vtkCamera.h>
#include <vtkDICOMImageReader.h>
#include <vtkImageChangeInformation.h>
#include <vtkImageData.h>
#include <vtkImageProperty.h>
#include <vtkImageResliceMapper.h>
#include <vtkImageSlice.h>
#include <vtkImageStack.h>
#include <vtkInteractorStyleImage.h>
#include <vtkMath.h>
#include <vtkNIFTIImageReader.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>

#include <vtkResliceCursor.h>
#include <vtkResliceCursorActor.h>
#include <vtkResliceCursorLineRepresentation.h>
#include <vtkResliceCursorPolyDataAlgorithm.h>
#include <vtkResliceCursorWidget.h>

void setupCamera(vtkCamera* camera);
vtkSmartPointer<vtkImageData> loadDicom(const char* filename); vtkSmartPointer<vtkImageData> loadNifti(const char* filename);

int main(int, char*[])
{
        // Setup renderer
        vtkNew<vtkRenderer> renderer;
        renderer->SetBackground(0.0, 0.0, 0.0);
        renderer->GetActiveCamera()->ParallelProjectionOn();
        renderer->ResetCameraClippingRange();
        renderer->ResetCamera();

        // Setup renderWindow
        vtkNew<vtkRenderWindow> renderWindow;
        renderWindow->AddRenderer(renderer);

        // Setup interaction style
        vtkNew<vtkInteractorStyleImage> interactorStyle;
        interactorStyle->SetInteractionModeToImageSlicing();

        // Setup window interactor
        vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
        renderWindowInteractor->SetRenderWindow(renderWindow);
        renderWindowInteractor->SetInteractorStyle(interactorStyle);

        // Setup camera
        setupCamera(renderer->GetActiveCamera());

        // Load data from DICOM series
//      vtkSmartPointer<vtkImageData> imageData =
//              loadDicom("<path_to_DICOM_series>"");

        // Load data from Nifti file
        vtkSmartPointer<vtkImageData> imageData =
                loadNifti("<path_to_nii_file>");

        // setup slice mapper
        vtkNew<vtkImageResliceMapper> resliceMapper;
        resliceMapper->SetInputData(imageData);
        resliceMapper->SliceFacesCameraOn();
        resliceMapper->SliceAtFocalPointOn();
        resliceMapper->JumpToNearestSliceOn();
        resliceMapper->BorderOff();

        // Set to full window and centered level:
        double window = imageData->GetScalarRange()[1] -
imageData->GetScalarRange()[0];
        double level = imageData->GetScalarRange()[0] + window / 2.0;

        // Setup prop holding the slice
        vtkNew<vtkImageSlice> imageSlice;
        imageSlice->SetMapper(resliceMapper);
        imageSlice->GetProperty()->SetColorWindow(window);
        imageSlice->GetProperty()->SetColorLevel(level);
        imageSlice->GetProperty()->SetLayerNumber(0);
        imageSlice->GetProperty()->SetInterpolationTypeToNearest();
       
        // Setup prop holding the multiple slices
        vtkNew<vtkImageStack> imageStack;
        imageStack->SetActiveLayer(imageSlice->GetProperty()->GetLayerNumber());
        imageStack->AddImage(imageSlice); // add slice

        vtkNew<vtkResliceCursor> resliceCursor;
        resliceCursor->SetCenter(imageData->GetCenter());
        resliceCursor->SetThickMode(0);
        resliceCursor->SetImage(imageData);

        vtkNew<vtkResliceCursorLineRepresentation> cursorRepresentation;
        cursorRepresentation->GetResliceCursorActor()->
           GetCursorAlgorithm()->SetResliceCursor(resliceCursor);
        cursorRepresentation->GetResliceCursorActor()->
            BasicPipeline.cxx
<https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fvtk.1045678.n5.nabble.com%2Ffile%2Ft341857%2FBasicPipeline.cxx&amp;data=02%7C01%7Classo%40queensu.ca%7C80118413b7ba4ceb15d108d665185599%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C1%7C636807552523602151&amp;sdata=nT57nY7HqbSgYg8flXNrjvfhqXVDbvDHbyEOMCVE3V0%3D&amp;reserved=0>
GetCursorAlgorithm()->SetReslicePlaneNormal(2);

        vtkNew<vtkResliceCursorWidget> resliceCursorWidget;
        resliceCursorWidget->SetInteractor(renderWindowInteractor);
        resliceCursorWidget->SetDefaultRenderer(renderer);
        resliceCursorWidget->SetRepresentation(cursorRepresentation);
        resliceCursorWidget->SetManageWindowLevel(false);
        resliceCursorWidget->EnabledOn();
        //resliceCursorWidget->ProcessEventsOff();

        // Add actors to renderer
        renderer->AddViewProp(imageStack);
        renderer->ResetCamera();

        // Start interaction
        renderWindowInteractor->Initialize();
        renderWindow->Render();
        renderWindowInteractor->Start();

        return EXIT_SUCCESS;
}

void setupCamera(vtkCamera* camera)
{
        double viewUp[3] = { 0, 1, 0 };
        double leftToRight[3] = { 1, 0, 0 };

        // compute the view plane normal
        double normal[3];
        vtkMath::Cross(leftToRight, viewUp, normal);

        // get the camera focus
        double focus[3];
        camera->GetFocalPoint(focus);

        // get the camera distance from the focus
        double d = camera->GetDistance();

        // position the camera on view plane normal keeping the focus and the distance from it fixed
        camera->SetPosition(
                focus[0] + d*normal[0],
                focus[1] + d*normal[1],
                focus[2] + d*normal[2]);

        // make sure focus is the same
        camera->SetFocalPoint(focus);

        // setup view up vector
        camera->SetViewUp(viewUp);
        camera->OrthogonalizeViewUp();
}

vtkSmartPointer<vtkImageData> loadDicom(const char* filename) {
        vtkNew<vtkDICOMImageReader> reader;
        reader->FileLowerLeftOn();
        reader->SetDirectoryName(filename);
        reader->UpdateInformation();

        vtkNew<vtkImageChangeInformation> imageInfo;
        imageInfo->SetOutputOrigin(0.0, 0.0, 0.0);
        imageInfo->SetOutputSpacing(reader->GetPixelSpacing());
        imageInfo->SetInputConnection(reader->GetOutputPort());
        imageInfo->Update();

        return imageInfo->GetOutput();
}

vtkSmartPointer<vtkImageData> loadNifti(const char* filename) {
        vtkNew<vtkNIFTIImageReader> niftiiReader;
        niftiiReader->SetFileName(filename);

        vtkNew<vtkImageChangeInformation> imageInfo;
        imageInfo->SetOutputOrigin(0.0, 0.0, 0.0);
        imageInfo->SetInputConnection(niftiiReader->GetOutputPort());
        imageInfo->Update();

        return imageInfo->GetOutput();//data;
}





--
Sent from: https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fvtk.1045678.n5.nabble.com%2FVTK-Users-f1224199.html&amp;data=02%7C01%7Classo%40queensu.ca%7C80118413b7ba4ceb15d108d665185599%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C1%7C636807552523602151&amp;sdata=y%2FPL7RWRxL9djen9OHHFpV8mML1l8tDDID8vwEPDzr4%3D&amp;reserved=0
_______________________________________________
Powered by https://na01.safelinks.protection.outlook.com/?url=www.kitware.com&amp;data=02%7C01%7Classo%40queensu.ca%7C80118413b7ba4ceb15d108d665185599%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C1%7C636807552523602151&amp;sdata=a5wXXUd01fJsRRfeOlVc%2Bk6JcNbeRrCaawzEeOBEpIQ%3D&amp;reserved=0

Visit other Kitware open-source projects at https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.kitware.com%2Fopensource%2Fopensource.html&amp;data=02%7C01%7Classo%40queensu.ca%7C80118413b7ba4ceb15d108d665185599%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C1%7C636807552523602151&amp;sdata=GTPQfYrm85nLVvMYqtzwxYrfNS%2BHK2U5E%2F8%2FXjTuyGQ%3D&amp;reserved=0

Please keep messages on-topic and check the VTK FAQ at: https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.vtk.org%2FWiki%2FVTK_FAQ&amp;data=02%7C01%7Classo%40queensu.ca%7C80118413b7ba4ceb15d108d665185599%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C1%7C636807552523602151&amp;sdata=3OkV0h9SM82LHRbPbSKbfXkZuLWSqAjPyULJuBV%2FrGQ%3D&amp;reserved=0

Search the list archives at: https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmarkmail.org%2Fsearch%2F%3Fq%3Dvtkusers&amp;data=02%7C01%7Classo%40queensu.ca%7C80118413b7ba4ceb15d108d665185599%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C1%7C636807552523602151&amp;sdata=ydyX30Af9G0j8PwVigfaCkucOiFqv0SdNKwyi7vx56Y%3D&amp;reserved=0

Follow this link to subscribe/unsubscribe:
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpublic.kitware.com%2Fmailman%2Flistinfo%2Fvtkusers&amp;data=02%7C01%7Classo%40queensu.ca%7C80118413b7ba4ceb15d108d665185599%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C1%7C636807552523602151&amp;sdata=zYNgte5262YQQDT42ydJgSd1qTiDwQBW4DeWwgOlCzE%3D&amp;reserved=0


------------------------------

Message: 5
Date: Wed, 19 Dec 2018 01:24:28 -0700 (MST)
From: mozendi <[hidden email]>
To: [hidden email]
Subject: Re: [vtkusers] Visualizing normal vectors
Message-ID: <[hidden email]>
Content-Type: text/plain; charset=us-ascii

Dear Andaharoo,
Thank you for your recommendation. I tried to modify my codes according to
your recommendations, my code is getting compiled successfully. However,
when I run it I am getting an error message. The screenshot and my code are
below. Could you please tell me what is wrong with my code?
Thanks in advance
<http://vtk.1045678.n5.nabble.com/file/t341822/vtk_error_message.png>


#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkDelimitedTextReader.h>
#include <vtkDoubleArray.h>
#include <vtkTable.h>
#include <vtkPointData.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkArrowSource.h>
#include <vtkGlyph3D.h>
#include <vtkPointSource.h>
# include "vtkGlyph3DMapper.h"
# include "vtkGlyph3DMapper.h"
#include <vtkOpenGLGlyph3DMapper.h>
#include <vector>


int main(int argc, char* argv[])
{
        vtkSmartPointer<vtkDelimitedTextReader> reader =
vtkSmartPointer<vtkDelimitedTextReader>::New();
        reader->SetFileName("points_and_normals.xyz");
        reader->DetectNumericColumnsOn();
        reader->SetFieldDelimiterCharacters(" ");
        reader->Update();

        vtkTable* table = reader->GetOutput();
        vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
        vtkSmartPointer<vtkDoubleArray> normals =
vtkSmartPointer<vtkDoubleArray>::New();
        normals->SetNumberOfComponents(3); //3d normals (ie x,y,z)

        std::cout << "Table has " << table->GetNumberOfRows()
                << " rows." << std::endl;
        std::cout << "Table has " << table->GetNumberOfColumns()
                << " columns." << std::endl;

        for (vtkIdType i = 0; i < table->GetNumberOfRows(); i++)
        {

                points->InsertNextPoint((table->GetValue(i, 0)).ToDouble(),
                        (table->GetValue(i, 1)).ToDouble(),
                        (table->GetValue(i, 2)).ToDouble());

                double n[3];
                n[0] = (table->GetValue(i, 3)).ToDouble();
                n[1] = (table->GetValue(i, 4)).ToDouble();
                n[2] = (table->GetValue(i, 5)).ToDouble();
                normals->InsertNextTuple(n);
        }

        std::cout << "There are " << points->GetNumberOfPoints()
                << " points." << std::endl;
               

        vtkSmartPointer<vtkPolyData> polydata =
vtkSmartPointer<vtkPolyData>::New();
        polydata->SetPoints(points);
        //polydata->GetPointData()->SetNormals(normals);
        polydata->GetPointData()->AddArray(normals);
       
        vtkSmartPointer<vtkOpenGLGlyph3DMapper> Glyph3D =
vtkSmartPointer<vtkOpenGLGlyph3DMapper>::New();
        Glyph3D->SetInputData(polydata);
        Glyph3D->SetOrientationArray("normals");
        Glyph3D->SetScaleFactor(.5);
        Glyph3D->Update();
               
        vtkSmartPointer<vtkActor> glyph3DActor =        vtkSmartPointer<vtkActor>::New();
        glyph3DActor->SetMapper(Glyph3D);
        glyph3DActor->GetProperty()->SetColor(0.8900, 0.8100, 0.3400);

        vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
        vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
        renderWindow->AddRenderer(renderer);
        vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
        renderWindowInteractor->SetRenderWindow(renderWindow);
        renderer->AddActor(glyph3DActor);
        renderer->SetBackground(.5, .5, .5);
        renderWindow->Render();
        renderWindowInteractor->Start();
        return EXIT_SUCCESS;
}





--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html


------------------------------

Message: 6
Date: Wed, 19 Dec 2018 02:26:23 -0700 (MST)
From: Andaharoo <[hidden email]>
To: [hidden email]
Subject: Re: [vtkusers] Visualizing normal vectors
Message-ID: <[hidden email]>
Content-Type: text/plain; charset=us-ascii

Your error said an array index went out of bounds. What line? Also I noticed
you never set the source data for the glyph. Could be unrelated to your
current error message, but a problem.

The glyph mapper takes two inputs. The glyph data (positions, normals,
scalars, etc) and the source (thing to copy). So if you want arrows as the
normals do this:

vtkSmartPointer<vtkOpenGLGlyph3DMapper> glyph3D =
vtkSmartPointer<vtkOpenGLGlyph3DMapper>::New();
glyph3D ->SetInputData(polydata);
vtkSmartPointer<vtkArrowSource> glyphSource =
vtkSmartPointer<vtkArrowSource>::New();
glyphSource->Update();
glyph3D->SetSourceData(glyphSource->GetOutput());
glyph3D ->SetOrientationArray("normals");
glyph3D ->SetScaleFactor(0.5);
glyph3D ->Update();



--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html


------------------------------

Subject: Digest Footer

_______________________________________________
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

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://public.kitware.com/mailman/listinfo/vtkusers


------------------------------

End of vtkusers Digest, Vol 176, Issue 22
*****************************************

_______________________________________________
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

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://public.kitware.com/mailman/listinfo/vtkusers
Reply | Threaded
Open this post in threaded view
|

Re: vtkusers Digest, Vol 176, Issue 22

Andras Lasso

It would help if you wrote a bit about yourself, your constraints, and especially what you would like to do – not just that you want VTK DLLs.

 

VTK is bundled with many application frameworks (ParaView, 3D Slicer, etc.), therefore - as others suggested - an obvious solution would be to use those to build your custom application. These frameworks contain not just VTK but other libraries necessary to build a complete application. You don’t need ­any compiler, don’t need to worry about GUI toolkit, etc. since all features are available and extensible using Python.

 

Andras

 

From: vtkusers <[hidden email]> On Behalf Of A Z
Sent: Wednesday, December 19, 2018 8:47 PM
To: [hidden email]
Subject: Re: [vtkusers] vtkusers Digest, Vol 176, Issue 22
Importance: High

 

I'm in a situation where I'm in a secure environment,

and I can't use Visual Studio or other sorts of tools

to compile and build the VTK.  Particularly,

this is an issue if I need VTK in 64 bit (for Windows).

 

The other thing is that high speed internet through

the hardware of the phone network is not all that great

where we are.  We are prepared to download the VTK once,

byt not Visual Studio, who who knows what else

Cygwin might need.  :(

 

What I think I simply finally and just plain need

is for the VTK to buld the 64 bit Windows .dlls for me,

and offer them for download via an internet site.

 

Can someone who is part of the VTK team acomplish this for me,

but for other similar members of the public as well?


From: vtkusers <[hidden email]> on behalf of [hidden email] <[hidden email]>
Sent: Thursday, 20 December 2018 4:00 AM
To: [hidden email]
Subject: vtkusers Digest, Vol 176, Issue 22

 

Send vtkusers mailing list submissions to
        [hidden email]

To subscribe or unsubscribe via the World Wide Web, visit
        https://public.kitware.com/mailman/listinfo/vtkusers
or, via email, send a message with subject or body 'help' to
        [hidden email]

You can reach the person managing the list at
        [hidden email]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of vtkusers digest..."


Today's Topics:

   1. Problem with displaying cross-hairs on 2D views when using
      vtkImageResliceMapper -> vtkImageSlice -> vtkImageStack pipeline
      (ochampao)
   2. The SetRate() function of vtkFFMPEGWriter is not working
      (=?ISO-8859-1?B?eWlydWkxMjEw?=)
   3. Re: Visualizing normal vectors (Andaharoo)
   4. Re: Problem with displaying cross-hairs on 2D views when
      using vtkImageResliceMapper -> vtkImageSlice -> vtkImageStack
      pipeline (Andras Lasso)
   5. Re: Visualizing normal vectors (mozendi)
   6. Re: Visualizing normal vectors (Andaharoo)


----------------------------------------------------------------------

Message: 1
Date: Tue, 18 Dec 2018 11:40:46 -0700 (MST)
From: ochampao <[hidden email]>
To: [hidden email]
Subject: [vtkusers] Problem with displaying cross-hairs on 2D views
        when using vtkImageResliceMapper -> vtkImageSlice -> vtkImageStack
        pipeline
Message-ID: <[hidden email]>
Content-Type: text/plain; charset=us-ascii

Hi vtkUsers,

I am developing a four-pane viewer for displaying medical images. The 3
views display slices of the volumes in the 3 standard anatomical views
(axial, coronal, sagittal) whereas the 4th one displays some 3D surface
rendering of the volume. For now, I will only focus on the 2D views.

The 2D views use the following pipeline: vtkImageResliceMapper ->
vtkImageSlice -> vtkImageStack. This allows the application to overlay
slices from multiple volumes simultaneously. The attached code is a minimal
example of the 2D pipeline I use in my application. The slices displayed are
determined by the focal point of the camera in each 2D view.

What I would like to do is display a set of cross-hairs on each of the 2D
views, but I don't know how to achieve this using the pipeline I am
currently using.

I am aware of the classes:
vtkResliceCursorWidget,
vtkResliceCursor,
vtkResliceCursorLineRepresentation,
vtkImagePlaneWidget,
vtkResliceImageViewer

I have tried using these classes (see commented code in attached source
code), but they don't seem compatible with my current pipeline. For example,
when using vtkResliceCursorWidget the cross-hairs are visible and I can
interact with them but slicing stops working. I also see some weird
artefacts around the border of the slice. Also, to use these classes I need
to specify the volume which the reslice cursor will be slicing
(vtkResliceCursor->SetImage(imageData)), but in my case I have multiple
volumes.

I am also aware of and tried using vtkCursor2D/vtkCursor3D. Although they
are close to what I have in mind, they allow very limited customization of
their look.

Essentially what I would like to implement is something that looks like the
cursor of vtkResliceCursorWidget/vtkImagePlaneWidget/vtkResliceImageViewer
but does not handle slicing.

Can someone recommend how can I achieve this, or point me to some
classes/examples? Is their a way of using
vtkResliceCursorWidget/vtkImagePlaneWidget/vtkResliceImageViewer with my
current pipeline, or would I need to change it?

Thanks a lot for your help.
Panos

========================================================
Basic Pipeline Minimal Example
========================================================
#include <vtkCamera.h>
#include <vtkDICOMImageReader.h>
#include <vtkImageChangeInformation.h>
#include <vtkImageData.h>
#include <vtkImageProperty.h>
#include <vtkImageResliceMapper.h>
#include <vtkImageSlice.h>
#include <vtkImageStack.h>
#include <vtkInteractorStyleImage.h>
#include <vtkMath.h>
#include <vtkNIFTIImageReader.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>

#include <vtkResliceCursor.h>
#include <vtkResliceCursorActor.h>
#include <vtkResliceCursorLineRepresentation.h>
#include <vtkResliceCursorPolyDataAlgorithm.h>
#include <vtkResliceCursorWidget.h>

void setupCamera(vtkCamera* camera);
vtkSmartPointer<vtkImageData> loadDicom(const char* filename);
vtkSmartPointer<vtkImageData> loadNifti(const char* filename);

int main(int, char*[])
{
        // Setup renderer
        vtkNew<vtkRenderer> renderer;
        renderer->SetBackground(0.0, 0.0, 0.0);
        renderer->GetActiveCamera()->ParallelProjectionOn();
        renderer->ResetCameraClippingRange();
        renderer->ResetCamera();

        // Setup renderWindow
        vtkNew<vtkRenderWindow> renderWindow;
        renderWindow->AddRenderer(renderer);

        // Setup interaction style
        vtkNew<vtkInteractorStyleImage> interactorStyle;
        interactorStyle->SetInteractionModeToImageSlicing();

        // Setup window interactor
        vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
        renderWindowInteractor->SetRenderWindow(renderWindow);
        renderWindowInteractor->SetInteractorStyle(interactorStyle);

        // Setup camera
        setupCamera(renderer->GetActiveCamera());

        // Load data from DICOM series
//      vtkSmartPointer<vtkImageData> imageData =
//              loadDicom("<path_to_DICOM_series>"");

        // Load data from Nifti file
        vtkSmartPointer<vtkImageData> imageData =
                loadNifti("<path_to_nii_file>");

        // setup slice mapper
        vtkNew<vtkImageResliceMapper> resliceMapper;
        resliceMapper->SetInputData(imageData);
        resliceMapper->SliceFacesCameraOn();
        resliceMapper->SliceAtFocalPointOn();
        resliceMapper->JumpToNearestSliceOn();
        resliceMapper->BorderOff();

        // Set to full window and centered level:
        double window = imageData->GetScalarRange()[1] -
imageData->GetScalarRange()[0];
        double level = imageData->GetScalarRange()[0] + window / 2.0;

        // Setup prop holding the slice
        vtkNew<vtkImageSlice> imageSlice;
        imageSlice->SetMapper(resliceMapper);
        imageSlice->GetProperty()->SetColorWindow(window);
        imageSlice->GetProperty()->SetColorLevel(level);
        imageSlice->GetProperty()->SetLayerNumber(0);
        imageSlice->GetProperty()->SetInterpolationTypeToNearest();
       
        // Setup prop holding the multiple slices
        vtkNew<vtkImageStack> imageStack;
        imageStack->SetActiveLayer(imageSlice->GetProperty()->GetLayerNumber());
        imageStack->AddImage(imageSlice); // add slice

        vtkNew<vtkResliceCursor> resliceCursor;
        resliceCursor->SetCenter(imageData->GetCenter());
        resliceCursor->SetThickMode(0);
        resliceCursor->SetImage(imageData);

        vtkNew<vtkResliceCursorLineRepresentation> cursorRepresentation;
        cursorRepresentation->GetResliceCursorActor()->
           GetCursorAlgorithm()->SetResliceCursor(resliceCursor);
        cursorRepresentation->GetResliceCursorActor()->
            BasicPipeline.cxx
<http://vtk.1045678.n5.nabble.com/file/t341857/BasicPipeline.cxx>
GetCursorAlgorithm()->SetReslicePlaneNormal(2);

        vtkNew<vtkResliceCursorWidget> resliceCursorWidget;
        resliceCursorWidget->SetInteractor(renderWindowInteractor);
        resliceCursorWidget->SetDefaultRenderer(renderer);
        resliceCursorWidget->SetRepresentation(cursorRepresentation);
        resliceCursorWidget->SetManageWindowLevel(false);
        resliceCursorWidget->EnabledOn();
        //resliceCursorWidget->ProcessEventsOff();

        // Add actors to renderer
        renderer->AddViewProp(imageStack);
        renderer->ResetCamera();

        // Start interaction
        renderWindowInteractor->Initialize();
        renderWindow->Render();
        renderWindowInteractor->Start();

        return EXIT_SUCCESS;
}

void setupCamera(vtkCamera* camera)
{
        double viewUp[3] = { 0, 1, 0 };
        double leftToRight[3] = { 1, 0, 0 };

        // compute the view plane normal
        double normal[3];
        vtkMath::Cross(leftToRight, viewUp, normal);

        // get the camera focus
        double focus[3];
        camera->GetFocalPoint(focus);

        // get the camera distance from the focus
        double d = camera->GetDistance();

        // position the camera on view plane normal keeping the focus and the
distance from it fixed
        camera->SetPosition(
                focus[0] + d*normal[0],
                focus[1] + d*normal[1],
                focus[2] + d*normal[2]);

        // make sure focus is the same
        camera->SetFocalPoint(focus);

        // setup view up vector
        camera->SetViewUp(viewUp);
        camera->OrthogonalizeViewUp();
}

vtkSmartPointer<vtkImageData> loadDicom(const char* filename)
{
        vtkNew<vtkDICOMImageReader> reader;
        reader->FileLowerLeftOn();
        reader->SetDirectoryName(filename);
        reader->UpdateInformation();

        vtkNew<vtkImageChangeInformation> imageInfo;
        imageInfo->SetOutputOrigin(0.0, 0.0, 0.0);
        imageInfo->SetOutputSpacing(reader->GetPixelSpacing());
        imageInfo->SetInputConnection(reader->GetOutputPort());
        imageInfo->Update();

        return imageInfo->GetOutput();
}

vtkSmartPointer<vtkImageData> loadNifti(const char* filename)
{
        vtkNew<vtkNIFTIImageReader> niftiiReader;
        niftiiReader->SetFileName(filename);

        vtkNew<vtkImageChangeInformation> imageInfo;
        imageInfo->SetOutputOrigin(0.0, 0.0, 0.0);
        imageInfo->SetInputConnection(niftiiReader->GetOutputPort());
        imageInfo->Update();

        return imageInfo->GetOutput();//data;
}





--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html


------------------------------

Message: 2
Date: Wed, 19 Dec 2018 08:25:13 +0800
From: "=?ISO-8859-1?B?eWlydWkxMjEw?=" <[hidden email]>
To: "=?ISO-8859-1?B?dnRrdXNlcnM=?=" <[hidden email]>
Subject: [vtkusers] The SetRate() function of vtkFFMPEGWriter is not
        working
Message-ID: <[hidden email]>
Content-Type: text/plain; charset="iso-8859-1"

Hello, VTKer


I am using vtkFFMPEGWriter to write a video, no matter the frame rate I set, the output video is still 600 frames/sec.

The code I used has been attached. Can anybody check the problem for me? Thank you so much.


Regards,
YiRui
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20181219/8caa3726/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: [hidden email]
Type: image/jpeg
Size: 5053 bytes
Desc: not available
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20181219/8caa3726/attachment-0001.jpg>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 1.png
Type: application/octet-stream
Size: 5053 bytes
Desc: not available
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20181219/8caa3726/attachment-0003.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: CMakeLists.txt
Type: application/octet-stream
Size: 303 bytes
Desc: not available
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20181219/8caa3726/attachment-0004.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: FFMPEG.cxx
Type: application/octet-stream
Size: 1027 bytes
Desc: not available
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20181219/8caa3726/attachment-0005.obj>

------------------------------

Message: 3
Date: Tue, 18 Dec 2018 18:37:04 -0700 (MST)
From: Andaharoo <[hidden email]>
To: [hidden email]
Subject: Re: [vtkusers] Visualizing normal vectors
Message-ID: <[hidden email]>
Content-Type: text/plain; charset=us-ascii

I'd recommend using vtkOpenGLGlyph3DMapper instead. Much faster, assuming you
have some gpu. Just make sure the normal array/orientation array is in the
input polyData's point data.

IE:
polyData->GetPointData()->AddArray(your normal array)

Then just specify the array the mapper should use with
SetOrientationArray(your arrays name here). It will then search for the
array in the input polydata. I frequently use this to draw thousands of
oriented arrows with VTK.



--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html


------------------------------

Message: 4
Date: Wed, 19 Dec 2018 06:31:31 +0000
From: Andras Lasso <[hidden email]>
To: ochampao <[hidden email]>, "[hidden email]"
        <[hidden email]>
Subject: Re: [vtkusers] Problem with displaying cross-hairs on 2D
        views when using vtkImageResliceMapper -> vtkImageSlice ->
        vtkImageStack pipeline
Message-ID:
        <[hidden email]>
       
Content-Type: text/plain; charset="us-ascii"

It is great that you are interested in medical imaging and has chosen to work with VTK. I would recommend to put your talent and effort into contributing to an existing open-source medical image viewer instead of spending time with redeveloping basic features. You could work on more interesting things, develop new features, and you would very quickly become a useful, valued member of a community.

If you are interested in answers to your question (and your future questions) you can have a look at source code of existing VTK-based open-source medical image viewers, such as 3D Slicer, MITK, medInria, Horos, Ibis, CustusX, CamiTK, Invesalius, etc.

Andras

-----Original Message-----
From: vtkusers <[hidden email]> On Behalf Of ochampao
Sent: Tuesday, December 18, 2018 1:41 PM
To: [hidden email]
Subject: [vtkusers] Problem with displaying cross-hairs on 2D views when using vtkImageResliceMapper -> vtkImageSlice -> vtkImageStack pipeline

Hi vtkUsers,

I am developing a four-pane viewer for displaying medical images. The 3 views display slices of the volumes in the 3 standard anatomical views (axial, coronal, sagittal) whereas the 4th one displays some 3D surface rendering of the volume. For now, I will only focus on the 2D views.

The 2D views use the following pipeline: vtkImageResliceMapper -> vtkImageSlice -> vtkImageStack. This allows the application to overlay slices from multiple volumes simultaneously. The attached code is a minimal example of the 2D pipeline I use in my application. The slices displayed are determined by the focal point of the camera in each 2D view.

What I would like to do is display a set of cross-hairs on each of the 2D views, but I don't know how to achieve this using the pipeline I am currently using.

I am aware of the classes:
vtkResliceCursorWidget,
vtkResliceCursor,
vtkResliceCursorLineRepresentation,
vtkImagePlaneWidget,
vtkResliceImageViewer

I have tried using these classes (see commented code in attached source code), but they don't seem compatible with my current pipeline. For example, when using vtkResliceCursorWidget the cross-hairs are visible and I can interact with them but slicing stops working. I also see some weird artefacts around the border of the slice. Also, to use these classes I need to specify the volume which the reslice cursor will be slicing (vtkResliceCursor->SetImage(imageData)), but in my case I have multiple volumes.

I am also aware of and tried using vtkCursor2D/vtkCursor3D. Although they are close to what I have in mind, they allow very limited customization of their look.

Essentially what I would like to implement is something that looks like the cursor of vtkResliceCursorWidget/vtkImagePlaneWidget/vtkResliceImageViewer
but does not handle slicing.

Can someone recommend how can I achieve this, or point me to some classes/examples? Is their a way of using vtkResliceCursorWidget/vtkImagePlaneWidget/vtkResliceImageViewer with my current pipeline, or would I need to change it?

Thanks a lot for your help.
Panos

========================================================
Basic Pipeline Minimal Example
========================================================
#include <vtkCamera.h>
#include <vtkDICOMImageReader.h>
#include <vtkImageChangeInformation.h>
#include <vtkImageData.h>
#include <vtkImageProperty.h>
#include <vtkImageResliceMapper.h>
#include <vtkImageSlice.h>
#include <vtkImageStack.h>
#include <vtkInteractorStyleImage.h>
#include <vtkMath.h>
#include <vtkNIFTIImageReader.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>

#include <vtkResliceCursor.h>
#include <vtkResliceCursorActor.h>
#include <vtkResliceCursorLineRepresentation.h>
#include <vtkResliceCursorPolyDataAlgorithm.h>
#include <vtkResliceCursorWidget.h>

void setupCamera(vtkCamera* camera);
vtkSmartPointer<vtkImageData> loadDicom(const char* filename); vtkSmartPointer<vtkImageData> loadNifti(const char* filename);

int main(int, char*[])
{
        // Setup renderer
        vtkNew<vtkRenderer> renderer;
        renderer->SetBackground(0.0, 0.0, 0.0);
        renderer->GetActiveCamera()->ParallelProjectionOn();
        renderer->ResetCameraClippingRange();
        renderer->ResetCamera();

        // Setup renderWindow
        vtkNew<vtkRenderWindow> renderWindow;
        renderWindow->AddRenderer(renderer);

        // Setup interaction style
        vtkNew<vtkInteractorStyleImage> interactorStyle;
        interactorStyle->SetInteractionModeToImageSlicing();

        // Setup window interactor
        vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
        renderWindowInteractor->SetRenderWindow(renderWindow);
        renderWindowInteractor->SetInteractorStyle(interactorStyle);

        // Setup camera
        setupCamera(renderer->GetActiveCamera());

        // Load data from DICOM series
//      vtkSmartPointer<vtkImageData> imageData =
//              loadDicom("<path_to_DICOM_series>"");

        // Load data from Nifti file
        vtkSmartPointer<vtkImageData> imageData =
                loadNifti("<path_to_nii_file>");

        // setup slice mapper
        vtkNew<vtkImageResliceMapper> resliceMapper;
        resliceMapper->SetInputData(imageData);
        resliceMapper->SliceFacesCameraOn();
        resliceMapper->SliceAtFocalPointOn();
        resliceMapper->JumpToNearestSliceOn();
        resliceMapper->BorderOff();

        // Set to full window and centered level:
        double window = imageData->GetScalarRange()[1] -
imageData->GetScalarRange()[0];
        double level = imageData->GetScalarRange()[0] + window / 2.0;

        // Setup prop holding the slice
        vtkNew<vtkImageSlice> imageSlice;
        imageSlice->SetMapper(resliceMapper);
        imageSlice->GetProperty()->SetColorWindow(window);
        imageSlice->GetProperty()->SetColorLevel(level);
        imageSlice->GetProperty()->SetLayerNumber(0);
        imageSlice->GetProperty()->SetInterpolationTypeToNearest();
       
        // Setup prop holding the multiple slices
        vtkNew<vtkImageStack> imageStack;
        imageStack->SetActiveLayer(imageSlice->GetProperty()->GetLayerNumber());
        imageStack->AddImage(imageSlice); // add slice

        vtkNew<vtkResliceCursor> resliceCursor;
        resliceCursor->SetCenter(imageData->GetCenter());
        resliceCursor->SetThickMode(0);
        resliceCursor->SetImage(imageData);

        vtkNew<vtkResliceCursorLineRepresentation> cursorRepresentation;
        cursorRepresentation->GetResliceCursorActor()->
           GetCursorAlgorithm()->SetResliceCursor(resliceCursor);
        cursorRepresentation->GetResliceCursorActor()->
            BasicPipeline.cxx
<https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fvtk.1045678.n5.nabble.com%2Ffile%2Ft341857%2FBasicPipeline.cxx&amp;data=02%7C01%7Classo%40queensu.ca%7C80118413b7ba4ceb15d108d665185599%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C1%7C636807552523602151&amp;sdata=nT57nY7HqbSgYg8flXNrjvfhqXVDbvDHbyEOMCVE3V0%3D&amp;reserved=0>
GetCursorAlgorithm()->SetReslicePlaneNormal(2);

        vtkNew<vtkResliceCursorWidget> resliceCursorWidget;
        resliceCursorWidget->SetInteractor(renderWindowInteractor);
        resliceCursorWidget->SetDefaultRenderer(renderer);
        resliceCursorWidget->SetRepresentation(cursorRepresentation);
        resliceCursorWidget->SetManageWindowLevel(false);
        resliceCursorWidget->EnabledOn();
        //resliceCursorWidget->ProcessEventsOff();

        // Add actors to renderer
        renderer->AddViewProp(imageStack);
        renderer->ResetCamera();

        // Start interaction
        renderWindowInteractor->Initialize();
        renderWindow->Render();
        renderWindowInteractor->Start();

        return EXIT_SUCCESS;
}

void setupCamera(vtkCamera* camera)
{
        double viewUp[3] = { 0, 1, 0 };
        double leftToRight[3] = { 1, 0, 0 };

        // compute the view plane normal
        double normal[3];
        vtkMath::Cross(leftToRight, viewUp, normal);

        // get the camera focus
        double focus[3];
        camera->GetFocalPoint(focus);

        // get the camera distance from the focus
        double d = camera->GetDistance();

        // position the camera on view plane normal keeping the focus and the distance from it fixed
        camera->SetPosition(
                focus[0] + d*normal[0],
                focus[1] + d*normal[1],
                focus[2] + d*normal[2]);

        // make sure focus is the same
        camera->SetFocalPoint(focus);

        // setup view up vector
        camera->SetViewUp(viewUp);
        camera->OrthogonalizeViewUp();
}

vtkSmartPointer<vtkImageData> loadDicom(const char* filename) {
        vtkNew<vtkDICOMImageReader> reader;
        reader->FileLowerLeftOn();
        reader->SetDirectoryName(filename);
        reader->UpdateInformation();

        vtkNew<vtkImageChangeInformation> imageInfo;
        imageInfo->SetOutputOrigin(0.0, 0.0, 0.0);
        imageInfo->SetOutputSpacing(reader->GetPixelSpacing());
        imageInfo->SetInputConnection(reader->GetOutputPort());
        imageInfo->Update();

        return imageInfo->GetOutput();
}

vtkSmartPointer<vtkImageData> loadNifti(const char* filename) {
        vtkNew<vtkNIFTIImageReader> niftiiReader;
        niftiiReader->SetFileName(filename);

        vtkNew<vtkImageChangeInformation> imageInfo;
        imageInfo->SetOutputOrigin(0.0, 0.0, 0.0);
        imageInfo->SetInputConnection(niftiiReader->GetOutputPort());
        imageInfo->Update();

        return imageInfo->GetOutput();//data;
}





--
Sent from: https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fvtk.1045678.n5.nabble.com%2FVTK-Users-f1224199.html&amp;data=02%7C01%7Classo%40queensu.ca%7C80118413b7ba4ceb15d108d665185599%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C1%7C636807552523602151&amp;sdata=y%2FPL7RWRxL9djen9OHHFpV8mML1l8tDDID8vwEPDzr4%3D&amp;reserved=0
_______________________________________________
Powered by https://na01.safelinks.protection.outlook.com/?url=www.kitware.com&amp;data=02%7C01%7Classo%40queensu.ca%7C80118413b7ba4ceb15d108d665185599%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C1%7C636807552523602151&amp;sdata=a5wXXUd01fJsRRfeOlVc%2Bk6JcNbeRrCaawzEeOBEpIQ%3D&amp;reserved=0

Visit other Kitware open-source projects at https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.kitware.com%2Fopensource%2Fopensource.html&amp;data=02%7C01%7Classo%40queensu.ca%7C80118413b7ba4ceb15d108d665185599%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C1%7C636807552523602151&amp;sdata=GTPQfYrm85nLVvMYqtzwxYrfNS%2BHK2U5E%2F8%2FXjTuyGQ%3D&amp;reserved=0

Please keep messages on-topic and check the VTK FAQ at: https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.vtk.org%2FWiki%2FVTK_FAQ&amp;data=02%7C01%7Classo%40queensu.ca%7C80118413b7ba4ceb15d108d665185599%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C1%7C636807552523602151&amp;sdata=3OkV0h9SM82LHRbPbSKbfXkZuLWSqAjPyULJuBV%2FrGQ%3D&amp;reserved=0

Search the list archives at: https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmarkmail.org%2Fsearch%2F%3Fq%3Dvtkusers&amp;data=02%7C01%7Classo%40queensu.ca%7C80118413b7ba4ceb15d108d665185599%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C1%7C636807552523602151&amp;sdata=ydyX30Af9G0j8PwVigfaCkucOiFqv0SdNKwyi7vx56Y%3D&amp;reserved=0

Follow this link to subscribe/unsubscribe:
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpublic.kitware.com%2Fmailman%2Flistinfo%2Fvtkusers&amp;data=02%7C01%7Classo%40queensu.ca%7C80118413b7ba4ceb15d108d665185599%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C1%7C636807552523602151&amp;sdata=zYNgte5262YQQDT42ydJgSd1qTiDwQBW4DeWwgOlCzE%3D&amp;reserved=0


------------------------------

Message: 5
Date: Wed, 19 Dec 2018 01:24:28 -0700 (MST)
From: mozendi <[hidden email]>
To: [hidden email]
Subject: Re: [vtkusers] Visualizing normal vectors
Message-ID: <[hidden email]>
Content-Type: text/plain; charset=us-ascii

Dear Andaharoo,
Thank you for your recommendation. I tried to modify my codes according to
your recommendations, my code is getting compiled successfully. However,
when I run it I am getting an error message. The screenshot and my code are
below. Could you please tell me what is wrong with my code?
Thanks in advance
<http://vtk.1045678.n5.nabble.com/file/t341822/vtk_error_message.png>


#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkDelimitedTextReader.h>
#include <vtkDoubleArray.h>
#include <vtkTable.h>
#include <vtkPointData.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkArrowSource.h>
#include <vtkGlyph3D.h>
#include <vtkPointSource.h>
# include "vtkGlyph3DMapper.h"
# include "vtkGlyph3DMapper.h"
#include <vtkOpenGLGlyph3DMapper.h>
#include <vector>


int main(int argc, char* argv[])
{
        vtkSmartPointer<vtkDelimitedTextReader> reader =
vtkSmartPointer<vtkDelimitedTextReader>::New();
        reader->SetFileName("points_and_normals.xyz");
        reader->DetectNumericColumnsOn();
        reader->SetFieldDelimiterCharacters(" ");
        reader->Update();

        vtkTable* table = reader->GetOutput();
        vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
        vtkSmartPointer<vtkDoubleArray> normals =
vtkSmartPointer<vtkDoubleArray>::New();
        normals->SetNumberOfComponents(3); //3d normals (ie x,y,z)

        std::cout << "Table has " << table->GetNumberOfRows()
                << " rows." << std::endl;
        std::cout << "Table has " << table->GetNumberOfColumns()
                << " columns." << std::endl;

        for (vtkIdType i = 0; i < table->GetNumberOfRows(); i++)
        {

                points->InsertNextPoint((table->GetValue(i, 0)).ToDouble(),
                        (table->GetValue(i, 1)).ToDouble(),
                        (table->GetValue(i, 2)).ToDouble());

                double n[3];
                n[0] = (table->GetValue(i, 3)).ToDouble();
                n[1] = (table->GetValue(i, 4)).ToDouble();
                n[2] = (table->GetValue(i, 5)).ToDouble();
                normals->InsertNextTuple(n);
        }

        std::cout << "There are " << points->GetNumberOfPoints()
                << " points." << std::endl;
               

        vtkSmartPointer<vtkPolyData> polydata =
vtkSmartPointer<vtkPolyData>::New();
        polydata->SetPoints(points);
        //polydata->GetPointData()->SetNormals(normals);
        polydata->GetPointData()->AddArray(normals);
       
        vtkSmartPointer<vtkOpenGLGlyph3DMapper> Glyph3D =
vtkSmartPointer<vtkOpenGLGlyph3DMapper>::New();
        Glyph3D->SetInputData(polydata);
        Glyph3D->SetOrientationArray("normals");
        Glyph3D->SetScaleFactor(.5);
        Glyph3D->Update();
               
        vtkSmartPointer<vtkActor> glyph3DActor =        vtkSmartPointer<vtkActor>::New();
        glyph3DActor->SetMapper(Glyph3D);
        glyph3DActor->GetProperty()->SetColor(0.8900, 0.8100, 0.3400);

        vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
        vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
        renderWindow->AddRenderer(renderer);
        vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
        renderWindowInteractor->SetRenderWindow(renderWindow);
        renderer->AddActor(glyph3DActor);
        renderer->SetBackground(.5, .5, .5);
        renderWindow->Render();
        renderWindowInteractor->Start();
        return EXIT_SUCCESS;
}





--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html


------------------------------

Message: 6
Date: Wed, 19 Dec 2018 02:26:23 -0700 (MST)
From: Andaharoo <[hidden email]>
To: [hidden email]
Subject: Re: [vtkusers] Visualizing normal vectors
Message-ID: <[hidden email]>
Content-Type: text/plain; charset=us-ascii

Your error said an array index went out of bounds. What line? Also I noticed
you never set the source data for the glyph. Could be unrelated to your
current error message, but a problem.

The glyph mapper takes two inputs. The glyph data (positions, normals,
scalars, etc) and the source (thing to copy). So if you want arrows as the
normals do this:

vtkSmartPointer<vtkOpenGLGlyph3DMapper> glyph3D =
vtkSmartPointer<vtkOpenGLGlyph3DMapper>::New();
glyph3D ->SetInputData(polydata);
vtkSmartPointer<vtkArrowSource> glyphSource =
vtkSmartPointer<vtkArrowSource>::New();
glyphSource->Update();
glyph3D->SetSourceData(glyphSource->GetOutput());
glyph3D ->SetOrientationArray("normals");
glyph3D ->SetScaleFactor(0.5);
glyph3D ->Update();



--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html


------------------------------

Subject: Digest Footer

_______________________________________________
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

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://public.kitware.com/mailman/listinfo/vtkusers


------------------------------

End of vtkusers Digest, Vol 176, Issue 22
*****************************************


_______________________________________________
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

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://public.kitware.com/mailman/listinfo/vtkusers