maweigert / spimagine

GPU accelerated volume rendering / processing in Python
BSD 3-Clause "New" or "Revised" License
117 stars 17 forks source link

updating volshow widget with new volume data #11

Closed VolkerH closed 7 years ago

VolkerH commented 7 years ago

Hi, this is not really an issue, rather a question. How do I update the data in an active volshow widget with new volume data (while keeping all current view settings) ? Is there an easy way to do this?

maweigert commented 7 years ago

If the updated data has the same shape and dtype as the old one, you can do

w = volshow(data)
w.glWidget.renderer.update_data(new_data)
w.glWidget.refresh()

and it should be updated with all the current transforms/settings still in place.

VolkerH commented 7 years ago

Thanks for the quick reply. unfortunately it doesn't seem to be quite that easy. when I do

w = volshow(data)

followed shortly after by

w.glWidget.renderer.update_data(data.transpose())
w.glWidget.refresh()

the volume goes black rather than showing the transpose of the data. Anyway, I now know what functions to use and will go digging around in the source code when I find the time.

Next question, when I have multichannel data, e.g. RGB - I assume I need to handle the coloration by mapping to single channel and using an appropriate colormap/LUT?

maweigert commented 7 years ago

the volume goes black rather than showing the transpose of the data.

volshow(data) by default internally scales the data and the current transforms are adjusted to that scale whichrenderer.update_data is not aware of. If you do

w = volshow(data, autoscale = False)
w.glWidget.renderer.update_data(data.transpose())
w.glWidget.refresh()

you should see something.

Next question, when I have multichannel data, e.g. RGB - I assume I need to handle the coloration by mapping to single channel and using an appropriate colormap/LUT?

Yeah, multichannel support is quite high on the todo list ;)
You could work around it like you said and directly set a colormap via

w.glWidget._set_colormap_array(arr)

where arr can be a (N,3) array of colors that you could fill with linear ramps of different colors. But thats a bit hacky still ;)

VolkerH commented 7 years ago

Ok, thanks a lot for all your help. Autoscale was indeed the problem. For now, I can live with adjusting the colourmap to display multichannel data. Shouldn't be too difficult.

VolkerH commented 7 years ago

Playing around with w.glWidget._set_colormap_array(arr) at the moment. I notice that the maximum number of entries in the colormap is 214. I can live with that but as I'm not that familiar with GPU programming I'm somewhat surprised that it isn't a multiple of 8, i.e. 216 as in unsigned short. I will map down my 24 bpp to a 14 bpp LUT, that's not a problem, but I'm curious where this limitation comes from (GPU ?)

maweigert commented 7 years ago

Playing around with w.glWidget._set_colormap_array(arr) at the moment. I notice that the maximum number of entries in the colormap is 214

Actually there should be no such limit. Could you provide an example where this show up?

E.g.

import numpy as np
from matplotlib.pyplot import cm
from spimagine import volshow 

data = np.einsum("ij,k",np.ones((100,)*2), np.linspace(0,1,100))
w = volshow(data)
w.glWidget._set_colormap_array(cm.hot(np.linspace(0,1,400)))

just works fine here

VolkerH commented 7 years ago

oh ... this was a markdown error (should have used backticks) I didn't mean 214 but 2 to the power of 14, I didn't check how my own text was formatted - apologies.

This colormap still works:

rcolor=np.random.random((2**14,3))
w.glWidget._set_colormap_array(rcolor)

whereas this fails:

rcolor=np.random.random((2**15,3))
w.glWidget._set_colormap_array(rcolor)
maweigert commented 7 years ago

Ah, I see. This seems to be a limitation of the maximal texture size of the GPU (as the colormaps are uploaded as textures) which e.g. on my machine is

import OpenGL.GL as GL
print(GL.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE))
#16384

is exactly 16384 = 2^14. So I therefore don't see an immediate fix to that :(