Skip to content

Commit 240d79c

Browse files
committed
Replace convex isosceles trapezoid check with a simple convexity check (roll no longer generally zero unless at least 2-axis gimbal).
1 parent 66f42ed commit 240d79c

File tree

1 file changed

+38
-29
lines changed

1 file changed

+38
-29
lines changed

gisnav/geo.py

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -208,38 +208,47 @@ def __init__(self, corners: np.ndarray, crs: str = _GeoObject.DEFAULT_CRS):
208208

209209
def __post_init__(self):
210210
"""Post-initialization validity checks"""
211-
if not (self._geoseries[0].is_valid and self._is_convex_isosceles_trapezoid()):
212-
raise GeoValueError(f'Not a valid convex isosceles trapezoid: {self._geoseries[0]}')
211+
#if not (self._geoseries[0].is_valid and self._is_convex_isosceles_trapezoid()):
212+
# raise GeoValueError(f'Not a valid convex isosceles trapezoid: {self._geoseries[0]}')
213+
if not (self._geoseries[0].is_valid and not self._is_convex()):
214+
raise GeoValueError(f'Not a valid convex trapezoid: {self._geoseries[0]}')
213215

214-
def _is_convex_isosceles_trapezoid(self, diagonal_length_tolerance: float = 0.1) -> bool:
215-
"""Returns True if the quadrilateral is a convex isosceles trapezoid
216+
def _is_convex(self) -> bool:
217+
"""Returns True if the geoseries is convex
216218
217-
.. note::
218-
If the estimated field of view (FOV) is not a convex isosceles trapezoid, it is a sign that (1) the match
219-
was bad or (2) the gimbal the camera is mounted on has not had enough time to stabilize (camera has
220-
non-zero roll). Matches where the FOV is not a convex isosceles trapezoid should be rejected assuming we
221-
can't tell (1) from (2) and that it is better to wait for a good position estimate than to use a bad one.
222-
223-
.. seealso::
224-
:func:`.create_src_corners` for the assumed order of the quadrilateral corners.
225-
226-
:param diagonal_length_tolerance: Tolerance for relative length difference between trapezoid diagonals
227-
:return: True if the quadrilateral is a convex isosceles trapezoid
219+
:return: True if the geoseries is convex
228220
"""
229-
ul, ll, lr, ur = tuple(map(lambda pt: pt.squeeze().tolist(), self.coords))
230-
231-
# Check convexity (exclude self-crossing trapezoids)
232-
# Note: inverted y-axis, origin at upper left corner of image
233-
if not (ul[0] < ur[0] and ul[1] < ll[1] and lr[0] > ll[0] and lr[1] > ur[1]):
234-
return False
235-
236-
# Check diagonals same length within tolerance
237-
ul_lr_length = math.sqrt((ul[0] - lr[0]) ** 2 + (ul[1] - lr[1]) ** 2)
238-
ll_ur_length = math.sqrt((ll[0] - ur[0]) ** 2 + (ll[1] - ur[1]) ** 2)
239-
if abs((ul_lr_length / ll_ur_length) - 1) > diagonal_length_tolerance:
240-
return False
241-
242-
return True
221+
return self._geoseries[0].bounds == self._geoseries[0].convex_hull.bounds
222+
223+
#def _is_convex_isosceles_trapezoid(self, diagonal_length_tolerance: float = 0.1) -> bool:
224+
# """Returns True if the quadrilateral is a convex isosceles trapezoid
225+
#
226+
# .. note::
227+
# If the estimated field of view (FOV) is not a convex isosceles trapezoid, it is a sign that (1) the match
228+
# was bad or (2) the gimbal the camera is mounted on has not had enough time to stabilize (camera has
229+
# non-zero roll). Matches where the FOV is not a convex isosceles trapezoid should be rejected assuming we
230+
# can't tell (1) from (2) and that it is better to wait for a good position estimate than to use a bad one.
231+
#
232+
# .. seealso::
233+
# :func:`.create_src_corners` for the assumed order of the quadrilateral corners.
234+
#
235+
# :param diagonal_length_tolerance: Tolerance for relative length difference between trapezoid diagonals
236+
# :return: True if the quadrilateral is a convex isosceles trapezoid
237+
# """
238+
# ul, ll, lr, ur = tuple(map(lambda pt: pt.squeeze().tolist(), self.coords))
239+
#
240+
# # Check convexity (exclude self-crossing trapezoids)
241+
# # Note: inverted y-axis, origin at upper left corner of image
242+
# if not (ul[0] < ur[0] and ul[1] < ll[1] and lr[0] > ll[0] and lr[1] > ur[1]):
243+
# return False
244+
#
245+
# # Check diagonals same length within tolerance
246+
# ul_lr_length = math.sqrt((ul[0] - lr[0]) ** 2 + (ul[1] - lr[1]) ** 2)
247+
# ll_ur_length = math.sqrt((ll[0] - ur[0]) ** 2 + (ll[1] - ur[1]) ** 2)
248+
# if abs((ul_lr_length / ll_ur_length) - 1) > diagonal_length_tolerance:
249+
# return False
250+
#
251+
# return True
243252

244253

245254
class GeoValueError(ValueError):

0 commit comments

Comments
 (0)