Skip to content

Comments

New Transform type: Homography#11949

Merged
rouault merged 17 commits intoOSGeo:masterfrom
NathanMOlson:11940_homography2
Mar 13, 2025
Merged

New Transform type: Homography#11949
rouault merged 17 commits intoOSGeo:masterfrom
NathanMOlson:11940_homography2

Conversation

@NathanMOlson
Copy link
Contributor

@NathanMOlson NathanMOlson commented Mar 12, 2025

What does this PR do?

Adds new transform type, Homography.
Adds functions to compute homography from a list of GCPs.
Adds functions to serialize and deserialize a homography
Automatically selects homography transform when there are 4 or 5 GCPs present. Homography provides an exact fit for 4 GCPs, and a better fit for 5 GCPs than the existing method (affine transformation).

What are related issues/pull requests?

#11940

Tasklist

- [ ] AI (Copilot or something similar) supported my development of this PR

  • Make sure code is correctly formatted (cf pre-commit configuration)
  • Add test case(s)
  • Add documentation
    - [ ] Updated Python API documentation (swig/include/python/docs/)
  • Review
  • Adjust for comments
  • All CI builds and checks have passed

Environment

Provide environment details, if relevant:

  • OS: WSL
  • Compiler: gcc

Add new transform type, Homography.
Add functions to compute homography from a list of GCPs.
Add functions to serialize and deserialize a homography
Automatically select homography transfrom when there are 4 or 5 GCPs present.
Copy link
Member

@rouault rouault left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like an excellent work, although I'm not familiar with the maths involved

return FALSE;
}

GDALMatrix LtL(9, 9);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there references giving context for all the below maths that could be included as code comments ? / how did you derive that ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LtL ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a link to https://www.cs.unc.edu/~ronisen/teaching/fall_2023/pdf_slides/lecture9_transformation.pdf, and changed LtL to AtA to match the notation in that document. Is there a preferred alternative to this kind of link? I can't guarantee how long the link will be available.

return FALSE;
}

// "Hour-glass" like shape of GCPs. Cf https://github.com/OSGeo/gdal/issues/11618
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand that comment. Hour-glass like shape is one possibility, not necesarily all the cases

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully the new comments clarify things.

}
double cross12 = x[1] * y[2] - x[2] * y[1];
double cross23 = x[2] * y[3] - x[3] * y[2];
if (cross12 * cross23 <= 0.0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this check do ? Should we emit an error when it fails ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check verifies that the normalized transform maps the unit square to a convex quadrilateral.

Regarding emitting an error, I followed the precedent of GDALGCPsToGeoTransform(), which returns FALSE without emitting an error in all cases that fail to compute a valid GeoTransform. I can change it to emit errors in those cases if needed.

/* Compose the resulting transformation with the normalization */
/* homographies. */
/* -------------------------------------------------------------------- */
double h1p2[9] = {0.0};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is it named h1p2 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following the precedent set by gt1p2 in GDALGCPsToGeoTransform() (gt = geotransform, h = homography).

This is an intermediate homography, which maps between pixels and normalized geo coordinates.

@coveralls
Copy link
Collaborator

coveralls commented Mar 12, 2025

Coverage Status

coverage: 69.166% (-1.3%) from 70.425%
when pulling 28c3ec3 on NathanMOlson:11940_homography2
into dd6009a on OSGeo:master.

@rouault rouault merged commit d8e3962 into OSGeo:master Mar 13, 2025
34 of 37 checks passed
@rouault rouault added this to the 3.11.0 milestone Mar 13, 2025
Jwohnlf pushed a commit to Jwohnlf/gdal that referenced this pull request Mar 23, 2025
Add new transform type, Homography.
Add functions to compute homography from a list of GCPs.
Add functions to serialize and deserialize a homography
Automatically select homography transfrom when there are 4 or 5 GCPs present.

Fixes OSGeo#11940
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants