Example #1
0
def main():
    gdal.AllRegister()
    path = auxil.select_directory('Choose working directory')
    #path = arcpy.GetParameterAsText(0)
    if path:
        os.chdir(path)
    file1 = auxil.select_infile(title='Choose first image')
    #file1 = arcpy.GetParameterAsText(1)
    if file1:
        inDataset1 = gdal.Open(file1, GA_ReadOnly)
        cols = inDataset1.RasterXSize
        rows = inDataset1.RasterYSize
        bands = inDataset1.RasterCount
    else:
        return
    pos1 = auxil.select_pos(bands)
    if not pos1:
        return
    dims = auxil.select_dims([0, 0, cols, rows])
    if dims:
        x10, y10, cols1, rows1 = dims
    else:
        return
#  second image
    file2 = auxil.select_infile(title='Choose second image')
    #file2 = arcpy.GetParameterAsText(2)
    if file2:
        inDataset2 = gdal.Open(file2, GA_ReadOnly)
        cols = inDataset2.RasterXSize
        rows = inDataset2.RasterYSize
        bands = inDataset2.RasterCount
    else:
        return
    pos2 = auxil.select_pos(bands)
    if not pos2:
        return
    dims = auxil.select_dims([0, 0, cols, rows])
    if dims:
        x20, y20, cols, rows = dims
    else:
        return
#  penalization
    lam = auxil.select_penal(0.0)
    if lam is None:
        return
#  outfile
    outfile, fmt = auxil.select_outfilefmt()
    if not outfile:
        return
#  match dimensions
    bands = len(pos2)
    if (rows1 != rows) or (cols1 != cols) or (len(pos1) != bands):
        sys.stderr.write("Size mismatch")
        sys.exit(1)
    print('=========================')
    print('       iMAD')
    print('=========================')
    print(time.asctime())
    print('time1: ' + file1)
    print('time2: ' + file2)
    print('Delta    [canonical correlations]')
    #  iteration of MAD
    cpm = auxil.Cpm(2 * bands)
    delta = 1.0
    oldrho = np.zeros(bands)
    itr = 0
    tile = np.zeros((cols, 2 * bands))
    sigMADs = 0
    means1 = 0
    means2 = 0
    A = 0
    B = 0
    rasterBands1 = []
    rasterBands2 = []
    for b in pos1:
        rasterBands1.append(inDataset1.GetRasterBand(b))
    for b in pos2:
        rasterBands2.append(inDataset2.GetRasterBand(b))
    while (delta > 0.001) and (itr < 100):
        #      spectral tiling for statistics
        for row in range(rows):
            for k in range(bands):
                tile[:,
                     k] = rasterBands1[k].ReadAsArray(x10, y10 + row, cols, 1)
                tile[:, bands + k] = rasterBands2[k].ReadAsArray(
                    x20, y20 + row, cols, 1)
#          eliminate no-data pixels (assuming all zeroes)
            tst1 = np.sum(tile[:, 0:bands], axis=1)
            tst2 = np.sum(tile[:, bands::], axis=1)
            idx1 = set(np.where((tst1 > 0))[0])
            idx2 = set(np.where((tst2 > 0))[0])
            idx = list(idx1.intersection(idx2))
            if itr > 0:
                mads = np.asarray((tile[:, 0:bands] - means1) * A -
                                  (tile[:, bands::] - means2) * B)
                chisqr = np.sum((mads / sigMADs)**2, axis=1)
                wts = 1 - stats.chi2.cdf(chisqr, [bands])
                cpm.update(tile[idx, :], wts[idx])
            else:
                cpm.update(tile[idx, :])
#     weighted covariance matrices and means
        S = cpm.covariance()
        means = cpm.means()
        #     reset prov means object
        cpm.__init__(2 * bands)
        s11 = S[0:bands, 0:bands]
        s11 = (1 - lam) * s11 + lam * np.eye(bands)
        s22 = S[bands:, bands:]
        s22 = (1 - lam) * s22 + lam * np.eye(bands)
        s12 = S[0:bands, bands:]
        s21 = S[bands:, 0:bands]
        c1 = s12 * linalg.inv(s22) * s21
        b1 = s11
        c2 = s21 * linalg.inv(s11) * s12
        b2 = s22
        #     solution of generalized eigenproblems
        if bands > 1:
            mu2a, A = auxil.geneiv(c1, b1)
            mu2b, B = auxil.geneiv(c2, b2)
            #          sort a
            idx = np.argsort(mu2a)
            A = A[:, idx]
            #          sort b
            idx = np.argsort(mu2b)
            B = B[:, idx]
            mu2 = mu2b[idx]
        else:
            mu2 = c1 / b1
            A = 1 / np.sqrt(b1)
            B = 1 / np.sqrt(b2)
#      canonical correlations
        mu = np.sqrt(mu2)
        a2 = np.diag(A.T * A)
        b2 = np.diag(B.T * B)
        sigma = np.sqrt((2 - lam * (a2 + b2)) / (1 - lam) - 2 * mu)
        rho = mu * (1 - lam) / np.sqrt((1 - lam * a2) * (1 - lam * b2))
        #      stopping criterion
        delta = max(abs(rho - oldrho))
        print(delta, rho)
        oldrho = rho
        #      tile the sigmas and means
        sigMADs = np.tile(sigma, (cols, 1))
        means1 = np.tile(means[0:bands], (cols, 1))
        means2 = np.tile(means[bands::], (cols, 1))
        #      ensure sum of positive correlations between X and U is positive
        D = np.diag(1 / np.sqrt(np.diag(s11)))
        s = np.ravel(np.sum(D * s11 * A, axis=0))
        A = A * np.diag(s / np.abs(s))
        #      ensure positive correlation between each pair of canonical variates
        cov = np.diag(A.T * s12 * B)
        B = B * np.diag(cov / np.abs(cov))
        itr += 1


# write results to disk
    driver = gdal.GetDriverByName(fmt)
    outDataset = driver.Create(outfile, cols, rows, bands + 1, GDT_Float32)
    projection = inDataset1.GetProjection()
    geotransform = inDataset1.GetGeoTransform()
    if geotransform is not None:
        gt = list(geotransform)
        gt[0] = gt[0] + x10 * gt[1]
        gt[3] = gt[3] + y10 * gt[5]
        outDataset.SetGeoTransform(tuple(gt))
    if projection is not None:
        outDataset.SetProjection(projection)
    outBands = []
    for k in range(bands + 1):
        outBands.append(outDataset.GetRasterBand(k + 1))
    for row in range(rows):
        for k in range(bands):
            tile[:, k] = rasterBands1[k].ReadAsArray(x10, y10 + row, cols, 1)
            tile[:, bands + k] = rasterBands2[k].ReadAsArray(
                x20, y20 + row, cols, 1)
        mads = np.asarray((tile[:, 0:bands] - means1) * A -
                          (tile[:, bands::] - means2) * B)
        chisqr = np.sum((mads / sigMADs)**2, axis=1)
        for k in range(bands):
            outBands[k].WriteArray(np.reshape(mads[:, k], (1, cols)), 0, row)
        outBands[bands].WriteArray(np.reshape(chisqr, (1, cols)), 0, row)
    for outBand in outBands:
        outBand.FlushCache()
    outDataset = None
    inDataset1 = None
    inDataset2 = None
    print('result written to: ' + outfile)
    print('--------done---------------------')
