Discussion:
[vtkusers] vtkImageActor erases other actors?
Andreas Pedroni
2018-11-18 11:43:23 UTC
Permalink
Dear list

I would like to display a 3D object in front of a vtkImageActor (using Python 3.6 and vtk on Mac OS, see code below). However, the vtkImageActor erases the 3D object. I read in the manual that one should use AddProp() with the renderer to add a vtkImageActor to a render scene. But there is no AddProp() method for the renderer class. I’d be very thankful for any suggestions.

Best
Andreas


import vtk
import cv2
from vtk.util import numpy_support

IMAGEPATH = ‚/models3d/'
VIDEOPATH = "20180816-133303.mp4“

def main():
cap = cv2.VideoCapture(VIDEOPATH)
success, frame = cap.read()

frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
vtk_array = numpy_support.numpy_to_vtk(frame.reshape((-1, 3), order='F'), deep=False)

# Create a vtkImage Object. This is filled with the vtkArray data later
vtk_image = vtk.vtkImageData()
vtk_image.SetDimensions(720, 1280, 1)
vtk_image.SetSpacing(720, 1280, 1)
vtk_image.SetOrigin(720, 1280, 0)
vtk_image.GetPointData().SetScalars(vtk_array)
# create the Texture for a plane

# The Screen where the movie is mapped onto
plane = vtk.vtkPlaneSource()

plane_mapper = vtk.vtkPolyDataMapper()
plane_mapper.SetInputConnection(plane.GetOutputPort())

plane_actor = vtk.vtkImageActor()
plane_actor.SetInputData(vtk_image)
plane_actor.SetScale(1, 0.5625, 1)
plane_actor.SetOrientation(180, 180, 90)

# add the spine object
obj_importer = vtk.vtkOBJReader()
obj_importer.SetFileName(IMAGEPATH + 'Spine.obj')
obj_importer.Update()

spine_mapper = vtk.vtkPolyDataMapper()
spine_mapper.SetInputConnection(obj_importer.GetOutputPort())

spine_actor = vtk.vtkActor()
spine_actor.SetMapper(spine_mapper)
spine_actor.SetOrientation(90, 10, 90)
spine_actor.SetScale(0.3, 0.3, 0.3)

# set up the renderer and the window
ren = vtk.vtkRenderer()
ren_win = vtk.vtkRenderWindow()
ren_win.AddRenderer(ren)
ren_win.SetSize(1500, 1500)

ren.AddActor(spine_actor)
ren.AddActor(plane_actor)

ren.SetBackground(0, 0, 0.1)

iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(ren_win)

# Initialize must be called prior to creating timer events.
iren.Initialize()

# start the interaction and timer
iren.Start()

if __name__ == '__main__':
main()






_______________________________________________
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/v
David Gobbi
2018-11-18 13:52:30 UTC
Permalink
Hi Andreas,

Thanks for sending the code along with your question. The method you want
is AddViewProp(), but it's just a new name for AddActor() and it actually
has the same behavior.

For the image actor, you probably want code like the following.
vtk_image = vtk.vtkImageData()
vtk_image.SetDimensions(720, 1280, 1)
vtk_image.SetSpacing(1.0, 1.0, 1.0)
vtk_image.SetOrigin(-(720 - 1)/2.0, -(1280 - 1)/2.0, 0.0)

The "Spacing" is the size of each pixel, and the "Origin" is the position
of the first pixel in the image (in this case, I set it so that the center
of the image will be at (0,0,0), I'm not sure if this is what you want but
it is a good place to start).

After creating the image data, it is a good idea to add an assert to ensure
the array is the correct size:
assert vtk_image.GetNumberOfPoints() == vtk_array.GetNumberOfTuples()

For the following code, I'm not sure what you are trying to do, but the
effect will be to vertically squash the frame so that it is square:
plane_actor.SetScale(1, 0.5625, 1)

