Commit 0e4a1edf authored by Daniel Scheffler's avatar Daniel Scheffler
Browse files

Merge branch 'enhancement/fix_unhelpful_errormsg' into 'master'

Enhancement/fix unhelpful errormsg

Closes #38

See merge request !10
parents 35823252 e9d7b5d5
Pipeline #14723 passed with stages
in 2 minutes and 18 seconds
......@@ -1244,7 +1244,7 @@ class COREG(object):
self._ssim_improved = has_improved
def calculate_spatial_shifts(self):
# type: (COREG) -> str
# type: () -> str
"""Compute the global X/Y shift between reference and the target image within the matching window.
:return: 'success' or 'fail'
......@@ -1419,7 +1419,7 @@ class COREG(object):
return inv_coreg_info
def correct_shifts(self):
# type: (COREG) -> dict
# type: () -> dict
"""Correct the already calculated X/Y shift of the target image.
:return: COREG.deshift_results (dictionary)
......
......@@ -72,8 +72,8 @@ class COREG_LOCAL(object):
ignore_errors=True):
"""Get an instance of COREG_LOCAL.
:param im_ref(str, GeoArray): source path of reference image (any GDAL compatible image format is supported)
:param im_tgt(str, GeoArray): source path of image to be shifted (any GDAL compatible image format is
:param im_ref(str | GeoArray): source path of reference image (any GDAL compatible image format is supported)
:param im_tgt(str | GeoArray): source path of image to be shifted (any GDAL compatible image format is
supported)
:param grid_res: tie point grid resolution in pixels of the target image (x-direction)
:param max_points(int): maximum number of points used to find coregistration tie points
......@@ -151,14 +151,14 @@ class COREG_LOCAL(object):
given)
:param binary_ws(bool): use binary X/Y dimensions for the matching window (default: True)
:param force_quadratic_win(bool): force a quadratic matching window (default: 1)
:param mask_baddata_ref(str, BadDataMask):
:param mask_baddata_ref(str | BadDataMask):
path to a 2D boolean mask file (or an instance of BadDataMask) for the
reference image where all bad data pixels (e.g. clouds) are marked with
True and the remaining pixels with False. Must have the same geographic
extent and projection like 'im_ref'. The mask is used to check if the
chosen matching window position is valid in the sense of useful data.
Otherwise this window position is rejected.
:param mask_baddata_tgt(str, BadDataMask):
:param mask_baddata_tgt(str | BadDataMask):
path to a 2D boolean mask file (or an instance of BadDataMask) for the
image to be shifted where all bad data pixels (e.g. clouds) are marked
with True and the remaining pixels with False. Must have the same
......@@ -317,25 +317,7 @@ class COREG_LOCAL(object):
if self._tiepoint_grid:
return self._tiepoint_grid
else:
self._tiepoint_grid = Tie_Point_Grid(self.COREG_obj, self.grid_res,
max_points=self.max_points,
outFillVal=self.outFillVal,
resamp_alg_calc=self.rspAlg_calc,
tieP_filter_level=self.tieP_filter_level,
outlDetect_settings=dict(
min_reliability=self.min_reliability,
rs_max_outlier=self.rs_max_outlier,
rs_tolerance=self.rs_tolerance),
dir_out=self.projectDir,
CPUs=self.CPUs,
progress=self.progress,
v=self.v,
q=self.q)
self._tiepoint_grid.get_CoRegPoints_table()
if self.v:
print('Visualizing CoReg points grid...')
self.view_CoRegPoints(figsize=(10, 10))
self.calculate_spatial_shifts()
return self._tiepoint_grid
@property
......@@ -350,10 +332,30 @@ class COREG_LOCAL(object):
@property
def success(self):
self._success = self.tiepoint_grid.GCPList != []
if not self._success and not self.q:
warnings.warn('No valid GCPs could by identified.')
return self._success
def calculate_spatial_shifts(self):
self._tiepoint_grid = \
Tie_Point_Grid(self.COREG_obj, self.grid_res,
max_points=self.max_points,
outFillVal=self.outFillVal,
resamp_alg_calc=self.rspAlg_calc,
tieP_filter_level=self.tieP_filter_level,
outlDetect_settings=dict(
min_reliability=self.min_reliability,
rs_max_outlier=self.rs_max_outlier,
rs_tolerance=self.rs_tolerance),
dir_out=self.projectDir,
CPUs=self.CPUs,
progress=self.progress,
v=self.v,
q=self.q)
self._tiepoint_grid.get_CoRegPoints_table()
if self.v:
print('Visualizing CoReg points grid...')
self.view_CoRegPoints(figsize=(10, 10))
def show_image_footprints(self):
"""Show a web map containing the calculated footprints and overlap area of the input images.
......@@ -541,7 +543,7 @@ class COREG_LOCAL(object):
else:
plt.close(fig)
def view_CoRegPoints_folium(self, attribute2plot='ABS_SHIFT', cmap=None, exclude_fillVals=True):
def view_CoRegPoints_folium(self, attribute2plot='ABS_SHIFT'):
warnings.warn(UserWarning('This function is still under construction and may not work as expected!'))
assert self.CoRegPoints_table is not None, 'Calculate tie point grid first!'
......@@ -596,13 +598,18 @@ class COREG_LOCAL(object):
if self._coreg_info:
return self._coreg_info
else:
if not self._tiepoint_grid:
self.calculate_spatial_shifts()
TPG = self._tiepoint_grid
self._coreg_info = {
'GCPList': self.tiepoint_grid.GCPList,
'mean_shifts_px': {'x': self.tiepoint_grid.mean_x_shift_px,
'y': self.tiepoint_grid.mean_y_shift_px},
'mean_shifts_map': {'x': self.tiepoint_grid.mean_x_shift_map,
'y': self.tiepoint_grid.mean_y_shift_map},
'updated map info means': self._get_updated_map_info_meanShifts(),
'GCPList': TPG.GCPList,
'mean_shifts_px': {'x': TPG.mean_x_shift_px if TPG.GCPList else None,
'y': TPG.mean_y_shift_px if TPG.GCPList else None},
'mean_shifts_map': {'x': TPG.mean_x_shift_map if TPG.GCPList else None,
'y': TPG.mean_y_shift_map if TPG.GCPList else None},
'updated map info means': self._get_updated_map_info_meanShifts() if TPG.GCPList else None,
'original map info': geotransform2mapinfo(self.imref.gt, self.imref.prj),
'reference projection': self.imref.prj,
'reference geotransform': self.imref.gt,
......@@ -625,13 +632,14 @@ class COREG_LOCAL(object):
the mean shift of the remaining points)(default: 5 tie points)
:return:
"""
coreg_info = self.coreg_info
if not self._tiepoint_grid:
self.calculate_spatial_shifts()
if self.tiepoint_grid.GCPList:
if max_GCP_count:
coreg_info['GCPList'] = coreg_info['GCPList'][:max_GCP_count]
self.coreg_info['GCPList'] = self.coreg_info['GCPList'][:max_GCP_count]
DS = DESHIFTER(self.im2shift, coreg_info,
DS = DESHIFTER(self.im2shift, self.coreg_info,
path_out=self.path_out,
fmt_out=self.fmt_out,
out_crea_options=self.out_creaOpt,
......
......@@ -52,7 +52,7 @@ class DESHIFTER(object):
def __init__(self, im2shift, coreg_results, **kwargs):
"""Get an instance of DESHIFTER.
:param (str, GeoArray) im2shift:
:param (str | GeoArray) im2shift:
path of an image to be de-shifted or alternatively a GeoArray object
:param (dict) coreg_results :
......
......@@ -229,10 +229,9 @@ class Tie_Point_Grid(object):
GDF = GDF[inliers].copy()
# GDF = GDF[GDF['geometry'].within(self.COREG_obj.overlap_poly.simplify(tolerance=15))] # works but much slower
# FIXME track that
assert not GDF.empty, 'No coregistration point could be placed within the overlap area. Check your input data!'
# exclude all point where bad data mask is True (e.g. points on clouds etc.)
# exclude all points where bad data mask is True (e.g. points on clouds etc.)
orig_len_GDF = len(GDF) # length of GDF after dropping all points outside the overlap polygon
mapXY = np.array(GDF.loc[:, ['X_UTM', 'Y_UTM']])
GDF['REF_BADDATA'] = self.COREG_obj.ref.mask_baddata.read_pointData(mapXY) \
......@@ -242,8 +241,12 @@ class Tie_Point_Grid(object):
GDF = GDF[(~GDF['REF_BADDATA']) & (~GDF['TGT_BADDATA'])]
if self.COREG_obj.ref.mask_baddata is not None or self.COREG_obj.shift.mask_baddata is not None:
if not self.q:
print('According to the provided bad data mask(s) %s points of initially %s have been excluded.'
% (orig_len_GDF - len(GDF), orig_len_GDF))
if not GDF.empty:
print('With respect to the provided bad data mask(s) %s points of initially %s have been excluded.'
% (orig_len_GDF - len(GDF), orig_len_GDF))
else:
warnings.warn('With respect to the provided bad data mask(s) no coregistration point could be '
'placed within an image area usable for coregistration.')
return GDF
......@@ -418,6 +421,12 @@ class Tie_Point_Grid(object):
self.CoRegPoints_table = GDF
if not self.q:
if GDF.empty:
warnings.warn('No valid GCPs could by identified.')
else:
print("%d valid tie points remain after filtering." % len(GDF[GDF.OUTLIER.__eq__(False)]))
return self.CoRegPoints_table
def calc_rmse(self, include_outliers=False):
......@@ -592,9 +601,6 @@ class Tie_Point_Grid(object):
GDF_row.X_IM, GDF_row.Y_IM), axis=1)
self.GCPList = GDF.GCP.tolist()
if not self.q:
print('Found %s valid tie points.' % len(self.GCPList))
return self.GCPList
def test_if_singleprocessing_equals_multiprocessing_result(self):
......
......@@ -22,5 +22,5 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
__version__ = '1.0.2'
__versionalias__ = '2020-10-12_02'
__version__ = '1.0.3'
__versionalias__ = '2020-10-19_01'
......@@ -2,7 +2,7 @@ Local image co-registration
***************************
This local co-registration module of AROSICS has been designed to detect and correct geometric shifts present locally
in your input image. The class :class:`~arosics.COREG_LOCAL` calculates a grid of spatial shifts with points spread
in your input image. The class :class:`arosics.COREG_LOCAL` calculates a grid of spatial shifts with points spread
over the whole overlap area of the input images. Based on this grid a correction of local shifts can be performed.
......
......@@ -64,7 +64,7 @@ req_setup = [
# ipython is needed for testing interactive plotting
req_test = ['coverage', 'nose', 'nose2', 'nose-htmloutput', 'rednose', 'ipython']
req_doc = ['sphinx-argparse', 'sphinx_rtd_theme']
req_doc = ['sphinx-argparse', 'sphinx_rtd_theme', 'sphinx-autodoc-typehints']
req_lint = ['flake8', 'pycodestyle', 'pydocstyle']
......
......@@ -80,9 +80,8 @@ class CompleteWorkflow_INTER1_S2A_S2A(unittest.TestCase):
# get instance of COREG_LOCAL object
CRL = COREG_LOCAL(self.ref_path, self.tgt_path, **self.coreg_kwargs)
# use the getter of the CoRegPoints_table to calculate tie point grid
# noinspection PyStatementEffect
CRL.CoRegPoints_table
# calculate tie point grid
CRL.calculate_spatial_shifts()
# test tie point grid visualization
with warnings.catch_warnings():
......@@ -119,10 +118,7 @@ class CompleteWorkflow_INTER1_S2A_S2A(unittest.TestCase):
# get instance of COREG_LOCAL object
CRL = COREG_LOCAL(ref, tgt, **dict(CPUs=32,
**self.coreg_kwargs))
# use the getter of the CoRegPoints_table to calculate tie point grid
# noinspection PyStatementEffect
CRL.CoRegPoints_table
CRL.calculate_spatial_shifts()
# if __name__ == '__main__':
......
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