Skip to content

Instantly share code, notes, and snippets.

@pangyuteng
Last active April 27, 2024 16:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pangyuteng/facd430d0d9761fc67fff4ff2e5fffc3 to your computer and use it in GitHub Desktop.
Save pangyuteng/facd430d0d9761fc67fff4ff2e5fffc3 to your computer and use it in GitHub Desktop.
render isosurface and save as gif using vtk and moviepy

demo gif

source /anaconda3/bin/activate py36

wget https://github.com/jonclayden/RNifti/raw/master/inst/extdata/example.nii.gz

python isosurface_vtk.py

#
import sys
import numpy as np
import vtk
from vtk.util.colors import salmon
reader = vtk.vtkNIFTIImageReader()
reader.SetFileName('example.nii.gz')
reader.Update()
threshold = vtk.vtkImageThreshold ()
threshold.SetInputConnection(reader.GetOutputPort())
#threshold.ThresholdBetween(1,1) #th
threshold.ThresholdByLower(50) #th
threshold.ReplaceInOn()
threshold.SetInValue(0) # set all values below th to 0
threshold.ReplaceOutOn()
threshold.SetOutValue(1) # set all values above th to 1
threshold.Update()
'''
voi = vtk.vtkExtractVOI()
voi.SetInputConnection(threshold.GetOutputPort())
voi.SetVOI(0,95, 0,95, 0,59)
voi.SetSampleRate(1,1,1)
#voi.SetSampleRate(3,3,3)
voi.Update()#necessary for GetScalarRange()
srange= voi.GetOutput().GetScalarRange()#needs Update() before!
print("Range", srange)
'''
dmc = vtk.vtkDiscreteMarchingCubes()
dmc.SetInputConnection(threshold.GetOutputPort())
#dmc.SetInputConnection(voi.GetOutputPort())
dmc.GenerateValues(1, 1, 1)
dmc.Update()
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(dmc.GetOutputPort())
mapper.Update()
actor = vtk.vtkActor()
actor.SetMapper(mapper)
mapper.ScalarVisibilityOff()
actor.GetProperty().SetColor(salmon)
actor.GetProperty().SetOpacity(0.5)
actor.RotateX(90)
renderer = vtk.vtkRenderer()
renderWindow = vtk.vtkRenderWindow()
renderWindow.SetOffScreenRendering(1)
renderWindow.AddRenderer(renderer)
renderer.AddActor(actor)
renderer.SetBackground(1.0, 1.0, 1.0)
center = actor.GetCenter()
camera = renderer.MakeCamera()
camera.SetPosition(0,0,800)
camera.SetFocalPoint(center)
renderer.SetActiveCamera(camera)
renderWindow.Render()
focal_point = camera.GetFocalPoint()
view_up = camera.GetViewUp()
position = camera.GetPosition()
axis = [0,0,0]
axis[0] = -1*camera.GetViewTransformMatrix().GetElement(0,0)
axis[1] = -1*camera.GetViewTransformMatrix().GetElement(0,1)
axis[2] = -1*camera.GetViewTransformMatrix().GetElement(0,2)
print(position,focal_point,view_up,)
print(camera.GetViewTransformMatrix())
print(camera.GetViewTransformMatrix().GetElement(0,0))
print(camera.GetViewTransformMatrix().GetElement(0,1))
print(camera.GetViewTransformMatrix().GetElement(0,2))
frame_list = []
for n,q in enumerate([10]*35):
transform = vtk.vtkTransform()
transform.Identity()
transform.Translate(*center)
transform.RotateWXYZ(q,view_up)
transform.RotateWXYZ(0,axis)
transform.Translate(*[-1*x for x in center])
new_position = [0,0,0]
new_focal_point = [0,0,0]
transform.TransformPoint(position,new_position)
transform.TransformPoint(focal_point,new_focal_point)
camera.SetPosition(new_position)
camera.SetFocalPoint(new_focal_point)
focal_point = camera.GetFocalPoint()
view_up = camera.GetViewUp()
position = camera.GetPosition()
camera.OrthogonalizeViewUp();
renderer.ResetCameraClippingRange();
renderWindow.Render()
windowToImageFilter = vtk.vtkWindowToImageFilter()
windowToImageFilter.SetInput(renderWindow)
windowToImageFilter.Update()
writer = vtk.vtkPNGWriter()
fpath = "zisosurface{}.png".format(n)
writer.SetFileName(fpath)
writer.SetInputConnection(windowToImageFilter.GetOutputPort())
writer.Write()
frame_list.append(fpath)
duration = 2
fps = 17.5
time_list = list(np.arange(0,duration,1./fps))
img_dict = {a:f for a,f in zip(time_list,frame_list)}
import PIL
from moviepy import editor
def make_frame(t):
fpath= img_dict[t]
im = PIL.Image.open(fpath)
ar = np.asarray(im)
return ar
gif_path = 'ani.gif'
clip = editor.VideoClip(make_frame, duration=duration)
clip.write_gif(gif_path, fps=fps)
'''
ref
https://www.programcreek.com/python/example/9480/vtk.vtkRenderWindows
https://pyscience.wordpress.com/2014/09/11/surface-extraction-creating-a-mesh-from-pixel-data-using-python-and-vtk/
https://stackoverflow.com/questions/43046798/how-to-rotate-a-vtk-scene-around-a-specific-point
https://gamedev.stackexchange.com/questions/20758/how-can-i-orbit-a-camera-about-its-target-point
'''
@pangyuteng
Copy link
Author

related: offscreen vtk inside container using vtk-osmesa
https://github.com/pangyuteng/public-scratch/tree/master/docker/dcm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment