Пример #1
0
def test_dimension_error():

    x = np.random.rand(5, 5, 3).astype(np.float32)

    # If ndim match, do not raise exception
    assert type(SpectralArray(x, ndim_exp=3, dtype=np.float32, copy=True)) == SpectralArray

    # If they do not match, throw DimensionError
    for ndim in [1, 2, 4, 5, 7, 11]:
        with raises(DimensionError) as cm:
            tmp_arr = SpectralArray(x, ndim_exp=ndim,
                                    dtype=np.float32, copy=False)

        assert f"Expected {ndim}D input. Found 3D." == str(cm.value)
Пример #2
0
    def _read_envi(path: Path) -> Tuple[ndarray, BandInfo, dict]:
        """Read array data from ENVI binary and header file.

        This function uses imageio to read the image and adds the
        BandInfo and metadata from the ENVI header file.

        Args:
            path: Path to ENVI binary file (usually .raw or .img).

        Returns:
            image, bandinfo, meta
            Tuple containing ndarray of the image data, BandInfo object and
            metadata dictionary.
        """
        hsi = imageio.imread(path, format='gdal')
        if hsi.ndim == 2:
            hsi = hsi[..., np.newaxis]

        # Transpose axis as imageio uses (ch, x, y) shape for spectral images
        hsi = np.transpose(hsi, (1, 2, 0))

        meta = SpectralArray.read_envi_header(path.with_suffix('.hdr'))
        bandinfo = BandInfo.from_envi_header(meta)

        return hsi, bandinfo, meta
Пример #3
0
def test_spectral_array_operations():
    num_ch = 10
    arr = np.random.rand(3, 3, num_ch).astype(np.float32)
    info = BandInfo.from_equidistant(num_channels=num_ch,
                                     lambda_start=400, lambda_end=70)
    meta = dict(entry="Entry", setting="Setting")

    tmp_arr = SpectralArray(arr, dtype=np.float32, copy=True,
                            meta=meta, band_info=info)

    # Multiplication
    tmp = 0.5*tmp_arr
    assert np.array_equal(0.5*arr, tmp)
    assert num_ch == tmp.num_channels
    assert meta == tmp.meta
    assert info == tmp.band_info

    # Addition
    tmp = tmp_arr + arr
    assert np.array_equal(2*arr, tmp)
    assert num_ch == tmp.num_channels
    assert meta == tmp.meta
    assert info == tmp.band_info

    tmp = arr + tmp_arr
    assert np.array_equal(2 * arr, tmp)
    assert num_ch == tmp.num_channels
    assert meta == tmp.meta
    assert info == tmp.band_info

    return
Пример #4
0
def test_spectral_array_dtype_default():

    dtype_def = np.float32

    for d in [np.float16, np.float64, np.uint8]:
        arr = np.random.rand(5, 4, 3, 2).astype(d)
        tmp = SpectralArray(arr, dtype=None)
        assert tmp.dtype == dtype_def
Пример #5
0
def test_spectral_array_copy():
    """Test copying of SpectralArray"""

    num_ch = 10
    arr = np.random.rand(3, 3, num_ch).astype(np.float32)
    info = BandInfo.from_equidistant(num_channels=num_ch,
                                     lambda_start=400, lambda_end=70)
    meta = dict(entry="Entry", setting="Setting")

    tmp_arr = SpectralArray(arr, dtype=np.float32, copy=True,
                            meta=meta, band_info=info)

    tmp_arr_copy = tmp_arr.copy()

    assert np.array_equal(tmp_arr, tmp_arr_copy)
    assert tmp_arr.num_channels == tmp_arr_copy.num_channels
    assert tmp_arr.meta == tmp_arr_copy.meta
    assert tmp_arr.band_info == tmp_arr_copy.band_info

    return
