Historical Map  1.0
Plugin for automatic extraction of old forest from historical map
 All Classes Namespaces Files Functions Variables
function_dataraster.py
Go to the documentation of this file.
1 """!@brief Manage data (opening/saving raster, get ROI...)"""
2 # -*- coding: utf-8 -*-
3 
4 import scipy as sp
5 from osgeo import gdal
6 
7 def open_data_band(filename):
8  """!@brief The function open and load the image given its name.
9  The function open and load the image given its name.
10  The type of the data is checked from the file and the scipy array is initialized accordingly.
11  Input:
12  filename: the name of the file
13  Output:
14  data : the opened data with gdal.Open() method
15  im : empty table with right dimension (array)
16 
17  """
18  data = gdal.Open(filename,gdal.GA_ReadOnly)
19  if data is None:
20  print 'Impossible to open '+filename
21  exit()
22  nc = data.RasterXSize
23  nl = data.RasterYSize
24 # d = data.RasterCount
25 
26  # Get the type of the data
27  gdal_dt = data.GetRasterBand(1).DataType
28  if gdal_dt == gdal.GDT_Byte:
29  dt = 'uint8'
30  elif gdal_dt == gdal.GDT_Int16:
31  dt = 'int16'
32  elif gdal_dt == gdal.GDT_UInt16:
33  dt = 'uint16'
34  elif gdal_dt == gdal.GDT_Int32:
35  dt = 'int32'
36  elif gdal_dt == gdal.GDT_UInt32:
37  dt = 'uint32'
38  elif gdal_dt == gdal.GDT_Float32:
39  dt = 'float32'
40  elif gdal_dt == gdal.GDT_Float64:
41  dt = 'float64'
42  elif gdal_dt == gdal.GDT_CInt16 or gdal_dt == gdal.GDT_CInt32 or gdal_dt == gdal.GDT_CFloat32 or gdal_dt == gdal.GDT_CFloat64 :
43  dt = 'complex64'
44  else:
45  print 'Data type unkown'
46  exit()
47 
48  # Initialize the array
49  im = sp.empty((nl,nc),dtype=dt)
50  return data,im
51 
52 '''
53 Old function that open all the bands
54 '''
55 #
56 # for i in range(d):
57 # im[:,:,i]=data.GetRasterBand(i+1).ReadAsArray()
58 #
59 # GeoTransform = data.GetGeoTransform()
60 # Projection = data.GetProjection()
61 # data = None
62 
63 
64 def create_empty_tiff(outname,im,d,GeoTransform,Projection):
65  '''!@brief Write an empty image on the hard drive.
66 
67  Input:
68  outname: the name of the file to be written
69  im: the image cube
70  GeoTransform: the geotransform information
71  Projection: the projection information
72  Output:
73  Nothing --
74  '''
75  nl = im.shape[0]
76  nc = im.shape[1]
77 
78  driver = gdal.GetDriverByName('GTiff')
79  dt = im.dtype.name
80  # Get the data type
81  if dt == 'bool' or dt == 'uint8':
82  gdal_dt=gdal.GDT_Byte
83  elif dt == 'int8' or dt == 'int16':
84  gdal_dt=gdal.GDT_Int16
85  elif dt == 'uint16':
86  gdal_dt=gdal.GDT_UInt16
87  elif dt == 'int32':
88  gdal_dt=gdal.GDT_Int32
89  elif dt == 'uint32':
90  gdal_dt=gdal.GDT_UInt32
91  elif dt == 'int64' or dt == 'uint64' or dt == 'float16' or dt == 'float32':
92  gdal_dt=gdal.GDT_Float32
93  elif dt == 'float64':
94  gdal_dt=gdal.GDT_Float64
95  elif dt == 'complex64':
96  gdal_dt=gdal.GDT_CFloat64
97  else:
98  print 'Data type non-suported'
99  exit()
100 
101  dst_ds = driver.Create(outname,nc,nl, d, gdal_dt)
102  dst_ds.SetGeoTransform(GeoTransform)
103  dst_ds.SetProjection(Projection)
104 
105  return dst_ds
106 
107  '''
108  Old function that cannot manage to write on each band outside the script
109  '''
110 # if d==1:
111 # out = dst_ds.GetRasterBand(1)
112 # out.WriteArray(im)
113 # out.FlushCache()
114 # else:
115 # for i in range(d):
116 # out = dst_ds.GetRasterBand(i+1)
117 # out.WriteArray(im[:,:,i])
118 # out.FlushCache()
119 # dst_ds = None
120 
121 def get_samples_from_roi(raster_name,roi_name):
122  '''!@brief Get the set of pixels given the thematic map.
123  Get the set of pixels given the thematic map. Both map should be of same size. Data is read per block.
124  Input:
125  raster_name: the name of the raster file, could be any file that GDAL can open
126  roi_name: the name of the thematic image: each pixel whose values is greater than 0 is returned
127  Output:
128  X: the sample matrix. A nXd matrix, where n is the number of referenced pixels and d is the number of variables. Each
129  line of the matrix is a pixel.
130  Y: the label of the pixel
131  Written by Mathieu Fauvel.
132  '''
133 
134  ## Open Raster
135  raster = gdal.Open(raster_name,gdal.GA_ReadOnly)
136  if raster is None:
137  print 'Impossible to open '+raster_name
138  exit()
139 
140  ## Open ROI
141  roi = gdal.Open(roi_name,gdal.GA_ReadOnly)
142  if roi is None:
143  print 'Impossible to open '+roi_name
144  exit()
145 
146  ## Some tests
147  if (raster.RasterXSize != roi.RasterXSize) or (raster.RasterYSize != roi.RasterYSize):
148  print 'Images should be of the same size'
149  exit()
150 
151  ## Get block size
152  band = raster.GetRasterBand(1)
153  block_sizes = band.GetBlockSize()
154  x_block_size = block_sizes[0]
155  y_block_size = block_sizes[1]
156  del band
157 
158  ## Get the number of variables and the size of the images
159  d = raster.RasterCount
160  nc = raster.RasterXSize
161  nl = raster.RasterYSize
162 
163  ## Read block data
164  X = sp.array([]).reshape(0,d)
165  Y = sp.array([]).reshape(0,1)
166  for i in range(0,nl,y_block_size):
167  if i + y_block_size < nl: # Check for size consistency in Y
168  lines = y_block_size
169  else:
170  lines = nl - i
171  for j in range(0,nc,x_block_size): # Check for size consistency in X
172  if j + x_block_size < nc:
173  cols = x_block_size
174  else:
175  cols = nc - j
176 
177  # Load the reference data
178 
179  ROI = roi.GetRasterBand(1).ReadAsArray(j, i, cols, lines)
180 
181  t = sp.nonzero(ROI)
182 
183  if t[0].size > 0:
184  Y = sp.concatenate((Y,ROI[t].reshape((t[0].shape[0],1)).astype('uint8')))
185  # Load the Variables
186  Xtp = sp.empty((t[0].shape[0],d))
187  for k in xrange(d):
188  band = raster.GetRasterBand(k+1).ReadAsArray(j, i, cols, lines)
189  Xtp[:,k] = band[t]
190  try:
191  X = sp.concatenate((X,Xtp))
192  except MemoryError:
193  print 'Impossible to allocate memory: ROI too big'
194  exit()
195 
196  # Clean/Close variables
197  del Xtp,band
198  roi = None # Close the roi file
199  raster = None # Close the raster file
200 
201  return X,Y
202 
203 def predict_image(raster_name,classif_name,classifier,mask_name=None):
204  """!@brief Classify the whole raster image, using per block image analysis
205  The classifier is given in classifier and options in kwargs.
206 
207  Input:
208  raster_name (str)
209  classif_name (str)
210  classifier (str)
211  mask_name(str)
212 
213  Return:
214  Nothing but raster written on disk
215  Written by Mathieu Fauvel.
216  """
217  # Parameters
218  block_sizes = 512
219 
220  # Open Raster and get additionnal information
221  raster = gdal.Open(raster_name,gdal.GA_ReadOnly)
222  if raster is None:
223  print 'Impossible to open '+raster_name
224  exit()
225 
226  # If provided, open mask
227  if mask_name is None:
228  mask=None
229  else:
230  mask = gdal.Open(mask_name,gdal.GA_ReadOnly)
231  if mask is None:
232  print 'Impossible to open '+mask_name
233  exit()
234  # Check size
235  if (raster.RasterXSize != mask.RasterXSize) or (raster.RasterYSize != mask.RasterYSize):
236  print 'Image and mask should be of the same size'
237  exit()
238 
239  # Get the size of the image
240  d = raster.RasterCount
241  nc = raster.RasterXSize
242  nl = raster.RasterYSize
243 
244  # Get the geoinformation
245  GeoTransform = raster.GetGeoTransform()
246  Projection = raster.GetProjection()
247 
248  # Set the block size
249  x_block_size = block_sizes
250  y_block_size = block_sizes
251 
252  ## Initialize the output
253  driver = gdal.GetDriverByName('GTiff')
254  dst_ds = driver.Create(classif_name, nc,nl, 1, gdal.GDT_UInt16)
255  dst_ds.SetGeoTransform(GeoTransform)
256  dst_ds.SetProjection(Projection)
257  out = dst_ds.GetRasterBand(1)
258 
259  ## Set the classifiers
260  if classifier['name'] is 'NPFS':
261  ## With GMM
262  model = classifier['model']
263  ids = classifier['ids']
264  nv = len(ids)
265  elif classifier['name'] is 'GMM':
266  model = classifier['model']
267 
268  ## Perform the classification
269  for i in range(0,nl,y_block_size):
270  if i + y_block_size < nl: # Check for size consistency in Y
271  lines = y_block_size
272  else:
273  lines = nl - i
274  for j in range(0,nc,x_block_size): # Check for size consistency in X
275  if j + x_block_size < nc:
276  cols = x_block_size
277  else:
278  cols = nc - j
279 
280  # Do the prediction
281  if classifier['name'] is 'NPFS':
282  # Load the data
283  X = sp.empty((cols*lines,nv))
284  for ind,v in enumerate(ids):
285  X[:,ind] = raster.GetRasterBand(int(v+1)).ReadAsArray(j, i, cols, lines).reshape(cols*lines)
286 
287  # Do the prediction
288  if mask is None:
289  yp = model.predict_gmm(X)[0].astype('uint16')
290  else:
291  mask_temp=mask.GetRasterBand(1).ReadAsArray(j, i, cols, lines).reshape(cols*lines)
292  t = sp.where(mask_temp!=0)[0]
293  yp=sp.zeros((cols*lines,))
294  yp[t]= model.predict_gmm(X[t,:])[0].astype('uint16')
295 
296  elif classifier['name'] is 'GMM':
297  # Load the data
298  X = sp.empty((cols*lines,d))
299  for ind in xrange(d):
300  X[:,ind] = raster.GetRasterBand(int(ind+1)).ReadAsArray(j, i, cols, lines).reshape(cols*lines)
301 
302  # Do the prediction
303  if mask is None:
304  yp = model.predict_gmm(X)[0].astype('uint16')
305  else:
306  mask_temp=mask.GetRasterBand(1).ReadAsArray(j, i, cols, lines).reshape(cols*lines)
307  t = sp.where(mask_temp!=0)[0]
308  yp=sp.zeros((cols*lines,))
309  yp[t]= model.predict_gmm(X[t,:])[0].astype('uint16')
310 
311  # Write the data
312  out.WriteArray(yp.reshape(lines,cols),j,i)
313  out.FlushCache()
314  del X,yp
315 
316  # Clean/Close variables
317  raster = None
318  dst_ds = None
319 
320 def smooth_image(raster_name,mask_name,output_name,l,t):
321  """!@brief Apply a smoothing filter on all the pixels of the input image
322 
323  Input:
324  raster_name: the name of the originale SITS
325  mask_name: the name of the mask. In that file, every pixel with value greater than 0 is masked.
326  output_name: the name of the smoothed image
327 
328  TO DO:
329  - check the input file format (uint16 or float)
330  - parallelization
331 
332  Written by Mathieu Fauvel
333  """
334  # Get
335  import smoother as sm
336  # Open Raster and get additionnal information
337  raster = gdal.Open(raster_name,gdal.GA_ReadOnly)
338  if raster is None:
339  print 'Impossible to open '+raster_name
340  exit()
341 
342  # Open Mask and get additionnal information
343  mask = gdal.Open(mask_name,gdal.GA_ReadOnly)
344  if raster is None:
345  print 'Impossible to open '+mask_name
346  exit()
347 
348  # Check size
349  if (raster.RasterXSize != mask.RasterXSize) or (raster.RasterYSize != mask.RasterYSize) or (raster.RasterCount != mask.RasterCount):
350  print 'Image and mask should be of the same size'
351  exit()
352 
353  # Get the size of the image
354  d = raster.RasterCount
355  nc = raster.RasterXSize
356  nl = raster.RasterYSize
357 
358  # Get the geoinformation
359  GeoTransform = raster.GetGeoTransform()
360  Projection = raster.GetProjection()
361 
362  # Get block size
363  band = raster.GetRasterBand(1)
364  block_sizes = band.GetBlockSize()
365  x_block_size = block_sizes[0]
366  y_block_size = block_sizes[1]
367  del band
368 
369  # Initialize the output
370  driver = gdal.GetDriverByName('GTiff')
371  dst_ds = driver.Create(output_name, nc,nl, d, gdal.GDT_Float64)
372  dst_ds.SetGeoTransform(GeoTransform)
373  dst_ds.SetProjection(Projection)
374 
375  for i in xrange(0,nl,y_block_size):
376  if i + y_block_size < nl: # Check for size consistency in Y
377  lines = y_block_size
378  else:
379  lines = nl - i
380  for j in xrange(0,nc,x_block_size): # Check for size consistency in X
381  if j + x_block_size < nc:
382  cols = x_block_size
383  else:
384  cols = nc - j
385 
386  # Get the data
387  X = sp.empty((cols*lines,d))
388  M = sp.empty((cols*lines,d),dtype='int')
389  for ind in xrange(d):
390  X[:,ind] = raster.GetRasterBand(int(ind+1)).ReadAsArray(j, i, cols, lines).reshape(cols*lines)
391  M[:,ind] = mask.GetRasterBand(int(ind+1)).ReadAsArray(j, i, cols, lines).reshape(cols*lines)
392  # Put all masked value to 1
393  M[M>0]=1
394 
395  # Do the smoothing
396  Xf = sp.empty((cols*lines,d))
397  for ind in xrange(cols*lines): # This part can be speed up by doint it in parallel
398  smoother = sm.Whittaker(x=X[ind,:],t=t,w=1-M[ind,:],order=2)
399  Xf[ind,:] = smoother.smooth(l)
400 
401  # Write the data
402  for ind in xrange(d):
403  out = dst_ds.GetRasterBand(ind+1)
404  out.WriteArray(Xf[:,ind].reshape(lines,cols),j,i)
405  out.FlushCache()
406 
407  # Free memory
408  del X,Xf,M,out
409 
410  # Clean/Close variables
411  raster = None
412  mask = None
413  dst_ds = None
414 
def predict_image
Classify the whole raster image, using per block image analysis The classifier is given in classifier...
def create_empty_tiff
Write an empty image on the hard drive.
def smooth_image
Apply a smoothing filter on all the pixels of the input image.
def open_data_band
The function open and load the image given its name.
def get_samples_from_roi
Get the set of pixels given the thematic map.