Skip to content

Commit

Permalink
Merge branch 'enhancement/fix_unhelpful_errormsg' into 'master'
Browse files Browse the repository at this point in the history
Enhancement/fix unhelpful errormsg

Closes #38

See merge request danschef/arosics!10
  • Loading branch information
danschef committed Oct 19, 2020
2 parents 3582325 + e9d7b5d commit 0e4a1ed
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 56 deletions.
4 changes: 2 additions & 2 deletions arosics/CoReg.py
Original file line number Diff line number Diff line change
Expand Up @@ -1244,7 +1244,7 @@ def ssim_improved(self, has_improved):
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'
Expand Down Expand Up @@ -1419,7 +1419,7 @@ def _get_inverted_coreg_info(self):
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)
Expand Down
78 changes: 43 additions & 35 deletions arosics/CoReg_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ def __init__(self, im_ref, im_tgt, grid_res, max_points=None, window_size=(256,
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
Expand Down Expand Up @@ -151,14 +151,14 @@ def __init__(self, im_ref, im_tgt, grid_res, max_points=None, window_size=(256,
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
Expand Down Expand Up @@ -317,25 +317,7 @@ def tiepoint_grid(self):
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
Expand All @@ -350,10 +332,30 @@ def CoRegPoints_table(self):
@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.
Expand Down Expand Up @@ -541,7 +543,7 @@ def view_CoRegPoints(self, shapes2plot='points', attribute2plot='ABS_SHIFT', cma
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!'

Expand Down Expand Up @@ -596,13 +598,18 @@ def coreg_info(self):
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,
Expand All @@ -625,13 +632,14 @@ def correct_shifts(self, max_GCP_count=None, cliptoextent=False, min_points_loca
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,
Expand Down
2 changes: 1 addition & 1 deletion arosics/DeShifter.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 :
Expand Down
20 changes: 13 additions & 7 deletions arosics/Tie_Point_Grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,9 @@ def _exclude_bad_XYpos(self, GDF):
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) \
Expand All @@ -242,8 +241,12 @@ def _exclude_bad_XYpos(self, GDF):
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

Expand Down Expand Up @@ -418,6 +421,12 @@ def get_CoRegPoints_table(self):

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):
Expand Down Expand Up @@ -592,9 +601,6 @@ def to_GCPList(self):
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):
Expand Down
4 changes: 2 additions & 2 deletions arosics/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 1 addition & 1 deletion docs/usage/local_coreg.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.


Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
# 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']

Expand Down
10 changes: 3 additions & 7 deletions tests/test_COREG_LOCAL.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,8 @@ def test_calculation_of_tie_point_grid(self):
# 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():
Expand Down Expand Up @@ -119,10 +118,7 @@ def test_calculation_of_tie_point_grid_float_coords(self):
# 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__':
Expand Down

0 comments on commit 0e4a1ed

Please sign in to comment.