Beispiel #1
0
def _prepared_data_and_metadata(hdr_file, image, **kwargs):
    '''
    Return data array and metadata dict representing `image`.
    '''
    import os
    import sys
    import spectral
    from spectral.io.spyfile import SpyFile, interleave_transpose

    endian_out = str(kwargs.get('byteorder', sys.byteorder)).lower()
    if endian_out in ('0', 'little'):
        endian_out = 'little'
    elif endian_out in ('1', 'big'):
        endian_out = 'big'
    else:
        raise ValueError('Invalid byte order: "%s".' % endian_out)

    if isinstance(image, np.ndarray):
        data = image
        src_interleave = 'bip'
        swap = False
    elif isinstance(image, SpyFile):
        if image.using_memmap is True:
            data = image._memmap
            src_interleave = {spectral.BSQ: 'bsq', spectral.BIL: 'bil',
                              spectral.BIP: 'bip'}[image.interleave]
            swap = image.swap
        else:
            data = image.load(dtype=image.dtype, scale=False)
            src_interleave = 'bip'
            swap = False
    else:
        data = image.load()
        src_interleave = 'bip'
        swap = False

    metadata = kwargs.get('metadata', {}).copy()
    add_image_info_to_metadata(image, metadata)
    if hasattr(image, 'bands'):
        add_band_info_to_metadata(image.bands, metadata)

    dtype = np.dtype(kwargs.get('dtype', data.dtype)).char
    _validate_dtype(dtype)
    if dtype != data.dtype.char:
        data = data.astype(dtype)
    metadata['data type'] = dtype_to_envi[dtype]

    interleave = kwargs.get('interleave', 'bip').lower()
    if interleave not in ['bil', 'bip', 'bsq']:
        raise ValueError('Invalid interleave: %s'
                         % str(kwargs['interleave']))
    if interleave != src_interleave:
        data = data.transpose(interleave_transpose(src_interleave, interleave))
    metadata['interleave'] = interleave
    metadata['byte order'] = 1 if endian_out == 'big' else 0
    if (endian_out == sys.byteorder and not data.dtype.isnative) or \
      (endian_out != sys.byteorder and data.dtype.isnative):
        data = data.byteswap()

    return data, metadata
Beispiel #2
0
def save_image(hdr_file, image, **kwargs):
    '''
    Saves an image to disk.

    Arguments:

        `hdr_file` (str):

            Header file (with ".hdr" extension) name with path.

        `image` (SpyFile object or numpy.ndarray):

            The image to save.

    Keyword Arguments:

        `dtype` (numpy dtype or type string):

            The numpy data type with which to store the image.  For example,
            to store the image in 16-bit unsigned integer format, the argument
            could be any of `numpy.uint16`, "u2", "uint16", or "H".

        `force` (bool):

            If the associated image file or header already exist and `force` is
            True, the files will be overwritten; otherwise, if either of the
            files exist, an exception will be raised.

        `ext` (str):

            The extension to use for the image file.  If not specified, the
            default extension ".img" will be used.  If `ext` is an empty
            string, the image file will have the same name as the header but
            without the ".hdr" extension.

        `interleave` (str):

            The band interleave format to use in the file.  This argument
            should be one of "bil", "bip", or "bsq".  If not specified, the
            image will be written in BIP interleave.

        `byteorder` (int or string):

            Specifies the byte order (endian-ness) of the data as
            written to disk. For little endian, this value should be
            either 0 or "little".  For big endian, it should be
            either 1 or "big". If not specified, native byte order
            will be used.

        `metadata` (dict):

            A dict containing ENVI header parameters (e.g., parameters
            extracted from a source image).

    Example::

        >>> # Save the first 10 principal components of an image
        >>> data = open_image('92AV3C.lan').load()
        >>> pc = principal_components(data)
        >>> pcdata = pc.reduce(num=10).transform(data)
        >>> envi.save_image('pcimage.hdr', pcdata, dtype=np.float32)

    If the source image being saved was already in ENVI format, then the
    SpyFile object for that image will contain a `metadata` dict that can be
    passed as the `metadata` keyword. However, care should be taken to ensure
    that all the metadata fields from the source image are still accurate
    (e.g., band names or wavelengths will no longer be correct if the data
    being saved are from a principal components transformation).
    '''
    import os
    import sys
    import __builtin__
    import spectral
    from spectral.io.spyfile import SpyFile, interleave_transpose

    metadata = kwargs.get('metadata', {}).copy()
    force = kwargs.get('force', False)
    img_ext = kwargs.get('ext', '.img')
    
    endian_out = str(kwargs.get('byteorder', sys.byteorder)).lower()
    if endian_out in ('0', 'little'):
        endian_out = 'little'
    elif endian_out in ('1', 'big'):
        endian_out = 'big'
    else:
        raise ValueError('Invalid byte order: "%s".' % endian_out)

    (hdr_file, img_file) = check_new_filename(hdr_file, img_ext, force)

    if isinstance(image, np.ndarray):
        data = image
        src_interleave = 'bip'
        swap = False
    elif isinstance(image, SpyFile):
        if image.using_memmap is True:
            data = image._memmap
            src_interleave = {spectral.BSQ: 'bsq', spectral.BIL: 'bil',
                              spectral.BIP: 'bip'}[image.interleave]
            swap = image.swap
        else:
            data = image.load(dtype=image.dtype, scale=False)
            src_interleave = 'bip'
            swap = False
        if image.scale_factor != 1:
            metadata['reflectance scale factor'] = image.scale_factor
    else:
        data = image.load()
        src_interleave = 'bip'
        swap = False
    dtype = np.dtype(kwargs.get('dtype', data.dtype)).char
    if dtype != data.dtype.char:
        data = data.astype(dtype)
    metadata['data type'] = dtype_to_envi[dtype]
    # A few header parameters need to be set independent of what is provided
    # in the supplied metadata.

    # Always write data from start of file, regardless of what was in
    # provided metadata.
    offset = int(metadata.get('header offset', 0))
    if offset != 0:
        print 'Ignoring non-zero header offset in provided metadata.'
    metadata['header offset'] = 0

    metadata['lines'] = image.shape[0]
    metadata['samples'] = image.shape[1]
    if len(image.shape) == 3:
        metadata['bands'] = image.shape[2]
    else:
        metadata['bands'] = 1
    metadata['file type'] = 'ENVI Standard'
    interleave = kwargs.get('interleave', 'bip').lower()
    if interleave not in ['bil', 'bip', 'bsq']:
        raise ValueError('Invalid interleave: %s'
                         % str(kwargs['interleave']))
    if interleave != src_interleave:
        data = data.transpose(interleave_transpose(src_interleave, interleave))
    metadata['interleave'] = interleave
    metadata['byte order'] = 1 if endian_out == 'big' else 0
    if (endian_out == sys.byteorder and not data.dtype.isnative) or \
      (endian_out != sys.byteorder and data.dtype.isnative):
        data = data.byteswap()

    if hasattr(image, 'bands'):
        add_band_info_to_metadata(image.bands, metadata)

    write_envi_header(hdr_file, metadata, is_library=False)
    print 'Saving', img_file
    bufsize = data.shape[0] * data.shape[1] * np.dtype(dtype).itemsize
    fout = __builtin__.open(img_file, 'wb', bufsize)
    fout.write(data.tostring())
    fout.close()