I hope this helps,
David
Post by Andreas Pedroni
Dear list
I would like to display a 3D object in front of a vtkImageActor (using
Python 3.6 and vtk on Mac OS, see code below). However, the vtkImageActor
erases the 3D object. I read in the manual that one should use AddProp()
with the renderer to add a vtkImageActor to a render scene. But there is no
AddProp() method for the renderer class. I’d be very thankful for any
suggestions.
Best
Andreas
import vtk
import cv2
from vtk.util import numpy_support
IMAGEPATH = ‚/models3d/'
VIDEOPATH = "20180816-133303.mp4“
cap = cv2.VideoCapture(VIDEOPATH)
success, frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
vtk_array = numpy_support.numpy_to_vtk(frame.reshape((-1, 3), order='F'), deep=False)
# Create a vtkImage Object. This is filled with the vtkArray data later
vtk_image = vtk.vtkImageData()
vtk_image.SetDimensions(720, 1280, 1)
vtk_image.SetSpacing(720, 1280, 1)
vtk_image.SetOrigin(720, 1280, 0)
vtk_image.GetPointData().SetScalars(vtk_array)
# create the Texture for a plane
# The Screen where the movie is mapped onto
plane = vtk.vtkPlaneSource()
plane_mapper = vtk.vtkPolyDataMapper()
plane_mapper.SetInputConnection(plane.GetOutputPort())
plane_actor = vtk.vtkImageActor()
plane_actor.SetInputData(vtk_image)
plane_actor.SetScale(1, 0.5625, 1)
plane_actor.SetOrientation(180, 180, 90)
# add the spine object
obj_importer = vtk.vtkOBJReader()
obj_importer.SetFileName(IMAGEPATH + 'Spine.obj')
obj_importer.Update()
spine_mapper = vtk.vtkPolyDataMapper()
spine_mapper.SetInputConnection(obj_importer.GetOutputPort())
spine_actor = vtk.vtkActor()
spine_actor.SetMapper(spine_mapper)
spine_actor.SetOrientation(90, 10, 90)
spine_actor.SetScale(0.3, 0.3, 0.3)
# set up the renderer and the window
ren = vtk.vtkRenderer()
ren_win = vtk.vtkRenderWindow()
ren_win.AddRenderer(ren)
ren_win.SetSize(1500, 1500)
ren.AddActor(spine_actor)
ren.AddActor(plane_actor)
ren.SetBackground(0, 0, 0.1)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(ren_win)
# Initialize must be called prior to creating timer events.
iren.Initialize()
# start the interaction and timer
iren.Start()
main()
Andreas Pedroni
2018-11-18 20:26:27 UTC
Permalink
Dear David

Thank you very much for your answer. I tried your suggestions but unfortunately I did not lead to a solution to my problem.
It seems that only the ren.AddActor(plane_actor) has an effect on the rendered image. The ren.AddActor(spine_actor) is not shown. But when I comment out ren.AddActor(plane_actor) the spine_actor is shown.
It is also only a problem if I use a vtk.vtkImageActor(), which I have chosen as it is supposed to be more efficient(?) than doing it with a vtk.vtkPlaneSource().

