def newBand(geoPicture1, geoPicture2): with RedirectStdStreams(stdout=sys.stderr, stderr=sys.stderr): geoPicture = geoPicture1 imageIndices = {} for zi in numpy.array([1,2]): if zi==2: geoPicture = geoPicture2 imageArray = FloodClassUtils.radianceCorrection(geoPicture) #Need to create a mask of locations where all pixels are nonzero. alphaBand = (geoPicture.picture[:,:,geoPicture.bands.index(geoPicture.bands[0])] > 0) for band in geoPicture.bands[1:]: numpy.logical_and(alphaBand, geoPicture.picture[:,:,geoPicture.bands.index(band)], alphaBand) #Find size of the image array rasterXsize = geoPicture.picture.shape[1] rasterYsize = geoPicture.picture.shape[0] rowIndex, colIndex = numpy.mgrid[0:rasterYsize,0:rasterXsize] #This is an array of the alphaBand offset by 1 in all directions surrounding a pixel. polygons = numpy.dstack((alphaBand[1:-1,1:-1],alphaBand[:-2,1:-1],alphaBand[:-2,2:],alphaBand[1:-1,2:],alphaBand[2:,2:], \ alphaBand[2:,1:-1],alphaBand[2:,:-2],alphaBand[1:-1,:-2],alphaBand[:-2,:-2])) #Polygons will be an array containing "1"s on the border of the image. polygons = numpy.array(numpy.logical_and(polygons.sum(2) > 0,polygons.sum(2) < 9),dtype=int) #The offset array is used to detect the outline polygons = numpy.hstack((numpy.zeros((polygons.shape[0]+2,1)),numpy.vstack((numpy.zeros((polygons.shape[1])),polygons,numpy.zeros((polygons.shape[1])))),numpy.zeros((polygons.shape[0]+2,1)))) #There are too many points to calculate all lat/long. Will calculate some, then interpolate. interpSize = 100j yy, xx = numpy.mgrid[0:(rasterYsize-1):(3*interpSize), 0:(rasterXsize-1):interpSize] yy = yy.reshape(-1,1) xx = xx.reshape(-1,1) yLat = numpy.zeros((yy.size,1)) xLong = numpy.zeros((xx.size,1)) for ij in numpy.arange(yy.size): yLat[ij], xLong[ij] = latLong(geoPicture,xx[ij,0],yy[ij,0]) yLat = scipy.interpolate.griddata( numpy.hstack((xx,yy)), yLat, (colIndex.reshape(-1,1), rowIndex.reshape(-1,1)), method = 'cubic' ) #Use spline interpolation xLong = scipy.interpolate.griddata( numpy.hstack((xx,yy)), xLong, (colIndex.reshape(-1,1), rowIndex.reshape(-1,1)), method = 'cubic' ) #of calculated lat/long points boxLatMin, boxLongMin = latLong(geoPicture,0,rasterYsize-1) boxLatMax, boxLongMax = latLong(geoPicture,rasterXsize-1,0) yLat = yLat.reshape(rasterYsize,rasterXsize) xLong = xLong.reshape(rasterYsize,rasterXsize) imageIndices['image' + str(zi)] = numpy.dstack( (rowIndex, colIndex, yLat, xLong, alphaBand, polygons, imageArray) ) imageIndices['bound' + str(zi)] = [boxLatMin,boxLatMax,boxLongMin,boxLongMax] imageIndices['bands' + str(zi)] = geoPicture.bands #clear some variables from memory imageArray = [] presentBands = [] presentBandsNum = [] alphaBand = [] rowIndex = [] colIndex = [] polygons = [] p1 = [] yy = [] xx = [] yLat = [] xLong = [] boundBox1 = imageIndices['bound1'] boundBox2 = imageIndices['bound2'] #Test whether there is any overlap, if not, don't do anything. crnr1 = int( (boundBox1[0] <= boundBox2[0] < boundBox1[1]) & (boundBox1[2] <= boundBox2[2] < boundBox1[3]) ) crnr2 = int( (boundBox1[0] < boundBox2[1] <= boundBox1[1]) & (boundBox1[2] <= boundBox2[2] < boundBox1[3]) ) crnr3 = int( (boundBox1[0] <= boundBox2[0] < boundBox1[1]) & (boundBox1[2] < boundBox2[3] <= boundBox1[3]) ) crnr4 = int( (boundBox1[0] < boundBox2[1] <= boundBox1[1]) & (boundBox1[2] < boundBox2[3] <= boundBox1[3]) ) chk_crnr = crnr1+crnr2+crnr3+crnr4 if chk_crnr > 0: #Is at least one corner from image two inside of image one polygon1 = imageIndices['image1'] polygon2 = imageIndices['image2'] presentBands1 = imageIndices['bands1'] presentBands2 = imageIndices['bands2'] #Only use bands common to both images for change detection presentBands = [] for pB in presentBands1: if pB in presentBands2: presentBands.append([int(pB.lstrip('B')),int(presentBands1.index(pB)),int(presentBands2.index(pB))]) presentBands = numpy.array(presentBands) polygon1 = numpy.dstack((polygon1[:,:,:6], polygon1[:,:,(6 + presentBands[:,1]) ] )) #Depth 6 is the beginning of the image bands. polygon2 = numpy.dstack((polygon2[:,:,:6], polygon2[:,:,(6 + presentBands[:,2]) ] )) imageIndices = [] presentBands1 = [] presentBands2 = [] presentBands = [] interBand1, pR2, pC2 = interpImage(polygon1,polygon2) interBand2, pR1, pC1 = interpImage(polygon2,polygon1) change_prob, imageArray1, imageArray2 = changeProb(polygon1, polygon2, interBand1,interBand2,2,1) #Find cloud pixels from both images to eliminate from change test nonCloudAddress1 = cloudFilter(imageArray1,[]) nonCloudAddress2 = cloudFilter(imageArray2,nonCloudAddress1) change_prob[change_prob < 0 ] = 0 change_prob[change_prob > 1 ] = 0 change_prob[numpy.arange(change_prob.size)[numpy.array(1-nonCloudAddress2.reshape(-1,),dtype=bool)],:] = 0 interBand = numpy.array(interBand1) #Create a rectangular array into which the parallelogram will be placed imageArrayFinal2 = numpy.zeros((polygon1[:,:,0].shape[0],polygon1[:,:,0].shape[1],3), dtype=numpy.float) for ij in numpy.arange(interBand.shape[0]): imageArrayFinal2[interBand[ij,0],interBand[ij,1],0] = 1 - change_prob[ij] #1 imageArrayFinal2[interBand[ij,0],interBand[ij,1],1] = 1 - change_prob[ij] #1-.5*change_prob[ij] imageArrayFinal2[interBand[ij,0],interBand[ij,1],2] = 1 - change_prob[ij] #1-.75*change_prob[ij] imageArrayFinal2 = imageArrayFinal2 + polygon1[:,:,5].reshape(polygon1[:,:,0].shape[0],polygon1[:,:,0].shape[1],1) for i in numpy.arange(pR2.shape[0]): imageArrayFinal2[pR2[i],pC2[i],0:3] = 1 geoPicture.bands.extend(["CHANGE_BAND"]) geoPicture.picture = numpy.dstack((polygon1[:,:,6:],imageArrayFinal2)) else: sys.stderr.write('These two images do not overlap.') imageArrayFinal2 = numpy.zeros((geoPicture.picture.shape[0],geoPicture.picture.shape[1],3), dtype=numpy.float) geoPicture.bands.extend(["CHANGE_BAND"]) geoPicture.picture = imageArrayFinal2 geoPictureOutput = GeoPictureSerializer.GeoPicture() geoPictureOutput.picture = geoPicture.picture geoPictureOutput.metadata = geoPicture.metadata geoPictureOutput.bands = geoPicture.bands return geoPictureOutput
def main(trainingDirectory, landCoverList, band_list=[], band_weight_list=[]): # If bandList is empty, i.e., no band grouping list was input at command line. A default list, contained in FloodClassUtils.py, # will be used. # Note that if a "band_weight_list" is input, it should correspond with the band_list, and it should be known apriori that # all serialized files input to this code contain the required bands. if band_list == []: band_list = FloodClassUtils.bandList() landCoverTypesListLength = 10 ** 50 landCoverTypes = {} flagTwo = True for landName in landCoverList: flagOne = True fileList = os.listdir(trainingDirectory + "/" + landName) for serialFile in fileList: # read in and deserialize geoPicture = GeoPictureSerializer.deserialize(open(trainingDirectory + "/" + landName + "/" + serialFile)) # do radiance correction on bands geoPicture = FloodClassUtils.radianceCorrection(geoPicture) # find bands common to training set and requested set finalBandList, bandsPresent = FloodClassUtils.commonBand(geoPicture, band_list) # Combine bands geoPicture.picture = FloodClassUtils.bandSynth(geoPicture, finalBandList, band_weight_list) # The band list of common bands are added to the geoPicture to replace the original geoPicture.bands = bandsPresent missingBandList = [] for i in numpy.arange(len(FloodClassUtils.bandList())): missingBandSet = set(FloodClassUtils.bandList()[i]) - set(finalBandList[i]) missingBandList.append(list(missingBandSet)) sys.stderr.write( "\nThe following requested bands are missing from serialized file " + str(serialFile) + ":\n" + str(missingBandList) + "\n" ) # Need to create a mask of locations where all pixels are nonzero. alphaBand = geoPicture.picture[:, :, geoPicture.bands.index(geoPicture.bands[0])] > 0 for band in geoPicture.bands[1:]: numpy.logical_and(alphaBand, geoPicture.picture[:, :, geoPicture.bands.index(band)], alphaBand) # Make bands into 2-d array # Find size of the image array rasterXsize = geoPicture.picture.shape[1] rasterYsize = geoPicture.picture.shape[0] rasterDepth = geoPicture.picture.shape[2] # Reshape all arrays geoPicture.picture = geoPicture.picture.reshape(rasterXsize * rasterYsize, rasterDepth) alphaBand = alphaBand.reshape(rasterXsize * rasterYsize) geoPicture.picture = geoPicture.picture[alphaBand, :] if flagOne == True: landCoverTypes[landName] = geoPicture.picture flagOne = False else: landCoverTypes[landName] = numpy.concatenate((landCoverTypes[landName], geoPicture.picture), axis=0) # Note that the classification digit is tied to the order of the landCoverList, i.e., classification digit = landCoverList_position + 1 landCoverTypes[landName] = numpy.concatenate( ( landCoverTypes[landName], (landCoverList.index(landName) + 1) * numpy.ones((landCoverTypes[landName].shape[0], 1), dtype=int), ), axis=1, ) landCoverTypes[landName] = landCoverTypes[landName][ numpy.random.permutation(landCoverTypes[landName].shape[0]), : ] landCoverTypesListLength = min(landCoverTypes[landName].shape[0], landCoverTypesListLength) if flagTwo == True: sampleLength = numpy.minimum(5000, landCoverTypesListLength) train = landCoverTypes[landName][:sampleLength, :] flagTwo = False else: train = numpy.concatenate((train, landCoverTypes[landName][:sampleLength, :]), axis=0) numpy.savetxt("trainingSet.txt", train, fmt=rasterDepth * "%-12.5f " + "%-d")