Example #2
0
def main():
    usage = '''
Usage:
-----------------------------------------------------
python %s [-h] [-n] [-i max iterations] [-p bandPositions] 
[-d spatialDimensions] filename1 filename2
-----------------------------------------------------
bandPositions and spatialDimensions are lists, 
e.g., -p [1,2,3] -d [0,0,400,400]
-n stops any graphics output
-----------------------------------------------------
The output MAD variate file is has the same format
as filename1 and is named

      path/MAD(filebasename1-filebasename2).ext1
      
where filename1 = path/filebasename1.ext1
      filename2 = path/filebasename2.ext2

For ENVI files, ext1 or ext2 is the empty string.       
-----------------------------------------------------''' % sys.argv[0]
    options, args = getopt.getopt(sys.argv[1:], 'hnp:i:d:')
    pos = None
    dims = None
    niter = 50
    graphics = True
    for option, value in options:
        if option == '-h':
            print usage
            return
        elif option == '-n':
            graphics = False
        elif option == '-p':
            pos = eval(value)
        elif option == '-d':
            dims = eval(value)
        elif option == '-i':
            niter = eval(value)
    if len(args) != 2:
        print 'Incorrect number of arguments'
        print usage
        return
    gdal.AllRegister()
    fn1 = args[0]
    fn2 = args[1]
    path = os.path.dirname(fn1)
    basename1 = os.path.basename(fn1)
    root1, ext1 = os.path.splitext(basename1)
    basename2 = os.path.basename(fn2)
    root2, ext2 = os.path.splitext(basename2)
    outfn = path + '/' + 'MAD(%s-%s)%s' % (root1, basename2, ext1)
    inDataset1 = gdal.Open(fn1, GA_ReadOnly)
    inDataset2 = gdal.Open(fn2, GA_ReadOnly)
    try:
        cols = inDataset1.RasterXSize
        rows = inDataset1.RasterYSize
        bands = inDataset1.RasterCount
        cols2 = inDataset2.RasterXSize
        rows2 = inDataset2.RasterYSize
        bands2 = inDataset2.RasterCount
    except Exception as e:
        print 'Error: %s  --Images could not be read.' % e
        sys.exit(1)
    if bands != bands2:
        sys.stderr.write("Size mismatch")
        sys.exit(1)
    if pos is None:
        pos = range(1, bands + 1)
    else:
        bands = len(pos)
    if dims is None:
        x0 = 0
        y0 = 0
    else:
        x0, y0, cols, rows = dims
# if second image is warped, assume it has same dimensions as dims
    if root2.find('_warp') != -1:
        x2 = 0
        y2 = 0
    else:
        x2 = x0
        y2 = y0
    print '------------IRMAD -------------'
    print time.asctime()
    print 'time1: ' + fn1
    print 'time2: ' + fn2
    start = time.time()
    #  iteration of MAD
    cpm = auxil.Cpm(2 * bands)
    delta = 1.0
    oldrho = np.zeros(bands)
    itr = 0
    tile = np.zeros((cols, 2 * bands))
    sigMADs = 0
    means1 = 0
    means2 = 0
    A = 0
    B = 0
    rasterBands1 = []
    rasterBands2 = []
    rhos = np.zeros((niter, bands))
    for b in pos:
        rasterBands1.append(inDataset1.GetRasterBand(b))
    for b in pos:
        rasterBands2.append(inDataset2.GetRasterBand(b))
    while (delta > 0.001) and (itr < niter):
        #      spectral tiling for statistics
        for row in range(rows):
            for k in range(bands):
                tile[:, k] = rasterBands1[k].ReadAsArray(x0, y0 + row, cols, 1)
                tile[:, bands + k] = rasterBands2[k].ReadAsArray(
                    x2, y2 + row, cols, 1)
#          eliminate no-data pixels
            tile = np.nan_to_num(tile)
            tst1 = np.sum(tile[:, 0:bands], axis=1)
            tst2 = np.sum(tile[:, bands::], axis=1)
            idx1 = set(np.where((tst1 != 0))[0])
            idx2 = set(np.where((tst2 != 0))[0])
            idx = list(idx1.intersection(idx2))
            if itr > 0:
                mads = np.asarray((tile[:, 0:bands] - means1) * A -
                                  (tile[:, bands::] - means2) * B)
                chisqr = np.sum((mads / sigMADs)**2, axis=1)
                wts = 1 - stats.chi2.cdf(chisqr, [bands])
                cpm.update(tile[idx, :], wts[idx])
            else:
                cpm.update(tile[idx, :])
#     weighted covariance matrices and means
        S = cpm.covariance()
        means = cpm.means()
        #     reset prov means object
        cpm.__init__(2 * bands)
        s11 = S[0:bands, 0:bands]
        s22 = S[bands:, bands:]
        s12 = S[0:bands, bands:]
        s21 = S[bands:, 0:bands]
        c1 = s12 * linalg.inv(s22) * s21
        b1 = s11
        c2 = s21 * linalg.inv(s11) * s12
        b2 = s22
        #     solution of generalized eigenproblems
        if bands > 1:
            mu2a, A = auxil.geneiv(c1, b1)
            mu2b, B = auxil.geneiv(c2, b2)
            #          sort a
            idx = np.argsort(mu2a)
            A = A[:, idx]
            #          sort b
            idx = np.argsort(mu2b)
            B = B[:, idx]
            mu2 = mu2b[idx]
        else:
            mu2 = c1 / b1
            A = 1 / np.sqrt(b1)
            B = 1 / np.sqrt(b2)


