Exemple #1
0
def NFINDR(data, wvl, path):
    print('Running NFINDR')
    nfindr = eea.NFINDR()
    U = nfindr.extract(data, 5, maxit=5, normalize=False, ATGP_init=True)
    nfindr.plot(path, axes=wvl, suffix='test_cls')
    # U[0,:] is a false positive, we remove it
    return U[[1, 2, 3, 4], :]
Exemple #2
0
def get_endmembers(data, header, q, path, mask, suffix, output=False):
    print('Endmembers extraction with NFINDR')
    ee = eea.NFINDR()
    U = ee.extract(data, q, maxit=5, normalize=True, ATGP_init=True, mask=mask)
    if output == True:
        ee.plot(path, axes=header, suffix=suffix)
    return U
def get_endmembers(data, header, result_path):
    print('Endmembers extraction with NFINDR')
    nfindr = eea.NFINDR()
    U = nfindr.extract(data, 12, maxit=5, normalize=True, ATGP_init=True)
    nfindr.plot(result_path, axes=header, suffix='gas')
    # return an array of endmembers
    return U
Exemple #4
0
 def __init__(self, hcube, n_em, suffix):
     self.suffix = suffix
     self.nfindr = eea.NFINDR()
     self.U = self.nfindr.extract(hcube,
                                  n_em,
                                  maxit=5,
                                  normalize=False,
                                  ATGP_init=True)
     #        self.xxls = amp.FCLS()
     self.xxls = amp.NNLS()
     self.amaps = self.xxls.map(hcube, self.U, normalize=False)
Exemple #5
0
def test_NFINDR(data, wvl, mask, path):
    print('Testing NFINDR')
    nfindr = eea.NFINDR()
    pr = profile()
#    U = nfindr.extract(data, 4, normalize=1, ATGP_init=True)
    #U = nfindr.extract(data, 4, maxit=5, normalize=False, ATGP_init=True)
#    U = nfindr.extract(data, 8, maxit=5, normalize=False, ATGP_init=True, mask=mask)
    U = nfindr.extract(data, 8, maxit=5, normalize=False, ATGP_init=False, mask=mask)
#    U = nfindr.extract(data, 4, maxit=5, normalize=True, ATGP_init=True)
    stat(pr)
    print(str(nfindr))
    print('  Iterations:', nfindr.get_iterations())
    print('  End members indexes:', nfindr.get_idx())
    nfindr.plot(path, axes=wvl, suffix='test1')
    nfindr.plot(path, suffix='test2')
    U = U[[0,1],:]
    test_amap(data, U, 'NFINDR', path, mask, amaps='UCLS')
    test_amap(data, U, 'NFINDR', path, mask, amaps='NNLS')
    test_amap(data, U, 'NFINDR', path, mask, amaps='FCLS')
def nfindr(data, N):
    #N is the # of endmembers you want to find

    data = data.reshape(1, data.shape[0], data.shape[1])
    #data = data.reshape(data.shape[1], data.shape[0])
    #====================================================
    #Ae,indice,Yp = VCA.vca(data.transpose(), 3)
    #endmembers = Ae.transpose()
    #====================================================
    nfindr = eea.NFINDR()
    endmembers = nfindr.extract(M=data, q=N)
    centroid_smooth = []
    for centroid in endmembers:
        x = np.array(list(range(len(centroid))))
        y = np.array(centroid)
        p30 = np.poly1d(np.polyfit(x, y, 10))
        centroid_smooth.append(p30(x) / max(p30(x)))
    centroid_smooth_df = pd.DataFrame(centroid_smooth)
    #the outputfile will contain exactly N endmembers, you can choose closest signals to ground truth for comparison of methods
    centroid_smooth_df.to_csv('../data/NFINDR_estimations.csv',
                              header=None,
                              index=False)