Beispiel #3
0
def _prepared_data_and_metadata(hdr_file, image, **kwargs):
    '''
    Return data array and metadata dict representing `image`.
    '''
    import os
    import sys
    import spectral
    from spectral.io.spyfile import SpyFile, interleave_transpose

    endian_out = str(kwargs.get('byteorder', sys.byteorder)).lower()
    if endian_out in ('0', 'little'):
        endian_out = 'little'
    elif endian_out in ('1', 'big'):
        endian_out = 'big'
    else:
        raise ValueError('Invalid byte order: "%s".' % endian_out)

    if isinstance(image, np.ndarray):
        data = image
        src_interleave = 'bip'
        if len(data.shape) == 2:
            data = data[:, :, np.newaxis]
        swap = False
        metadata = {}
    elif isinstance(image, SpyFile):
        if image.using_memmap is True:
            data = image._memmap
            src_interleave = {
                spectral.BSQ: 'bsq',
                spectral.BIL: 'bil',
                spectral.BIP: 'bip'
            }[image.interleave]
            swap = image.swap
        else:
            data = image.load(dtype=image.dtype, scale=False)
            src_interleave = 'bip'
            swap = False
        metadata = image.metadata.copy()
    else:
        data = image.load(scale=False)
        src_interleave = 'bip'
        swap = False
        if hasattr(image, 'metadata'):
            metadata = image.metadata.copy()
        else:
            metadata = {}

    metadata.update(kwargs.get('metadata', {}))
    add_image_info_to_metadata(image, metadata)
    if hasattr(image, 'bands'):
        add_band_info_to_metadata(image.bands, metadata)

    dtype = np.dtype(kwargs.get('dtype', data.dtype)).char
    _validate_dtype(dtype)
    if dtype != data.dtype.char:
        data = data.astype(dtype)
    metadata['data type'] = dtype_to_envi[dtype]

    interleave = kwargs.get('interleave', 'bip').lower()
    if interleave not in ['bil', 'bip', 'bsq']:
        raise ValueError('Invalid interleave: %s' % str(kwargs['interleave']))
    if interleave != src_interleave:
        data = data.transpose(interleave_transpose(src_interleave, interleave))
    metadata['interleave'] = interleave
    metadata['byte order'] = 1 if endian_out == 'big' else 0
    if (endian_out == sys.byteorder and not data.dtype.isnative) or \
      (endian_out != sys.byteorder and data.dtype.isnative):
        data = data.byteswap()

    return data, metadata