#      canonical correlations
        rho = np.sqrt(mu2)
        b2 = np.diag(B.T * B)
        sigma = np.sqrt(2 * (1 - rho))
        #      stopping criterion
        delta = max(abs(rho - oldrho))
        rhos[itr, :] = rho
        oldrho = rho
        #      tile the sigmas and means
        sigMADs = np.tile(sigma, (cols, 1))
        means1 = np.tile(means[0:bands], (cols, 1))
        means2 = np.tile(means[bands::], (cols, 1))
        #      ensure sum of positive correlations between X and U is positive
        D = np.diag(1 / np.sqrt(np.diag(s11)))
        s = np.ravel(np.sum(D * s11 * A, axis=0))
        A = A * np.diag(s / np.abs(s))
        #      ensure positive correlation between each pair of canonical variates
        cov = np.diag(A.T * s12 * B)
        B = B * np.diag(cov / np.abs(cov))
        itr += 1
    print 'rho: %s' % str(rho)
    # write results to disk
    driver = inDataset1.GetDriver()
    outDataset = driver.Create(outfn, cols, rows, bands + 1, GDT_Float32)
    projection = inDataset1.GetProjection()
    geotransform = inDataset1.GetGeoTransform()
    if geotransform is not None:
        gt = list(geotransform)
        gt[0] = gt[0] + x0 * gt[1]
        gt[3] = gt[3] + y0 * gt[5]
        outDataset.SetGeoTransform(tuple(gt))
    if projection is not None:
        outDataset.SetProjection(projection)
    outBands = []
    for k in range(bands + 1):
        outBands.append(outDataset.GetRasterBand(k + 1))
    for row in range(rows):
        for k in range(bands):
            tile[:, k] = rasterBands1[k].ReadAsArray(x0, y0 + row, cols, 1)
            tile[:, bands + k] = rasterBands2[k].ReadAsArray(
                x2, y2 + row, cols, 1)
        mads = np.asarray((tile[:, 0:bands] - means1) * A -
                          (tile[:, bands::] - means2) * B)
        chisqr = np.sum((mads / sigMADs)**2, axis=1)
        for k in range(bands):
            outBands[k].WriteArray(np.reshape(mads[:, k], (1, cols)), 0, row)
        outBands[bands].WriteArray(np.reshape(chisqr, (1, cols)), 0, row)
    for outBand in outBands:
        outBand.FlushCache()
    outDataset = None
    inDataset1 = None
    inDataset2 = None
    print 'result written to: ' + outfn
    print 'elapsed time: %s' % str(time.time() - start)
    x = np.array(range(itr - 1))
    if graphics:
        plt.plot(x, rhos[0:itr - 1, :])
        plt.title('Canonical correlations')
        plt.show()
Example #3
0
def main():     
    gdal.AllRegister()
    path = auxil.select_directory('Choose working directory')
    if path:
        os.chdir(path)        
#  first image    
    file1 = auxil.select_infile(title='Choose first image') 
    if file1:                   
        inDataset1 = gdal.Open(file1,GA_ReadOnly)     
        cols = inDataset1.RasterXSize
        rows = inDataset1.RasterYSize    
        bands = inDataset1.RasterCount
    else:
        return
    pos1 =  auxil.select_pos(bands) 
    if not pos1:
        return   
    dims = auxil.select_dims([0,0,cols,rows])
    if dims:
        x10,y10,cols1,rows1 = dims
    else:
        return 
#  second image     
    file2 = auxil.select_infile(title='Choose second image') 
    if file2:                  
        inDataset2 = gdal.Open(file2,GA_ReadOnly)     
        cols = inDataset2.RasterXSize
        rows = inDataset2.RasterYSize    
        bands = inDataset2.RasterCount
    else:
        return   
    pos2 =  auxil.select_pos(bands)   
    if not pos2:
        return 
    dims=auxil.select_dims([0,0,cols,rows])  
    if dims:
        x20,y20,cols,rows = dims
    else:
        return    
#  penalization    
    lam = auxil.select_penal(0.0)    
    if lam is None:
        return    
#  outfile
    outfile, fmt = auxil.select_outfilefmt()  
    if not outfile:
        return  
