3232'''
3333Various functions and algorithms for processing spectral data.
3434'''
35- from __future__ import division , print_function , unicode_literals
35+ from __future__ import absolute_import , division , print_function , unicode_literals
3636
37- import numpy
37+ import math
38+ from numbers import Integral
3839import numpy as np
40+ import pickle
3941
40- from warnings import warn
41-
42+ import spectral as spy
43+ from ..io .spyfile import SpyFile , TransformedImage
44+ from ..utilities .errors import has_nan , NaNValueError
45+ from .spymath import matrix_sqrt
46+ from .transforms import LinearTransform
4247
4348class Iterator :
4449 '''
@@ -233,11 +238,7 @@ def mean_cov(image, mask=None, index=None):
233238 Calculate the mean and covariance of of the given vectors. The argument
234239 can be an Iterator, a SpyFile object, or an `MxNxB` array.
235240 '''
236- import spectral
237- import numpy as np
238- from numpy import zeros , transpose , dot , newaxis
239-
240- status = spectral ._status
241+ status = spy ._status
241242
242243 if isinstance (image , np .ndarray ):
243244 X = image .astype (np .float64 )
@@ -262,8 +263,8 @@ def mean_cov(image, mask=None, index=None):
262263 nSamples = it .get_num_elements ()
263264 B = it .get_num_bands ()
264265
265- sumX = zeros ((B ,), 'd' )
266- sumX2 = zeros ((B , B ), 'd' )
266+ sumX = np . zeros ((B ,), 'd' )
267+ sumX2 = np . zeros ((B , B ), 'd' )
267268 count = 0
268269
269270 statusInterval = max (1 , nSamples / 100 )
@@ -273,10 +274,10 @@ def mean_cov(image, mask=None, index=None):
273274 status .update_percentage (float (count ) / nSamples * 100. )
274275 count += 1
275276 sumX += x
276- x = x .astype (np .float64 )[:, newaxis ]
277+ x = x .astype (np .float64 )[:, np . newaxis ]
277278 sumX2 += x .dot (x .T )
278279 mean = (sumX / count )
279- sumX = sumX [:, newaxis ]
280+ sumX = sumX [:, np . newaxis ]
280281 cov = (sumX2 - sumX .dot (sumX .T ) / count ) / (count - 1 )
281282 status .end_percentage ()
282283 return (mean , cov , count )
@@ -400,7 +401,6 @@ class PrincipalComponents:
400401 A callable function that returns a function for denoising data.
401402 '''
402403 def __init__ (self , vals , vecs , stats ):
403- from .transforms import LinearTransform
404404 self .eigenvalues = vals
405405 self .eigenvectors = vecs
406406 self .stats = stats
@@ -434,9 +434,7 @@ def reduce(self, N=0, **kwargs):
434434 will be retained (starting from greatest to smallest) until
435435 `fraction` of total image variance is retained.
436436 '''
437- import spectral
438-
439- status = spectral ._status
437+ status = spy ._status
440438
441439 num = kwargs .get ('num' , None )
442440 eigs = kwargs .get ('eigs' , None )
@@ -453,7 +451,7 @@ def reduce(self, N=0, **kwargs):
453451 if not 0 < fraction <= 1 :
454452 raise Exception ('fraction must be in range (0,1].' )
455453 N = len (self .eigenvalues )
456- cumsum = numpy .cumsum (self .eigenvalues )
454+ cumsum = np .cumsum (self .eigenvalues )
457455 sum = cumsum [- 1 ]
458456 # Count how many values to retain.
459457 for i in range (N ):
@@ -532,7 +530,6 @@ def get_denoising_transform(self, **kwargs):
532530 Returns a callable :class:`~spectral.algorithms.transforms.LinearTransform`
533531 object for denoising image data.
534532 '''
535- from .transforms import LinearTransform
536533 V = self .reduce (self , ** kwargs ).eigenvectors
537534 f = LinearTransform (V .dot (V .T ), pre = - self .mean ,
538535 post = self .mean )
@@ -586,14 +583,12 @@ def principal_components(image):
586583
587584 A callable function that returns a function for denoising data.
588585 '''
589- from numpy import sqrt , sum
590-
591586 if isinstance (image , GaussianStats ):
592587 stats = image
593588 else :
594589 stats = calc_stats (image )
595590
596- (L , V ) = numpy .linalg .eig (stats .cov )
591+ (L , V ) = np .linalg .eig (stats .cov )
597592
598593 # numpy says eigenvalues may not be sorted so we'll sort them, if needed.
599594 if not np .alltrue (np .diff (L ) <= 0 ):
@@ -635,7 +630,6 @@ class FisherLinearDiscriminant:
635630 linear discriminant.
636631 '''
637632 def __init__ (self , vals , vecs , mean , cov_b , cov_w ):
638- from .transforms import LinearTransform
639633 self .eigenvalues = vals
640634 self .eigenvectors = vecs
641635 self .mean = mean
@@ -673,8 +667,6 @@ class covariances, mean vector, and a callable transform to convert data to
673667 Richards, J.A. & Jia, X. Remote Sensing Digital Image Analysis: An
674668 Introduction. (Springer: Berlin, 1999).
675669 '''
676- import math
677-
678670 C = len (classes ) # Number of training sets
679671 rank = len (classes ) - 1
680672
@@ -716,7 +708,7 @@ class covariances, mean vector, and a callable transform to convert data to
716708
717709
718710def log_det (x ):
719- return sum (numpy .log ([eigv for eigv in numpy .linalg .eigvals (x )
711+ return sum (np .log ([eigv for eigv in np .linalg .eigvals (x )
720712 if eigv > 0 ]))
721713
722714
@@ -796,7 +788,6 @@ def sqrt_cov(self):
796788 such that S.dot(S) == C.
797789 '''
798790 if self ._sqrt_cov is None :
799- from spectral .algorithms .spymath import matrix_sqrt
800791 pcs = self .principal_components
801792 self ._sqrt_cov = matrix_sqrt (eigs = (pcs .eigenvalues ,
802793 pcs .eigenvectors ),
@@ -810,7 +801,6 @@ def sqrt_inv_cov(self):
810801 such that S.dot(S) == inv(C).
811802 '''
812803 if self ._sqrt_inv_cov is None :
813- from spectral .algorithms .spymath import matrix_sqrt
814804 pcs = self .principal_components
815805 self ._sqrt_inv_cov = matrix_sqrt (eigs = (pcs .eigenvalues ,
816806 pcs .eigenvectors ),
@@ -834,7 +824,6 @@ def log_det_cov(self):
834824
835825 def transform (self , xform ):
836826 '''Returns a version of the stats transformed by a linear transform.'''
837- from spectral .algorithms .transforms import LinearTransform
838827 if not isinstance (xform , LinearTransform ):
839828 raise TypeError ('Expected a LinearTransform object.' )
840829 m = xform (self .mean )
@@ -843,8 +832,6 @@ def transform(self, xform):
843832
844833 def get_whitening_transform (self ):
845834 '''Returns transform that centers and whitens data for these stats.'''
846- from spectral .algorithms .transforms import LinearTransform
847- from spectral .algorithms .spymath import matrix_sqrt
848835 C_1 = np .linalg .inv (self .cov )
849836 return LinearTransform (matrix_sqrt (C_1 , True ), pre = - self .mean )
850837
@@ -887,7 +874,6 @@ def calc_stats(image, mask=None, index=None, allow_nan=False):
887874
888875 This object will have members `mean`, `cov`, and `nsamples`.
889876 '''
890- from spectral .algorithms .spymath import has_nan , NaNValueError
891877 (mean , cov , N ) = mean_cov (image , mask , index )
892878 if has_nan (mean ) and not allow_nan :
893879 raise NaNValueError ('NaN values present in data.' )
@@ -1003,12 +989,6 @@ def transform(self, transform):
1003989
1004990 After `transform` is applied, the class statistics will have `C` bands.
1005991 '''
1006-
1007- from .transforms import LinearTransform
1008- from numpy .linalg import det , inv
1009- import math
1010- from spectral .io .spyfile import TransformedImage
1011-
1012992 if isinstance (transform , np .ndarray ):
1013993 transform = LinearTransform (transform )
1014994 self .stats .mean = transform (self .stats .mean )
@@ -1090,7 +1070,6 @@ def calc_stats(self):
10901070 self .nbands = list (self .classes .values ())[0 ].nbands
10911071
10921072 def save (self , filename , calc_stats = False ):
1093- import pickle
10941073 for c in list (self .classes .values ()):
10951074 if c .stats is None :
10961075 if calc_stats == False :
@@ -1116,7 +1095,6 @@ def save(self, filename, calc_stats=False):
11161095 f .close ()
11171096
11181097 def load (self , filename , image ):
1119- import pickle
11201098 f = open (filename , 'rb' )
11211099 mask = pickle .load (f )
11221100 nclasses = pickle .load (f )
@@ -1255,14 +1233,10 @@ def bdist_terms(a, b):
12551233 RETURN VALUE:
12561234 A 2-tuple of the linear and quadratic terms
12571235 '''
1258- from math import exp
1259- from numpy import dot , transpose
1260- from numpy .linalg import inv
1261-
12621236 m = a .stats .mean - b .stats .mean
12631237 avgCov = (a .stats .cov + b .stats .cov ) / 2
12641238
1265- lin_term = (1 / 8. ) * dot (transpose (m ), dot (inv (avgCov ), m ))
1239+ lin_term = (1 / 8. ) * np . dot (np . transpose (m ), np . dot (np . inv (avgCov ), m ))
12661240
12671241 quad_term = 0.5 * (log_det (avgCov )
12681242 - 0.5 * a .stats .log_det_cov
@@ -1293,18 +1267,15 @@ def transform_image(matrix, image):
12931267 :class:`spectral.TransformedImage` object and no transformation of data
12941268 will occur until elements of the object are accessed.
12951269 '''
1296- from spectral .io .spyfile import TransformedImage
1297- from spectral .io .spyfile import SpyFile
1298-
12991270 if isinstance (image , SpyFile ):
13001271 return TransformedImage (matrix , image )
13011272 elif isinstance (image , np .ndarray ):
13021273 (M , N , B ) = image .shape
1303- ximage = numpy .zeros ((M , N , matrix .shape [0 ]), float )
1274+ ximage = np .zeros ((M , N , matrix .shape [0 ]), float )
13041275
13051276 for i in range (M ):
13061277 for j in range (N ):
1307- ximage [i , j ] = numpy .dot (matrix , image [i , j ].astype (float ))
1278+ ximage [i , j ] = np .dot (matrix , image [i , j ].astype (float ))
13081279 return ximage
13091280 else :
13101281 raise 'Unrecognized image type passed to transform_image.'
@@ -1331,25 +1302,22 @@ def orthogonalize(vecs, start=0):
13311302 A new `CxB` containing an orthonormal basis for the given vectors.
13321303 '''
13331304
1334- from numpy import transpose , dot , identity
1335- from numpy .linalg import inv
1336- from math import sqrt
1337-
13381305 (M , N ) = vecs .shape
1339- basis = numpy .array (transpose (vecs ))
1306+ basis = np .array (np . transpose (vecs ))
13401307 eye = identity (N ).astype (float )
13411308 if start == 0 :
1342- basis [:, 0 ] /= sqrt (dot (basis [:, 0 ], basis [:, 0 ]))
1309+ basis [:, 0 ] /= math . sqrt (np . dot (basis [:, 0 ], basis [:, 0 ]))
13431310 start = 1
13441311
13451312 for i in range (start , M ):
1346- v = basis [:, i ] / sqrt (dot (basis [:, i ], basis [:, i ]))
1313+ v = basis [:, i ] / math . sqrt (np . dot (basis [:, i ], basis [:, i ]))
13471314 U = basis [:, :i ]
1348- P = eye - dot (U , dot (inv (dot (transpose (U ), U )), transpose (U )))
1349- basis [:, i ] = dot (P , v )
1350- basis [:, i ] /= sqrt (dot (basis [:, i ], basis [:, i ]))
1315+ P = eye - np .dot (U , np .dot (np .inv (np .dot (np .transpose (U ), U )),
1316+ np .transpose (U )))
1317+ basis [:, i ] = np .dot (P , v )
1318+ basis [:, i ] /= math .sqrt (np .dot (basis [:, i ], basis [:, i ]))
13511319
1352- return transpose (basis )
1320+ return np . transpose (basis )
13531321
13541322
13551323def unmix (data , members ):
@@ -1373,23 +1341,19 @@ def unmix(data, members):
13731341 Note that depending on endmembers given, fractional abundances for
13741342 endmembers may be negative.
13751343 '''
1376-
1377- from numpy import transpose , dot , zeros
1378- from numpy .linalg import inv
1379-
13801344 assert members .shape [1 ] == data .shape [2 ], \
13811345 'Matrix dimensions are not aligned.'
13821346
13831347 members = members .astype (float )
13841348 # Calculate the pseudo inverse
1385- pi = dot (members , transpose (members ))
1386- pi = dot (inv (pi ), members )
1349+ pi = np . dot (members , np . transpose (members ))
1350+ pi = np . dot (np . inv (pi ), members )
13871351
13881352 (M , N , B ) = data .shape
1389- unmixed = zeros ((M , N , members .shape [0 ]), float )
1353+ unmixed = np . zeros ((M , N , members .shape [0 ]), float )
13901354 for i in range (M ):
13911355 for j in range (N ):
1392- unmixed [i , j ] = dot (pi , data [i , j ].astype (float ))
1356+ unmixed [i , j ] = np . dot (pi , data [i , j ].astype (float ))
13931357 return unmixed
13941358
13951359
@@ -1462,8 +1426,6 @@ def msam(data, members):
14621426 # The modifications to the `spectral_angles` function were contributed by
14631427 # Christian Mielke.
14641428
1465- import math
1466-
14671429 assert members .shape [1 ] == data .shape [2 ], \
14681430 'Matrix dimensions are not aligned.'
14691431
@@ -1623,7 +1585,6 @@ def get_denoising_transform(self, **kwargs):
16231585 Returns a callable :class:`~spectral.algorithms.transforms.LinearTransform`
16241586 object for denoising image data.
16251587 '''
1626- from spectral .algorithms .transforms import LinearTransform
16271588 N = self ._num_from_kwargs (** kwargs )
16281589 V = self .napc .eigenvectors
16291590 Vr = np .array (V )
@@ -1681,7 +1642,6 @@ def get_reduction_transform(self, **kwargs):
16811642 Returns a callable :class:`~spectral.algorithms.transforms.LinearTransform`
16821643 object for reducing the dimensionality of image data.
16831644 '''
1684- from spectral .algorithms .transforms import LinearTransform
16851645 N = self ._num_from_kwargs (** kwargs )
16861646 V = self .napc .eigenvectors
16871647 f = LinearTransform (V [:, :N ].T .dot (self .noise .sqrt_inv_cov ),
@@ -1741,8 +1701,6 @@ def mnf(signal, noise):
17411701 principal components transform." Geoscience and Remote Sensing, IEEE
17421702 Transactions on 28.3 (1990): 295-304.
17431703 '''
1744- from spectral .algorithms .transforms import LinearTransform
1745- from spectral .algorithms .algorithms import PrincipalComponents , GaussianStats
17461704 C = noise .sqrt_inv_cov .dot (signal .cov ).dot (noise .sqrt_inv_cov )
17471705 (L , V ) = np .linalg .eig (C )
17481706 # numpy says eigenvalues may not be sorted so we'll sort them, if needed.
@@ -1825,11 +1783,6 @@ def ppi(X, niters, threshold=0, centered=False, start=None, display=0,
18251783 Partial Unmixing of AVIRIS Data," Pasadena, California, USA, 23 Jan 1995,
18261784 URI: http://hdl.handle.net/2014/33635
18271785 '''
1828- from numbers import Integral
1829- import spectral as spy
1830- from spectral .algorithms .algorithms import calc_stats
1831-
1832-
18331786 if display is not None :
18341787 if not isinstance (display , Integral ) or isinstance (display , bool ) or \
18351788 display < 0 :
0 commit comments