Exemple #7
0
    def define_endmembers(self, method='load', plotit=True, **kwargs):

        indices = kwargs.get('indices', None)
        components = kwargs.get('components', None)
        endmember_array = kwargs.get('endmember_array', None)

        self.em_defined = True

        if method == 'nfindr':
            self.n_components = components
            nfindr = eea.NFINDR()
            extraction_map = np.copy(self.small_hs_map)
            extraction_map[extraction_map < 0] = 0.00
            self.endmembers = nfindr.extract(extraction_map,
                                             self.n_components,
                                             normalize=True)
        elif method == 'pick':
            self.n_components = len(indices)
            self.endmembers = np.zeros(
                [self.n_components,
                 len(self.wavelength_list[0])])
            for i in range(len(indices)):
                self.endmembers[i, :] = self.small_hs_map[indices[i][0],
                                                          indices[i][1], :]
        elif method == 'load':
            self.n_components = len(endmember_array)
            self.endmembers = endmember_array
        if plotit:
            for i in range(len(self.endmembers)):
                plt.plot(self.wavelength_list[0][1:],
                         self.endmembers[i, :][1:],
                         label='Component ' + str(i + 1))
                plt.ylabel('Endmember intensity, V')
                plt.xlabel('Wavenumber, cm$^{-1}$')
                plt.legend()
            plt.show()