#  match dimensions       
    bands = len(pos2)
    if (rows1 != rows) or (cols1 != cols) or (len(pos1) != bands):
        sys.stderr.write("Size mismatch")
        sys.exit(1)         
    print '========================='
    print '       iMAD'
    print '========================='
    print time.asctime()     
    print 'time1: '+file1
    print 'time2: '+file2   
    print 'Delta    [canonical correlations]'   
#  iteration of MAD    
    cpm = auxil.Cpm(2*bands)    
    delta = 1.0
    oldrho = np.zeros(bands)     
    itr = 0
    tile = np.zeros((cols,2*bands))
    sigMADs = 0
    means1 = 0
    means2 = 0
    A = 0
    B = 0
    rasterBands1 = []
    rasterBands2 = [] 
    for b in pos1:
        rasterBands1.append(inDataset1.GetRasterBand(b)) 
    for b in pos2:
        rasterBands2.append(inDataset2.GetRasterBand(b))                    
    while (delta > 0.001) and (itr < 100):   
#      spectral tiling for statistics
        for row in range(rows):
            for k in range(bands):
                tile[:,k] = rasterBands1[k].ReadAsArray(x10,y10+row,cols,1)
                tile[:,bands+k] = rasterBands2[k].ReadAsArray(x20,y20+row,cols,1)
#          eliminate no-data pixels (assuming all zeroes)                  
            tst1 = np.sum(tile[:,0:bands],axis=1) 
            tst2 = np.sum(tile[:,bands::],axis=1) 
            idx1 = set(np.where(  (tst1>0)  )[0]) 
            idx2 = set(np.where(  (tst2>0)  )[0]) 
            idx = list(idx1.intersection(idx2))    
            if itr>0:
                mads = np.asarray((tile[:,0:bands]-means1)*A - (tile[:,bands::]-means2)*B)
                chisqr = np.sum((mads/sigMADs)**2,axis=1)
                wts = 1-stats.chi2.cdf(chisqr,[bands])
                cpm.update(tile[idx,:],wts[idx])
            else:
                cpm.update(tile[idx,:])               
#     weighted covariance matrices and means 
        S = cpm.covariance() 
        means = cpm.means()    
#     reset prov means object           
        cpm.__init__(2*bands)  
        s11 = S[0:bands,0:bands]
        s11 = (1-lam)*s11 + lam*np.eye(bands)
        s22 = S[bands:,bands:] 
        s22 = (1-lam)*s22 + lam*np.eye(bands)
        s12 = S[0:bands,bands:]
        s21 = S[bands:,0:bands]        
        c1 = s12*linalg.inv(s22)*s21 
        b1 = s11
        c2 = s21*linalg.inv(s11)*s12
        b2 = s22
#     solution of generalized eigenproblems 
        if bands>1:
            mu2a,A = auxil.geneiv(c1,b1)                
            mu2b,B = auxil.geneiv(c2,b2)               
#          sort a   
            idx = np.argsort(mu2a)
            A = A[:,idx]        
#          sort b   
            idx = np.argsort(mu2b)
            B = B[:,idx] 
            mu2 = mu2b[idx]
        else:
            mu2 = c1/b1
            A = 1/np.sqrt(b1)
            B = 1/np.sqrt(b2)   
#      canonical correlations             
        mu = np.sqrt(mu2)
        a2 = np.diag(A.T*A)
        b2 = np.diag(B.T*B)
        sigma = np.sqrt( (2-lam*(a2+b2))/(1-lam)-2*mu )
        rho=mu*(1-lam)/np.sqrt( (1-lam*a2)*(1-lam*b2) )
#      stopping criterion
        delta = max(abs(rho-oldrho))
        print delta,rho 
        oldrho = rho  
#      tile the sigmas and means             
        sigMADs = np.tile(sigma,(cols,1)) 
        means1 = np.tile(means[0:bands],(cols,1)) 
        means2 = np.tile(means[bands::],(cols,1))
#      ensure sum of positive correlations between X and U is positive
        D = np.diag(1/np.sqrt(np.diag(s11)))  
        s = np.ravel(np.sum(D*s11*A,axis=0)) 
        A = A*np.diag(s/np.abs(s))          
#      ensure positive correlation between each pair of canonical variates        
        cov = np.diag(A.T*s12*B)    
        B = B*np.diag(cov/np.abs(cov))          
        itr += 1                 
