prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  skimage.io.imread returns incorrect dimensions (according to docs)
  See here: http://stackoverflow.com/questions/30088841
  
  Importing a TIFF image using skimage.io.imread returns an array with shape (3,M,N) instead of (M,N,3). This breaks the flatten and as_grey features. The results are the same calling `imread` with `plugin='tifffile'`.
  
  ```
  In [1]: im = skimage.io.imread('image.tif')
  
  In [2]: im.shape
  Out[2]: (3, 768, 1024)
  
  In [3]: im = skimage.io.imread('image.tif', as_grey = True)
  
  In [4]: im.shape
  Out[4]: (3, 768)
  
  In [5]: im = skimage.io.imread('image.tif', flatten = True)
  
  In [6]: im.shape
  Out[6]: (3, 768)
  ```
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `skimage/io/_io.py`
  Content:
  ```
  1 from io import BytesIO
  2 import warnings
  3 
  4 import numpy as np
  5 import six
  6 
  7 from ..io.manage_plugins import call_plugin
  8 from ..color import rgb2grey
  9 from .util import file_or_url_context
  10 from ..exposure import is_low_contrast
  11 from .._shared._warnings import all_warnings
  12 
  13 
  14 __all__ = ['imread', 'imread_collection', 'imsave', 'imshow', 'show']
  15 
  16 
  17 def imread(fname, as_grey=False, plugin=None, flatten=None,
  18            **plugin_args):
  19     """Load an image from file.
  20 
  21     Parameters
  22     ----------
  23     fname : string
  24         Image file name, e.g. ``test.jpg`` or URL.
  25     as_grey : bool
  26         If True, convert color images to grey-scale (32-bit floats).
  27         Images that are already in grey-scale format are not converted.
  28     plugin : str
  29         Name of plugin to use (Python Imaging Library by default).
  30 
  31     Other Parameters
  32     ----------------
  33     flatten : bool
  34         Backward compatible keyword, superseded by `as_grey`.
  35 
  36     Returns
  37     -------
  38     img_array : ndarray
  39         The different colour bands/channels are stored in the
  40         third dimension, such that a grey-image is MxN, an
  41         RGB-image MxNx3 and an RGBA-image MxNx4.
  42 
  43     Other parameters
  44     ----------------
  45     plugin_args : keywords
  46         Passed to the given plugin.
  47 
  48     """
  49     # Backward compatibility
  50     if flatten is not None:
  51         as_grey = flatten
  52 
  53     with file_or_url_context(fname) as fname:
  54         img = call_plugin('imread', fname, plugin=plugin, **plugin_args)
  55 
  56     if as_grey and getattr(img, 'ndim', 0) >= 3:
  57         img = rgb2grey(img)
  58 
  59     return img
  60 
  61 
  62 def imread_collection(load_pattern, conserve_memory=True,
  63                       plugin=None, **plugin_args):
  64     """
  65     Load a collection of images.
  66 
  67     Parameters
  68     ----------
  69     load_pattern : str or list
  70         List of objects to load. These are usually filenames, but may
  71         vary depending on the currently active plugin.  See the docstring
  72         for ``ImageCollection`` for the default behaviour of this parameter.
  73     conserve_memory : bool, optional
  74         If True, never keep more than one in memory at a specific
  75         time.  Otherwise, images will be cached once they are loaded.
  76 
  77     Returns
  78     -------
  79     ic : ImageCollection
  80         Collection of images.
  81 
  82     Other parameters
  83     ----------------
  84     plugin_args : keywords
  85         Passed to the given plugin.
  86 
  87     """
  88     return call_plugin('imread_collection', load_pattern, conserve_memory,
  89                        plugin=plugin, **plugin_args)
  90 
  91 
  92 def imsave(fname, arr, plugin=None, **plugin_args):
  93     """Save an image to file.
  94 
  95     Parameters
  96     ----------
  97     fname : str
  98         Target filename.
  99     arr : ndarray of shape (M,N) or (M,N,3) or (M,N,4)
  100         Image data.
  101     plugin : str
  102         Name of plugin to use.  By default, the different plugins are
  103         tried (starting with the Python Imaging Library) until a suitable
  104         candidate is found.
  105 
  106     Other parameters
  107     ----------------
  108     plugin_args : keywords
  109         Passed to the given plugin.
  110 
  111     """
  112     if is_low_contrast(arr):
  113         warnings.warn('%s is a low contrast image' % fname)
  114     return call_plugin('imsave', fname, arr, plugin=plugin, **plugin_args)
  115 
  116 
  117 def imshow(arr, plugin=None, **plugin_args):
  118     """Display an image.
  119 
  120     Parameters
  121     ----------
  122     arr : ndarray or str
  123         Image data or name of image file.
  124     plugin : str
  125         Name of plugin to use.  By default, the different plugins are
  126         tried (starting with the Python Imaging Library) until a suitable
  127         candidate is found.
  128 
  129     Other parameters
  130     ----------------
  131     plugin_args : keywords
  132         Passed to the given plugin.
  133 
  134     """
  135     if isinstance(arr, six.string_types):
  136         arr = call_plugin('imread', arr, plugin=plugin)
  137     return call_plugin('imshow', arr, plugin=plugin, **plugin_args)
  138 
  139 
  140 def show():
  141     '''Display pending images.
  142 
  143     Launch the event loop of the current gui plugin, and display all
  144     pending images, queued via `imshow`. This is required when using
  145     `imshow` from non-interactive scripts.
  146 
  147     A call to `show` will block execution of code until all windows
  148     have been closed.
  149 
  150     Examples
  151     --------
  152     >>> import skimage.io as io
  153 
  154     >>> for i in range(4):
  155     ...     ax_im = io.imshow(np.random.rand(50, 50))
  156     >>> io.show() # doctest: +SKIP
  157 
  158     '''
  159     return call_plugin('_app_show')
  160
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/skimage/io/_io.py b/skimage/io/_io.py
  --- a/skimage/io/_io.py
  +++ b/skimage/io/_io.py
  @@ -53,8 +53,16 @@
       with file_or_url_context(fname) as fname:
           img = call_plugin('imread', fname, plugin=plugin, **plugin_args)
   
  -    if as_grey and getattr(img, 'ndim', 0) >= 3:
  -        img = rgb2grey(img)
  +    if not hasattr(img, 'ndim'):
  +        return img
  +
  +    if img.ndim > 2:
  +        if img.shape[-1] not in (3, 4) and img.shape[-3] in (3, 4):
  +            img = np.swapaxes(img, -1, -3)
  +            img = np.swapaxes(img, -2, -3)
  +
  +        if as_grey:
  +            img = rgb2grey(img)
   
       return img
  
verification_info: {"golden_diff": "diff --git a/skimage/io/_io.py b/skimage/io/_io.py\n--- a/skimage/io/_io.py\n+++ b/skimage/io/_io.py\n@@ -53,8 +53,16 @@\n     with file_or_url_context(fname) as fname:\n         img = call_plugin('imread', fname, plugin=plugin, **plugin_args)\n \n-    if as_grey and getattr(img, 'ndim', 0) >= 3:\n-        img = rgb2grey(img)\n+    if not hasattr(img, 'ndim'):\n+        return img\n+\n+    if img.ndim > 2:\n+        if img.shape[-1] not in (3, 4) and img.shape[-3] in (3, 4):\n+            img = np.swapaxes(img, -1, -3)\n+            img = np.swapaxes(img, -2, -3)\n+\n+        if as_grey:\n+            img = rgb2grey(img)\n \n     return img\n", "issue": "skimage.io.imread returns incorrect dimensions (according to docs)\nSee here: http://stackoverflow.com/questions/30088841\n\nImporting a TIFF image using skimage.io.imread returns an array with shape (3,M,N) instead of (M,N,3). This breaks the flatten and as_grey features. The results are the same calling `imread` with `plugin='tifffile'`.\n\n```\nIn [1]: im = skimage.io.imread('image.tif')\n\nIn [2]: im.shape\nOut[2]: (3, 768, 1024)\n\nIn [3]: im = skimage.io.imread('image.tif', as_grey = True)\n\nIn [4]: im.shape\nOut[4]: (3, 768)\n\nIn [5]: im = skimage.io.imread('image.tif', flatten = True)\n\nIn [6]: im.shape\nOut[6]: (3, 768)\n```\n\n", "before_files": [{"content": "from io import BytesIO\nimport warnings\n\nimport numpy as np\nimport six\n\nfrom ..io.manage_plugins import call_plugin\nfrom ..color import rgb2grey\nfrom .util import file_or_url_context\nfrom ..exposure import is_low_contrast\nfrom .._shared._warnings import all_warnings\n\n\n__all__ = ['imread', 'imread_collection', 'imsave', 'imshow', 'show']\n\n\ndef imread(fname, as_grey=False, plugin=None, flatten=None,\n           **plugin_args):\n    \"\"\"Load an image from file.\n\n    Parameters\n    ----------\n    fname : string\n        Image file name, e.g. ``test.jpg`` or URL.\n    as_grey : bool\n        If True, convert color images to grey-scale (32-bit floats).\n        Images that are already in grey-scale format are not converted.\n    plugin : str\n        Name of plugin to use (Python Imaging Library by default).\n\n    Other Parameters\n    ----------------\n    flatten : bool\n        Backward compatible keyword, superseded by `as_grey`.\n\n    Returns\n    -------\n    img_array : ndarray\n        The different colour bands/channels are stored in the\n        third dimension, such that a grey-image is MxN, an\n        RGB-image MxNx3 and an RGBA-image MxNx4.\n\n    Other parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    \"\"\"\n    # Backward compatibility\n    if flatten is not None:\n        as_grey = flatten\n\n    with file_or_url_context(fname) as fname:\n        img = call_plugin('imread', fname, plugin=plugin, **plugin_args)\n\n    if as_grey and getattr(img, 'ndim', 0) >= 3:\n        img = rgb2grey(img)\n\n    return img\n\n\ndef imread_collection(load_pattern, conserve_memory=True,\n                      plugin=None, **plugin_args):\n    \"\"\"\n    Load a collection of images.\n\n    Parameters\n    ----------\n    load_pattern : str or list\n        List of objects to load. These are usually filenames, but may\n        vary depending on the currently active plugin.  See the docstring\n        for ``ImageCollection`` for the default behaviour of this parameter.\n    conserve_memory : bool, optional\n        If True, never keep more than one in memory at a specific\n        time.  Otherwise, images will be cached once they are loaded.\n\n    Returns\n    -------\n    ic : ImageCollection\n        Collection of images.\n\n    Other parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    \"\"\"\n    return call_plugin('imread_collection', load_pattern, conserve_memory,\n                       plugin=plugin, **plugin_args)\n\n\ndef imsave(fname, arr, plugin=None, **plugin_args):\n    \"\"\"Save an image to file.\n\n    Parameters\n    ----------\n    fname : str\n        Target filename.\n    arr : ndarray of shape (M,N) or (M,N,3) or (M,N,4)\n        Image data.\n    plugin : str\n        Name of plugin to use.  By default, the different plugins are\n        tried (starting with the Python Imaging Library) until a suitable\n        candidate is found.\n\n    Other parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    \"\"\"\n    if is_low_contrast(arr):\n        warnings.warn('%s is a low contrast image' % fname)\n    return call_plugin('imsave', fname, arr, plugin=plugin, **plugin_args)\n\n\ndef imshow(arr, plugin=None, **plugin_args):\n    \"\"\"Display an image.\n\n    Parameters\n    ----------\n    arr : ndarray or str\n        Image data or name of image file.\n    plugin : str\n        Name of plugin to use.  By default, the different plugins are\n        tried (starting with the Python Imaging Library) until a suitable\n        candidate is found.\n\n    Other parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    \"\"\"\n    if isinstance(arr, six.string_types):\n        arr = call_plugin('imread', arr, plugin=plugin)\n    return call_plugin('imshow', arr, plugin=plugin, **plugin_args)\n\n\ndef show():\n    '''Display pending images.\n\n    Launch the event loop of the current gui plugin, and display all\n    pending images, queued via `imshow`. This is required when using\n    `imshow` from non-interactive scripts.\n\n    A call to `show` will block execution of code until all windows\n    have been closed.\n\n    Examples\n    --------\n    >>> import skimage.io as io\n\n    >>> for i in range(4):\n    ...     ax_im = io.imshow(np.random.rand(50, 50))\n    >>> io.show() # doctest: +SKIP\n\n    '''\n    return call_plugin('_app_show')\n", "path": "skimage/io/_io.py"}], "after_files": [{"content": "from io import BytesIO\nimport warnings\n\nimport numpy as np\nimport six\n\nfrom ..io.manage_plugins import call_plugin\nfrom ..color import rgb2grey\nfrom .util import file_or_url_context\nfrom ..exposure import is_low_contrast\nfrom .._shared._warnings import all_warnings\n\n\n__all__ = ['imread', 'imread_collection', 'imsave', 'imshow', 'show']\n\n\ndef imread(fname, as_grey=False, plugin=None, flatten=None,\n           **plugin_args):\n    \"\"\"Load an image from file.\n\n    Parameters\n    ----------\n    fname : string\n        Image file name, e.g. ``test.jpg`` or URL.\n    as_grey : bool\n        If True, convert color images to grey-scale (32-bit floats).\n        Images that are already in grey-scale format are not converted.\n    plugin : str\n        Name of plugin to use (Python Imaging Library by default).\n\n    Other Parameters\n    ----------------\n    flatten : bool\n        Backward compatible keyword, superseded by `as_grey`.\n\n    Returns\n    -------\n    img_array : ndarray\n        The different colour bands/channels are stored in the\n        third dimension, such that a grey-image is MxN, an\n        RGB-image MxNx3 and an RGBA-image MxNx4.\n\n    Other parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    \"\"\"\n    # Backward compatibility\n    if flatten is not None:\n        as_grey = flatten\n\n    with file_or_url_context(fname) as fname:\n        img = call_plugin('imread', fname, plugin=plugin, **plugin_args)\n\n    if not hasattr(img, 'ndim'):\n        return img\n\n    if img.ndim > 2:\n        if img.shape[-1] not in (3, 4) and img.shape[-3] in (3, 4):\n            img = np.swapaxes(img, -1, -3)\n            img = np.swapaxes(img, -2, -3)\n\n        if as_grey:\n            img = rgb2grey(img)\n\n    return img\n\n\ndef imread_collection(load_pattern, conserve_memory=True,\n                      plugin=None, **plugin_args):\n    \"\"\"\n    Load a collection of images.\n\n    Parameters\n    ----------\n    load_pattern : str or list\n        List of objects to load. These are usually filenames, but may\n        vary depending on the currently active plugin.  See the docstring\n        for ``ImageCollection`` for the default behaviour of this parameter.\n    conserve_memory : bool, optional\n        If True, never keep more than one in memory at a specific\n        time.  Otherwise, images will be cached once they are loaded.\n\n    Returns\n    -------\n    ic : ImageCollection\n        Collection of images.\n\n    Other parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    \"\"\"\n    return call_plugin('imread_collection', load_pattern, conserve_memory,\n                       plugin=plugin, **plugin_args)\n\n\ndef imsave(fname, arr, plugin=None, **plugin_args):\n    \"\"\"Save an image to file.\n\n    Parameters\n    ----------\n    fname : str\n        Target filename.\n    arr : ndarray of shape (M,N) or (M,N,3) or (M,N,4)\n        Image data.\n    plugin : str\n        Name of plugin to use.  By default, the different plugins are\n        tried (starting with the Python Imaging Library) until a suitable\n        candidate is found.\n\n    Other parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    \"\"\"\n    if is_low_contrast(arr):\n        warnings.warn('%s is a low contrast image' % fname)\n    return call_plugin('imsave', fname, arr, plugin=plugin, **plugin_args)\n\n\ndef imshow(arr, plugin=None, **plugin_args):\n    \"\"\"Display an image.\n\n    Parameters\n    ----------\n    arr : ndarray or str\n        Image data or name of image file.\n    plugin : str\n        Name of plugin to use.  By default, the different plugins are\n        tried (starting with the Python Imaging Library) until a suitable\n        candidate is found.\n\n    Other parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    \"\"\"\n    if isinstance(arr, six.string_types):\n        arr = call_plugin('imread', arr, plugin=plugin)\n    return call_plugin('imshow', arr, plugin=plugin, **plugin_args)\n\n\ndef show():\n    '''Display pending images.\n\n    Launch the event loop of the current gui plugin, and display all\n    pending images, queued via `imshow`. This is required when using\n    `imshow` from non-interactive scripts.\n\n    A call to `show` will block execution of code until all windows\n    have been closed.\n\n    Examples\n    --------\n    >>> import skimage.io as io\n\n    >>> for i in range(4):\n    ...     ax_im = io.imshow(np.random.rand(50, 50))\n    >>> io.show() # doctest: +SKIP\n\n    '''\n    return call_plugin('_app_show')\n", "path": "skimage/io/_io.py"}]}