Thanks again for helping!
Cheers
Andreas
Post by David Gobbi
Hi Andreas,
Thanks for sending the code along with your question. The method you want is AddViewProp(), but it's just a new name for AddActor() and it actually has the same behavior.
For the image actor, you probably want code like the following.
vtk_image = vtk.vtkImageData()
vtk_image.SetDimensions(720, 1280, 1)
vtk_image.SetSpacing(1.0, 1.0, 1.0)
vtk_image.SetOrigin(-(720 - 1)/2.0, -(1280 - 1)/2.0, 0.0)
The "Spacing" is the size of each pixel, and the "Origin" is the position of the first pixel in the image (in this case, I set it so that the center of the image will be at (0,0,0), I'm not sure if this is what you want but it is a good place to start).
assert vtk_image.GetNumberOfPoints() == vtk_array.GetNumberOfTuples()
plane_actor.SetScale(1, 0.5625, 1)
I hope this helps,
David
Dear list
I would like to display a 3D object in front of a vtkImageActor (using Python 3.6 and vtk on Mac OS, see code below). However, the vtkImageActor erases the 3D object. I read in the manual that one should use AddProp() with the renderer to add a vtkImageActor to a render scene. But there is no AddProp() method for the renderer class. I’d be very thankful for any suggestions.
Best
Andreas
import vtk
import cv2
from vtk.util import numpy_support
IMAGEPATH = ‚/models3d/'
VIDEOPATH = "20180816-133303.mp4“
cap = cv2.VideoCapture(VIDEOPATH)
success, frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
vtk_array = numpy_support.numpy_to_vtk(frame.reshape((-1, 3), order='F'), deep=False)
# Create a vtkImage Object. This is filled with the vtkArray data later
vtk_image = vtk.vtkImageData()
vtk_image.SetDimensions(720, 1280, 1)
vtk_image.SetSpacing(720, 1280, 1)
vtk_image.SetOrigin(720, 1280, 0)
vtk_image.GetPointData().SetScalars(vtk_array)
# create the Texture for a plane
# The Screen where the movie is mapped onto
plane = vtk.vtkPlaneSource()
plane_mapper = vtk.vtkPolyDataMapper()
plane_mapper.SetInputConnection(plane.GetOutputPort())
plane_actor = vtk.vtkImageActor()
plane_actor.SetInputData(vtk_image)
plane_actor.SetScale(1, 0.5625, 1)
plane_actor.SetOrientation(180, 180, 90)
# add the spine object
obj_importer = vtk.vtkOBJReader()
obj_importer.SetFileName(IMAGEPATH + 'Spine.obj')
obj_importer.Update()
spine_mapper = vtk.vtkPolyDataMapper()
spine_mapper.SetInputConnection(obj_importer.GetOutputPort())
spine_actor = vtk.vtkActor()
spine_actor.SetMapper(spine_mapper)
spine_actor.SetOrientation(90, 10, 90)
spine_actor.SetScale(0.3, 0.3, 0.3)
# set up the renderer and the window
ren = vtk.vtkRenderer()
ren_win = vtk.vtkRenderWindow()
ren_win.AddRenderer(ren)
ren_win.SetSize(1500, 1500)
ren.AddActor(spine_actor)
ren.AddActor(plane_actor)
ren.SetBackground(0, 0, 0.1)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(ren_win)
# Initialize must be called prior to creating timer events.
iren.Initialize()
# start the interaction and timer
iren.Start()
main()
David Gobbi
2018-11-18 21:39:37 UTC
Permalink
Hi Andreas,

My comments about vtkImageActor might not be the full solution, but I can
guarantee that they are part of the solution.

If the objects cannot be displayed together, it is probably because they
are either too far apart in world coordinates, or perhaps the image actor
is simply obscuring (in front of) the spine actor. To help with debugging
the coordinates, you can print the bounding box for the image data and for
the poly data to make sure they are in roughly the same location. Use the
data's GetBounds() method to do this. Note that the actors also have a
GetBounds method, which returns the bounding box after the actor
transformations have taken place.

David
Post by Andreas Pedroni
Dear David
Thank you very much for your answer. I tried your suggestions but
unfortunately I did not lead to a solution to my problem.
It seems that only the ren.AddActor(plane_actor) has an effect on the
rendered image. The ren.AddActor(spine_actor) is not shown. But when I
comment out ren.AddActor(plane_actor) the spine_actor is shown.
It is also only a problem if I use a vtk.vtkImageActor(), which I have
chosen as it is supposed to be more efficient(?) than doing it with a
vtk.vtkPlaneSource().
Thanks again for helping!
Cheers
Andreas
Hi Andreas,
Thanks for sending the code along with your question. The method you want
is AddViewProp(), but it's just a new name for AddActor() and it actually
has the same behavior.
For the image actor, you probably want code like the following.
vtk_image = vtk.vtkImageData()
vtk_image.SetDimensions(720, 1280, 1)
vtk_image.SetSpacing(1.0, 1.0, 1.0)
vtk_image.SetOrigin(-(720 - 1)/2.0, -(1280 - 1)/2.0, 0.0)
The "Spacing" is the size of each pixel, and the "Origin" is the position
of the first pixel in the image (in this case, I set it so that the center
of the image will be at (0,0,0), I'm not sure if this is what you want but
it is a good place to start).
After creating the image data, it is a good idea to add an assert to
assert vtk_image.GetNumberOfPoints() == vtk_array.GetNumberOfTuples()
For the following code, I'm not sure what you are trying to do, but the
plane_actor.SetScale(1, 0.5625, 1)
I hope this helps,
David
Post by Andreas Pedroni
Dear list
I would like to display a 3D object in front of a vtkImageActor (using
Python 3.6 and vtk on Mac OS, see code below). However, the vtkImageActor
erases the 3D object. I read in the manual that one should use AddProp()
with the renderer to add a vtkImageActor to a render scene. But there is no
AddProp() method for the renderer class. I’d be very thankful for any
suggestions.
Best
Andreas
import vtk
import cv2
from vtk.util import numpy_support
IMAGEPATH = ‚/models3d/'
VIDEOPATH = "20180816-133303.mp4“
cap = cv2.VideoCapture(VIDEOPATH)
success, frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
vtk_array = numpy_support.numpy_to_vtk(frame.reshape((-1, 3), order='F'), deep=False)
# Create a vtkImage Object. This is filled with the vtkArray data later
vtk_image = vtk.vtkImageData()
vtk_image.SetDimensions(720, 1280, 1)
vtk_image.SetSpacing(720, 1280, 1)
vtk_image.SetOrigin(720, 1280, 0)
vtk_image.GetPointData().SetScalars(vtk_array)
# create the Texture for a plane
# The Screen where the movie is mapped onto
plane = vtk.vtkPlaneSource()
plane_mapper = vtk.vtkPolyDataMapper()
plane_mapper.SetInputConnection(plane.GetOutputPort())
plane_actor = vtk.vtkImageActor()
plane_actor.SetInputData(vtk_image)
plane_actor.SetScale(1, 0.5625, 1)
plane_actor.SetOrientation(180, 180, 90)
# add the spine object
obj_importer = vtk.vtkOBJReader()
obj_importer.SetFileName(IMAGEPATH + 'Spine.obj')
obj_importer.Update()
spine_mapper = vtk.vtkPolyDataMapper()
spine_mapper.SetInputConnection(obj_importer.GetOutputPort())
spine_actor = vtk.vtkActor()
spine_actor.SetMapper(spine_mapper)
spine_actor.SetOrientation(90, 10, 90)
spine_actor.SetScale(0.3, 0.3, 0.3)
# set up the renderer and the window
ren = vtk.vtkRenderer()
ren_win = vtk.vtkRenderWindow()
ren_win.AddRenderer(ren)
ren_win.SetSize(1500, 1500)
ren.AddActor(spine_actor)
ren.AddActor(plane_actor)
ren.SetBackground(0, 0, 0.1)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(ren_win)
# Initialize must be called prior to creating timer events.
iren.Initialize()
# start the interaction and timer
iren.Start()
main()
Andreas Pedroni
2018-11-19 04:54:05 UTC
Permalink
Dear David

Thanks for your answer. You were indeed right, the poly data object was hidden within the margins of the plane (I thought a plane has no thickness) and using GetBounds() showed that it did.

All the best
Andreas



Andreas Pedroni
Weinbergweg 2
5408 Ennetbaden
Schweiz
***@gmail.com
+41(0)79 300 17 42
Post by David Gobbi
Hi Andreas,
My comments about vtkImageActor might not be the full solution, but I can guarantee that they are part of the solution.
If the objects cannot be displayed together, it is probably because they are either too far apart in world coordinates, or perhaps the image actor is simply obscuring (in front of) the spine actor. To help with debugging the coordinates, you can print the bounding box for the image data and for the poly data to make sure they are in roughly the same location. Use the data's GetBounds() method to do this. Note that the actors also have a GetBounds method, which returns the bounding box after the actor transformations have taken place.
David
Dear David
Thank you very much for your answer. I tried your suggestions but unfortunately I did not lead to a solution to my problem.
It seems that only the ren.AddActor(plane_actor) has an effect on the rendered image. The ren.AddActor(spine_actor) is not shown. But when I comment out ren.AddActor(plane_actor) the spine_actor is shown.
It is also only a problem if I use a vtk.vtkImageActor(), which I have chosen as it is supposed to be more efficient(?) than doing it with a vtk.vtkPlaneSource().
Thanks again for helping!
Cheers
Andreas
Post by David Gobbi
Hi Andreas,
Thanks for sending the code along with your question. The method you want is AddViewProp(), but it's just a new name for AddActor() and it actually has the same behavior.
For the image actor, you probably want code like the following.
vtk_image = vtk.vtkImageData()
vtk_image.SetDimensions(720, 1280, 1)
vtk_image.SetSpacing(1.0, 1.0, 1.0)
vtk_image.SetOrigin(-(720 - 1)/2.0, -(1280 - 1)/2.0, 0.0)
The "Spacing" is the size of each pixel, and the "Origin" is the position of the first pixel in the image (in this case, I set it so that the center of the image will be at (0,0,0), I'm not sure if this is what you want but it is a good place to start).
assert vtk_image.GetNumberOfPoints() == vtk_array.GetNumberOfTuples()
plane_actor.SetScale(1, 0.5625, 1)
I hope this helps,
David
Dear list
I would like to display a 3D object in front of a vtkImageActor (using Python 3.6 and vtk on Mac OS, see code below). However, the vtkImageActor erases the 3D object. I read in the manual that one should use AddProp() with the renderer to add a vtkImageActor to a render scene. But there is no AddProp() method for the renderer class. I’d be very thankful for any suggestions.
Best
Andreas
import vtk
import cv2
from vtk.util import numpy_support
IMAGEPATH = ‚/models3d/'
VIDEOPATH = "20180816-133303.mp4“
cap = cv2.VideoCapture(VIDEOPATH)
success, frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
vtk_array = numpy_support.numpy_to_vtk(frame.reshape((-1, 3), order='F'), deep=False)
# Create a vtkImage Object. This is filled with the vtkArray data later
vtk_image = vtk.vtkImageData()
vtk_image.SetDimensions(720, 1280, 1)
vtk_image.SetSpacing(720, 1280, 1)
vtk_image.SetOrigin(720, 1280, 0)
vtk_image.GetPointData().SetScalars(vtk_array)
# create the Texture for a plane
# The Screen where the movie is mapped onto
plane = vtk.vtkPlaneSource()
plane_mapper = vtk.vtkPolyDataMapper()
plane_mapper.SetInputConnection(plane.GetOutputPort())
plane_actor = vtk.vtkImageActor()
plane_actor.SetInputData(vtk_image)
plane_actor.SetScale(1, 0.5625, 1)
plane_actor.SetOrientation(180, 180, 90)
# add the spine object
obj_importer = vtk.vtkOBJReader()
obj_importer.SetFileName(IMAGEPATH + 'Spine.obj')
obj_importer.Update()
spine_mapper = vtk.vtkPolyDataMapper()
spine_mapper.SetInputConnection(obj_importer.GetOutputPort())
spine_actor = vtk.vtkActor()
spine_actor.SetMapper(spine_mapper)
spine_actor.SetOrientation(90, 10, 90)
spine_actor.SetScale(0.3, 0.3, 0.3)
# set up the renderer and the window
ren = vtk.vtkRenderer()
ren_win = vtk.vtkRenderWindow()
ren_win.AddRenderer(ren)
ren_win.SetSize(1500, 1500)
ren.AddActor(spine_actor)
ren.AddActor(plane_actor)
ren.SetBackground(0, 0, 0.1)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(ren_win)
# Initialize must be called prior to creating timer events.
iren.Initialize()
# start the interaction and timer
iren.Start()
main()
Loading...