# write results to disk
    driver = gdal.GetDriverByName(fmt)    
    outDataset = driver.Create(outfile,cols,rows,bands+1,GDT_Float32)
    projection = inDataset1.GetProjection()
    geotransform = inDataset1.GetGeoTransform()
    if geotransform is not None:
        gt = list(geotransform)
        gt[0] = gt[0] + x10*gt[1]
        gt[3] = gt[3] + y10*gt[5]
        outDataset.SetGeoTransform(tuple(gt))
    if projection is not None:
        outDataset.SetProjection(projection)            
    outBands = [] 
    for k in range(bands+1):
        outBands.append(outDataset.GetRasterBand(k+1))   
    for row in range(rows):
        for k in range(bands):
            tile[:,k] = rasterBands1[k].ReadAsArray(x10,y10+row,cols,1)
            tile[:,bands+k] = rasterBands2[k].ReadAsArray(x20,y20+row,cols,1)       
        mads = np.asarray((tile[:,0:bands]-means1)*A - (tile[:,bands::]-means2)*B)
        chisqr = np.sum((mads/sigMADs)**2,axis=1) 
        for k in range(bands):
            outBands[k].WriteArray(np.reshape(mads[:,k],(1,cols)),0,row)
        outBands[bands].WriteArray(np.reshape(chisqr,(1,cols)),0,row)                        
    for outBand in outBands: 
        outBand.FlushCache()
    outDataset = None
    inDataset1 = None
    inDataset2 = None  
    print 'result written to: '+outfile
    print '--------done---------------------'     
Example #4
0
def imad(current, prev):
    import numpy as np
    from numpy import linalg
    import auxil.auxil as auxil

    image1 = ee.Image(ee.Dictionary(current).get('image1'))
    image2 = ee.Image(ee.Dictionary(current).get('image2'))
    weights = ee.Image(ee.Dictionary(prev).get('weights'))
    region = image1.geometry()
    bNames1 = image1.bandNames()
    bNames2 = image2.bandNames()
    nBands = len(bNames1.getInfo())
    centeredImage1 = centerw(image1, weights)
    centeredImage2 = centerw(image2, weights)
    centeredImage = ee.Image.cat(centeredImage1, centeredImage2)
    covarArray = covw(centeredImage, weights)
    # -------- cannot be iterated!!! --------
    S = np.mat(covarArray.getInfo())
    # ---------------------------------------
    s11 = S[0:nBands, 0:nBands]
    s22 = S[nBands:, nBands:]
    s12 = S[0:nBands, nBands:]
    s21 = S[nBands:, 0:nBands]
    c1 = s12 * linalg.inv(s22) * s21
    b1 = s11
    c2 = s21 * linalg.inv(s11) * s12
    b2 = s22
    #  solution of generalized eigenproblems
    mu2a, A = auxil.geneiv(c1, b1)
    mu2b, B = auxil.geneiv(c2, b2)
    #  sort a
    idx = np.argsort(mu2a)
    A = A[:, idx]
    #  sort b
    idx = np.argsort(mu2b)
    B = B[:, idx]
    mu2 = mu2b[idx]
    #  canonical correlations and MAD variances
    rho = np.sqrt(mu2)
    print rho
    s2 = (2 * (1 - rho)).tolist()
    variance = ee.Image.constant(s2)
    #  ensure sum of positive correlations between X and U is positive
    tmp = np.diag(1 / np.sqrt(np.diag(s11)))
    s = np.ravel(np.sum(tmp * s11 * A, axis=0))
    A = A * np.diag(s / np.abs(s))
    #  ensure positive correlation
    tmp = np.diag(A.T * s12 * B)
    B = B * np.diag(tmp / abs(tmp))
    #  canonical and MAD variates
    Arr = ee.Array(A.tolist())
    Brr = ee.Array(B.tolist())
    centeredImage1Array = centeredImage1.toArray().toArray(1)
    centeredImage2Array = centeredImage2.toArray().toArray(1)
    U = ee.Image(Arr).matrixMultiply(centeredImage1Array) \
        .arrayProject([0]) \
        .arrayFlatten([bNames1])
    V = ee.Image(Brr).matrixMultiply(centeredImage2Array) \
        .arrayProject([0]) \
        .arrayFlatten([bNames2])
    MAD = U.subtract(V)
    #  chi square image
    chi2 = (MAD.pow(2)) \
            .divide(variance) \
            .reduce(ee.Reducer.sum()) \
            .clip(region)
    #  no-change probability
    weights = ee.Image.constant(1.0).subtract(chi2cdf(chi2, 6.0))
    return ee.Dictionary({'weights': weights, 'MAD': MAD})
