Yep - I use:
(and there are similar 2d and 1d implementations if you need).
Hi, I use (for a list of paired points in the code called pairedfiducials ) https://github.com/PerrineGilloteaux/ec-clem/blob/master/easyclemv0/SimilarityRegistrationAnalytic3D.java for 3D
for 2D: https://github.com/PerrineGilloteaux/ec-clem/blob/master/easyclemv0/SimilarityRegistrationAnalytic.java
It requires jama. https://math.nist.gov/javanumerics/jama/
It is Penrose formulation of registration, which is the analytical form equivalent to a least square. Penrose Roger. On best approximate solution of linear matrix equations. Proceedings of the Cambridge Philosophical Society. 1956;52:17–19.
PS: I ve considered isotropic scaling (which was the correct physical assumption in my applications), but you can extend to anisotropic scaling.
The Javadoc should be sufficient to be able to run this, but in case you need some example code for illustration, the following forum thread from 2015 (the first days of the ImageJ forum) has some:
In case you don’t have paired point data yet, but just two point clouds that need to be matched, you can use
Matching.extractCandidates as mentioned in the same post.
That topic also discusses that the closed form weighted least squares solution doesn’t work on data that are almost co-planar, such as auto-fluorescent beads mounted on a microscope slide.
I’d still be interested in an iterative optimization solution to this problem implemented in Java, in case anyone knows.
For this type of problem I would also suggest looking at OpenCV, in particular at estimateAffine3D (https://docs.opencv.org/3.4/d9/d0c/group__calib3d.html#ga396afb6411b30770e56ab69548724715).
You may not want to pull in another large dependeny but OpenCV implements gold standard algorithms for estimating geometric transforms including proper scaling of the input coordinates to improve numerical stability (the seminal paper in computer vision is here https://www.cse.unr.edu/~bebis/CS485/Handouts/hartley.pdf … the concepts outlined there also apply for affine and perspective translations).
They are straightforward to use in python (using the openCV python wrappers) but I think they should not be too difficult to use in Java using for example https://github.com/openpnp/opencv
I’m not sure how they handle the degenerate case of point sets that are intrinsically only 2D or 1D, but you can quickly check for those using eigenvalues.
yes I deal with coplanarity or nearly coplanarity. For example if you download Channel 1 and 2 from the thread you have mentionned
Then the points of interest is from this list of nearly coplanar points attached here
Points for channel 1
Point for channel 2
- purpose show that this implementation can deal with nearly coplanar point. Open Channel one and channel 2 in ICY; launch the plugin importRoiPointsFromFile and choose result1.txt (resp result2) , unit micrometers, sequence channel 1 (resp channel 2), launch ec-clem (" I want to compute the transformation in 3D") select source and target (channel 1 and 2), press play, click update transformation. The matrix is saved in an xml called _transfo.xml
Then I ve corrected the positions of rois of the stack so they are all perfectly coplanar (same z everyone)
- purpose: show that you can register 3D to 2D. Extract Slice 11 on channel 2 (to pretend you have 2D data) , load with importRoiPointsfromfile this csv file (same as channel 2 points but with all z at 0), launch ec clem one-way 3d as source and 2D as target (extract the virtual oblique slice from channel 1 to match slice 11) or the other : place the 2D slice in 3D.
The paper can be requested from research gate, I have access to Cambridge press , I m sending you the paper by email (do not think I can put it on the forum with my institutional access). My implementation is available on the GitHub link I ve posted previously.
For automatic matching, or if the number of points are not the same in both images you can use ec-clem autofinder (also support 3D to 2D or 2D to 3D)