-
Notifications
You must be signed in to change notification settings - Fork 0
/
Hysime.py
108 lines (89 loc) · 2.96 KB
/
Hysime.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
103
104
105
106
107
108
#
# Code taken from PySptools by Christian Therien
# https://pysptools.sourceforge.io/index.html
#
import numpy as np
def hysime(y, n, Rn):
"""
Hyperspectral signal subspace estimation
Parameters:
y: `numpy array`
hyperspectral data set (each row is a pixel)
with ((m*n) x p), where p is the number of bands
and (m*n) the number of pixels.
n: `numpy array`
((m*n) x p) matrix with the noise in each pixel.
Rn: `numpy array`
noise correlation matrix (p x p)
Returns: `tuple integer, numpy array`
* kf signal subspace dimension
* Ek matrix which columns are the eigenvectors that span
the signal subspace.
Copyright:
Jose Nascimento ([email protected]) & Jose Bioucas-Dias ([email protected])
For any comments contact the authors
"""
y = y.T
n = n.T
Rn = Rn.T
L, N = y.shape
Ln, Nn = n.shape
d1, d2 = Rn.shape
x = y - n
Ry = np.dot(y, y.T) / N
Rx = np.dot(x, x.T) / N
E, dx, V = np.linalg.svd(Rx)
Rn = Rn + np.sum(np.diag(Rx))/L/10**10 * np.eye(L)
Py = np.diag(np.dot(E.T, np.dot(Ry, E)))
Pn = np.diag(np.dot(E.T, np.dot(Rn, E)))
cost_F = -Py + 2 * Pn
kf = np.sum(cost_F < 0)
ind_asc = np.argsort(cost_F)
Ek = E[:, ind_asc[0:kf]]
return kf, Ek
def est_noise(y, noise_type='additive'):
"""
This function infers the noise in a
hyperspectral data set, by assuming that the
reflectance at a given band is well modelled
by a linear regression on the remaining bands.
Parameters:
y: `numpy array`
a HSI cube ((m*n) x p)
noise_type: `string [optional 'additive'|'poisson']`
Returns: `tuple numpy array, numpy array`
* the noise estimates for every pixel (N x p)
* the noise correlation matrix estimates (p x p)
Copyright:
Jose Nascimento ([email protected]) and Jose Bioucas-Dias ([email protected])
For any comments contact the authors
"""
def est_additive_noise(r):
small = 1e-6
L, N = r.shape
w = np.zeros((L, N), dtype=np.float)
RR = np.dot(r, r.T)
RRi = np.linalg.pinv(RR+small*np.eye(L))
RRi = np.matrix(RRi)
for i in range(L):
XX = RRi - (RRi[:, i]*RRi[i, :]) / RRi[i, i]
RRa = RR[:, i]
RRa[i] = 0
beta = np.dot(XX, RRa)
beta[0, i] = 0
w[i, :] = r[i, :] - np.dot(beta, r)
Rw = np.diag(np.diag(np.dot(w, w.T) / N))
return w, Rw
y = y.T
L, N = y.shape
# verb = 'poisson'
if noise_type == 'poisson':
sqy = np.sqrt(y * (y > 0))
u, Ru = est_additive_noise(sqy)
x = (sqy - u)**2
w = np.sqrt(x)*u*2
Rw = np.dot(w, w.T) / N
# additive
else:
w, Rw = est_additive_noise(y)
return w.T, Rw.T