Example #5
0
def main():   
    usage = '''
Usage:
-----------------------------------------------------
python %s [-h] [-n] [-i max iterations] [-p bandPositions] 
[-d spatialDimensions] filename1 filename2
-----------------------------------------------------
bandPositions and spatialDimensions are lists, 
e.g., -p [1,2,3] -d [0,0,400,400]
-n stops any graphics output
-----------------------------------------------------
The output MAD variate file is has the same format
as filename1 and is named

      path/MAD(filebasename1-filebasename2).ext1
      
where filename1 = path/filebasename1.ext1
      filename2 = path/filebasename2.ext2

For ENVI files, ext1 or ext2 is the empty string.       
-----------------------------------------------------''' %sys.argv[0]
    options, args = getopt.getopt(sys.argv[1:],'hnp:i:d:')
    pos = None
    dims = None  
    niter = 50  
    graphics = True        
    for option, value in options:
        if option == '-h':
            print usage
            return
        elif option == '-n':
            graphics = False
        elif option == '-p':
            pos = eval(value)
        elif option == '-d':
            dims = eval(value) 
        elif option == '-i':
            niter = eval(value)
    if len(args) != 2:
        print 'Incorrect number of arguments'
        print usage
        return                                    
    gdal.AllRegister()
    fn1 = args[0]
    fn2 = args[1]
    path = os.path.dirname(fn1)
    basename1 = os.path.basename(fn1)
    root1, ext1 = os.path.splitext(basename1)
    basename2 = os.path.basename(fn2)
    root2, ext2 = os.path.splitext(basename2)
    outfn = path + '/' + 'MAD(%s-%s)%s'%(root1,basename2,ext1)     
    inDataset1 = gdal.Open(fn1,GA_ReadOnly)     
    inDataset2 = gdal.Open(fn2,GA_ReadOnly) 
    try:   
        cols = inDataset1.RasterXSize
        rows = inDataset1.RasterYSize    
        bands = inDataset1.RasterCount
        cols2 = inDataset2.RasterXSize
        rows2 = inDataset2.RasterYSize    
        bands2 = inDataset2.RasterCount
    except Exception as e:
        print 'Error: %s  --Images could not be read.'%e
        sys.exit(1)     
    if bands != bands2:
        sys.stderr.write("Size mismatch")
        sys.exit(1)                
    if pos is None:
        pos = range(1,bands+1) 
    else:
        bands = len(pos) 
    if dims is None:
        x0 = 0
        y0 = 0
    else:
        x0,y0,cols,rows = dims    
# if second image is warped, assume it has same dimensions as dims        
    if root2.find('_warp') != -1:
        x2 = 0
        y2 = 0   
    else:
        x2 = x0
        y2 = y0    
    print '------------IRMAD -------------'
    print time.asctime()     
    print 'time1: '+fn1
    print 'time2: '+fn2   
    start = time.time()
#  iteration of MAD    
    cpm = auxil.Cpm(2*bands)    
    delta = 1.0
    oldrho = np.zeros(bands)     
    itr = 0
    tile = np.zeros((cols,2*bands))
    sigMADs = 0 
    means1 = 0
    means2 = 0
    A = 0
    B = 0
    rasterBands1 = []
    rasterBands2 = [] 
    rhos = np.zeros((niter,bands))
    for b in pos:
        rasterBands1.append(inDataset1.GetRasterBand(b)) 
    for b in pos:
        rasterBands2.append(inDataset2.GetRasterBand(b))                    
    while (delta > 0.001) and (itr < niter):   
#      spectral tiling for statistics
        for row in range(rows):
            for k in range(bands):
                tile[:,k] = rasterBands1[k].ReadAsArray(x0,y0+row,cols,1)
                tile[:,bands+k] = rasterBands2[k].ReadAsArray(x2,y2+row,cols,1)
