From ecaef256689528b6ffdc3eb0a0a6686901fd5daf Mon Sep 17 00:00:00 2001 From: Leila Wehbe Date: Fri, 10 Mar 2017 16:28:13 -0800 Subject: [PATCH 1/4] DOC: (webgl) added save_3d_views.py --- examples/webgl/save_3d_views.py | 86 +++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 examples/webgl/save_3d_views.py diff --git a/examples/webgl/save_3d_views.py b/examples/webgl/save_3d_views.py new file mode 100644 index 000000000..d40a3e9e4 --- /dev/null +++ b/examples/webgl/save_3d_views.py @@ -0,0 +1,86 @@ +""" +============= +Save 3D views +============= +The dynamic viewer generated by cortex can be used to produce images +of brains in 3D. This examples show how different views can be +captured into '.png' images after a dynamic viewer is instantiated. + +""" + +import os +import time +import numpy as np +import cortex + +# gather data Volume +volume = cortex.Volume.random(subject='S1', xfmname='fullhead') + +# select path for the generated images on disk +image_path = '/path/to/save/images' + +# pattern of the saved images names +file_pattern = "{base}_{view}_{surface}.png" +# in this case, let's use 'test' as a base name: +base_str = 'test' + +# create viewer (additional viewer parameters can be specified here, +# such as omitting ROI labels for example) +handle = cortex.webgl.show(data=volume) + +# wait to make sure the viewer was instantiated: +time.sleep(5.0) + +# Set up params + +# projection parameters +basic = dict(radius=400) # projection=['orthographic'], + +# different views available, more views can be added and the +# existing list can be removed +views = dict(lateral=dict(altitude=90.5, azimuth=181, pivot=180), + medial=dict(altitude=90.5, azimuth=0, pivot=180), + front=dict(altitude=90.5, azimuth=0, pivot=0), + back=dict(altitude=90.5, azimuth=181, pivot=0), + top=dict(altitude=0, azimuth=180, pivot=0), + bottom=dict(altitude=180, azimuth=0, pivot=0) + ) + +# different surfaces options can be used +surfaces = dict(inflated=dict(unfold=0.5), + fiducial=dict(unfold=0.0)) + + +# utility functions to set the different views +prefix = dict(altitude='camera.', azimuth='camera.', + pivot='surface.{subject}.', radius='camera.', + unfold='surface.{subject}.') +_tolists = lambda p: {prefix[k]+k:[v] for k,v in p.items()} +_combine = lambda a,b: ( lambda c: [c, c.update(b)][0] )(dict(a)) + + +# Save images by iterating over the different views and surfaces +for view,vparams in views.items(): + for surf,sparams in surfaces.items(): + # Combine basic, view, and surface parameters + params = _combine(_combine(basic, vparams), sparams) + # Set the view + handle._set_view(**_tolists(params)) + # Save image + filename = file_pattern.format(base=base_str, view=view, surface=surf) + output_path = os.path.join(image_path, filename) + handle.getImage(output_path, size =(1920, 1080)) + + # the block below trims the edges of the image: + # wait for image to be written + while not os.path.exists(output_path): + pass + time.sleep(0.5) + try: + import subprocess + subprocess.call(["convert", "-trim", output_path, output_path]) + except: + pass + +# Close the window! +handle.close() \ No newline at end of file From 71b4cb8a540aa399ed94f572dd71bc22e29ff587 Mon Sep 17 00:00:00 2001 From: Leila Wehbe Date: Fri, 10 Mar 2017 16:49:17 -0800 Subject: [PATCH 2/4] DOC: (webgl) remove unnecessary import --- examples/webgl/save_3d_views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/webgl/save_3d_views.py b/examples/webgl/save_3d_views.py index d40a3e9e4..1fdfc2d0a 100644 --- a/examples/webgl/save_3d_views.py +++ b/examples/webgl/save_3d_views.py @@ -10,7 +10,6 @@ import os import time -import numpy as np import cortex # gather data Volume From f26ebc76244e6200460b382268cf953d9081c605 Mon Sep 17 00:00:00 2001 From: Leila Wehbe Date: Fri, 10 Mar 2017 16:51:26 -0800 Subject: [PATCH 3/4] DOC: (webgl) remove double quotes --- examples/webgl/save_3d_views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/webgl/save_3d_views.py b/examples/webgl/save_3d_views.py index 1fdfc2d0a..a29325584 100644 --- a/examples/webgl/save_3d_views.py +++ b/examples/webgl/save_3d_views.py @@ -19,7 +19,7 @@ image_path = '/path/to/save/images' # pattern of the saved images names -file_pattern = "{base}_{view}_{surface}.png" +file_pattern = '{base}_{view}_{surface}.png' # in this case, let's use 'test' as a base name: base_str = 'test' @@ -77,7 +77,7 @@ time.sleep(0.5) try: import subprocess - subprocess.call(["convert", "-trim", output_path, output_path]) + subprocess.call(['convert', '-trim', output_path, output_path]) except: pass From 64f616091af86b3826e7fa95f547ec23fe2a9251 Mon Sep 17 00:00:00 2001 From: Leila Wehbe Date: Fri, 10 Mar 2017 17:03:38 -0800 Subject: [PATCH 4/4] DOC: (webgl) added animation.py --- examples/webgl/animation.py | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 examples/webgl/animation.py diff --git a/examples/webgl/animation.py b/examples/webgl/animation.py new file mode 100644 index 000000000..d7c5d9ccd --- /dev/null +++ b/examples/webgl/animation.py @@ -0,0 +1,43 @@ +""" +============== +make animation +============== +The dynamic viewer generated by cortex can be used to make an animation +such as a transition between inflated and flattened brain or a rotating +brain, of a cortical surface. We show here an example. + +""" + +import cortex + +# gather data Volume +volume = cortex.Volume.random(subject='S1', xfmname='fullhead') + +# select path for the animated movie on disk +animation_path = '/path/to/save/animation' + +# create viewer (additional viewer parameters can be specified here, +# such as omitting ROI labels for example) +handle = cortex.webgl.show(data=volume) + +# Called after a call of the form: js_handle = cortex.webgl.show(DataViewObject) +# Start with left hemisphere view +start_view = dict(azimuth=90, altitude=90.5) + +# utility functions to set the different views +prefix = dict(altitude='camera.', azimuth='camera.', + pivot='surface.{subject}.', radius='camera.', + unfold='surface.{subject}.') +_tolists = lambda p: {prefix[k]+k:[v] for k,v in p.items()} + +handle._set_view(**_tolists(start_view)) + +# Initialize list +animation = [] +# Append 5 key frames for a simple rotation +for az, idx in zip([90, 180, 270, 360, 450], [0, .5, 1.0, 1.5, 2.0]): + animation.append({'state':'camera.azimuth', 'idx':idx, 'value':[az]}) +# Animate! (use default settings) +handle.makeMovie(animation, filename=os.path.join(movie_path,'brainmovie%07d.png')) + +# the 'movie_path' directory will now have all the frames of the animation \ No newline at end of file