.. toctree::
:maxdepth: 2
The standard means of opening and accessing a hyperspectral image file with SPy is via the :func:`~spectral.image` function, which returns an instance of a |SpyFile| object.
.. automodule:: spectral.io.spyfile
It is important to note that image data are read by a |SpyFile| object on demand and the data are not cached. Each time the |SpyFile| subscript operator or one of the |SpyFile| read methods are called, data are read from the corresponding image data file, regardless of whether the same data have been previously read. This is done to avoid consuming too much memory when working with very large image files. It also improves performance when performing operations that only require reading a small portion of the data in a large image (e.g., reading RGB bands to display the image). The downside of reading data on demand and not caching the data is that there can be a significant run time penalty when running algorithms that require access to all of the data. Performance will be even worse if the algorithm requires iterative access to the data.
To improve performance of spectral algorithms, it is preferable to load the entire image into memory using the :meth:`~spectral.SpyFile.load` method, which returns an :class:`~spectral.ImageArray` object. :class:`~spectral.ImageArray` provides the full :class:`numpy.ndarray` interface, as well as the |SpyFile| interface.
.. ipython::
In [10]: arr = img.load()
In [11]: arr.__class__
Out[11]: spectral.spectral.ImageArray
In [12]: print(arr.info())
# Rows: 145
# Samples: 145
# Bands: 220
Data format: Float32
In [13]: arr.shape
Out[13]: (145, 145, 220)
Because SPy is primarily designed for processing in the spectral domain,
:class:`spectral.ImageArray` objects in memory will always have data interleaved
by pixel, regardless of the interleave of the source image data file. In other
words, the :class:`numpy.ndarray` shape will be (numRows, numCols, numBands).
:class:`~spectral.ImageArray` objects always contain 32-bit floats.
Note
Before calling the :meth:`load` method, it is important to consider the amount of memory
that will be consumed by the resulting ImageArray object. Since :class:`spectral.ImageArray` uses
32-bit floating point values, the amount of memory consumed will be approximately
4 * numRows * numCols * numBands bytes.
NumPy :class:`memmap` Interface
As an alternative to loading an entire image into memory, a somewhat slower (but more memory efficient) way to access image data is to use a numpy memmap object, as returned by the :meth:`~spectral.io.bipfile.BipFile.open_memmap` method of SpyFile objects. memmap objects can also be used to write date to an image file.
ENVI [1] is a popular commercial software package for processing and analyzing geospatial imagery. SPy can read images that have associated ENVI header files and can read & write spectral libraries with ENVI headers. ENVI files are opened automatically by the SPy :func:`~spectral.image` function but images can also be opened explicitly as ENVI files. It may be necessary to open an ENVI file explicitly if the data file is in a separate directory from the header or if the data file has an unusual file extension that SPy can not identify.
.. ipython::
In [14]: import spectral.io.envi as envi
In [15]: img = envi.open('cup95eff.int.hdr', 'cup95eff.int')
In [16]: import spectral.io.envi as envi
In [17]: lib = envi.open('spectra.hdr')
In [18]: lib.names[:5]
Out[18]:
['construction asphalt',
'construction concrete',
'red smooth-faced brick',
'weathered red brick',
'bare red brick']
.. seealso:: Functions for writing image data to files:
:func:`~spectral.io.envi.create_image`:
Creates a new image file with allocated storage on disk.
:func:`~spectral.io.envi.save_image`:
Saves an existing image or ndarray to a file with an ENVI header.
SPy supports data files generated by the Airborne Visible/Infrared Imaging Spectrometer (AVIRIS) [2]. AVIRIS files are automatically recognized by the :func:`~spectral.open_image` function; however, spectral band calibration files are not automatically recognized; therefore you may want to open the image as an AVIRIS file explicitly and specify the cal file.
.. ipython::
In [19]: img = aviris.open('f970619t01p02_r02_sc01.a.rfl', 'f970619t01p02_r02.a.spc')
You can also load the band calibration file separately (this may be necessary if the band calibration file is in AVIRIS format but the image is not).
.. ipython::
In [20]: img = open_image('92AV3C.lan')
In [21]: img.bands = aviris.read_aviris_bands('92AV3C.spc')
The ERDAS/Lan file format is automatically recognized by :func:`~spectral.image`. It is unlikely that a file would need to be opened explicitly as a Lan file but it can be done as follows.
.. ipython::
In [22]: import spectral.io.erdas as erdas
In [23]: img = erdas.open('92AV3C.lan')
| [1] | ENVI is a registered trademark of Exelis Visual Information Solutions. |
| [2] | http://aviris.jpl.nasa.gov/ |