This enables averaging of affine transformation matrices via quaternions
https://github.com/CCPPETMR/SIRF/pull/375
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
Hey Rich, there might be some issue with the quaternion averaging.
https://arc.aiaa.org/doi/abs/10.2514/1.28949
Looks like you should at least divide by the norm to make sure you have a unit quaternion.
I haven't looked at what you are doing, but in cases where the mean of a set is not clearly defined, one option is to pick from the set an entry that is closest to your expectation of the most representative. (In other words, pick one of the quaternions.) This approach enables you to choose based on expectations, for example, you could compute deformation fields for each quaternion and then select the quaternion that gives the deformation field closest to the mean deformation field within a region of interest.
for example, you could compute deformation fields for each quaternion and then select the quaternion that gives the deformation field closest to the mean deformation field within a region of interest.
It sounds like that involves human input. The current method is simply to align all quaternions with the first:
// Sum up all quaternions. Start with first, loop over rest
Quaternion result(quaternions[0]);
for (unsigned i=1; i<quaternions.size(); ++i) {
// But first, check whether subsequent quaternions need to be inverted.
// Because q and -q are the same rotation, but cannot be averaged, we have to make sure they are all the same.
if (quaternions[i].is_quaternion_close(quaternions[0])) {
result.w += quaternions[i].w;
result.x += quaternions[i].x;
result.y += quaternions[i].y;
result.z += quaternions[i].z;
}
else {
Quaternion flipped = quaternions[i].inverse_sign_quaternion();
result.w += flipped.w;
result.x += flipped.x;
result.y += flipped.y;
result.z += flipped.z;
}
Looks like you should at least divide by the norm to make sure you have a unit quaternion.
Good spot, I put in a normalise
method, but forgot to use it!
Merging #375 into master will not change coverage.
The diff coverage isn/a
.
@@ Coverage Diff @@ ## master #375 +/- ## ======================================= Coverage 50.05% 50.05% ======================================= Files 2 2 Lines 1720 1720 ======================================= Hits 861 861 Misses 859 859
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact)
,ø = not affected
,? = missing data
Powered by Codecov. Last update e600e14...5b2441c. Read the comment docs.
I think David is proposing that you use something more like a median than a mean. If you are trying to choose the best of a few possible transforms for a time point, that could be a good choice to eliminate outliers. If you can measure the distance between two quaternions, you could implement something like a simplified k-medoids algorithm to find a median. But it depends what you are trying to achieve, might not be suitable.
Ah I see. Seems overkill for my purpose, so I won't put it in. But you're right, it would be useful to make everything more robust in the future if more people start using it.
Closed #375.