def main(): gdal.AllRegister() path = auxil.select_directory('Choose working directory') if path: os.chdir(path) # MS image file1 = auxil.select_infile(title='Choose MS 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 num_bands = len(pos1) dims = auxil.select_dims([0, 0, cols, rows]) if dims: x10, y10, cols1, rows1 = dims else: return # PAN image file2 = auxil.select_infile(title='Choose PAN image') if file2: inDataset2 = gdal.Open(file2, GA_ReadOnly) bands = inDataset2.RasterCount else: return if bands > 1: print 'Must be a single band (panchromatic) image' return geotransform1 = inDataset1.GetGeoTransform() geotransform2 = inDataset2.GetGeoTransform() # outfile outfile, fmt = auxil.select_outfilefmt() if not outfile: return # resolution ratio ratio = auxil.select_integer(4, 'Resolution ratio (2 or 4)') if not ratio: return # MS registration band k1 = auxil.select_integer(1, 'MS band for registration') if not k1: return print '=========================' print ' ATWT Pansharpening' print '=========================' print time.asctime() print 'MS file: ' + file1 print 'PAN file: ' + file2 # read in MS image band = inDataset1.GetRasterBand(1) tmp = band.ReadAsArray(0, 0, 1, 1) dt = tmp.dtype MS = np.asarray(np.zeros((num_bands, rows1, cols1)), dtype=dt) k = 0 for b in pos1: band = inDataset1.GetRasterBand(b) MS[k, :, :] = band.ReadAsArray(x10, y10, cols1, rows1) k += 1 # if integer assume 11-bit quantization, otherwise must be byte if MS.dtype == np.int16: fact = 8.0 MS = auxil.byteStretch(MS, (0, 2**11)) else: fact = 1.0 # read in corresponding spatial subset of PAN image if (geotransform1 is None) or (geotransform2 is None): print 'Image not georeferenced, aborting' return # upper left corner pixel in PAN gt1 = list(geotransform1) gt2 = list(geotransform2) ulx1 = gt1[0] + x10 * gt1[1] uly1 = gt1[3] + y10 * gt1[5] x20 = int(round(((ulx1 - gt2[0]) / gt2[1]))) y20 = int(round(((uly1 - gt2[3]) / gt2[5]))) cols2 = cols1 * ratio rows2 = rows1 * ratio band = inDataset2.GetRasterBand(1) PAN = band.ReadAsArray(x20, y20, cols2, rows2) # if integer assume 11-bit quantization, otherwise must be byte if PAN.dtype == np.int16: PAN = auxil.byteStretch(PAN, (0, 2**11)) # out array sharpened = np.zeros((num_bands, rows2, cols2), dtype=np.float32) # compress PAN to resolution of MS image using DWT panDWT = auxil.DWTArray(PAN, cols2, rows2) r = ratio while r > 1: panDWT.filter() r /= 2 bn0 = panDWT.get_quadrant(0) # register (and subset) MS image to compressed PAN image using selected MSband lines0, samples0 = bn0.shape bn1 = MS[k1 - 1, :, :] # register (and subset) MS image to compressed PAN image (scale, angle, shift) = auxil.similarity(bn0, bn1) tmp = np.zeros((num_bands, lines0, samples0)) for k in range(num_bands): bn1 = MS[k, :, :] bn2 = ndii.zoom(bn1, 1.0 / scale) bn2 = ndii.rotate(bn2, angle) bn2 = ndii.shift(bn2, shift) tmp[k, :, :] = bn2[0:lines0, 0:samples0] MS = tmp smpl = np.random.randint(cols2 * rows2, size=100000) print 'Wavelet correlations:' # loop over MS bands for k in range(num_bands): msATWT = auxil.ATWTArray(PAN) r = ratio while r > 1: msATWT.filter() r /= 2 # sample PAN wavelet details X = msATWT.get_band(msATWT.num_iter) X = X.ravel()[smpl] # resize the ms band to scale of the pan image ms_band = ndii.zoom(MS[k, :, :], ratio) # sample details of MS band tmpATWT = auxil.ATWTArray(ms_band) r = ratio while r > 1: tmpATWT.filter() r /= 2 Y = tmpATWT.get_band(msATWT.num_iter) Y = Y.ravel()[smpl] # get band for injection bnd = tmpATWT.get_band(0) tmpATWT = None aa, bb, R = auxil.orthoregress(X, Y) print 'Band ' + str(k + 1) + ': %8.3f' % R # inject the filtered MS band msATWT.inject(bnd) # normalize wavelet components and expand msATWT.normalize(aa, bb) r = ratio while r > 1: msATWT.invert() r /= 2 sharpened[k, :, :] = msATWT.get_band(0) sharpened *= fact # rescale dynamic range msATWT = None # write to disk driver = gdal.GetDriverByName(fmt) outDataset = driver.Create(outfile, cols2, rows2, num_bands, GDT_Float32) gt1[0] += x10 * ratio gt1[3] -= y10 * ratio gt1[1] = gt2[1] gt1[2] = gt2[2] gt1[4] = gt2[4] gt1[5] = gt2[5] outDataset.SetGeoTransform(tuple(gt1)) projection1 = inDataset1.GetProjection() if projection1 is not None: outDataset.SetProjection(projection1) for k in range(num_bands): outBand = outDataset.GetRasterBand(k + 1) outBand.WriteArray(sharpened[k, :, :], 0, 0) outBand.FlushCache() outDataset = None print 'Result written to %s' % outfile inDataset1 = None inDataset2 = None
def main(): usage = ''' Usage: -------------------------------------------------------- python %s [-p "bandPositions"] [-d "spatialDimensions"] [-t no-change prob threshold] imadFile [fullSceneFile]' -------------------------------------------------------- bandPositions and spatialDimensions are quoted lists, e.g., -p [4,5,6] -d [0,0,400,400] -n stops graphics output SpatialDimensions MUST match those of imadFile spectral dimension of fullSceneFile, if present, MUST match those of target and reference images -------------------------------------------------------- imadFile is of form path/MAD(filebasename1-filebasename2.ext2).ext1 and the output file is named path/filebasename2_norm.ext2. That is, it is assumed that filename1 is reference and filename2 is target and the output retains the format of the target file. A similar convention is used to name the normalized full scene, if present: fullSceneFile_norm.ext Note that, for ENVI format, ext is the empty string. -------------------------------------------------------'''%sys.argv[0] options, args = getopt.getopt(sys.argv[1:],'hnp:d:t:') pos = None dims = None ncpThresh = 0.95 fsfn = None 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 == '-t': ncpThresh = eval(value) if (len(args) != 1) and (len(args) != 2): print 'Incorrect number of arguments' print usage sys.exit(1) imadfn = args[0] if len(args) == 2: fsfn = args[1] path = os.path.dirname(fsfn) basename = os.path.basename(fsfn) root, ext = os.path.splitext(basename) fsoutfn = path+'/'+root+'_norm_all'+ext path = os.path.dirname(imadfn) basename = os.path.basename(imadfn) root, ext = os.path.splitext(basename) b = root.find('(') e = root.find(')') referenceroot, targetbasename = root[b+1:e].split('-') referencefn = path + '/' + referenceroot + ext targetfn = path + '/' + targetbasename targetroot, targetext = os.path.splitext(targetbasename) outfn = path + '/' + targetroot + '_norm' + targetext imadDataset = gdal.Open(imadfn,GA_ReadOnly) try: imadbands = imadDataset.RasterCount cols = imadDataset.RasterXSize rows = imadDataset.RasterYSize except Exception as e: print 'Error: %s --Image could not be read'%e sys.exit(1) referenceDataset = gdal.Open(referencefn,GA_ReadOnly) targetDataset = gdal.Open(targetfn,GA_ReadOnly) if pos is None: pos = range(1,referenceDataset.RasterCount+1) if dims is None: x0 = 0; y0 = 0 else: x0,y0,cols,rows = dims chisqr = imadDataset.GetRasterBand(imadbands).ReadAsArray(0,0,cols,rows).ravel() ncp = 1 - stats.chi2.cdf(chisqr,[imadbands-1]) idx = where(ncp>ncpThresh) print time.asctime() print 'reference: '+referencefn print 'target : '+targetfn print 'no-change probability threshold: '+str(ncpThresh) print 'no-change pixels: '+str(len(idx[0])) start = time.time() driver = targetDataset.GetDriver() outDataset = driver.Create(outfn,cols,rows,len(pos),GDT_Float32) projection = imadDataset.GetProjection() geotransform = imadDataset.GetGeoTransform() if geotransform is not None: outDataset.SetGeoTransform(geotransform) if projection is not None: outDataset.SetProjection(projection) aa = [] bb = [] if graphics: plt.figure(1,(9,6)) j = 1 bands = len(pos) for k in pos: x = referenceDataset.GetRasterBand(k).ReadAsArray(x0,y0,cols,rows).astype(float).ravel() y = targetDataset.GetRasterBand(k).ReadAsArray(x0,y0,cols,rows).astype(float).ravel() b,a,R = orthoregress(y[idx],x[idx]) print 'band: %i slope: %f intercept: %f correlation: %f'%(k,b,a,R) my = max(y[idx]) if (j<7) and graphics: plt.subplot(2,3,j) plt.plot(y[idx],x[idx],'.') plt.plot([0,my],[a,a+b*my]) plt.title('Band %i'%k) if ((j<4) and (bands<4)) or j>3: plt.xlabel('Target') if (j==1) or (j==4): plt.ylabel('Reference') aa.append(a) bb.append(b) outBand = outDataset.GetRasterBand(j) outBand.WriteArray(resize(a+b*y,(rows,cols)),0,0) outBand.FlushCache() j += 1 if graphics: plt.show() plt.close() referenceDataset = None targetDataset = None outDataset = None print 'result written to: '+outfn if fsfn is not None: print 'normalizing '+fsfn+'...' fsDataset = gdal.Open(fsfn,GA_ReadOnly) try: cols = fsDataset.RasterXSize rows = fsDataset.RasterYSize except Exception as e: print 'Error %s -- Image could not be read in' sys.exit(1) driver = fsDataset.GetDriver() outDataset = driver.Create(fsoutfn,cols,rows,len(pos),GDT_Float32) projection = fsDataset.GetProjection() geotransform = fsDataset.GetGeoTransform() if geotransform is not None: outDataset.SetGeoTransform(geotransform) if projection is not None: outDataset.SetProjection(projection) j = 1 for k in pos: inBand = fsDataset.GetRasterBand(k) outBand = outDataset.GetRasterBand(j) for i in range(rows): y = inBand.ReadAsArray(0,i,cols,1) outBand.WriteArray(aa[j-1]+bb[j-1]*y,0,i) outBand.FlushCache() j += 1 outDataset = None fsDataset = None print 'full result written to: '+fsoutfn print 'elapsed time: %s'%str(time.time()-start)
def main(): gdal.AllRegister() path = auxil.select_directory('Choose working directory') if path: os.chdir(path) # MS image file1 = auxil.select_infile(title='Choose MS 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 num_bands = len(pos1) dims = auxil.select_dims([0, 0, cols, rows]) if dims: x10, y10, cols1, rows1 = dims else: return # PAN image file2 = auxil.select_infile(title='Choose PAN image') if file2: inDataset2 = gdal.Open(file2, GA_ReadOnly) bands = inDataset2.RasterCount else: return if bands > 1: print 'Must be a single band (panchromatic) image' return geotransform1 = inDataset1.GetGeoTransform() geotransform2 = inDataset2.GetGeoTransform() # outfile outfile, fmt = auxil.select_outfilefmt() if not outfile: return # resolution ratio ratio = auxil.select_integer(4, 'Resolution ratio (2 or 4)') if not ratio: return # MS registration band k1 = auxil.select_integer(1, 'MS band for registration') if not k1: return # fine adjust roll = auxil.select_integer(0, 'Fine adjust (-2 ... 2)') if roll is None: return print '=========================' print ' DWT Pansharpening' print '=========================' print time.asctime() print 'MS file: ' + file1 print 'PAN file: ' + file2 # image arrays band = inDataset1.GetRasterBand(1) tmp = band.ReadAsArray(0, 0, 1, 1) dt = tmp.dtype MS = np.asarray(np.zeros((num_bands, rows1, cols1)), dtype=dt) k = 0 for b in pos1: band = inDataset1.GetRasterBand(b) MS[k, :, :] = band.ReadAsArray(x10, y10, cols1, rows1) k += 1 # if integer assume 11bit quantization otherwise must be byte if MS.dtype == np.int16: fact = 8.0 MS = auxil.byteStretch(MS, (0, 2**11)) else: fact = 1.0 # read in corresponding spatial subset of PAN image if (geotransform1 is None) or (geotransform2 is None): print 'Image not georeferenced, aborting' return # upper left corner pixel in PAN gt1 = list(geotransform1) gt2 = list(geotransform2) ulx1 = gt1[0] + x10 * gt1[1] uly1 = gt1[3] + y10 * gt1[5] x20 = int(round(((ulx1 - gt2[0]) / gt2[1]))) y20 = int(round(((uly1 - gt2[3]) / gt2[5]))) cols2 = cols1 * ratio rows2 = rows1 * ratio band = inDataset2.GetRasterBand(1) PAN = band.ReadAsArray(x20, y20, cols2, rows2) # if integer assume 11-bit quantization, otherwise must be byte if PAN.dtype == np.int16: PAN = auxil.byteStretch(PAN, (0, 2**11)) # compress PAN to resolution of MS image panDWT = auxil.DWTArray(PAN, cols2, rows2) r = ratio while r > 1: panDWT.filter() r /= 2 bn0 = panDWT.get_quadrant(0) lines0, samples0 = bn0.shape bn1 = MS[k1 - 1, :, :] # register (and subset) MS image to compressed PAN image (scale, angle, shift) = auxil.similarity(bn0, bn1) tmp = np.zeros((num_bands, lines0, samples0)) for k in range(num_bands): bn1 = MS[k, :, :] bn2 = ndii.zoom(bn1, 1.0 / scale) bn2 = ndii.rotate(bn2, angle) bn2 = ndii.shift(bn2, shift) tmp[k, :, :] = bn2[0:lines0, 0:samples0] MS = tmp if roll != 0: # fine adjust PAN = np.roll(PAN, roll, axis=0) PAN = np.roll(PAN, roll, axis=1) panDWT = auxil.DWTArray(PAN, cols2, rows2) r = ratio while r > 1: panDWT.filter() r /= 2 # compress pan once more, extract wavelet quadrants, and restore panDWT.filter() fgpan = panDWT.get_quadrant(1) gfpan = panDWT.get_quadrant(2) ggpan = panDWT.get_quadrant(3) panDWT.invert() # output array sharpened = np.zeros((num_bands, rows2, cols2), dtype=np.float32) aa = np.zeros(3) bb = np.zeros(3) print 'Wavelet correlations:' for i in range(num_bands): # make copy of panDWT and inject ith ms band msDWT = copy.deepcopy(panDWT) msDWT.put_quadrant(MS[i, :, :], 0) # compress once more msDWT.filter() # determine wavelet normalization coefficents ms = msDWT.get_quadrant(1) aa[0], bb[0], R = auxil.orthoregress(fgpan.ravel(), ms.ravel()) Rs = 'Band ' + str(i + 1) + ': %8.3f' % R ms = msDWT.get_quadrant(2) aa[1], bb[1], R = auxil.orthoregress(gfpan.ravel(), ms.ravel()) Rs += '%8.3f' % R ms = msDWT.get_quadrant(3) aa[2], bb[2], R = auxil.orthoregress(ggpan.ravel(), ms.ravel()) Rs += '%8.3f' % R print Rs # restore once and normalize wavelet coefficients msDWT.invert() msDWT.normalize(aa, bb) # restore completely and collect result r = 1 while r < ratio: msDWT.invert() r *= 2 sharpened[i, :, :] = msDWT.get_quadrant(0) sharpened *= fact # write to disk driver = gdal.GetDriverByName(fmt) outDataset = driver.Create(outfile, cols2, rows2, num_bands, GDT_Float32) projection1 = inDataset1.GetProjection() if projection1 is not None: outDataset.SetProjection(projection1) gt1 = list(geotransform1) gt1[0] += x10 * ratio gt1[3] -= y10 * ratio gt1[1] = gt2[1] gt1[2] = gt2[2] gt1[4] = gt2[4] gt1[5] = gt2[5] outDataset.SetGeoTransform(tuple(gt1)) for k in range(num_bands): outBand = outDataset.GetRasterBand(k + 1) outBand.WriteArray(sharpened[k, :, :], 0, 0) outBand.FlushCache() outDataset = None print 'Result written to %s' % outfile inDataset1 = None inDataset2 = None
def main(): usage = ''' Usage: ----------------------------------------------------------------------- python %s [-d spatialDimensions] [-p bandPositions [-r resolution ratio] [-b registration band] msfilename panfilename ----------------------------------------------------------------------- bandPositions and spatialDimensions are lists, e.g., -p [1,2,3] -d [0,0,400,400] Outfile name is msfilename_pan with same format as msfilename -----------------------------------------------------''' %sys.argv[0] options, args = getopt.getopt(sys.argv[1:],'hd:p:r:b:') ratio = 4 dims1 = None pos1 = None k1 = 1 for option, value in options: if option == '-h': print usage return elif option == '-r': ratio = eval(value) elif option == '-d': dims1 = eval(value) elif option == '-p': pos1 = eval(value) elif option == '-b': k1 = eval(value) if len(args) != 2: print 'Incorrect number of arguments' print usage sys.exit(1) gdal.AllRegister() file1 = args[0] file2 = args[1] path = os.path.dirname(file1) basename1 = os.path.basename(file1) root1, ext1 = os.path.splitext(basename1) outfile = '%s/%s_pan%s'%(path,root1,ext1) # MS image inDataset1 = gdal.Open(file1,GA_ReadOnly) try: cols = inDataset1.RasterXSize rows = inDataset1.RasterYSize bands = inDataset1.RasterCount except Exception as e: print 'Error: %e --Image could not be read'%e sys.exit(1) if pos1 is None: pos1 = range(1,bands+1) num_bands = len(pos1) if dims1 is None: dims1 = [0,0,cols,rows] x10,y10,cols1,rows1 = dims1 # PAN image inDataset2 = gdal.Open(file2,GA_ReadOnly) try: bands = inDataset2.RasterCount except Exception as e: print 'Error: %e --Image could not be read'%e sys.exit(1) if bands>1: print 'PAN image must be a single band' sys.exit(1) geotransform1 = inDataset1.GetGeoTransform() geotransform2 = inDataset2.GetGeoTransform() if (geotransform1 is None) or (geotransform2 is None): print 'Image not georeferenced, aborting' sys.exit(1) print '=========================' print ' ATWT Pansharpening' print '=========================' print time.asctime() print 'MS file: '+file1 print 'PAN file: '+file2 # read in MS image band = inDataset1.GetRasterBand(1) tmp = band.ReadAsArray(0,0,1,1) dt = tmp.dtype MS = np.asarray(np.zeros((num_bands,rows1,cols1)),dtype = dt) k = 0 for b in pos1: band = inDataset1.GetRasterBand(b) MS[k,:,:] = band.ReadAsArray(x10,y10,cols1,rows1) k += 1 # if integer assume 11-bit quantization, otherwise must be byte if MS.dtype == np.int16: fact = 8.0 MS = auxil.byteStretch(MS,(0,2**11)) else: fact = 1.0 # read in corresponding spatial subset of PAN image gt1 = list(geotransform1) gt2 = list(geotransform2) ulx1 = gt1[0] + x10*gt1[1] uly1 = gt1[3] + y10*gt1[5] x20 = int(round(((ulx1 - gt2[0])/gt2[1]))) y20 = int(round(((uly1 - gt2[3])/gt2[5]))) cols2 = cols1*ratio rows2 = rows1*ratio band = inDataset2.GetRasterBand(1) PAN = band.ReadAsArray(x20,y20,cols2,rows2) # if integer assume 11-bit quantization, otherwise must be byte if PAN.dtype == np.int16: PAN = auxil.byteStretch(PAN,(0,2**11)) # out array sharpened = np.zeros((num_bands,rows2,cols2),dtype=np.float32) # compress PAN to resolution of MS image using DWT panDWT = auxil.DWTArray(PAN,cols2,rows2) r = ratio while r > 1: panDWT.filter() r /= 2 bn0 = panDWT.get_quadrant(0) # register (and subset) MS image to compressed PAN image using selected MSband lines0,samples0 = bn0.shape bn1 = MS[k1-1,:,:] # register (and subset) MS image to compressed PAN image (scale,angle,shift) = auxil.similarity(bn0,bn1) tmp = np.zeros((num_bands,lines0,samples0)) for k in range(num_bands): bn1 = MS[k,:,:] bn2 = ndii.zoom(bn1, 1.0/scale) bn2 = ndii.rotate(bn2, angle) bn2 = ndii.shift(bn2, shift) tmp[k,:,:] = bn2[0:lines0,0:samples0] MS = tmp smpl = np.random.randint(cols2*rows2,size=100000) print 'Wavelet correlations:' # loop over MS bands for k in range(num_bands): msATWT = auxil.ATWTArray(PAN) r = ratio while r > 1: msATWT.filter() r /= 2 # sample PAN wavelet details X = msATWT.get_band(msATWT.num_iter) X = X.ravel()[smpl] # resize the ms band to scale of the pan image ms_band = ndii.zoom(MS[k,:,:],ratio) # sample details of MS band tmpATWT = auxil.ATWTArray(ms_band) r = ratio while r > 1: tmpATWT.filter() r /= 2 Y = tmpATWT.get_band(msATWT.num_iter) Y = Y.ravel()[smpl] # get band for injection bnd = tmpATWT.get_band(0) tmpATWT = None aa,bb,R = auxil.orthoregress(X,Y) print 'Band '+str(k+1)+': %8.3f'%R # inject the filtered MS band msATWT.inject(bnd) # normalize wavelet components and expand msATWT.normalize(aa,bb) r = ratio while r > 1: msATWT.invert() r /= 2 sharpened[k,:,:] = msATWT.get_band(0) sharpened *= fact # rescale dynamic range msATWT = None # write to disk driver = inDataset1.GetDriver() outDataset = driver.Create(outfile,cols2,rows2,num_bands,GDT_Float32) gt1[0] += x10*ratio gt1[3] -= y10*ratio gt1[1] = gt2[1] gt1[2] = gt2[2] gt1[4] = gt2[4] gt1[5] = gt2[5] outDataset.SetGeoTransform(tuple(gt1)) projection1 = inDataset1.GetProjection() if projection1 is not None: outDataset.SetProjection(projection1) for k in range(num_bands): outBand = outDataset.GetRasterBand(k+1) outBand.WriteArray(sharpened[k,:,:],0,0) outBand.FlushCache() outDataset = None print 'Result written to %s'%outfile inDataset1 = None inDataset2 = None
def main(): gdal.AllRegister() path = auxil.select_directory('Choose working directory') if path: os.chdir(path) # MS image file1 = auxil.select_infile(title='Choose MS 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 num_bands = len(pos1) dims = auxil.select_dims([0,0,cols,rows]) if dims: x10,y10,cols1,rows1 = dims else: return # PAN image file2 = auxil.select_infile(title='Choose PAN image') if file2: inDataset2 = gdal.Open(file2,GA_ReadOnly) bands = inDataset2.RasterCount else: return if bands>1: print 'Must be a single band (panchromatic) image' return geotransform1 = inDataset1.GetGeoTransform() geotransform2 = inDataset2.GetGeoTransform() # outfile outfile, fmt = auxil.select_outfilefmt() if not outfile: return # resolution ratio ratio = auxil.select_integer(4, 'Resolution ratio (2 or 4)') if not ratio: return # MS registration band k1 = auxil.select_integer(1, 'MS band for registration') if not k1: return # fine adjust roll = auxil.select_integer(0, 'Fine adjust (-2 ... 2)') if roll is None: return print '=========================' print ' DWT Pansharpening' print '=========================' print time.asctime() print 'MS file: '+file1 print 'PAN file: '+file2 # image arrays band = inDataset1.GetRasterBand(1) tmp = band.ReadAsArray(0,0,1,1) dt = tmp.dtype MS = np.asarray(np.zeros((num_bands,rows1,cols1)),dtype=dt) k = 0 for b in pos1: band = inDataset1.GetRasterBand(b) MS[k,:,:] = band.ReadAsArray(x10,y10,cols1,rows1) k += 1 # if integer assume 11bit quantization otherwise must be byte if MS.dtype == np.int16: fact = 8.0 MS = auxil.byteStretch(MS,(0,2**11)) else: fact = 1.0 # read in corresponding spatial subset of PAN image if (geotransform1 is None) or (geotransform2 is None): print 'Image not georeferenced, aborting' return # upper left corner pixel in PAN gt1 = list(geotransform1) gt2 = list(geotransform2) ulx1 = gt1[0] + x10*gt1[1] uly1 = gt1[3] + y10*gt1[5] x20 = int(round(((ulx1 - gt2[0])/gt2[1]))) y20 = int(round(((uly1 - gt2[3])/gt2[5]))) cols2 = cols1*ratio rows2 = rows1*ratio band = inDataset2.GetRasterBand(1) PAN = band.ReadAsArray(x20,y20,cols2,rows2) # if integer assume 11-bit quantization, otherwise must be byte if PAN.dtype == np.int16: PAN = auxil.byteStretch(PAN,(0,2**11)) # compress PAN to resolution of MS image panDWT = auxil.DWTArray(PAN,cols2,rows2) r = ratio while r > 1: panDWT.filter() r /= 2 bn0 = panDWT.get_quadrant(0) lines0,samples0 = bn0.shape bn1 = MS[k1-1,:,:] # register (and subset) MS image to compressed PAN image (scale,angle,shift) = auxil.similarity(bn0,bn1) tmp = np.zeros((num_bands,lines0,samples0)) for k in range(num_bands): bn1 = MS[k,:,:] bn2 = ndii.zoom(bn1, 1.0/scale) bn2 = ndii.rotate(bn2, angle) bn2 = ndii.shift(bn2, shift) tmp[k,:,:] = bn2[0:lines0,0:samples0] MS = tmp if roll != 0: # fine adjust PAN = np.roll(PAN,roll,axis=0) PAN = np.roll(PAN,roll,axis=1) panDWT = auxil.DWTArray(PAN,cols2,rows2) r = ratio while r > 1: panDWT.filter() r /= 2 # compress pan once more, extract wavelet quadrants, and restore panDWT.filter() fgpan = panDWT.get_quadrant(1) gfpan = panDWT.get_quadrant(2) ggpan = panDWT.get_quadrant(3) panDWT.invert() # output array sharpened = np.zeros((num_bands,rows2,cols2),dtype=np.float32) aa = np.zeros(3) bb = np.zeros(3) print 'Wavelet correlations:' for i in range(num_bands): # make copy of panDWT and inject ith ms band msDWT = copy.deepcopy(panDWT) msDWT.put_quadrant(MS[i,:,:],0) # compress once more msDWT.filter() # determine wavelet normalization coefficents ms = msDWT.get_quadrant(1) aa[0],bb[0],R = auxil.orthoregress(fgpan.ravel(), ms.ravel()) Rs = 'Band '+str(i+1)+': %8.3f'%R ms = msDWT.get_quadrant(2) aa[1],bb[1],R = auxil.orthoregress(gfpan.ravel(), ms.ravel()) Rs += '%8.3f'%R ms = msDWT.get_quadrant(3) aa[2],bb[2],R = auxil.orthoregress(ggpan.ravel(), ms.ravel()) Rs += '%8.3f'%R print Rs # restore once and normalize wavelet coefficients msDWT.invert() msDWT.normalize(aa,bb) # restore completely and collect result r = 1 while r < ratio: msDWT.invert() r *= 2 sharpened[i,:,:] = msDWT.get_quadrant(0) sharpened *= fact # write to disk driver = gdal.GetDriverByName(fmt) outDataset = driver.Create(outfile,cols2,rows2,num_bands,GDT_Float32) projection1 = inDataset1.GetProjection() if projection1 is not None: outDataset.SetProjection(projection1) gt1 = list(geotransform1) gt1[0] += x10*ratio gt1[3] -= y10*ratio gt1[1] = gt2[1] gt1[2] = gt2[2] gt1[4] = gt2[4] gt1[5] = gt2[5] outDataset.SetGeoTransform(tuple(gt1)) for k in range(num_bands): outBand = outDataset.GetRasterBand(k+1) outBand.WriteArray(sharpened[k,:,:],0,0) outBand.FlushCache() outDataset = None print 'Result written to %s'%outfile inDataset1 = None inDataset2 = None
def main(): gdal.AllRegister() path = auxil.select_directory('Choose working directory') if path: os.chdir(path) # reference image file1 = auxil.select_infile(title='Choose reference 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 # target image file2 = auxil.select_infile(title='Choose target 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, cols2, rows2 = dims else: return # match dimensions bands = len(pos2) if (rows1 != rows2) or (cols1 != cols2) or (len(pos1) != bands): sys.stderr.write("Size mismatch") sys.exit(1) # iMAD image file3 = auxil.select_infile(title='Choose iMAD image') if file3: inDataset3 = gdal.Open(file3, GA_ReadOnly) cols = inDataset3.RasterXSize rows = inDataset3.RasterYSize imadbands = inDataset3.RasterCount else: return dims = auxil.select_dims([0, 0, cols, rows]) if dims: x30, y30, cols, rows = dims else: return if (rows1 != rows) or (cols1 != cols): sys.stderr.write("Size mismatch") sys.exit(1) # outfile outfile, fmt = auxil.select_outfilefmt() if not outfile: return # full scene fsfile = auxil.select_infile(title='Choose full target scene if desired') # no-change threshold ncpThresh = auxil.select_ncp(0.95) if ncpThresh is None: return chisqr = inDataset3.GetRasterBand(imadbands).ReadAsArray( x30, y30, cols, rows).ravel() ncp = 1 - stats.chi2.cdf(chisqr, [imadbands - 1]) idx = np.where(ncp > ncpThresh)[0] # split train/test in ratio 2:1 tmp = np.asarray(range(len(idx))) tst = idx[np.where(np.mod(tmp, 3) == 0)] trn = idx[np.where(np.mod(tmp, 3) > 0)] print '=========================================' print ' RADCAL' print '=========================================' print time.asctime() print 'reference: ' + file1 print 'target : ' + file2 print 'no-change probability threshold: ' + str(ncpThresh) print 'no-change pixels (train): ' + str(len(trn)) print 'no-change pixels (test): ' + str(len(tst)) driver = gdal.GetDriverByName(fmt) outDataset = driver.Create(outfile, cols, rows, bands, 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) aa = [] bb = [] i = 1 for k in pos1: x = inDataset1.GetRasterBand(k).ReadAsArray( x10, y10, cols, rows).astype(float).ravel() y = inDataset2.GetRasterBand(k).ReadAsArray( x20, y20, cols, rows).astype(float).ravel() b, a, R = auxil.orthoregress(y[trn], x[trn]) print '--------------------' print 'spectral band: ', k print 'slope: ', b print 'intercept: ', a print 'correlation: ', R print 'means(tgt,ref,nrm): ', np.mean(y[tst]), np.mean( x[tst]), np.mean(a + b * y[tst]) print 't-test, p-value: ', stats.ttest_rel(x[tst], a + b * y[tst]) print 'vars(tgt,ref,nrm) ', np.var(y[tst]), np.var( x[tst]), np.var(a + b * y[tst]) print 'F-test, p-value: ', auxil.fv_test(x[tst], a + b * y[tst]) aa.append(a) bb.append(b) outBand = outDataset.GetRasterBand(i) outBand.WriteArray(np.resize(a + b * y, (rows, cols)), 0, 0) outBand.FlushCache() if i <= 10: plt.figure(i) ymax = max(y[idx]) xmax = max(x[idx]) plt.plot(y[idx], x[idx], 'k.', [0, ymax], [a, a + b * ymax], 'k-') plt.axis([0, ymax, 0, xmax]) plt.title('Band ' + str(k)) plt.xlabel('Target') plt.ylabel('Reference') i += 1 outDataset = None print 'result written to: ' + outfile if fsfile is not None: path = os.path.dirname(fsfile) basename = os.path.basename(fsfile) root, ext = os.path.splitext(basename) fsoutfile = path + '/' + root + '_norm' + ext print 'normalizing ' + fsfile + '...' fsDataset = gdal.Open(fsfile, GA_ReadOnly) cols = fsDataset.RasterXSize rows = fsDataset.RasterYSize driver = fsDataset.GetDriver() outDataset = driver.Create(fsoutfile, cols, rows, bands, GDT_Float32) projection = fsDataset.GetProjection() geotransform = fsDataset.GetGeoTransform() if geotransform is not None: outDataset.SetGeoTransform(geotransform) if projection is not None: outDataset.SetProjection(projection) j = 0 for k in pos2: inBand = fsDataset.GetRasterBand(k) outBand = outDataset.GetRasterBand(j + 1) for i in range(rows): y = inBand.ReadAsArray(0, i, cols, 1) outBand.WriteArray(aa[j] + bb[j] * y, 0, i) outBand.FlushCache() j += 1 outDataset = None print 'result written to: ' + fsoutfile plt.show() print '-------done-----------------------------'
def main(): usage = ''' Usage: ----------------------------------------------------------------------- python %s [-d spatialDimensions] [-p bandPositions [-r resolution ratio] [-b registration band] msfilename panfilename ----------------------------------------------------------------------- bandPositions and spatialDimensions are lists, e.g., -p [1,2,3] -d [0,0,400,400] Outfile name is msfilename_pan with same format as msfilename -----------------------------------------------------''' %sys.argv[0] options, args = getopt.getopt(sys.argv[1:],'hd:p:r:b:') ratio = 4 dims1 = None pos1 = None k1 = 1 for option, value in options: if option == '-h': print usage return elif option == '-r': ratio = eval(value) elif option == '-d': dims1 = eval(value) elif option == '-p': pos1 = eval(value) elif option == '-b': k1 = eval(value) if len(args) != 2: print 'Incorrect number of arguments' print usage sys.exit(1) gdal.AllRegister() file1 = args[0] file2 = args[1] path = os.path.dirname(file1) basename1 = os.path.basename(file1) root1, ext1 = os.path.splitext(basename1) outfile = '%s/%s_pan%s'%(path,root1,ext1) # MS image inDataset1 = gdal.Open(file1,GA_ReadOnly) try: cols = inDataset1.RasterXSize rows = inDataset1.RasterYSize bands = inDataset1.RasterCount except Exception as e: print 'Error: %e --Image could not be read'%e sys.exit(1) if pos1 is None: pos1 = range(1,bands+1) num_bands = len(pos1) if dims1 is None: dims1 = [0,0,cols,rows] x10,y10,cols1,rows1 = dims1 # PAN image inDataset2 = gdal.Open(file2,GA_ReadOnly) try: bands = inDataset2.RasterCount except Exception as e: print 'Error: %e --Image could not be read'%e sys.exit(1) if bands>1: print 'PAN image must be a single band' sys.exit(1) geotransform1 = inDataset1.GetGeoTransform() geotransform2 = inDataset2.GetGeoTransform() if (geotransform1 is None) or (geotransform2 is None): print 'Image not georeferenced, aborting' sys.exit(1) print '=========================' print ' DWT Pansharpening' print '=========================' print time.asctime() print 'MS file: '+file1 print 'PAN file: '+file2 # image arrays band = inDataset1.GetRasterBand(1) tmp = band.ReadAsArray(0,0,1,1) dt = tmp.dtype MS = np.asarray(np.zeros((num_bands,rows1,cols1)),dtype=dt) k = 0 for b in pos1: band = inDataset1.GetRasterBand(b) MS[k,:,:] = band.ReadAsArray(x10,y10,cols1,rows1) k += 1 # if integer assume 11bit quantization otherwise must be byte if MS.dtype == np.int16: fact = 8.0 MS = auxil.byteStretch(MS,(0,2**11)) else: fact = 1.0 # read in corresponding spatial subset of PAN image if (geotransform1 is None) or (geotransform2 is None): print 'Image not georeferenced, aborting' return # upper left corner pixel in PAN gt1 = list(geotransform1) gt2 = list(geotransform2) ulx1 = gt1[0] + x10*gt1[1] uly1 = gt1[3] + y10*gt1[5] x20 = int(round(((ulx1 - gt2[0])/gt2[1]))) y20 = int(round(((uly1 - gt2[3])/gt2[5]))) cols2 = cols1*ratio rows2 = rows1*ratio band = inDataset2.GetRasterBand(1) PAN = band.ReadAsArray(x20,y20,cols2,rows2) # if integer assume 11-bit quantization, otherwise must be byte if PAN.dtype == np.int16: PAN = auxil.byteStretch(PAN,(0,2**11)) # compress PAN to resolution of MS image panDWT = auxil.DWTArray(PAN,cols2,rows2) r = ratio while r > 1: panDWT.filter() r /= 2 bn0 = panDWT.get_quadrant(0) lines0,samples0 = bn0.shape bn1 = MS[k1,:,:] # register (and subset) MS image to compressed PAN image (scale,angle,shift) = auxil.similarity(bn0,bn1) tmp = np.zeros((num_bands,lines0,samples0)) for k in range(num_bands): bn1 = MS[k,:,:] bn2 = ndii.zoom(bn1, 1.0/scale) bn2 = ndii.rotate(bn2, angle) bn2 = ndii.shift(bn2, shift) tmp[k,:,:] = bn2[0:lines0,0:samples0] MS = tmp # compress pan once more, extract wavelet quadrants, and restore panDWT.filter() fgpan = panDWT.get_quadrant(1) gfpan = panDWT.get_quadrant(2) ggpan = panDWT.get_quadrant(3) panDWT.invert() # output array sharpened = np.zeros((num_bands,rows2,cols2),dtype=np.float32) aa = np.zeros(3) bb = np.zeros(3) print 'Wavelet correlations:' for i in range(num_bands): # make copy of panDWT and inject ith ms band msDWT = copy.deepcopy(panDWT) msDWT.put_quadrant(MS[i,:,:],0) # compress once more msDWT.filter() # determine wavelet normalization coefficents ms = msDWT.get_quadrant(1) aa[0],bb[0],R = auxil.orthoregress(fgpan.ravel(), ms.ravel()) Rs = 'Band '+str(i+1)+': %8.3f'%R ms = msDWT.get_quadrant(2) aa[1],bb[1],R = auxil.orthoregress(gfpan.ravel(), ms.ravel()) Rs += '%8.3f'%R ms = msDWT.get_quadrant(3) aa[2],bb[2],R = auxil.orthoregress(ggpan.ravel(), ms.ravel()) Rs += '%8.3f'%R print Rs # restore once and normalize wavelet coefficients msDWT.invert() msDWT.normalize(aa,bb) # restore completely and collect result r = 1 while r < ratio: msDWT.invert() r *= 2 sharpened[i,:,:] = msDWT.get_quadrant(0) sharpened *= fact # write to disk driver = inDataset1.GetDriver() outDataset = driver.Create(outfile,cols2,rows2,num_bands,GDT_Float32) projection1 = inDataset1.GetProjection() if projection1 is not None: outDataset.SetProjection(projection1) gt1 = list(geotransform1) gt1[0] += x10*ratio gt1[3] -= y10*ratio gt1[1] = gt2[1] gt1[2] = gt2[2] gt1[4] = gt2[4] gt1[5] = gt2[5] outDataset.SetGeoTransform(tuple(gt1)) for k in range(num_bands): outBand = outDataset.GetRasterBand(k+1) outBand.WriteArray(sharpened[k,:,:],0,0) outBand.FlushCache() outDataset = None print 'Result written to %s'%outfile inDataset1 = None inDataset2 = None
def main(): gdal.AllRegister() path = auxil.select_directory('Choose working directory') if path: os.chdir(path) # reference image file1 = auxil.select_infile(title='Choose reference 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 # target image file2 = auxil.select_infile(title='Choose target 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,cols2,rows2 = dims else: return # match dimensions bands = len(pos2) if (rows1 != rows2) or (cols1 != cols2) or (len(pos1) != bands): sys.stderr.write("Size mismatch") sys.exit(1) # iMAD image file3 = auxil.select_infile(title='Choose iMAD image') if file3: inDataset3 = gdal.Open(file3,GA_ReadOnly) cols = inDataset3.RasterXSize rows = inDataset3.RasterYSize imadbands = inDataset3.RasterCount else: return dims=auxil.select_dims([0,0,cols,rows]) if dims: x30,y30,cols,rows = dims else: return if (rows1 != rows) or (cols1 != cols): sys.stderr.write("Size mismatch") sys.exit(1) # outfile outfile, fmt = auxil.select_outfilefmt() if not outfile: return # full scene fsfile = auxil.select_infile(title='Choose full target scene if desired') # no-change threshold ncpThresh = auxil.select_ncp(0.95) if ncpThresh is None: return chisqr = inDataset3.GetRasterBand(imadbands).ReadAsArray(x30,y30,cols,rows).ravel() ncp = 1 - stats.chi2.cdf(chisqr,[imadbands-1]) idx = np.where(ncp>ncpThresh)[0] # split train/test in ratio 2:1 tmp = np.asarray(range(len(idx))) tst = idx[np.where(np.mod(tmp,3) == 0)] trn = idx[np.where(np.mod(tmp,3) > 0)] print '=========================================' print ' RADCAL' print '=========================================' print time.asctime() print 'reference: '+file1 print 'target : '+file2 print 'no-change probability threshold: '+str(ncpThresh) print 'no-change pixels (train): '+str(len(trn)) print 'no-change pixels (test): '+str(len(tst)) driver = gdal.GetDriverByName(fmt) outDataset = driver.Create(outfile,cols,rows,bands,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) aa = [] bb = [] i = 1 for k in pos1: x = inDataset1.GetRasterBand(k).ReadAsArray(x10,y10,cols,rows).astype(float).ravel() y = inDataset2.GetRasterBand(k).ReadAsArray(x20,y20,cols,rows).astype(float).ravel() b,a,R = auxil.orthoregress(y[trn],x[trn]) print '--------------------' print 'spectral band: ', k print 'slope: ', b print 'intercept: ', a print 'correlation: ', R print 'means(tgt,ref,nrm): ', np.mean(y[tst]),np.mean(x[tst]),np.mean(a+b*y[tst]) print 't-test, p-value: ', stats.ttest_rel(x[tst], a+b*y[tst]) print 'vars(tgt,ref,nrm) ', np.var(y[tst]),np.var(x[tst]),np.var(a+b*y[tst]) print 'F-test, p-value: ', auxil.fv_test(x[tst], a+b*y[tst]) aa.append(a) bb.append(b) outBand = outDataset.GetRasterBand(i) outBand.WriteArray(np.resize(a+b*y,(rows,cols)),0,0) outBand.FlushCache() if i <= 10: plt.figure(i) ymax = max(y[idx]) xmax = max(x[idx]) plt.plot(y[idx],x[idx],'k.',[0,ymax],[a,a+b*ymax],'k-') plt.axis([0,ymax,0,xmax]) plt.title('Band '+str(k)) plt.xlabel('Target') plt.ylabel('Reference') i += 1 outDataset = None print 'result written to: '+outfile if fsfile is not None: path = os.path.dirname(fsfile) basename = os.path.basename(fsfile) root, ext = os.path.splitext(basename) fsoutfile = path+'/'+root+'_norm'+ext print 'normalizing '+fsfile+'...' fsDataset = gdal.Open(fsfile,GA_ReadOnly) cols = fsDataset.RasterXSize rows = fsDataset.RasterYSize driver = fsDataset.GetDriver() outDataset = driver.Create(fsoutfile,cols,rows,bands,GDT_Float32) projection = fsDataset.GetProjection() geotransform = fsDataset.GetGeoTransform() if geotransform is not None: outDataset.SetGeoTransform(geotransform) if projection is not None: outDataset.SetProjection(projection) j = 0 for k in pos2: inBand = fsDataset.GetRasterBand(k) outBand = outDataset.GetRasterBand(j+1) for i in range(rows): y = inBand.ReadAsArray(0,i,cols,1) outBand.WriteArray(aa[j]+bb[j]*y,0,i) outBand.FlushCache() j += 1 outDataset = None print 'result written to: '+fsoutfile plt.show() print '-------done-----------------------------'
def main(): usage = ''' Usage: ----------------------------------------------------------------------- python %s [-d spatialDimensions] [-p bandPositions [-r resolution ratio] [-b registration band] msfilename panfilename ----------------------------------------------------------------------- bandPositions and spatialDimensions are lists, e.g., -p [1,2,3] -d [0,0,400,400] Outfile name is msfilename_pan with same format as msfilename -----------------------------------------------------''' % sys.argv[0] options, args = getopt.getopt(sys.argv[1:], 'hd:p:r:b:') ratio = 4 dims1 = None pos1 = None k1 = 1 for option, value in options: if option == '-h': print usage return elif option == '-r': ratio = eval(value) elif option == '-d': dims1 = eval(value) elif option == '-p': pos1 = eval(value) elif option == '-b': k1 = eval(value) if len(args) != 2: print 'Incorrect number of arguments' print usage sys.exit(1) gdal.AllRegister() file1 = args[0] file2 = args[1] path = os.path.dirname(file1) basename1 = os.path.basename(file1) root1, ext1 = os.path.splitext(basename1) outfile = '%s/%s_pan%s' % (path, root1, ext1) # MS image inDataset1 = gdal.Open(file1, GA_ReadOnly) try: cols = inDataset1.RasterXSize rows = inDataset1.RasterYSize bands = inDataset1.RasterCount except Exception as e: print 'Error: %e --Image could not be read' % e sys.exit(1) if pos1 is None: pos1 = range(1, bands + 1) num_bands = len(pos1) if dims1 is None: dims1 = [0, 0, cols, rows] x10, y10, cols1, rows1 = dims1 # PAN image inDataset2 = gdal.Open(file2, GA_ReadOnly) try: bands = inDataset2.RasterCount except Exception as e: print 'Error: %e --Image could not be read' % e sys.exit(1) if bands > 1: print 'PAN image must be a single band' sys.exit(1) geotransform1 = inDataset1.GetGeoTransform() geotransform2 = inDataset2.GetGeoTransform() if (geotransform1 is None) or (geotransform2 is None): print 'Image not georeferenced, aborting' sys.exit(1) print '=========================' print ' DWT Pansharpening' print '=========================' print time.asctime() print 'MS file: ' + file1 print 'PAN file: ' + file2 # image arrays band = inDataset1.GetRasterBand(1) tmp = band.ReadAsArray(0, 0, 1, 1) dt = tmp.dtype MS = np.asarray(np.zeros((num_bands, rows1, cols1)), dtype=dt) k = 0 for b in pos1: band = inDataset1.GetRasterBand(b) MS[k, :, :] = band.ReadAsArray(x10, y10, cols1, rows1) k += 1 # if integer assume 11bit quantization otherwise must be byte if MS.dtype == np.int16: fact = 8.0 MS = auxil.byteStretch(MS, (0, 2**11)) else: fact = 1.0 # read in corresponding spatial subset of PAN image if (geotransform1 is None) or (geotransform2 is None): print 'Image not georeferenced, aborting' return # upper left corner pixel in PAN gt1 = list(geotransform1) gt2 = list(geotransform2) ulx1 = gt1[0] + x10 * gt1[1] uly1 = gt1[3] + y10 * gt1[5] x20 = int(round(((ulx1 - gt2[0]) / gt2[1]))) y20 = int(round(((uly1 - gt2[3]) / gt2[5]))) cols2 = cols1 * ratio rows2 = rows1 * ratio band = inDataset2.GetRasterBand(1) PAN = band.ReadAsArray(x20, y20, cols2, rows2) # if integer assume 11-bit quantization, otherwise must be byte if PAN.dtype == np.int16: PAN = auxil.byteStretch(PAN, (0, 2**11)) # compress PAN to resolution of MS image panDWT = auxil.DWTArray(PAN, cols2, rows2) r = ratio while r > 1: panDWT.filter() r /= 2 bn0 = panDWT.get_quadrant(0) lines0, samples0 = bn0.shape bn1 = MS[k1, :, :] # register (and subset) MS image to compressed PAN image (scale, angle, shift) = auxil.similarity(bn0, bn1) tmp = np.zeros((num_bands, lines0, samples0)) for k in range(num_bands): bn1 = MS[k, :, :] bn2 = ndii.zoom(bn1, 1.0 / scale) bn2 = ndii.rotate(bn2, angle) bn2 = ndii.shift(bn2, shift) tmp[k, :, :] = bn2[0:lines0, 0:samples0] MS = tmp # compress pan once more, extract wavelet quadrants, and restore panDWT.filter() fgpan = panDWT.get_quadrant(1) gfpan = panDWT.get_quadrant(2) ggpan = panDWT.get_quadrant(3) panDWT.invert() # output array sharpened = np.zeros((num_bands, rows2, cols2), dtype=np.float32) aa = np.zeros(3) bb = np.zeros(3) print 'Wavelet correlations:' for i in range(num_bands): # make copy of panDWT and inject ith ms band msDWT = copy.deepcopy(panDWT) msDWT.put_quadrant(MS[i, :, :], 0) # compress once more msDWT.filter() # determine wavelet normalization coefficents ms = msDWT.get_quadrant(1) aa[0], bb[0], R = auxil.orthoregress(fgpan.ravel(), ms.ravel()) Rs = 'Band ' + str(i + 1) + ': %8.3f' % R ms = msDWT.get_quadrant(2) aa[1], bb[1], R = auxil.orthoregress(gfpan.ravel(), ms.ravel()) Rs += '%8.3f' % R ms = msDWT.get_quadrant(3) aa[2], bb[2], R = auxil.orthoregress(ggpan.ravel(), ms.ravel()) Rs += '%8.3f' % R print Rs # restore once and normalize wavelet coefficients msDWT.invert() msDWT.normalize(aa, bb) # restore completely and collect result r = 1 while r < ratio: msDWT.invert() r *= 2 sharpened[i, :, :] = msDWT.get_quadrant(0) sharpened *= fact # write to disk driver = inDataset1.GetDriver() outDataset = driver.Create(outfile, cols2, rows2, num_bands, GDT_Float32) projection1 = inDataset1.GetProjection() if projection1 is not None: outDataset.SetProjection(projection1) gt1 = list(geotransform1) gt1[0] += x10 * ratio gt1[3] -= y10 * ratio gt1[1] = gt2[1] gt1[2] = gt2[2] gt1[4] = gt2[4] gt1[5] = gt2[5] outDataset.SetGeoTransform(tuple(gt1)) for k in range(num_bands): outBand = outDataset.GetRasterBand(k + 1) outBand.WriteArray(sharpened[k, :, :], 0, 0) outBand.FlushCache() outDataset = None print 'Result written to %s' % outfile inDataset1 = None inDataset2 = None
def main(): gdal.AllRegister() path = auxil.select_directory('Choose working directory') if path: os.chdir(path) # MS image file1 = auxil.select_infile(title='Choose MS 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 num_bands = len(pos1) dims = auxil.select_dims([0,0,cols,rows]) if dims: x10,y10,cols1,rows1 = dims else: return # PAN image file2 = auxil.select_infile(title='Choose PAN image') if file2: inDataset2 = gdal.Open(file2,GA_ReadOnly) cols = inDataset2.RasterXSize rows = inDataset2.RasterYSize bands = inDataset2.RasterCount else: return if bands>1: print 'Must be a single band (panchromatic) image' return dims=auxil.select_dims([0,0,cols,rows]) if dims: x20,y20,cols2,rows2 = dims else: return # outfile outfile, fmt = auxil.select_outfilefmt() if not outfile: return # resolution ratio ratio = auxil.select_integer(4, 'Resolution ratio (2 or 4)') if not ratio: return # MS registration band k1 = auxil.select_integer(1, 'MS band for registration') if not k1: return print '=========================' print ' ATWT Pansharpening' print '=========================' print time.asctime() print 'MS file: '+file1 print 'PAN file: '+file2 # image arrays band = inDataset1.GetRasterBand(1) tmp = band.ReadAsArray(0,0,1,1) dt = tmp.dtype MS = np.asarray(np.zeros((num_bands,rows1,cols1)),dtype = dt) # result will be float32 sharpened = np.zeros((num_bands,rows2,cols2),dtype=np.float32) k = 0 for b in pos1: band = inDataset1.GetRasterBand(b) MS[k,:,:] = band.ReadAsArray(x10,y10,cols1,rows1) k += 1 band = inDataset2.GetRasterBand(1) PAN = band.ReadAsArray(x20,y20,cols2,rows2) # if integer assume 11bit quantization, otherwise must be byte if PAN.dtype == np.int16: PAN = auxil.byteStretch(PAN,(0,2**11)) if MS.dtype == np.int16: MS = auxil.byteStretch(MS,(0,2**11)) # compress PAN to resolution of MS image using DWT panDWT = auxil.DWTArray(PAN,cols2,rows2) r = ratio while r > 1: panDWT.filter() r /= 2 bn0 = panDWT.get_quadrant(0) # register (and subset) MS image to compressed PAN image using MSband lines0,samples0 = bn0.shape bn1 = MS[k1,:,:] # register (and subset) MS image to compressed PAN image (scale,angle,shift) = auxil.similarity(bn0,bn1) tmp = np.zeros((num_bands,lines0,samples0)) for k in range(num_bands): bn1 = MS[k,:,:] bn2 = ndii.zoom(bn1, 1.0/scale) bn2 = ndii.rotate(bn2, angle) bn2 = ndii.shift(bn2, shift) tmp[k,:,:] = bn2[0:lines0,0:samples0] MS = tmp smpl = np.random.randint(cols2*rows2,size=100000) print 'Wavelet correlations:' # loop over MS bands for k in range(num_bands): msATWT = auxil.ATWTArray(PAN) r = ratio while r > 1: msATWT.filter() r /= 2 # sample PAN wavelet details X = msATWT.get_band(msATWT.num_iter) X = X.ravel()[smpl] # resize the ms band to scale of the pan image ms_band = ndii.zoom(MS[k,:,:],ratio) # sample details of MS band tmpATWT = auxil.ATWTArray(ms_band) r = ratio while r > 1: tmpATWT.filter() r /= 2 Y = tmpATWT.get_band(msATWT.num_iter) Y = Y.ravel()[smpl] # get band for injection bnd = tmpATWT.get_band(0) tmpATWT = None aa,bb,R = auxil.orthoregress(X,Y) print 'Band '+str(k+1)+': %8.3f'%R # inject the filtered MS band msATWT.inject(bnd) # normalize wavelet components and expand msATWT.normalize(aa,bb) r = ratio while r > 1: msATWT.invert() r /= 2 sharpened[k,:,:] = msATWT.get_band(0) # write to disk if outfile: driver = gdal.GetDriverByName(fmt) outDataset = driver.Create(outfile, cols2,rows2,num_bands,GDT_Float32) projection1 = inDataset1.GetProjection() geotransform1 = inDataset1.GetGeoTransform() geotransform2 = inDataset2.GetGeoTransform() if geotransform2 is not None: gt2 = list(geotransform2) if geotransform1 is not None: gt1 = list(geotransform1) gt1[0] += x10*gt2[1] # using PAN pixel sizes gt1[3] += y10*gt2[5] gt1[1] = gt2[1] gt1[2] = gt2[2] gt1[4] = gt2[4] gt1[5] = gt2[5] outDataset.SetGeoTransform(tuple(gt1)) if projection1 is not None: outDataset.SetProjection(projection1) for k in range(num_bands): outBand = outDataset.GetRasterBand(k+1) outBand.WriteArray(sharpened[k,:,:],0,0) outBand.FlushCache() outDataset = None print 'Result written to %s'%outfile inDataset1 = None inDataset2 = None
def main(): usage = ''' Usage: -------------------------------------------------------- python %s [-p "bandPositions"] [-d "spatialDimensions"] [-t no-change prob threshold] imadFile [fullSceneFile]' -------------------------------------------------------- bandPositions and spatialDimensions are quoted lists, e.g., -p [4,5,6] -d [0,0,400,400] -n stops graphics output SpatialDimensions MUST match those of imadFile spectral dimension of fullSceneFile, if present, MUST match those of target and reference images -------------------------------------------------------- imadFile is of form path/MAD(filename1-filename2).ext and the output file is named path/filename2_norm.ext. That is, it is assumed that filename1 is reference and filename2 is target and the output retains the format of the imadFile. A similar convention is used to name the normalized full scene, if present: fullSceneFile_norm.ext Note that, for ENVI format, ext is the empty string. -------------------------------------------------------''' % sys.argv[0] options, args = getopt.getopt(sys.argv[1:], 'hnp:d:t:') pos = None dims = None ncpThresh = 0.95 fsfn = None 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 == '-t': ncpThresh = eval(value) if (len(args) != 1) and (len(args) != 2): print 'Incorrect number of arguments' print usage sys.exit(1) imadfn = args[0] if len(args) == 2: fsfn = args[1] path = os.path.dirname(fsfn) basename = os.path.basename(fsfn) root, ext = os.path.splitext(basename) fsoutfn = path + '/' + root + '_norm_all' + ext path = os.path.dirname(imadfn) basename = os.path.basename(imadfn) root, ext = os.path.splitext(basename) b = root.find('(') e = root.find(')') referenceroot, targetbasename = root[b + 1:e].split('-') referencefn = path + '/' + referenceroot + ext targetfn = path + '/' + targetbasename targetroot, targetext = os.path.splitext(targetbasename) outfn = path + '/' + targetroot + '_norm' + targetext imadDataset = gdal.Open(imadfn, GA_ReadOnly) try: imadbands = imadDataset.RasterCount cols = imadDataset.RasterXSize rows = imadDataset.RasterYSize except Exception as e: print 'Error: %s --Image could not be read' % e sys.exit(1) referenceDataset = gdal.Open(referencefn, GA_ReadOnly) targetDataset = gdal.Open(targetfn, GA_ReadOnly) if pos is None: pos = range(1, referenceDataset.RasterCount + 1) if dims is None: x0 = 0 y0 = 0 else: x0, y0, cols, rows = dims chisqr = imadDataset.GetRasterBand(imadbands).ReadAsArray( 0, 0, cols, rows).ravel() ncp = 1 - stats.chi2.cdf(chisqr, [imadbands - 1]) idx = where(ncp > ncpThresh)[0] m = len(idx) idx1 = random.permutation(m) idxall = idx[idx1] idxtrain = idxall[0:2 * m // 3] idxtest = idxall[2 * m // 3:] mtrain = len(idxtrain) mtest = len(idxtest) print time.asctime() print 'reference: ' + referencefn print 'target : ' + targetfn print 'no-change probability threshold: ' + str(ncpThresh) print 'no-change pixels for training: %i, for testing: %i' % (mtrain, mtest) start = time.time() driver = targetDataset.GetDriver() outDataset = driver.Create(outfn, cols, rows, len(pos), GDT_Float32) projection = imadDataset.GetProjection() geotransform = imadDataset.GetGeoTransform() if geotransform is not None: outDataset.SetGeoTransform(geotransform) if projection is not None: outDataset.SetProjection(projection) aa = [] bb = [] if graphics: plt.figure(1, (9, 6)) j = 1 bands = len(pos) for k in pos: x = referenceDataset.GetRasterBand(k).ReadAsArray( x0, y0, cols, rows).astype(float).ravel() y = targetDataset.GetRasterBand(k).ReadAsArray( x0, y0, cols, rows).astype(float).ravel() b, a, R = orthoregress(y[idxtrain], x[idxtrain]) my = max(y[idxtrain]) if (j < 7) and graphics: plt.subplot(2, 3, j) plt.plot(y[idxtrain], x[idxtrain], '.') plt.plot([0, my], [a, a + b * my]) plt.title('Band %i' % k) if ((j < 4) and (bands < 4)) or j > 3: plt.xlabel('Target') if (j == 1) or (j == 4): plt.ylabel('Reference') aa.append(a) bb.append(b) outBand = outDataset.GetRasterBand(j) _, Pt = stats.ttest_ind(x[idxtest], a + b * y[idxtest]) f = var(x[idxtest]) / var(a + b * y[idxtest]) if f < 1.0: f = 1 / f Pf = stats.f.sf(f, mtest - 1, mtest - 1) print 'band: %i slope: %f intercept: %f corr: %f P(t-test): %f P(F-test): %f' % ( k, b, a, R, Pt, Pf) outBand.WriteArray(resize(a + b * y, (rows, cols)), 0, 0) outBand.FlushCache() j += 1 if graphics: plt.show() plt.close() referenceDataset = None targetDataset = None outDataset = None print 'result written to: ' + outfn if fsfn is not None: print 'normalizing ' + fsfn + '...' fsDataset = gdal.Open(fsfn, GA_ReadOnly) try: cols = fsDataset.RasterXSize rows = fsDataset.RasterYSize except Exception as e: print 'Error %s -- Image could not be read in' sys.exit(1) driver = fsDataset.GetDriver() outDataset = driver.Create(fsoutfn, cols, rows, len(pos), GDT_Float32) projection = fsDataset.GetProjection() geotransform = fsDataset.GetGeoTransform() if geotransform is not None: outDataset.SetGeoTransform(geotransform) if projection is not None: outDataset.SetProjection(projection) j = 1 for k in pos: inBand = fsDataset.GetRasterBand(k) outBand = outDataset.GetRasterBand(j) for i in range(rows): y = inBand.ReadAsArray(0, i, cols, 1) outBand.WriteArray(aa[j - 1] + bb[j - 1] * y, 0, i) outBand.FlushCache() j += 1 outDataset = None fsDataset = None print 'full result written to: ' + fsoutfn print 'elapsed time: %s' % str(time.time() - start)