Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a general-purpose apply_matrix() function for DEMs #82

Closed
erikmannerfelt opened this issue Apr 8, 2021 · 2 comments
Closed

Add a general-purpose apply_matrix() function for DEMs #82

erikmannerfelt opened this issue Apr 8, 2021 · 2 comments
Labels
new-feature A new functionality / feature or request

Comments

@erikmannerfelt
Copy link
Contributor

In #71, we discussed errors associated to DEM gridding, since ICP (and possibly more future approaches) need to convert the DEM into a point cloud. ICP currently does:

  1. Convert DEM to point cloud (preparation)
  2. Match the ref and tba point clouds (estimates the rigid transform)
  3. Re-grid the tba DEM after transforming it (applies the rigid transform)

Step 3 currently uses scipy.interpolate.griddata which is extremely slow! A faster and more reliable approach would be fantastic to have. Something with the approximate signature:

def apply_matrix(dem: np.ndarray, transform: rio.transform.Affine, matrix: np.ndarray) -> np.ndarray:
    # do matrix magic
    return transformed_dem

One idea I had was to describe the 3D rigid transform as a 2D similarity transform and a linear vertical correction:

A 3D rigid transform from above (from 2D) would include horizontal translation, horizontal rotation, horizontal scaling (due to rotation-induced perspective differences), and elevation (bias + rotation) differences. As far as I understand, the first 3 parts could be described as a 2D similarity transform, and the final as a deramp.

The advantage of such an approach is that the DEM never has to be converted to a point cloud and regridded; it just needs to be moved and twisted a bit. I guess the most difficult part of this, however, would be to mathematically do the conversion...

This general-purpose function is integral for #79 to implement.

I am also all-ears to other alternatives.

@erikmannerfelt erikmannerfelt added the enhancement Feature improvement or request label Apr 8, 2021
@erikmannerfelt
Copy link
Contributor Author

In my sleep, I came up with a hacky solution that should work for now:

  1. Transform a set of arbitrary points using the 3D rigid transform.
  2. Estimate a 2D (horizontal) SimilarityTransform using skimage.transform.estimate_transform(orig_points2D, trans_points2D, "similarity")
  3. Estimate a (vertical) deramp using the trusty xdem tools
  4. Apply the SimilarityTransform using skimage and then apply the deramp.

The great advantage of this is that the input DEM is never converted into a point cloud, and thus doesn't need regridding, but is just warped (skimage) and value corrected (deramp).

Of course, the best would be to estimate the SimilarityTransform and Deramp mathematically instead of empirically deriving them, but that's beyond my math knowledge!

@erikmannerfelt
Copy link
Contributor Author

Added in #87

@erikmannerfelt erikmannerfelt added new-feature A new functionality / feature or request and removed enhancement Feature improvement or request labels Jul 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new-feature A new functionality / feature or request
Projects
None yet
Development

No branches or pull requests

1 participant