Exemple #8
0
def main():

    try:
        import pysptools.eea as eea
    except ImportError:
        gs.fatal(_("Cannot import pysptools \
                      (https://pypi.python.org/pypi/pysptools) library."
                      " Please install it (pip install pysptools)"
                      " or ensure that it is on path"
                      " (use PYTHONPATH variable)."))

    try:
        # sklearn is a dependency of used pysptools functionality
        import sklearn
    except ImportError:
        gs.fatal(_("Cannot import sklearn \
                      (https://pypi.python.org/pypi/scikit-learn) library."
                      " Please install it (pip install scikit-learn)"
                      " or ensure that it is on path"
                      " (use PYTHONPATH variable)."))

    try:
        from cvxopt import solvers, matrix
    except ImportError:
        gs.fatal(_("Cannot import cvxopt \
                      (https://pypi.python.org/pypi/cvxopt) library."
                      " Please install it (pip install cvxopt)"
                      " or ensure that it is on path"
                      " (use PYTHONPATH variable)."))

    # Parse input options
    input = options['input']
    output = options['output']
    prefix = options['prefix']
    endmember_n = int(options['endmember_n'])
    endmembers = options['endmembers']
    if options['maxit']:
        maxit = options['maxit']
    else:
        maxit = 0
    extraction_method = options['extraction_method']
    unmixing_method = options['unmixing_method']
    atgp_init = True if not flags['n'] else False

    # List maps in imagery group
    try:
        maps = gs.read_command('i.group', flags='g', group=input,
                               quiet=True).rstrip('\n').split('\n')
    except:
        pass

    # Validate input
    # q and maxit can be None according to manual, but does not work in current pysptools version
    if endmember_n <= 0:
        gs.fatal('Number of endmembers has to be > 0')
        """if (extraction_method == 'PPI' or
            extraction_method == 'NFINDR'):
            gs.fatal('Extraction methods PPI and NFINDR require endmember_n >= 2')
        endmember_n = None"""

    if maxit <= 0:
        maxit = 3 * len(maps)

    if endmember_n > len(maps) + 1:
        gs.warning('More endmembers ({}) requested than bands in \
                   input imagery group ({})'.format(endmember_n, len(maps)))
        if extraction_method != 'PPI':
            gs.fatal('Only PPI method can extract more endmembers than number \
                     of bands in the imagery group')

    if not atgp_init and extraction_method != 'NFINDR':
        gs.verbose('ATGP is only taken into account in \
                   NFINDR extraction method...')

    # Get metainformation from input bands
    band_types = {}
    img = None
    n = 0
    gs.verbose('Reading imagery group...')
    for m in maps:
        map = m.split('@')

        # Build numpy stack from imagery group
        raster = r.raster2numpy(map[0], mapset=map[1])
        if raster == np.float64:
            raster = float32(raster)
            gs.warning('{} is of type Float64.\
                        Float64 is currently not supported.\
                        Reducing precision to Float32'.format(raster))

        # Determine map type
        band_types[map[0]] = get_rastertype(raster)

        # Create cube and mask from GRASS internal NoData value
        if n == 0:
            img = raster
            # Create mask from GRASS internal NoData value
            mask = mask_rasternd(raster)
        else:
            img = np.dstack((img, raster))
            mask = np.logical_and((mask_rasternd(raster)), mask)

        n = n + 1

    # Read a mask if present and give waringing if not
    # Note that otherwise NoData is read as values
    gs.verbose('Checking for MASK...')
    try:
        MASK = r.raster2numpy('MASK', mapset=getenv('MAPSET')) == 1
        mask = np.logical_and(MASK, mask)
        MASK = None
    except:
        pass

    if extraction_method == 'NFINDR':
    # Extract endmembers from valid pixels using NFINDR function from pysptools
        gs.verbose('Extracting endmembers using NFINDR...')
        nfindr = eea.NFINDR()
        E = nfindr.extract(img, endmember_n, maxit=maxit, normalize=False,
                           ATGP_init=atgp_init, mask=mask)
    elif extraction_method == 'PPI':
    # Extract endmembers from valid pixels using PPI function from pysptools
        gs.verbose('Extracting endmembers using PPI...')
        ppi = eea.PPI()
        E = ppi.extract(img, endmember_n, numSkewers=10000, normalize=False,
                        mask=mask)
    elif extraction_method == 'FIPPI':
    # Extract endmembers from valid pixels using FIPPI function from pysptools
        gs.verbose('Extracting endmembers using FIPPI...')
        fippi = eea.FIPPI()
        # q and maxit can be None according to manual, but does not work
        """if not maxit and not endmember_n:
            E = fippi.extract(img, q=None, normalize=False, mask=mask)
        if not maxit:
            E = fippi.extract(img, q=endmember_n, normalize=False, mask=mask)
        if not endmember_n:
            E = fippi.extract(img, q=int(), maxit=maxit, normalize=False,
                              mask=mask)
        else:
            E = fippi.extract(img, q=endmember_n, maxit=maxit, normalize=False,
                              mask=mask)"""
        E = fippi.extract(img, q=endmember_n, maxit=maxit, normalize=False,
                          mask=mask)

    # Write output file in format required for i.spec.unmix addon
    if output:
        gs.verbose('Writing spectra file...')
        n = 0
        with open(output, 'w') as o:
            o.write('# Channels: {}\n'.format('\t'.join(band_types.keys())))
            o.write('# Wrote {} spectra line wise.\n#\n'.format(endmember_n))
            o.write('Matrix: {0} by {1}\n'.format(endmember_n, len(maps)))
            for e in E:
                o.write('row{0}: {1}\n'.format(n, '\t'.join([str(i) for i in  e])))
                n = n + 1

    # Write vector map with endmember information if requested
    if endmembers:
        gs.verbose('Writing vector map with endmembers...')
        from grass.pygrass import utils as u
        from grass.pygrass.gis.region import Region
        from grass.pygrass.vector import Vector
        from grass.pygrass.vector import VectorTopo
        from grass.pygrass.vector.geometry import Point

        # Build attribute table
        # Deinfe columns for attribute table
        cols = [(u'cat',       'INTEGER PRIMARY KEY')]
        for b in band_types.keys():
            cols.append((b.replace('.','_'), band_types[b]))
        
        # Get region information
        reg = Region()

        # Create vector map
        new = Vector(endmembers)
        new.open('w', tab_name=endmembers, tab_cols=cols)

        cat = 1
        for e in E:
            # Get indices
            idx = np.where((img[:,:]==e).all(-1))

            # Numpy array is ordered rows, columns (y,x)
            if len(idx[0]) == 0 or len(idx[1]) == 0:
                gs.warning('Could not compute coordinated for endmember {}. \
                            Please consider rescaling your data to integer'.format(cat))
                cat = cat + 1
                continue

            coords = u.pixel2coor((idx[1][0], idx[0][0]), reg)
            point = Point(coords[1] + reg.ewres / 2.0,
                          coords[0] - reg.nsres / 2.0)

            # Get attributes
            n = 0
            attr = []
            for b in band_types.keys():
                if band_types[b] == u'INTEGER':
                    attr.append(int(e[n]))
                else:
                    attr.append(float(e[n]))
                n = n + 1

            # Write geometry with attributes
            new.write(point, cat=cat,
                      attrs=tuple(attr))
            cat = cat + 1

        # Close vector map
        new.table.conn.commit()
        new.close(build=True)

    if prefix:
        # Run spectral unmixing
        import pysptools.abundance_maps as amaps
        if unmixing_method == 'FCLS':
            fcls = amaps.FCLS()
            result = fcls.map(img, E, normalize=False, mask=mask)
        elif unmixing_method == 'NNLS':
            nnls = amaps.NNLS()
            result = nnls.map(img, E, normalize=False, mask=mask)
        elif unmixing_method == 'UCLS':
            ucls = amaps.UCLS()
            result = ucls.map(img, E, normalize=False, mask=mask)

        # Write results
        for l in range(endmember_n):
            rastname = '{0}_{1}'.format(prefix, l + 1)
            r.numpy2raster(result[:,:,l], 'FCELL', rastname)
