Commit dacc2fd2 authored by Daniel Scheffler's avatar Daniel Scheffler
Browse files

Commit before deletion of ClassifierGenerator and RSImagePredictor without clustering.

parent 0ddae00e
......@@ -248,15 +248,15 @@ class SpectralHomogenizer(object):
:rtype: Tuple[np.ndarray, Union[np.ndarray, None]]
"""
# TODO: add LBA validation to .predict()
if n_clusters > 1:
PR = RSImage_ClusterPredictor(method=method,
classifier_rootDir=self.classifier_rootDir,
n_clusters=n_clusters,
classif_alg=classif_alg,
kNN_n_neighbors=kNN_n_neighbors)
else:
PR = RSImage_Predictor(method=method,
classifier_rootDir=self.classifier_rootDir)
# if n_clusters > 1:
PR = RSImage_ClusterPredictor(method=method,
classifier_rootDir=self.classifier_rootDir,
n_clusters=n_clusters,
classif_alg=classif_alg,
kNN_n_neighbors=kNN_n_neighbors)
# else:
# PR = RSImage_Predictor(method=method,
# classifier_rootDir=self.classifier_rootDir)
######################
# get the classifier #
......@@ -1597,6 +1597,8 @@ class RSImage_Predictor(object):
image_predicted = GeoArray(np.empty((image.rows, image.cols, classifier.tgt_n_bands), dtype=image.dtype),
geotransform=image.gt, projection=image.prj, nodata=image.nodata)
from time import time
t0 = time()
for ((rS, rE), (cS, cE)), im_tile in image.tiles(tilesize=(1000, 1000)):
# 3D -> 2D
spectra = im2spectra(im_tile)
......@@ -1608,7 +1610,7 @@ class RSImage_Predictor(object):
tiledata_pred = spectra2im(spectra_pred, tgt_rows=im_tile.shape[0], tgt_cols=im_tile.shape[1])
image_predicted[rS:rE + 1, cS:cE + 1] = tiledata_pred
print(time()-t0)
# re-apply nodata values to predicted result
if image.nodata is not None:
image_predicted[image.mask_nodata[:] == 0] = image.nodata
......@@ -1616,6 +1618,9 @@ class RSImage_Predictor(object):
# copy mask_nodata
image_predicted.mask_nodata = image.mask_nodata
GeoArray(image_predicted).save(
'/home/gfz-fe/scheffler/temp/SPECHOM_py/image_predicted_QRnoclust_MinDist_noB9.bsq')
return image_predicted
@staticmethod
......@@ -1644,6 +1649,8 @@ class RSImage_Predictor(object):
if im_predicted.nodata is not None:
errors[im_predicted.mask_nodata[:] == 0] = im_predicted.nodata
GeoArray(errors).save('/home/gfz-fe/scheffler/temp/SPECHOM_py/errors_QRnoclust_MinDist_noB9.bsq')
return errors
......@@ -1662,7 +1669,7 @@ class RSImage_ClusterPredictor(object):
E.g., 50 means that the image to be converted to the spectral target sensor
is clustered into 50 spectral clusters and one separate machine learner per
cluster is applied to the input data to predict the homogenized image. If
'spechomo_n_clusters' is set to 1, the source image is not clustered and
'n_clusters' is set to 1, the source image is not clustered and
only one machine learning classifier is used for prediction.
:param classif_alg: algorithm to be used for image classification
(to define which cluster each pixel belongs to)
......@@ -1682,7 +1689,7 @@ class RSImage_ClusterPredictor(object):
self.classif_alg = classif_alg
def get_classifier(self, src_satellite, src_sensor, src_LBA, tgt_satellite, tgt_sensor, tgt_LBA):
# type: (str, str, list, str, str, list) -> any
# type: (str, str, list, str, str, list) -> Cluster_Learner
"""Select the correct machine learning classifier out of previously saves classifier collections.
Describe the classifier specifications with the given arguments.
......@@ -1755,7 +1762,7 @@ class RSImage_ClusterPredictor(object):
return cmap
def predict(self, image, classifier, nodataVal=None, CPUs=1):
# type: (Union[np.ndarray, GeoArray], any, float, int) -> GeoArray
# type: (Union[np.ndarray, GeoArray], Cluster_Learner, float, int) -> GeoArray
"""Apply the prediction function of the given specifier to the given remote sensing image.
:param image: 3D array representing the input image
......@@ -1769,10 +1776,13 @@ class RSImage_ClusterPredictor(object):
# assign each input pixel to a cluster (compute classfication with cluster centers as endmembers)
if not self.classif_map:
from time import time
t0 = time()
self.classif_map = self.classify_image(image, classifier, nodataVal=nodataVal)
print(time() - t0)
if self.n_clusters > 1:
from time import time
t0 = time()
self.classif_map = self.classify_image(image, classifier, nodataVal=nodataVal)
print(time() - t0)
else:
self.classif_map = np.full((image.rows, image.cols), classifier.cluster_pixVals[0], np.int8)
# adjust classifier
if CPUs is None or CPUs > 1:
......@@ -1783,7 +1793,9 @@ class RSImage_ClusterPredictor(object):
# NOTE: prediction is applied in 1000 x 1000 tiles to save memory (because classifier.predict returns float32)
image_predicted = GeoArray(np.empty((image.rows, image.cols, classifier.tgt_n_bands), dtype=image.dtype),
geotransform=image.gt, projection=image.prj, nodata=image.nodata)
from time import time
t0 = time()
print('predicting...')
for ((rS, rE), (cS, cE)), im_tile in image.tiles(tilesize=(1000, 1000)):
print('Predicting tile ((%s, %s), (%s, %s))...' % (rS, rE, cS, cE))
......@@ -1793,6 +1805,7 @@ class RSImage_ClusterPredictor(object):
im_tile_pred = classifier.predict(im_tile, classif_map_tile, nodataVal=nodataVal).astype(image.dtype)
image_predicted[rS:rE + 1, cS:cE + 1] = im_tile_pred
print(time()-t0)
# re-apply nodata values to predicted result
if image.nodata is not None:
image_predicted[image.mask_nodata[:] == 0] = image.nodata
......@@ -1800,10 +1813,10 @@ class RSImage_ClusterPredictor(object):
# copy mask_nodata
image_predicted.mask_nodata = image.mask_nodata
# GeoArray(image_predicted).save(
# '/home/gfz-fe/scheffler/temp/SPECHOM_py/image_predicted_QRclust50_MinDist_noB9.bsq')
# GeoArray(self.classif_map).save(
# '/home/gfz-fe/scheffler/temp/SPECHOM_py/classif_map_QRclust50_MinDist_noB9.bsq')
GeoArray(image_predicted).save(
'/home/gfz-fe/scheffler/temp/SPECHOM_py/image_predicted_QRclust1_MinDist_noB9.bsq')
GeoArray(self.classif_map).save(
'/home/gfz-fe/scheffler/temp/SPECHOM_py/classif_map_QRclust1_MinDist_noB9.bsq')
return image_predicted
......@@ -1847,7 +1860,7 @@ class RSImage_ClusterPredictor(object):
# errors[im_predicted == im_predicted.nodata] = im_predicted.nodata
errors[im_predicted.mask_nodata.astype(np.int8) == 0] = im_predicted.nodata
# GeoArray(errors).save('/home/gfz-fe/scheffler/temp/SPECHOM_py/errors_QRclust50_MinDist_noB9.bsq')
GeoArray(errors).save('/home/gfz-fe/scheffler/temp/SPECHOM_py/errors_LRclust1_MinDist_noB9_clusterpred.bsq')
return errors
......@@ -1898,3 +1911,36 @@ class Cluster_Learner(object):
im_pred[mask_pixVal] = classifier.predict(im_src[mask_pixVal]).astype(im_src.dtype)
return im_pred
def predict(self, im_src, cmap, nodataVal=None):
"""
:param im_src:
:param cmap: classification map that assigns each image spectrum to its corresponding cluster
-> must be a 1D np.ndarray with the same Y-dimension like src_spectra
:param nodataVal:
:return:
"""
cluster_labels = sorted(list(np.unique(cmap)))
if len(cluster_labels) > 1:
# iterate over all cluster labels and apply corresponding machine learner parameters
# to predict target spectra
im_pred = np.empty((im_src.shape[0], im_src.shape[1], self.tgt_n_bands), dtype=im_src.dtype)
for pixVal in cluster_labels:
if pixVal == nodataVal:
continue
classifier = self.MLdict[pixVal]
mask_pixVal = cmap == pixVal
im_pred[mask_pixVal] = classifier.predict(im_src[mask_pixVal]).astype(im_src.dtype)
else:
# predict target spectra directly
spectra = im2spectra(im_src)
classifier = self.MLdict[cluster_labels[0]]
spectra_pred = classifier.predict(spectra).astype(im_src.dtype)
im_pred = spectra2im(spectra_pred, im_src.shape[0], im_src.shape[1])
return im_pred
......@@ -239,16 +239,16 @@ class Test_SpectralHomogenizer(unittest.TestCase):
cfg = set_config(job_ID=26186196, db_host=db_host, reset_status=True, is_test=True)
cls.SpH = SpectralHomogenizer(classifier_rootDir=cfg.path_spechomo_classif)
cls.testArr_L8 = GeoArray(np.random.randint(1, 10000, (50, 50, 7), dtype=np.int16)) # no band 9, no pan
# cls.testArr_L8 = GeoArray(np.random.randint(1, 10000, (50, 50, 7), dtype=np.int16)) # no band 9, no pan
# cls.testArr_L8 = GeoArray('/home/gfz-fe/scheffler/temp/'
# 'Landsat-8__OLI_TIRS__LC81940242014072LGN00_L2B__250x250.bsq') # no pan
# cls.testArr_L8 = GeoArray('/home/gfz-fe/scheffler/temp/'
# 'Landsat-8__OLI_TIRS__LC81940242014072LGN00_L2B.bsq') # no pan
# cls.testArr_L8 = GeoArray('/home/gfz-fe/scheffler/temp/'
# 'clusterhomo_sourceL8_full_withoutB9.bsq') # no pan, no cirrus
cls.testArr_L8 = GeoArray('/home/gfz-fe/scheffler/temp/'
'clusterhomo_sourceL8_full_withoutB9.bsq') # no pan, no cirrus
# cls.cwl_L8 = [442.98, 482.59, 561.33, 654.61, 864.57, 1609.09, 2201.25]
cls.cwl_L8 = [442.98, 482.59, 561.33, 654.61, 864.57, 1373.48, 1609.09, 2201.25]
cls.cwl_L8 = [442.98, 482.59, 561.33, 654.61, 864.57, 1609.09, 2201.25]
# cls.cwl_L8 = [442.98, 482.59, 561.33, 654.61, 864.57, 1373.48, 1609.09, 2201.25]
def test_interpolate_cube_linear(self):
outarr = self.SpH.interpolate_cube(self.testArr_L8, self.cwl_L8, [500., 700., 1300.], kind='linear')
......@@ -265,7 +265,8 @@ class Test_SpectralHomogenizer(unittest.TestCase):
def test_predict_by_machine_learner__LR_L8_S2(self):
"""Test linear regression from Landsat-8 to Sentinel-2A."""
predarr, errors = self.SpH.predict_by_machine_learner(
self.testArr_L8, method='LR',
self.testArr_L8,
method='LR', n_clusters=1,
src_satellite='Landsat-8', src_sensor='OLI_TIRS',
src_LBA=['1', '2', '3', '4', '5', '6', '7'],
tgt_satellite='Sentinel-2A', tgt_sensor='MSI',
......@@ -284,7 +285,8 @@ class Test_SpectralHomogenizer(unittest.TestCase):
def test_predict_by_machine_learner__RR_L8_S2(self):
"""Test ridge regression from Landsat-8 to Sentinel-2A."""
predarr, errors = self.SpH.predict_by_machine_learner(
self.testArr_L8, method='RR',
self.testArr_L8,
method='RR', n_clusters=1,
src_satellite='Landsat-8', src_sensor='OLI_TIRS',
src_LBA=['1', '2', '3', '4', '5', '6', '7'],
tgt_satellite='Sentinel-2A', tgt_sensor='MSI',
......@@ -302,7 +304,8 @@ class Test_SpectralHomogenizer(unittest.TestCase):
def test_predict_by_machine_learner__QR_L8_S2(self):
"""Test quadratic regression from Landsat-8 to Sentinel-2A."""
predarr, errors = self.SpH.predict_by_machine_learner(
self.testArr_L8, method='QR',
self.testArr_L8,
method='QR', n_clusters=1,
src_satellite='Landsat-8', src_sensor='OLI_TIRS',
src_LBA=['1', '2', '3', '4', '5', '6', '7'],
tgt_satellite='Sentinel-2A', tgt_sensor='MSI',
......@@ -321,8 +324,8 @@ class Test_SpectralHomogenizer(unittest.TestCase):
"""Test quadratic regression in spectral clusters from Landsat-8 to Sentinel-2A."""
predarr, errors = self.SpH.predict_by_machine_learner(
self.testArr_L8,
method='QR',
n_clusters=50,
method='LR',
n_clusters=1,
classif_alg='MinDist',
src_satellite='Landsat-8', src_sensor='OLI_TIRS',
# src_LBA=['1', '2', '3', '4', '5', '6', '7'],
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment