diff --git a/fsl/data/image.py b/fsl/data/image.py
index e6a0513142d5180d22d09e123f57776a4cac673e..725951a5207002e8254da4aef58dfd32b1c76177 100644
--- a/fsl/data/image.py
+++ b/fsl/data/image.py
@@ -26,22 +26,23 @@ import fsl.data.imagefile as imagefile
 
 log = logging.getLogger(__name__)
 
-L2R = 0
-R2L = 1
-P2A = 2
-A2P = 3
-I2S = 4
-S2I = 5
-
-orientationLabels = {
-    L2R : ('L', 'R'),
-    R2L : ('R', 'L'),
-    P2A : ('P', 'A'),
-    A2P : ('A', 'P'),
-    S2I : ('S', 'I'),
-    I2S : ('I', 'S')
-}
-
+# Constants which represent the orientation of an axis,
+# in either voxel or world space.
+ORIENT_UNKNOWN = -1
+ORIENT_L2R     = 0
+ORIENT_R2L     = 1
+ORIENT_P2A     = 2
+ORIENT_A2P     = 3
+ORIENT_I2S     = 4
+ORIENT_S2I     = 5
+
+# Constants from the NIFTI1 specification that define
+# the 'space' in which an image is assumed to be.
+NIFTI_XFORM_UNKNOWN      = 0
+NIFTI_XFORM_SCANNER_ANAT = 1
+NIFTI_XFORM_ALIGNED_ANAT = 2
+NIFTI_XFORM_TALAIRACH    = 3
+NIFTI_XFORM_MNI_152      = 4
 
 def _loadImageFile(filename):
     """Given the name of an image file, loads it using nibabel.
@@ -384,15 +385,78 @@ class Image(props.HasProperties):
         else:                return worldp
 
 
-    def getOrientation(self, axis):
+    def getXFormCode(self):
+        """This method returns the code contained in the NIFTI1 header,
+        indicating the space to which the (transformed) image is oriented.
+        
+        """
+        sform_code = self.nibImage.get_header()['sform_code']
+        qform_code = self.nibImage.get_header()['qform_code']
+
+        # if the qform and sform codes don't
+        # match, I don't know what to do
+        if   sform_code != qform_code: return NIFTI_XFORM_UNKNOWN
+
+        # Invalid values
+        elif sform_code > 4:           return NIFTI_XFORM_UNKNOWN
+        elif sform_code < 0:           return NIFTI_XFORM_UNKNOWN
+
+        # All is well
+        else:                          return sform_code
+
+
+    def getWorldOrientation(self, axis):
+        """Returns a code representing the orientation of the specified axis
+        in world space.
+
+        This method returns one of the following values, indicating the
+        direction in which coordinates along the specified axis increase:
+          - :attr:`~fsl.data.image.ORIENT_L2R`:     Left to right
+          - :attr:`~fsl.data.image.ORIENT_R2L`:     Right to left
+          - :attr:`~fsl.data.image.ORIENT_A2P`:     Anterior to posterior
+          - :attr:`~fsl.data.image.ORIENT_P2A`:     Posterior to anterior
+          - :attr:`~fsl.data.image.ORIENT_I2S`:     Inferior to superior
+          - :attr:`~fsl.data.image.ORIENT_S2I`:     Superior to inferior
+          - :attr:`~fsl.data.image.ORIENT_UNKNOWN`: Orientation is unknown
+
+        The returned value is dictated by the XForm code contained in the
+        image file header (see the :meth:`getXFormCode` method). Basically,
+        if the XForm code is 'unknown', this method will return -1 for all
+        axes. Otherwise, it is assumed that the image is in RAS orientation
+        (i.e. the X axis increases from left to right, the Y axis increases
+        from  posterior to anterior, and the Z axis increases from inferior
+        to superior).
+        """
+
+        if self.getXFormCode() == NIFTI_XFORM_UNKNOWN:
+            return -1
+
+        if   axis == 0: return ORIENT_L2R
+        elif axis == 1: return ORIENT_P2A
+        elif axis == 2: return ORIENT_I2S
+
+        else: return -1
+
+
+    def getVoxelOrientation(self, axis):
+        """Returns a code representing the (estimated) orientation of the
+        specified voxelwise axis.
+
+        See the :meth:`getWorldOrientation` method for a description
+        of the return value.
+        """
+        
+        if self.getXFormCode() == NIFTI_XFORM_UNKNOWN:
+            return -1 
+        
         # the aff2axcodes returns one code for each 
         # axis in the image array (i.e. in voxel space),
         # which denotes the real world direction
         code = nib.orientations.aff2axcodes(self.nibImage.get_affine(),
-                                            ((R2L, L2R),
-                                             (A2P, P2A),
-                                             (S2I, I2S)))[axis]
-        return orientationLabels[code]
+                                            ((ORIENT_R2L, ORIENT_L2R),
+                                             (ORIENT_A2P, ORIENT_P2A),
+                                             (ORIENT_S2I, ORIENT_I2S)))[axis]
+        return code
 
         
     def _transform(self, p, a, axes):
diff --git a/fsl/fslview/strings.py b/fsl/fslview/strings.py
index bad57e3546e2bde8effdc724423bb14ce5a59a0e..cb0c7cbfbb1fda0bc279c1bc797bc74a8c34803e 100644
--- a/fsl/fslview/strings.py
+++ b/fsl/fslview/strings.py
@@ -5,6 +5,8 @@
 # Author: Paul McCarthy <pauldmccarthy@gmail.com>
 #
 
+import fsl.data.image as fslimage
+
 from views   .orthopanel         import OrthoPanel
 from views   .lightboxpanel      import LightBoxPanel
 from views   .timeseriespanel    import TimeSeriesPanel
@@ -49,3 +51,48 @@ orthoConfigMenu    = '{} display'
 lightBoxConfigMenu = '{} display'
 
 locationPanelOutOfBounds = 'Out of bounds'
+
+
+
+imageAxisLowLongLabels = {
+    fslimage.ORIENT_A2P     : 'Anterior',
+    fslimage.ORIENT_P2A     : 'Posterior',
+    fslimage.ORIENT_L2R     : 'Left',
+    fslimage.ORIENT_R2L     : 'Right',
+    fslimage.ORIENT_I2S     : 'Inferior',
+    fslimage.ORIENT_S2I     : 'Superior',
+    fslimage.ORIENT_UNKNOWN : 'Unknown'}
+
+imageAxisHighLongLabels = {
+    fslimage.ORIENT_A2P     : 'Posterior',
+    fslimage.ORIENT_P2A     : 'Anterior',
+    fslimage.ORIENT_L2R     : 'Right',
+    fslimage.ORIENT_R2L     : 'Left',
+    fslimage.ORIENT_I2S     : 'Superior',
+    fslimage.ORIENT_S2I     : 'Inferior',
+    fslimage.ORIENT_UNKNOWN : 'Unknown'}
+
+imageAxisLowShortLabels = {
+    fslimage.ORIENT_A2P     : 'A',
+    fslimage.ORIENT_P2A     : 'P',
+    fslimage.ORIENT_L2R     : 'L',
+    fslimage.ORIENT_R2L     : 'R',
+    fslimage.ORIENT_I2S     : 'I',
+    fslimage.ORIENT_S2I     : 'S',
+    fslimage.ORIENT_UNKNOWN : '?'}
+
+imageAxisHighShortLabels = {
+    fslimage.ORIENT_A2P     : 'P',
+    fslimage.ORIENT_P2A     : 'A',
+    fslimage.ORIENT_L2R     : 'R',
+    fslimage.ORIENT_R2L     : 'L',
+    fslimage.ORIENT_I2S     : 'S',
+    fslimage.ORIENT_S2I     : 'I',
+    fslimage.ORIENT_UNKNOWN : '?'}
+
+imageSpaceLabels = {
+    fslimage.NIFTI_XFORM_UNKNOWN      : 'Unknown',
+    fslimage.NIFTI_XFORM_SCANNER_ANAT : 'Scanner anatomical',
+    fslimage.NIFTI_XFORM_ALIGNED_ANAT : 'Aligned anatomical',
+    fslimage.NIFTI_XFORM_TALAIRACH    : 'Talairach', 
+    fslimage.NIFTI_XFORM_MNI_152      : 'MNI152'}
diff --git a/fsl/fslview/views/orthopanel.py b/fsl/fslview/views/orthopanel.py
index 4b5d924f5fd07db297efed906253ab03750bdb3d..cd343f5c70bd7ae467e9471adf42ca71ba84ab8d 100644
--- a/fsl/fslview/views/orthopanel.py
+++ b/fsl/fslview/views/orthopanel.py
@@ -19,6 +19,8 @@ log = logging.getLogger(__name__)
 import wx
 import props
 
+import fsl.data.image                 as fslimage
+
 import fsl.fslview.gl                 as fslgl
 import fsl.fslview.gl.wxglslicecanvas as slicecanvas
 import canvaspanel
@@ -221,16 +223,25 @@ class OrthoPanel(canvaspanel.CanvasPanel):
         self.bindProps('invertZ_X', self._zcanvas, 'invertX')
         self.bindProps('invertZ_Y', self._zcanvas, 'invertY') 
 
-        llName = '{}_layout'.format(self._name)
-        
-        self.addListener('layout',            llName, self._layoutChanged)
-        self.addListener('showColourBar',     llName, self._layoutChanged)
-        self.addListener('colourBarLocation', llName, self._layoutChanged)
-        self.addListener('showLabels',        llName, self._toggleLabels)
-
+        # Callbacks for ortho panel layout options
+        self.addListener('layout',            self._name, self._layoutChanged)
+        self.addListener('showColourBar',     self._name, self._layoutChanged)
+        self.addListener('colourBarLocation', self._name, self._layoutChanged)
+        self.addListener('showLabels',        self._name, self._toggleLabels)
+
+        # Callbacks for image list/selected image changes
+        self._imageList.addListener( 'images',
+                                     self._name,
+                                     self._imageListChanged)
+        self._displayCtx.addListener('selectedImage',
+                                     self._name,
+                                     self._imageListChanged)
+
+        self._imageListChanged()
         self._layoutChanged()
         self._toggleLabels()
 
+        # Callbacks for mouse events on the three xcanvases
         self._xcanvas.Bind(wx.EVT_LEFT_DOWN, self._onMouseEvent)
         self._ycanvas.Bind(wx.EVT_LEFT_DOWN, self._onMouseEvent)
         self._zcanvas.Bind(wx.EVT_LEFT_DOWN, self._onMouseEvent)
@@ -238,20 +249,16 @@ class OrthoPanel(canvaspanel.CanvasPanel):
         self._ycanvas.Bind(wx.EVT_MOTION,    self._onMouseEvent)
         self._zcanvas.Bind(wx.EVT_MOTION,    self._onMouseEvent)
 
+        # Callback for the display context location - when it
+        # changes, update the displayed canvas locations
         def move(*a):
             if self.posSync:
                 self.setPosition(*self._displayCtx.location)
 
         self.setPosition(*self._displayCtx.location)
         self._displayCtx.addListener('location', self._name, move) 
-        
-        def onDestroy(ev):
-            self._displayCtx.removeListener('location', self._name)
-            ev.Skip()
-
-        self.Bind(wx.EVT_WINDOW_DESTROY, onDestroy)
-        self.Bind(wx.EVT_SIZE, self._resize)
 
+        # Callbacks for toggling x/y/z canvas display
         def toggle(canvas, toggle):
             self._canvasSizer.Show(canvas, toggle)
             if self.layout.lower() == 'grid':
@@ -268,6 +275,55 @@ class OrthoPanel(canvaspanel.CanvasPanel):
                          lambda *a: toggle(self._zCanvasPanel,
                                            self.showZCanvas))
 
+        # Do some cleaning up if/when this panel is destroyed
+        self.Bind(wx.EVT_WINDOW_DESTROY, self._onDestroy)
+
+        # And finally, call the _resize method to
+        # re-layout things when this panel is resized
+        self.Bind(wx.EVT_SIZE, self._resize)
+
+
+    def _imageListChanged(self, *a):
+        """Called when the image list or selected image is changed.
+
+        Adds a listener to the currently selected image, to listen
+        for changes on its affine transformation matrix.
+        """
+        if len(self._imageList) == 0: return
+
+        for i, img in enumerate(self._imageList):
+
+            # Update anatomy labels when the image
+            # transformation matrix changes
+            if i == self._displayCtx.selectedImage:
+                img.addListener('transform', self._name, self._toggleLabels)
+            else:
+                img.removeListener('transform', self._name)
+
+
+    def _onDestroy(self, ev):
+        """Called when this panel is destroyed. 
+        
+        The display context and image list will probably live longer than
+        this OrthoPanel. So when this panel is destroyed, all those
+        registered listeners are removed.
+        """
+        ev.Skip()
+
+        # Do nothing if the destroyed window is not
+        # this panel (i.e. it is a child of this panel)
+        if ev.GetEventObject() != self: return
+
+        self._displayCtx.removeListener('location',      self._name)
+        self._displayCtx.removeListener('selectedImage', self._name)
+        self._imageList .removeListener('images',        self._name)
+
+        # The _imageListChanged method adds
+        # listeners to individual images,
+        # so we have to remove them too
+        for img in self._imageList:
+            img.removeListener('transform', self._name)
+        
             
     def _resize(self, ev):
         """
@@ -284,34 +340,79 @@ class OrthoPanel(canvaspanel.CanvasPanel):
     def _toggleLabels(self, *a):
         """Shows/hides labels depicting anatomical orientation on each canvas.
         """
+
+        allLabels =  [self._xLeftLabel, self._xRightLabel,
+                      self._xTopLabel,  self._xBottomLabel,
+                      self._yLeftLabel, self._yRightLabel,
+                      self._yTopLabel,  self._yBottomLabel,
+                      self._zLeftLabel, self._zRightLabel,
+                      self._zTopLabel,  self._zBottomLabel]
+
+
+        # Are we showing or hiding the labels?
         if self.showLabels: show = True
         else:               show = False
 
-        self._xLeftLabel  .Show(show)
-        self._xRightLabel .Show(show) 
-        self._xTopLabel   .Show(show)
-        self._xBottomLabel.Show(show)
-        self._yLeftLabel  .Show(show)
-        self._yRightLabel .Show(show) 
-        self._yTopLabel   .Show(show)
-        self._yBottomLabel.Show(show)
-        self._zLeftLabel  .Show(show)
-        self._zRightLabel .Show(show) 
-        self._zTopLabel   .Show(show)
-        self._zBottomLabel.Show(show)
-
-        self._xLeftLabel  .SetLabel('?')
-        self._xRightLabel .SetLabel('?')
-        self._xTopLabel   .SetLabel('?')
-        self._xBottomLabel.SetLabel('?')
-        self._yLeftLabel  .SetLabel('?')
-        self._yRightLabel .SetLabel('?')
-        self._yTopLabel   .SetLabel('?')
-        self._yBottomLabel.SetLabel('?')
-        self._zLeftLabel  .SetLabel('?')
-        self._zRightLabel .SetLabel('?')
-        self._zTopLabel   .SetLabel('?')
-        self._zBottomLabel.SetLabel('?')
+        for lbl in allLabels:
+            lbl.Show(show)
+
+        # If we're hiding the labels, do no more
+        if not show:
+            return
+
+        # Default colour is white - if the orientation labels
+        # cannot be determined, the background colour will be
+        # changed to red
+        colour = 'white'
+
+        if len(self._imageList) > 0:
+            image = self._imageList[self._displayCtx.selectedImage]
+
+            # The image is being displayed as it is stored on
+            # disk - the image.getOrientation method calculates
+            # and returns labels for each voxelwise axis.
+            if image.transform in ('pixdim', 'id'):
+                xorient = image.getVoxelOrientation(0)
+                yorient = image.getVoxelOrientation(1)
+                zorient = image.getVoxelOrientation(2)
+
+            # The image is being displayed in 'real world' space -
+            # the definition of this space may be present in the
+            # image meta data
+            else:
+                xorient = image.getWorldOrientation(0)
+                yorient = image.getWorldOrientation(1)
+                zorient = image.getWorldOrientation(2)
+
+                
+        if fslimage.ORIENT_UNKNOWN in (xorient, yorient, zorient):
+            colour = 'red'
+ 
+        # Imported here to avoid circular import issues
+        import fsl.fslview.strings as strings 
+
+        xlo = strings.imageAxisLowShortLabels[ xorient]
+        ylo = strings.imageAxisLowShortLabels[ yorient]
+        zlo = strings.imageAxisLowShortLabels[ zorient]
+        xhi = strings.imageAxisHighShortLabels[xorient]
+        yhi = strings.imageAxisHighShortLabels[yorient]
+        zhi = strings.imageAxisHighShortLabels[zorient]
+
+        for lbl in allLabels:
+            lbl.SetForegroundColour(colour)
+
+        self._xLeftLabel  .SetLabel(ylo)
+        self._xRightLabel .SetLabel(yhi)
+        self._xBottomLabel.SetLabel(zlo)
+        self._xTopLabel   .SetLabel(zhi)
+        self._yLeftLabel  .SetLabel(xlo)
+        self._yRightLabel .SetLabel(xhi)
+        self._yBottomLabel.SetLabel(zlo)
+        self._yTopLabel   .SetLabel(zhi)
+        self._zLeftLabel  .SetLabel(xlo)
+        self._zRightLabel .SetLabel(xhi)
+        self._zBottomLabel.SetLabel(ylo)
+        self._zTopLabel   .SetLabel(yhi)
 
         self._xCanvasPanel.Layout()
         self._yCanvasPanel.Layout()