-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
102 lines (90 loc) · 3.6 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
from spectral import *
import numpy as np
import scipy
def filter_out_invalid_spectra(image):
"""
Transforms 3D array into 2D array,
where each row represents one spectrum.
Only spectra that do not contain negative values are left.
Also type is transformed into float.
"""
(nrows, ncols, nbands) = image.shape
N = nrows * ncols
spectra = image.reshape((N, nbands))
invalid_inds = np.argwhere(np.any(spectra < 0, axis=1))
spectra = np.delete(spectra, invalid_inds, axis=0).astype(float)
return spectra
def filter_out_of_range_spectra(image, min_val, max_val):
"""
Transforms 3D array into 2D array,
where each row represents one spectrum.
Only spectra that do not contain values below min_val or above max_val are left.
Also type is transformed into float.
"""
(nrows, ncols, nbands) = image.shape
N = nrows * ncols
spectra = image.reshape((N, nbands))
invalid_inds = np.argwhere(np.any(np.logical_or(spectra < min_val, spectra > max_val), axis=1))
spectra = np.delete(spectra, invalid_inds, axis=0).astype(float)
return spectra
def find_image_coords_of_spectrum(image, spectrum):
(nrows, ncols, nbands) = image.shape
for i in range(nrows):
for j in range(ncols):
if np.array_equal(image[i, j], spectrum):
return (i, j)
return None
def replace_invalid(spectrum, value):
"""
Replaces invalid values in spectrum, by value.
Affects original spectrum, and also returns it.
"""
spectrum[spectrum < 0.0] = value
return spectrum
def interpolate_invalid(spectrum, kind='slinear'):
full_xs = list(range(len(spectrum)))
xs = [x for x, y in zip(full_xs, spectrum) if y > 0.0]
ys = [y for y in spectrum if y > 0.0]
if xs[0] > full_xs[0]:
xs.insert(0, full_xs[0])
ys.insert(0, ys[0])
if xs[-1] < full_xs[-1]:
xs.append(full_xs[-1])
ys.append(ys[-1])
f = scipy.interpolate.interp1d(xs, ys, kind=kind, assume_sorted=True)
return f(full_xs)
def lower_bound(array, min_val):
ret = np.argmax(array >= min_val)
return ret if array[ret] >= min_val else len(array)
def upper_bound(array, max_val):
ret = np.argmax(array > max_val)
return ret if array[ret] > max_val else len(array)
def resample_at(spectrum, src_wls, dest_wls, src_bw = None, dest_bw = None):
"""
Returns spectrum resampled to different wavelengths and bandwidths.
"""
resampler = BandResampler(src_wls, dest_wls, src_bw, dest_bw)
return resampler(spectrum)
def interpolate_at(spectrum, src_wls, dest_wls, kind='quadratic'):
"""
Returns spectrum interpoleted at specified wavelengths,
based on wavelengths and reflectances of original.
"""
f = scipy.interpolate.interp1d(src_wls, spectrum, kind=kind, assume_sorted=True, fill_value='extrapolate')
return f(dest_wls)
def cut_range(spectrum, src_wls, dst_wls):
"""
Return wavelengths and spectrum part between min wavelength and max wavelength.
Min wavelength is max(src_wls[0], dst_wls[0]).
Max wavelengths is min(src_wls[-1], dst_wls[-1]).
dst_wls can be ndarray, or simply 2-tuple with max and min wavelengths.
"""
min_wl = max(src_wls[0], dst_wls[0])
max_wl = min(src_wls[-1], dst_wls[-1])
min_index = np.argmax(src_wls >= min_wl)
max_index = -1 if src_wls[-1] <= max_wl else np.argmax(src_wls > max_wl)
range_wl = src_wls[min_index:max_index]
range_spec = spectrum[min_index:max_index]
return range_wl, range_spec