register axis to point cloud
3 次查看(过去 30 天)
显示 更早的评论
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: ![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1241057/image.png)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1241057/image.png)
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
2022-12-23
Axis line in form: ![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1241272/image.png)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1241272/image.png)
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].
采纳的回答
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);
[~,points]=fun(P);
dist2Lines=vecnorm(points-project(points,r_0_,V_dir))
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 个评论
Matt J
2022-12-28
No, I have no further suggestions, other than improve the measurements of r0 and V_dir.
更多回答(2 个)
Matt J
2022-12-21
7 个评论
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
registrationError
function x=project(x,r_0_,V_dir)
x = r_0_ + sum((x-r_0_).*V_dir).*V_dir;
end
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.
另请参阅
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!