Filter löschen
Filter löschen

register axis to point cloud

3 Ansichten (letzte 30 Tage)
JG
JG am 21 Dez. 2022
Bearbeitet: Matt J am 28 Dez. 2022
Hello everyone,
I try to register a set of 3 lines to a set of 3 points. The Coordinate System of both sets are not the same. So I need to find the rotation and translation of the lines so they pass through the points. Does anyone know a good method to do so?
little bit of Context:
the lines are the axis of a drilling wholes obtained by CT Scans and the points are marker obtained from a Motion Capture System. The markers were on the screw inserted into the drilling wholes. I need to match them in order that I can register the CT Data to the MotionCapture System
edit:
Here an example:
MoCap points:
MoCap_points = [243.9669 203.8436 215.5850
104.2774 117.8749 85.7087
-113.6220 -106.1354 -102.1162];
Axis line in form:
r_0_ = 1.0e+03 *[0.6269 0.6139 0.6055
-1.6006 -1.6178 -1.6009
-0.3004 -0.2963 -0.3010];
V_dir = [0.6183 0.0112 -0.2819
0.2555 -0.3098 0.3367
0.7432 0.9507 0.8984];
Each Colum is a different vectors.
Thanks for any suggestion,
JG
  3 Kommentare
Matt J
Matt J am 23 Dez. 2022
Axis line in form:
Is there any information you can give on the s_i ranges? These lines are finite 3D line segments, I assume, so s_i should range over some finite interval [sLower,sUpper].
JG
JG am 23 Dez. 2022
yes they are corresponding. The range of s_i shold be between 0 and 50.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Matt J
Matt J am 23 Dez. 2022
Bearbeitet: Matt J am 23 Dez. 2022
Here is an optimization implemented with fmincon. It achieved a lower registration error dist2Lines than my other answer, though, it's hard to say whether the naive initialization P0=eye(3,4) will work as well on other data sets.
MoCap_points = [243.9669 203.8436 215.5850
104.2774 117.8749 85.7087
-113.6220 -106.1354 -102.1162];
r_0_ = 1.0e+03 *[0.6269 0.6139 0.6055
-1.6006 -1.6178 -1.6009
-0.3004 -0.2963 -0.3010];
V_dir = [0.6183 0.0112 -0.2819
0.2555 -0.3098 0.3367
0.7432 0.9507 0.8984]; V_dir=normalize(V_dir,1,'n');
fun=@(P) objFcn(P,r_0_,V_dir, MoCap_points);
P0=eye(3,4);
[P,fval]=fmincon(fun,P0,[],[],[],[],[],[],@nlcFcn);
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 1.108598e-21.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 1.108598e-21.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 1.584718e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 1.584718e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 3.172984e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 3.172984e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 3.172984e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 3.172984e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 3.172984e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 3.172984e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 3.172984e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 3.172984e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 3.172984e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 3.172984e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 3.172984e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 3.172984e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 3.172984e-18.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 3.172984e-18.
Local minimum possible. Constraints satisfied. fmincon stopped because the size of the current step is less than the value of the step size tolerance and constraints are satisfied to within the value of the constraint tolerance.
[~,points]=fun(P);
dist2Lines=vecnorm(points-project(points,r_0_,V_dir))
dist2Lines = 1×3
1.0e-03 * 0.1395 0.0835 0.0937
function [fval,x]=objFcn(P,r_0_,V_dir, MoCap_points)
R=P(:,1:3); t=P(:,end);
x=R*MoCap_points+t;
fval=norm( x-project( x,r_0_,V_dir) ,'fro').^2;
end
function [c,ceq]=nlcFcn(P)
R=P(:,1:3);
ceq=R*R'-eye(3);
c=1-det(R);
end
function x=project(x,r_0_,V_dir)
x = r_0_ + sum((x-r_0_).*V_dir).*V_dir;
end
  12 Kommentare
JG
JG am 28 Dez. 2022
Yes I belive the solution is no precise enough, My end goal is to relate the joint centre of the CT data to the MoCap Data, but I supose there is nothig left to squeeze out of the data.
I would accept the answer if you have no further sugggestions
Thanks alot for your effort.
Matt J
Matt J am 28 Dez. 2022
No, I have no further suggestions, other than improve the measurements of r0 and V_dir.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (2)

Matt J
Matt J am 21 Dez. 2022
  7 Kommentare
Matt J
Matt J am 23 Dez. 2022
Bearbeitet: Matt J am 23 Dez. 2022
Here is an implementation using absor() from this FEX download,
The registration brings the points into an intersection with the lines to within a worst error of 1.45. I don't know what kind of registration error magnitudes you were expecting. Possibly, one could do better using fmincon().
MoCap_points = [243.9669 203.8436 215.5850
104.2774 117.8749 85.7087
-113.6220 -106.1354 -102.1162];
r_0_ = 1.0e+03 *[0.6269 0.6139 0.6055
-1.6006 -1.6178 -1.6009
-0.3004 -0.2963 -0.3010];
V_dir = [0.6183 0.0112 -0.2819
0.2555 -0.3098 0.3367
0.7432 0.9507 0.8984]; V_dir=normalize(V_dir,1,'n');
points=MoCap_points;
Niter=500;
for i=1:Niter
[registrationParams,points,registrationError]=absor(MoCap_points, project(points,r_0_,V_dir) );
end
registrationParams
registrationParams = struct with fields:
R: [3×3 double] t: [3×1 double] s: 1 M: [4×4 double] q: [4×1 double]
registrationError
registrationError = struct with fields:
errlsq: 2.2864 errmax: 1.4518
function x=project(x,r_0_,V_dir)
x = r_0_ + sum((x-r_0_).*V_dir).*V_dir;
end
JG
JG am 27 Dez. 2022
This answer would work too but to implement contraints that the points are located where the are positive the fmincon answer is more suited.

Melden Sie sich an, um zu kommentieren.


Image Analyst
Image Analyst am 22 Dez. 2022
I don't know if it's as sophisticated as your paper, but you can use the built-in imregister to align each slice to the prior one, or the first one.
Or you can find the centroids of the holes with regionprops and then use imtranslate to shift a slice to the desired position.
  1 Kommentar
JG
JG am 23 Dez. 2022
My problem is not find the axis it self. I try to find a best fit from the MoCap data to the Axis extracted from the CT. I have added an example in the post above

Melden Sie sich an, um zu kommentieren.

Produkte

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by