Difficulty fitting translation and rotation between two matrices of coordinate points
조회 수: 4 (최근 30일)
이전 댓글 표시
My current effort seems like a simple one, but for the life of me I cannot get a working version, with or without builtin functions.
In this example, I have two sets of points where one is a simple rotation of the other. My real world application will have to worry about rotation, translation, and potentially minor radial distortion issues (scaling based on radial distance). I need to be able to fit one set to another and extract (at least) the rotation and x and y translation of the transform. Later I hope to check non-linear radial distortions.
I tried using regionprop stuff via Centroid and Orientation to rotate around, but translation seems to get messed up, since the centroid and the rotaiton isn't about the center of the "image".
Over the weekend I learned about fitgeotrans and am trying to get that, or some similar family of functions to work. (Looks like having 2022b would give me more potentially useful tools, but alas, I have 2020b). Using fitgeotrans gives me a tform that includes a significant scaling factor, which isn't real. There should just be a rotation of ~30 degrees and maybe a translation of a few pixels.
ROTFID = [140,45;-96,-32;-58,186;60,-184;111,96;-76,-67;127,-146;-126,148;63,123;-43,-88;167,-83;-165,85];
FID = [99,109;-67,-76;-143,132;145,-130;49,138;-32,-96;184,-63;-182,65;-6,138;7,-98;-185,-9;187,11];
tform = tform = fitgeotrans(ROFID,FID, 'similarity');
%Regardless of Forward,Inverse, Fid or ROFID, the answer is clearly wrong
%with an unwanted and incorrect scale factor
answ = transformPointsForward(rform,ROFID);
I tried using imwrap and similar, with and without a reference via imref2d. I also tried a suggestion involving worldToIntrinsic which I did not understand and did not work.
I'd be happy to share my regionprop centroid/orientation half-solution, but I'm confident that solution will not proof robust in final application.
To show the above code gives a poor result:
figure
p1 = scatter(FID(:,1),FID(:,2));
hold;
p2 = scatter(ROFID(:,1),ROFID(:,2));
p3 = scatter(answ(:,1),answ(:,2));
p1 and p2 are rotations of eachother about 0,0. p3 has a strange scaling effect. I cannot seem to suppress it. I cannot seem to extract just the rotation and translation and apply it to the points (for visualizing purposes)
I can use something like this to get the angle, and translation from the matrix:
u = [0 1];
v = [0 0];
[x, y] = transformPointsForward(tform,u,v);
dx = x(2) - x(1);
dy = y(2) - y(1);
angle = (180/pi) *atan2(dy,dx);
translation = [tform.T(3,1) tform.T(3,2)];
%scale can also be gotten here, which is how I know it is wrong.
%scale
scale = 1 / sqrt(dx^2+dy^2);
There could be some shear in here I have not calculated, but the true answer should be 0. All I did was rotate the points in another program.
I hope I have been thorough in my end-goal and efforts so far. Thank you for reading and thinking.
댓글 수: 0
채택된 답변
Matt J
2022년 10월 10일
편집: Matt J
2022년 10월 10일
This FEX download handles your posted data pretty well,
ROTFID = [140,45;-96,-32;-58,186;60,-184;111,96;-76,-67;127,-146;-126,148;63,123;-43,-88;167,-83;-165,85];
FID = [99,109;-67,-76;-143,132;145,-130;49,138;-32,-96;184,-63;-182,65;-6,138;7,-98;-185,-9;187,11];
[reg,FIDFit,err]=absor(ROTFID',FID');
Certainly the rotation angle reg.theta looks close to what it should be,
reg =
struct with fields:
R: [2×2 double]
t: [2×1 double]
s: 1
M: [3×3 double]
theta: 29.9978
댓글 수: 4
Matt J
2022년 10월 11일
편집: Matt J
2022년 10월 11일
Your reordering didn't work. I still see huge errors
err =
struct with fields:
errlsq: 313.0658
errmax: 221.5083
It appears that the second and third points are interchanged this time,
>> [FID,FID_Fit']
ans =
99.0000 109.0000 99.4271 108.6695
-67.0000 -76.0000 -142.5308 131.9365
-143.0000 132.0000 -66.5749 -75.9065
145.0000 -130.0000 144.4901 -129.6796
49.0000 138.0000 48.8317 138.3697
-32.0000 -96.0000 -31.7676 -96.2400
184.0000 -63.0000 183.5570 -63.2961
-182.0000 65.0000 -182.4640 65.0535
-6.0000 138.0000 -6.2379 137.7882
7.0000 -98.0000 7.3101 -97.9520
-185.0000 -9.0000 -184.7872 -9.0047
187.0000 11.0000 186.7465 11.2615
Unfortuantely also, fitgeotrans does not let you do a scaling-free registration, i.e., both nonreflectivesimilarity and similarity both estimate an unknown global stretch factor. Conversely, ABSOR is scaling-free by default, but you can ask absor to estimate a global scaling factor as well with the the input option doScale=true.
추가 답변 (0개)
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!