import rasterTools as rt
import scipy as sp
import pysptools.eea as eea

# Load data set
im, GeoT, Proj = rt.open_data('../Data/Moffett_full.tif')
[h, w, b] = im.shape
wave = sp.loadtxt('../Data/wave_moffett.csv', delimiter=',')

# NFINDR
nfindr = eea.NFINDR()
Unf = nfindr.extract(im.astype(float), 3, normalize=True)

# Plot endmember
T = sp.concatenate((wave[:, sp.newaxis], Unf.T), axis=1)
sp.savetxt("../Unmixing/figures/endmembers.csv", T, delimiter=",")
Exemple #10
0
    def getWaterFraction(cls,
                         ds,
                         cloudThresh=-20,
                         constrain=True,
                         maskClouds=True):

        if maskClouds:
            atmsNoClouds = cls.maskClouds(ds, threshold=cloudThresh)
        else:
            atmsNoClouds = ds.copy()

        dBtr = atmsNoClouds.sel(band='C4').astype(
            np.float) - atmsNoClouds.sel(band='C3').astype(np.float)
        dBtr.coords['band'] = 'dBtr'

        channels = xr.concat([
            atmsNoClouds.sel(band=['C3', 'C4', 'C16']).isel(time=0, z=0),
            dBtr.isel(time=0, z=0)
        ],
                             dim='band')
        arr = channels.values
        arr[np.isnan(arr)] = -9999

        nClasses = 3
        nfindr = eea.NFINDR()
        U = nfindr.extract(arr,
                           nClasses,
                           maxit=100,
                           normalize=True,
                           ATGP_init=True)

        drop = np.argmin(list(map(lambda x: U[x, :].mean(), range(nClasses))))
        waterIdx = np.argmin(
            list(
                map(lambda x: np.delete(U, drop, axis=1)[x, :],
                    range(nClasses - 2))))

        if waterIdx == 0:
            bandList = ['water', 'land', 'mask']
        else:
            bandList = ['land', 'water', 'mask']

        nnls = amp.NNLS()
        amaps = nnls.map(arr, U, normalize=True)

        drop = np.argmin(
            list(map(lambda x: amaps[:, :, x].mean(), range(amaps.shape[2]))))

        unmixed = np.delete(amaps, drop, axis=2)

        unmixed[unmixed == 0] = np.nan

        scaled = np.zeros_like(unmixed)
        for i in range(scaled.shape[2]):
            summed = unmixed[:, :, i] / unmixed.sum(axis=2)
            scaled[:, :,
                   i] = (summed - np.nanmin(summed)) / (np.nanmax(summed) -
                                                        np.nanmin(summed))

        scaled = scaled - 0.25
        scaled[scaled < 0] = 0

        fWater = atmsNoClouds.sel(band=['C1', 'C2', 'mask']).copy()
        fWater[:, :, 0, :2, 0] = scaled[:, :, :]
        fWater.coords['band'] = bandList

        return fWater.raster.updateMask(atmsNoClouds.sel(band='mask'))
Exemple #11
0
def get_endmembers_nfindr(data, header):
    print('Endmembers extraction with NFINDR')
    nfindr = eea.NFINDR()
    U = nfindr.extract(data, 2, maxit=5, normalize=True, ATGP_init=True)
    nfindr.display(header, suffix='Cuprite Endmembers')
    return U