フィルターのクリア

register axis to point cloud

3 ビュー (過去 30 日間)
JG
JG 2022 年 12 月 21 日
編集済み: Matt J 2022 年 12 月 28 日
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 件のコメント
Matt J
Matt J 2022 年 12 月 23 日
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 2022 年 12 月 23 日
yes they are corresponding. The range of s_i shold be between 0 and 50.

サインインしてコメントする。

採用された回答

Matt J
Matt J 2022 年 12 月 23 日
編集済み: Matt J 2022 年 12 月 23 日
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 件のコメント
JG
JG 2022 年 12 月 28 日
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 2022 年 12 月 28 日
No, I have no further suggestions, other than improve the measurements of r0 and V_dir.

サインインしてコメントする。

その他の回答 (2 件)

Matt J
Matt J 2022 年 12 月 21 日
  7 件のコメント
Matt J
Matt J 2022 年 12 月 23 日
編集済み: Matt J 2022 年 12 月 23 日
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 2022 年 12 月 27 日
This answer would work too but to implement contraints that the points are located where the are positive the fmincon answer is more suited.

サインインしてコメントする。


Image Analyst
Image Analyst 2022 年 12 月 22 日
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 件のコメント
JG
JG 2022 年 12 月 23 日
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

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeSolver Outputs and Iterative Display についてさらに検索

製品

Community Treasure Hunt

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

Start Hunting!

Translated by