Skip to content

Commit

Permalink
Working version of RSPA
Browse files Browse the repository at this point in the history
  • Loading branch information
jpolchlo committed Jul 12, 2021
1 parent 9b7eb88 commit f2f47de
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/hyperspectral/hyperspectral/unmixing/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .rspa import rspa
55 changes: 55 additions & 0 deletions src/hyperspectral/hyperspectral/unmixing/rspa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import math

import numpy as np

def compute_alpha(x, y, β):
u = x / np.linalg.norm(x, 2)
assert np.linalg.norm(x, 2) > np.linalg.norm(y, 2), "x must be larger in norm than y"
num = (β * np.linalg.norm(x, 2)**2 - np.linalg.norm(y, 2)**2)
denom = (β * np.dot(u, x)**2 - np.dot(u, y)**2)
#print('Numerator: {}\nDenominator: {}'.format(num, denom))
return 1 - math.sqrt(1 - num / denom)

def select_key(spectra, d, p, β):
try:
from tqdm.autonotebook import trange
except:
trange = range

m = spectra.shape[1]
R = spectra
Y = R
Py = np.eye(m)
k = []
k1 = []
e = []
for i in trange(d, leave=False):
k.append(np.argmax(np.linalg.norm(Y, 2, axis=1)))
u = spectra[k[i]] / np.linalg.norm(spectra[k[i]], 2)
R = spectra - np.einsum('n,m->nm',np.matmul(spectra, u), u)
e.append(np.sum(np.linalg.norm(R, 2, axis=1)**p))
k1.append(np.argmax(np.linalg.norm(R, 2, axis=1)))
x = Y[k[i]]
y = Y[k1[i]]
#x = np.matmul(Py, spectra[k[i]])
#y = np.matmul(Py, spectra[k1[i]])
α = compute_alpha(x, y, β)
Y = Y - α * np.einsum('n,m->nm', np.matmul(Y, u), u)
#Py = np.matmul(np.eye(m) - α * np.outer(u, u), Py)
return k[np.argmin(e)]

def rspa(image, n, d, β=4.0, p=1, tol=1e-8):
if len(image.shape)==3:
spectra = image.reshape((image.shape[0]*image.shape[1], -1))
else:
spectra = image
R = spectra
k = 1
keys = []
while np.any(np.abs(R) > tol) and k <= n:
key = select_key(R, d, p, β)
u = R[key] / np.linalg.norm(R[key], 2)
R = R - np.einsum('n,m->nm', np.matmul(R, u), u)
keys.append(key)
k = k + 1
return spectra[keys]
1 change: 1 addition & 0 deletions src/hyperspectral/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
GDAL==3.0.4
jupyter==1.0.0
matplotlib==3.1.2
pysptools==0.15.0
rasterio==1.1.7
Shapely==1.7.1
tqdm==4.51.0

0 comments on commit f2f47de

Please sign in to comment.