// -----------------------------------------------------------------------------
// ********************************* SchmittC **********************************
// -----------------------------------------------------------------------------
//
//! file="amma/Surf3d/Regis/Schmitt.hh"
//! author = "Simon Cunnington"
//! date = "19/11/98"
//! userlevel = Normal
//! lib=Regis
//! rcsid = "$Id: Schmitt.hh,v 1.6 2000/02/16 14:13:07 ees1cg Exp $"
//! docentry = "3D Surface.Registration"
// Synopsis : Performs N Point Set Registration Using Schmitt's Method
// -----------------------------------------------------------------------------
//
// Authors : Simon Cunnington
//
// Current Details :
//
// $RCSfile: Schmitt.hh,v $
// $Revision: 1.6 $
// $Author: ees1cg $ modified this file on $Date: 2000/02/16 14:13:07 $
//
//
// Copyright (C) 1998-1999 University of Surrey, UK. All Rights Reserved.
//
// The copyright to the computer program(s) herein is the property of the
// University of Surrey, UK. The program(s) may be used and/or copied only
// with the written permission of the University of Surrey or in accordance
// with the terms and conditions stipulated in the agreement/contract under
// which the program(s) have been supplied. This copyright notice must not be
// removed.
//
#ifndef SCHMITT_HH
#define SCHMITT_HH
#include "amma/CorrSet.hh"
#include "amma/RigidT.hh"
#include "amma/Matrix.hh"
#include "amma/Array2d.hh"
#include "amma/VecSet.hh"
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
enum enumXYZ { x, y, z};
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
// -----------------------------------------------------------------------------
// ********** SchmittC *****************************************************
// -----------------------------------------------------------------------------
//
//: The SchmittC class registers N point sets using Schmitt's method.
//
//
// The SchmittC class registers N point sets using Schmitt's method.
//
// There are M overlapping sets of points (Schmitt's notation), which means
// that each view has a point set, so M is the number of views. The overlap
// between two different views, are subsets of the point sets belonging to
// each view, and this is a correspondence set.
//
// Algorithm
// - Calculate all constant matrices (Abar, Pbar, all Q's =Qr+Qt).
// - Main Loop: While not converged do
// -> Calculate all N^j's & hence the quaternions (rotations).
// -> Calculate Bbar (diff between rotated centroids).
// -> Calculate Xbar (translations).
// -> Update Rigid Transforms.
// -> Calculate MSE.
// -> Determine if convergence has occurred.
//
// The constructor allows guesses to be passed which will then be used to
// initialise the elements of rtsM. Each element being associated with a view.
//
// The expected rigid transforms can be passed via the function SetExpectedRTs,
// which is only used for the calculation of delta theta.
//
//
class SchmittC
{
/* MEMBER FUNCTIONS */
/* ---------------- */
public :
/* Constructors & Destructors */
/* -------------------------- */
SchmittC(CorrSetC corrset, SArray1dC rtguesses,
double rmsthresh=0.99, int trace=0,
int miniter=-1, int maxiter=1000);
//: Constructor. The Guesses that are passed are used to setup rtsM.
//: They are not applied to each view.
//
// The expected RTs are to be set by using SetExpectedRTs.
// However they are defaulted to Null Transforms!
~SchmittC(void);
//: Destructor.
/* Expected RTs */
/* ------------ */
void
SetExpectedRTs(SArray1dC expectedrts);
//: Used to set the expected RTs.
/* Main Function */
/* ------------- */
SArray1dC
Solve(void);
//: The main function which determines the optimal Rigid Transforms
//: for each view.
protected :
/* EigenVector */
/* ----------- */
VectorC
CalcEigenVector(MatrixC &nJ);
//: Determines eigenvectors & eigenvalues for nJ, and returns
//: the eigenvector that has the highest eigenvalue.
/* To Determine Convergence */
/* ------------------------ */
double
CalcMSE(void);
//: Calculates the Mean Square Error.
BooleanT
Converged(int iteration);
//: Determines whether convergence has occurred.
/* Matrice Calculations */
/* -------------------- */
void
CreateABarMatrices(void);
//: Creates the matrix "A bar" and it's inverse, and the fudge
//: (with extra column & row with 0's in).
//
// Sticking to Schmitt's notation.
//
// This should be called only once at the beginning.
void
RecalculateBBar(void);
//: Recalculates the matrix "B bar".
void
CalculatePBar(void);
//: Calculates the matrix "P bar".
void
RecalculateXBarMin(void);
//: Recalculates the matrix "X bar min", i.e. translations.
void
RecalculateQr(int alpha, int beta, MatrixC &qR);
//: Recalculates the matrix "Qr".
double
CalculateS(int alpha, int beta, enumXYZ index1, enumXYZ index2);
//: Calculates S with indices of xx, yy, zz or any combination.
//: To be used by RecalculateQr() only!
void
RecalculateQt(int alpha, int beta, MatrixC &qT);
//: Recalculates the matrix "Qt".
double
CalculateSBar(int alpha, int beta, enumXYZ index1, enumXYZ index2);
//: Calculates S Bar with indices of xx, yy, zz or any combination.
//: To be used by RecalculateQt() only!
void
RecalculateNj(int j, MatrixC &nJ);
//: Calculates N^j, which is used to determine the optimal quaternion
//: for the view j.
void
CreateAllQMatrices(void);
//: Creates an array of 4x4 Symmetrical Matrices, indexed by
//: alpha & beta, where each element is Qr + Qt.
/* MEMBER DATA */
/* ----------- */
protected :
/* Correspondence Set Info */
/* ----------------------- */
int nviewsM; // The total number of views.
int ncsetsM; // The total number of correspondence sets.
CorrSetC corrsetM; // Correspondence sets, with member functions
// which for example can apply an RT per view
SArray1dC csetsM; // Handle to correspondence sets,
// ie. csetsM = corrsetM.csetsM;
/* Rigid Transforms */
/* ---------------- */
SArray1dC rtsM; // Transforms associated with each view.
SArray1dC qtsM; // Quaternions associated with each view.
/* Matrices etc. Used In Algorithm */
/* ------------------------------- */
Array2dC lookupM; // Look Up Table: Each element contains the
// point set alpha beta.
MatrixC aBarInverseM; // _-1
// Matrix A .
//
// Note: indexing [0][0] == [alpha+1][beta+1]
MatrixC aBarInvPaddedM; // This has an extra column & row with 0's in.
Array2dC pBarM; // Contains centroids for point set alpha beta.
VectorSetC bBarM; // _ : Contains differences between rotated
// B : centroids of the overlaps.
//
// Note: bBarM[0] == bBarM[alpha+1]
VectorSetC xBarMinM; // Contains the translations.
//
// Note: xBarMinM[0] == xBarMinM[alpha+1]
Array2dC qM; // Array of 4x4 Symmetrical Matrices, indexed by
// alpha & beta, where each element is Qr + Qt
/* Expected RTs */
/* ------------ */
SArray1dC rtsexpectedM; // RTs expected (inverses of guesses)
/* Constants */
/* --------- */
/* Options */
const double RmsThreshM; // Used in convergence test
const int traceM; // Trace: 0->no trace, 1->basic, 2->full
const int minIterationsM; // Termination criteria is not used until the
// minimum number of iterations has been done.
const int maxIterationsM; // Maximum number of iterations allowed.
const double NearZeroM; // Used for equal to zero tests
};
#endif