Пример #6
0
def test_get_rgb_image():
    """Test conversion of true RGB from multispectral image"""
    testing.needs_internet()

    hsi_file = testing.get_remote_file(TEST_HSI_FILENAME)
    hsi = SpectralArray(np.load(hsi_file), dtype=np.float32)

    rgb_file = testing.get_remote_file(TEST_RGB_FILENAME)
    rgb = (imageio.imread(rgb_file) / 255.0).astype(np.float64)

    grey_file = testing.get_remote_file(TEST_GREY_FILENAME)
    grey = (imageio.imread(grey_file) / 255.0).astype(np.float64)[..., np.newaxis]

    assert np.allclose(rgb, hsi.get_rgb(), atol=0.01)

    # Test 1D real spectrum conversion
    for x, y in zip([0, 10, 20], [10, 100, 200]):
        spectrum = hsi[x, y, :]
        rgb_point = rgb[x, y, :]
        assert np.allclose(rgb_point, spectrum.get_rgb(), atol=0.01)

    # Calculate black and white from rgb
    grey_from_hsi = hsi.get_grey(weighted=True)
    grey_from_rgb = SpectralArray(rgb, dtype=np.float32).get_grey(weighted=True)
    grey_from_grey = SpectralArray(grey, dtype=np.float32).get_grey(weighted=True)

    assert np.allclose(grey, grey_from_grey, atol=0.01)
    assert np.allclose(grey, grey_from_rgb, atol=0.01)
    assert np.allclose(grey, grey_from_hsi, atol=0.01)

    return
Пример #7
0
def test_get_resampled():
    """Test SpectralArray resampling"""

    # Init SpectralArray
    num_ch = 100

    # 1D Spectrum
    arr = np.random.rand(num_ch).astype(np.float32)
    meta = dict(metadata="test")
    tmp = SpectralArray(arr, band_info=None, meta=meta, dtype=np.float32)

    tmp_dec = tmp.get_resampled_spectrum(num=13)

    assert 13 == tmp_dec.num_channels
    assert tmp_dec.band_info is None
    assert meta == tmp_dec.meta
    assert tmp_dec.dtype == np.float32

    # Test with BandInfo object
    band_info = BandInfo.from_equidistant(num_ch, 400, 700)
    band_info_down = BandInfo.from_equidistant(13, 400, 700)

    tmp = SpectralArray(arr, band_info=band_info, meta=None, dtype=np.float32)

    tmp_dec = tmp.get_resampled_spectrum(num=13)
    assert band_info_down == tmp_dec.band_info

    return
Пример #8
0
def test_get_subband():
    """Test SpectralArray subband"""

    # Init SpectralArray
    num_ch = 100

    # 1D Spectrum
    arr = np.random.rand(num_ch).astype(np.float32)
    meta = dict(metadata="test")
    tmp = SpectralArray(arr, band_info=None, meta=meta, dtype=np.float32)

    tmp_dec = tmp.get_subband(30, 51)

    assert np.array_equal(arr[..., 30:51], np.asarray(tmp_dec))
    assert tmp_dec.band_info is None
    assert meta == tmp_dec.meta
    assert tmp_dec.dtype == np.float32

    # Test with BandInfo object
    band_info = BandInfo.from_equidistant(num_ch, 400, 700)

    tmp = SpectralArray(arr, band_info=band_info, meta=None, dtype=np.float32)

    tmp_dec = tmp.get_subband(30, 51)
    assert np.array_equal(band_info.centers[30:51], tmp_dec.band_info.centers)

    return
Пример #9
0
def test_spectral_array_new():

    num_ch = 10
    arr = np.random.rand(3, 3, num_ch).astype(np.float32)
    info = BandInfo.from_equidistant(num_channels=num_ch,
                                     lambda_start=400, lambda_end=70)
    meta = dict(entry="Entry", setting="Setting")

    tmp_arr = SpectralArray(arr, dtype=np.float32, copy=True,
                            meta=meta, band_info=info)

    assert np.array_equal(arr, tmp_arr)
    assert tmp_arr.num_channels == num_ch
    assert meta == tmp_arr.meta
    assert info == tmp_arr.band_info

    # Test Data conversion
    for dtype in [np.float16, np.float32, np.float64]:
        tmp_arr = SpectralArray(arr, dtype=dtype, copy=True)
        assert np.allclose(arr.astype(dtype), tmp_arr)

    return
