Skip to content
Snippets Groups Projects
Commit e0cd0f38 authored by Paul McCarthy's avatar Paul McCarthy
Browse files

Merge branch 'master' into instance_constraints

Bringing bet/slicecanvas/etc fixes from master into image_constraints branch.
parents 787b2407 cb39c416
No related branches found
No related tags found
No related merge requests found
......@@ -151,15 +151,15 @@ def buildGUI(fslTool, toolCtx, fslEnvActive):
actions.append((
wx.ID_HELP,
'{} Help'.format(fslTool.toolName),
lambda ev: webpage.openFSLHelp(fslTool.helpPage)))
lambda *ev: webpage.openFSLHelp(fslTool.helpPage)))
for (name, func) in fslTool.actions:
actions.append((-1, name, lambda ev: func(frame, ctx)))
actions.append((wx.ID_ANY, name, lambda ev, f=func: f(frame, ctx)))
actions.append((
wx.ID_EXIT,
'Exit',
lambda ev: frame.Close()))
lambda *ev: frame.Close()))
for wxId, name, func in actions:
menuItem = fslMenu.Append(wxId, name)
......
......@@ -77,8 +77,8 @@ class Image(object):
lo, hi = sorted(tx[:, axis])
lo = lo - self.pixdim[axis] * 0.5
hi = hi + self.pixdim[axis] * 0.5
lo = float(lo - self.pixdim[axis] * 0.5)
hi = float(hi + self.pixdim[axis] * 0.5)
return (lo, hi)
......@@ -87,7 +87,9 @@ class Image(object):
"""
Transforms the given set of points in voxel coordinates to
points in world coordinates, according to the affine
transformation specified in the image file. Parameters:
transformation specified in the image file. The returned array
is either a numpy.float64 array, or a single integer value,
depending on the input. Parameters:
- p: N*A array, where N is the number of points, and A
is the number of axes to consider (default: 3)
......@@ -101,31 +103,39 @@ class Image(object):
"""
voxp = self._transform(p, self.worldToVoxMat, axes)
voxp = np.array(voxp, dtype=np.int64)
return voxp
if voxp.size == 1: return int(voxp[0])
else: return voxp
def voxToWorld(self, p, axes=None):
"""
Transforms the given set of points in world coordinates to
points in voxel coordinates, according to the affine
transformation specified in the image file. See the
worldToVox docstring for more details.
"""
return self._transform(p, self.voxToWorldMat, axes)
transformation specified in the image file. The returned
array is either a numpy.float64 array, or a single float
value, depending on the input. See the worldToVox
docstring for more details.
"""
worldp = self._transform(p, self.voxToWorldMat, axes)
if worldp.size == 1:
#print 'casting to float!'
return float(worldp)
else: return worldp
def _transform(self, p, a, axes):
"""
Transforms the given set of points p according to the given
affine transformation a. See the worldToVox docstring for
more details.
affine transformation a. The transformed points are returned
as a numpy.float64 array. See the worldToVox docstring for
more details.
"""
p = self._fillPoints(p, axes)
t = np.zeros((len(p), 3), dtype=p.dtype)
t = np.zeros((len(p), 3), dtype=np.float64)
x = p[:, 0]
y = p[:, 1]
......@@ -148,6 +158,7 @@ class Image(object):
"""
if not isinstance(p, collections.Iterable): p = [p]
p = np.array(p)
if axes is None: return p
......
......@@ -112,11 +112,12 @@ class ImageListPanel(wx.Panel):
except: lastDir = os.getcwd()
wildcard = imagefile.wildcard()
# wx wildcard handling is buggy, so i'm disabling it for now
dlg = wx.FileDialog(self.GetParent(),
message='Open image file',
defaultDir=lastDir,
wildcard=wildcard,
# wildcard=wildcard,
style=wx.FD_OPEN)
if dlg.ShowModal() != wx.ID_OK: return
......
......@@ -152,3 +152,16 @@ class OrthoFrame(wx.Frame):
wx.Frame.__init__(self, parent, title=title)
self.panel = OrthoPanel(self, imageList)
self.Layout()
class OrthoDialog(wx.Dialog):
"""
Convenience class for displaying an OrthoPanel in a (possibly modal)
dialog window.
"""
def __init__(self, parent, imageList, title=None):
wx.Dialog.__init__(self, parent, title=title)
self.panel = OrthoPanel(self, imageList)
self.Layout()
......@@ -120,17 +120,20 @@ class GLImageData(object):
yidxs = np.arange(self.ydim, dtype=np.float32)
yidxs, xidxs = np.meshgrid(yidxs, xidxs, indexing='ij')
# And put them into a single array (the image.voxToWorld
# method needs xyz coordinates, hence the N*3 shape here)
positionData = np.zeros((self.xdim * self.ydim, 3), dtype=np.float32)
positionData[:, xax] = xidxs.ravel(order='C')
positionData[:, yax] = yidxs.ravel(order='C')
# And put them into a single array
positionData = np.vstack((
xidxs.ravel(order='C'),
yidxs.ravel(order='C'))).transpose()
# Then we transform them from voxel
# coordinates to world coordinates
positionData = image.voxToWorld(positionData)[:, (xax, yax)]
# GL buffers for the geometry and position data
# coordinates to world coordinates,
# making sure that they are of type
# float32
positionData = image.voxToWorld(positionData, axes=(xax, yax))
positionData = np.array(positionData, dtype=np.float32)
# Define GL buffers for the geometry and position
# data containing the data we just created above
geomData = geomData .ravel(order='C')
positionData = positionData.ravel(order='C')
geomBuffer = vbo.VBO(geomData, gl.GL_STATIC_DRAW)
......@@ -461,6 +464,13 @@ class SliceCanvas(wxgl.GLCanvas):
self._ypos = None
self._zpos = None
self.xmin = 0
self.ymin = 0
self.zmin = 0
self.xmax = 1
self.ymax = 1
self.zmax = 1
# This flag is set by the _initGLData method
# when it has finished initialising the OpenGL
# shaders
......
......@@ -140,7 +140,7 @@ class Options(props.HasProperties):
cmd.append('-r')
cmd.append('{}'.format(self.headRadius))
if all((self.xCoordinate > 0.0,
if any((self.xCoordinate > 0.0,
self.yCoordinate > 0.0,
self.zCoordinate > 0.0)):
cmd.append('-c')
......@@ -193,40 +193,11 @@ def selectHeadCentre(opts, button):
image = fslimage.Image(opts.inputImage)
imageList = fslimage.ImageList([image])
parent = button.GetTopLevelParent()
frame = orthopanel.OrthoFrame(parent, imageList, opts.inputImage)
frame = orthopanel.OrthoDialog(parent, imageList, opts.inputImage)
panel = frame.panel
voxCoords = [opts.xCoordinate, opts.yCoordinate, opts.zCoordinate]
worldCoords = image.voxToWorld([voxCoords])[0]
panel.setLocation(*worldCoords)
# Whenever the x/y/z coordinates change on
# the Options object,update the orthopanel
# location
def updateViewX(val, *a): panel.setXLocation(image.voxToWorld(val, axes=0))
def updateViewY(val, *a): panel.setYLocation(image.voxToWorld(val, axes=1))
def updateViewZ(val, *a): panel.setZLocation(image.voxToWorld(val, axes=2))
optListeners = (
('xCoordinate', 'updateViewX_{}'.format(id(panel)), updateViewX),
('yCoordinate', 'updateViewY_{}'.format(id(panel)), updateViewY),
('zCoordinate', 'updateViewZ_{}'.format(id(panel)), updateViewZ))
for listener in optListeners:
opts.addListener(*listener)
def rmListeners(ev):
for listener in optListeners:
prop = listener[0]
name = listener[1]
opts.removeListener(prop, name)
# Remove the listeners when the dialog is closed
frame.Bind(wx.EVT_WINDOW_DESTROY, rmListeners)
# And whenever the x/y/z coordinates change
# on the dialog, update the option values.
# the ortho panel, update the option values.
def updateOpts(ev):
x = image.worldToVox(ev.x, axes=0)
y = image.worldToVox(ev.y, axes=1)
......@@ -247,10 +218,18 @@ def selectHeadCentre(opts, button):
panel.Bind(orthopanel.EVT_LOCATION_EVENT, updateOpts)
# Set the initial location on the orthopanel.
# TODO this ain't working, as it needs to be
# done after the frame has been displayed, i.e
# via wx.CallAfter or similar.
voxCoords = [opts.xCoordinate, opts.yCoordinate, opts.zCoordinate]
worldCoords = image.voxToWorld([voxCoords])[0]
panel.setLocation(*worldCoords)
# Position the dialog by the button that was clicked
pos = button.GetScreenPosition()
frame.SetPosition(pos)
frame.Show()
frame.ShowModal()
betView = props.NotebookGroup((
......@@ -297,10 +276,15 @@ def runBet(parent, opts):
if exitCode != 0: return
image = nb.load(imagefile.addExt(opts.outputImage))
frame = orthopanel.OrthoFrame(window,
image.get_data(),
title=opts.outputImage)
inImage = fslimage.Image(opts.inputImage)
outImage = fslimage.Image(opts.outputImage)
imageList = fslimage.ImageList([inImage, outImage])
outImage.display.cmap = 'Reds'
outImage.display.displayMin = 1
outImage.display.rangeClip = True
frame = orthopanel.OrthoFrame(parent, imageList, opts.outputImage)
frame.Show()
runwindow.checkAndRun('BET', opts, parent, Options.genBetCmd,
......
......@@ -30,6 +30,7 @@ class FslViewPanel(wx.Panel):
self.sizer.Add(self.listPanel, flag=wx.EXPAND)
self.Layout()
self.Fit()
def fslviewArguments(parser):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment