ImFusion SDK 4.3

Using Poses within the ImFusion SDK. More...

+ Collaboration diagram for Poses:

Detailed Description

Using Poses within the ImFusion SDK.

Overview

Poses are used to describe the (up to)affine transformation between an object and a coordinate system. This page describes how they are used, edited and serialized in ImFusionLib. Refer to Coordinate Systems for more information on the pose matrix conventions.

Usage

Poses can be described with 4x4 matrices or with 12 parameters (translation, rotation, scale, shear). Pose namespace takes care of the conversion between the matrix and the parameter representation. There are multiple Euler angle conventions, for reference this is the one we use:

mat3 Pose::eulerToMat(const vec3& rot)
{
vec3 rotRad = rot * (M_PI / 180.0);
double cx = cos(rotRad[0]), sx = sin(rotRad[0]), cy = cos(rotRad[1]), sy = sin(rotRad[1]), cz = cos(rotRad[2]), sz = sin(rotRad[2]);
// https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
// This appears to be the opposite direction (negative sines) and transposed form of XYZ Tait-Bryan.
// Inverting both the angles and the final matrix (by transposition) should cancel out.
mat3 M;
// clang-format off
M <<
cy*cz, cz*sx*sy - cx*sz, sx*sz + cx*cz*sy,
cy*sz, sx*sy*sz + cx*cz, cx*sy*sz - cz*sx,
-sy, cy*sx, cx*cy;
// clang-format on
return M;
}
mat4 eulerToMat(const vec3 &trans, const vec3 &rot)
Convert a translation and Euler angles to a homogeneous transformation matrix. Angles are in degrees.

Transformation GUI

In ImFusionLib there are many algorithms that require presenting and modifying a pose matrix. For example: calibration and registration of an ultrasound sweep, or the basic transformation of a 3D mesh. Algorithms requiring a GUI to edit a pose matrix can use a TransformationMatrixWidget widget. This widget offers a complete and flexible pose editor.

Example:

// Add the transformation widget
// FROMWORLD is the coordinate system used in the GUI; Returned matrices will be in this coordinate system.
auto * widget = new TransformationMatrixWidget(resetMat, parent, Data::FROMWORLD);
// Receives a matrix in onMatrixChange(const mat4&)
// Triggered when the user changes the values in the UI, or when there is an animation running
connect(widget, &TransformationMatrixWidget::matrixChanged, this, &Example::onMatrixChange);
// Receives the last animated matrix
connect(widget, &TransformationMatrixWidget::animationFinalized, this, &Example::onMatrixChange);
// Sets a matrix without triggering matrixChanged
widget->setMatrixSilent(matrix);
// Sets a matrix with animation.
// matrixChanged triggered at each step of the animation, and animationFinalized will be triggered at the end.
widget->setMatrixAnimated(animatedMat);
void matrixChanged(const mat4 &matrix) const
Signals when the transformation matrix changes.

Basic UI:

// Widget only containing Translation parameters, and copy and paste buttons
auto * widget = new TransformationMatrixWidget(mat, parent, Data::FROMWORLD, "World", "Data", TransformationMatrixWidget::Translation, TransformationMatrixWidget::CopyPaste);
@ Translation
Translation.
Definition TransformationMatrixWidget.h:45
@ CopyPaste
Copy, Paste.
Definition TransformationMatrixWidget.h:55

Flexible UI:

// Rigid parameters only
auto flags = Flags<TransformationMatrixWidget::Type>(TransformationMatrixWidget::Rigid);
// Global/Local, From/To World, copy and paste buttons.
// Using Tracker instead of World, and Image instead of Data, to clarify matrix convention to user
auto * widget = new TransformationMatrixWidget(mat4::Identity(), parent, Data::TOWORLD, "Tracker", "Image", flags, options);
@ Rigid
Translation, Rotation.
Definition TransformationMatrixWidget.h:48
@ ToFromWorld
To world, from world.
Definition TransformationMatrixWidget.h:57
@ GlobalLocal
Global or Local.
Definition TransformationMatrixWidget.h:56

Serialization

It's useful to input and output Poses in ImFusionLib. For example, copy a calibration matrix from Python and paste it in ImFusionLib. PoseIO namespace takes care of the serialization of the poses, represented as matrices or as parameters.

With files:

mat4 matrix;
std::string path = "matrix.txt";
bool successSave = PoseIO::poseToFile(matrix, path);
mat4 result;
bool successLoad = PoseIO::fileToPose(path, result);
bool fileToPose(const std::string &file, mat4 &outPose)
Recover matrix from file.
bool poseToFile(const mat4 &pose, const std::string &file)
Store matrix in file.

With clipboard:

// Using copy to clipboard is straightforward
// Or if you have a set of affine parameters
vec3 trans, rot, scale, shear;
// copy them to clipboard
PoseIO::affineToClipboard(trans, rot, scale, shear);
// Reading back from clipboard, try to parse affine params, or matrix
mat4 pose;
{
// matrix in pose
}
else if (PoseIO::clipboardToAffine(trans, rot, scale, shear))
{
mat4 pose = Pose::affineToMat(trans, rot, scale, shear);
// matrix in pose
}
mat4 affineToMat(const vec3 &trans, const vec3 &rot, const vec3 &scale, const vec3 &shear, bool linearScale=false)
Compose a homogenous transformation matrix from affine parameters.
void poseToClipboard(const mat4 &pose)
Store matrix to clipboard.
void affineToClipboard(const vec3 &trans, const vec3 &rot, const vec3 &scale, const vec3 &shear)
Store affine parameters to clipboard.
bool clipboardToPose(mat4 &outPose)
Recover matrix from clipboard.
bool clipboardToAffine(vec3 &outTrans, vec3 &outRot, vec3 &outScale, vec3 &outShear)
Recover affine parameters from clipboard.

Similarly, you can serialize the pose directly to a string with PoseIO::poseToString(matrix);

Namespaces

namespace  ImFusion::Pose
 Conversion of pose matrices.
 
namespace  ImFusion::PoseIO
 Input and output of pose matrices and affine parameters.
 

Classes

class  TransformationMatrixWidget
 Widget to transform a matrix, with global/local and toWorld/fromWorld modifiers. More...
 
Search Tab / S to search, Esc to close