#          eliminate no-data pixels    
            tile = np.nan_to_num(tile)              
            tst1 = np.sum(tile[:,0:bands],axis=1) 
            tst2 = np.sum(tile[:,bands::],axis=1) 
            idx1 = set(np.where(  (tst1>0)  )[0]) 
            idx2 = set(np.where(  (tst2>0)  )[0]) 
            idx = list(idx1.intersection(idx2))   
            if itr>0:
                mads = np.asarray((tile[:,0:bands]-means1)*A - (tile[:,bands::]-means2)*B)
                chisqr = np.sum((mads/sigMADs)**2,axis=1)
                wts = 1-stats.chi2.cdf(chisqr,[bands])
                cpm.update(tile[idx,:],wts[idx])
            else:
                cpm.update(tile[idx,:])               
#     weighted covariance matrices and means 
        S = cpm.covariance() 
        means = cpm.means()    
#     reset prov means object           
        cpm.__init__(2*bands)  
        s11 = S[0:bands,0:bands]
        s22 = S[bands:,bands:] 
        s12 = S[0:bands,bands:]
        s21 = S[bands:,0:bands]        
        c1 = s12*linalg.inv(s22)*s21 
        b1 = s11
        c2 = s21*linalg.inv(s11)*s12
        b2 = s22
#     solution of generalized eigenproblems 
        if bands>1:
            mu2a,A = auxil.geneiv(c1,b1)                
            mu2b,B = auxil.geneiv(c2,b2)               
#          sort a   
            idx = np.argsort(mu2a)      
            A = A[:,idx]        
#          sort b   
            idx = np.argsort(mu2b)
            B = B[:,idx] 
            mu2 = mu2b[idx]
        else:
            mu2 = c1/b1
            A = 1/np.sqrt(b1)
            B = 1/np.sqrt(b2)   
#      canonical correlations             
        rho = np.sqrt(mu2)
        b2 = np.diag(B.T*B)
        sigma = np.sqrt( 2*(1-rho ) )
#      stopping criterion
        delta = max(abs(rho-oldrho))
        rhos[itr,:] = rho
        oldrho = rho  
#      tile the sigmas and means             
        sigMADs = np.tile(sigma,(cols,1)) 
        means1 = np.tile(means[0:bands],(cols,1)) 
        means2 = np.tile(means[bands::],(cols,1))
#      ensure sum of positive correlations between X and U is positive
        D = np.diag(1/np.sqrt(np.diag(s11)))
        s = np.ravel(np.sum(D*s11*A,axis=0)) 
        A = A*np.diag(s/np.abs(s))          
#      ensure positive correlation between each pair of canonical variates        
        cov = np.diag(A.T*s12*B)    
        B = B*np.diag(cov/np.abs(cov))          
        itr += 1              
    print 'rho: %s'%str(rho)          
# write results to disk
    driver = inDataset1.GetDriver()    
    outDataset = driver.Create(outfn,cols,rows,bands+1,GDT_Float32)
    projection = inDataset1.GetProjection()
    geotransform = inDataset1.GetGeoTransform()
    if geotransform is not None:
        gt = list(geotransform)
        gt[0] = gt[0] + x0*gt[1]
        gt[3] = gt[3] + y0*gt[5]
        outDataset.SetGeoTransform(tuple(gt))
    if projection is not None:
        outDataset.SetProjection(projection)            
    outBands = [] 
    for k in range(bands+1):
        outBands.append(outDataset.GetRasterBand(k+1))   
    for row in range(rows):
        for k in range(bands):
            tile[:,k] = rasterBands1[k].ReadAsArray(x0,y0+row,cols,1)
            tile[:,bands+k] = rasterBands2[k].ReadAsArray(x2,y2+row,cols,1)       
        mads = np.asarray((tile[:,0:bands]-means1)*A - (tile[:,bands::]-means2)*B)
        chisqr = np.sum((mads/sigMADs)**2,axis=1) 
        for k in range(bands):
            outBands[k].WriteArray(np.reshape(mads[:,k],(1,cols)),0,row)
        outBands[bands].WriteArray(np.reshape(chisqr,(1,cols)),0,row)                        
    for outBand in outBands: 
        outBand.FlushCache()
    outDataset = None
    inDataset1 = None
    inDataset2 = None  
    print 'result written to: '+outfn
    print 'elapsed time: %s'%str(time.time()-start) 
    x = np.array(range(itr-1))
    if graphics:
        plt.plot(x,rhos[0:itr-1,:])
        plt.title('Canonical correlations')
        plt.show()