Пример #10
0
def test_spectral_array_errors():

    # Test input array type
    with raises(ValueError) as cm:
        tmp_arr = SpectralArray([1, 2, 3], dtype=np.float32, copy=True,
                                meta=None, band_info=None)
    assert "SpectralArray expects a numpy array." == str(cm.value)

    # Test input metadata type
    with raises(ValueError) as cm:
        tmp_arr = SpectralArray(np.asarray([1, 2, 3], dtype=np.uint8),
                                dtype=np.float32, copy=True,
                                meta="Not Meta", band_info=None)
    assert "SpectralArray expects meta data to be a dict." == str(cm.value)

    # Test input BandInfo type
    with raises(ValueError) as cm:
        tmp_arr = SpectralArray(np.asarray([1, 2, 3], dtype=np.uint8),
                                dtype=np.float32, copy=True,
                                meta=None, band_info="Not Bandinfo")
    assert "SpectralArray expects BandInfo or None instance." == str(cm.value)

    # Test input array size
    with raises(ValueError) as cm:
        tmp_arr = SpectralArray(np.asarray([], dtype=np.uint8),
                                dtype=np.float32, copy=True,
                                meta=None, band_info=None)
    assert "Invalid array size. Must have at least one axis." == str(cm.value)

    # Test invalid conversion

    # Test dtype argument
    with raises(ValueError) as cm:
        tmp_arr = SpectralArray(np.asarray([0.0, 0.1, 0.2], dtype=np.float32),
                                dtype=np.uint8, copy=True,
                                meta=None, band_info=None)
    assert "The passed dtype '<class 'numpy.uint8'>' is invalid. " \
           "Only numpy float types are allowed." == str(cm.value)

    # Test BandInfo compability
    info = BandInfo.from_equidistant(num_channels=10,
                                     lambda_start=400, lambda_end=700)
    arr = np.random.rand(5, 5, 11).astype(np.float32)

    with raises(ValueError) as cm:
        tmp_arr = SpectralArray(arr,
                                dtype=np.float32, copy=True,
                                meta=None, band_info=info)
    assert f"The numbers of channels of the band info object and the numbers "\
        f"of channels of the given data does not match. Found " \
        f"10 and 11 respectively." == str(cm.value)

    return
Пример #11
0
def test_band_info_envi():
    """Test ``from_envi`` class method.
    """
    testing.needs_internet()

    envi_file = testing.get_remote_file(TEST_ENVI_HDR)
    d = SpectralArray.read_envi_header(envi_file)

    band_info = BandInfo.from_envi_header(d)
    centers_exp = np.asarray([400.6, 450.3, 500, 551.7, 600.666, 760.9])
    bandwiths_exp = np.asarray([1.1, 1.2, 1.3, 1.4, 1.5, 1.6])

    assert 6 == band_info.num_channels
    assert band_info.type is None
    assert band_info.centers_std is None
    assert band_info.bandwidths_std is None
    assert np.array_equal(centers_exp, band_info.centers)
    assert np.array_equal(bandwiths_exp, band_info.bandwidths)

    return
Пример #12
0
def test_get_rgb():
    """Test RGB conversion on multiple arrays."""

    # For 1 color channel, return stacked copy
    num_ch = 1
    arr = np.random.rand(10, 10, num_ch).astype(np.float32)
    tmp = SpectralArray(arr)
    rgb = tmp.get_rgb()
    ref = np.squeeze(np.stack((arr, arr, arr), axis=-1))
    assert rgb.shape == (10, 10, 3)
    assert np.array_equal(ref, rgb)

    num_ch = 3
    arr = np.random.rand(10, 10, num_ch).astype(np.float32)
    tmp = SpectralArray(arr)
    rgb = tmp.get_rgb()
    assert rgb.shape == (10, 10, 3)
    assert np.array_equal(arr, rgb)

    # For more color channels, convert to RGB
    num_ch = 100

    # 1D Spectrum
    arr = np.random.rand(num_ch).astype(np.float32)
    tmp = SpectralArray(arr)
    rgb = tmp.get_rgb()
    assert rgb.shape == (3,)

    # 3D Spectrum
    arr = np.random.rand(10, 20, num_ch).astype(np.float32)
    tmp = SpectralArray(arr)
    rgb = tmp.get_rgb()
    assert rgb.shape == (10, 20, 3)

    # 4D Spectrum
    arr = np.random.rand(10, 20, 30, num_ch).astype(np.float32)
    tmp = SpectralArray(arr)
    rgb = tmp.get_rgb()
    assert rgb.shape == (10, 20, 30, 3)

    # 5D Spectrum
    arr = np.random.rand(10, 20, 30, 40, num_ch).astype(np.float32)
    tmp = SpectralArray(arr)
    rgb = tmp.get_rgb()
    assert rgb.shape == (10, 20, 30, 40, 3)

    return