This page provides a sample and instructions on how to use Motive API functions to calibrate a camera system.
Sample Code
The following sample code demonstrates calibration process using the Motive API. For details on specific functions, please refer to the page.
Masking
Auto-Masking
Auto-Masking is done directly by calling the TT_AutoMaskAllCameras function. When this is called, Motive will sample for a short amount of time and apply a mask to the camera imagers where light was detected.
<source> //== To auto-mask, call TT_AutoMaskAllCameras().
This function returns memory block of the mask. One bit per a pixel of the mask. Masking pixels are rasterized from left to right and from top to bottom of the camera's view.
Clear Masks
This function can clear existing masks from the 2D camera view. It returns true when it successfully removes pixel masks. Otherwise, masking is always additive through the API.
Set Camera Mask
The TT_SetCameraMask can be used to replace the existing camera mask for any camera. A mask is an array of bytes, one byte per mask pixel block. Returns true when masks are applied.
Wanding
Ground Plane
Setting ground plane is done directly by calling the TT_SetGroundPlane function. When this is called, camera system will search for 3-markers that resemble a calibration square and uses the inputted vertical offset value to configure the ground plane.
//== NaturalPoint Motive API Calibration Sample Application ==
include <windows.h>
include <conio.h>
include <stdio.h>
include <stdlib.h>
include <math.h>
include <string>
include "NPTrackingTools.h"
// Local function prototypes void CheckResult( NPRESULT result );
std::string CalibrationStateString( TT_CameraCalibrationStates state ) {
switch( state )
{
case TT_CameraCalibration_Initialized: return "Init ";
case TT_CameraCalibration_Sampling: return "Sampling";
case TT_CameraCalibration_Solving: return "Solving ";
case TT_CameraCalibration_Complete: return "Complete";
case TT_CameraCalibration_Uninitialized: break;
default: break;
}
return "Unknown ";
}
// Main application int main( int argc, char* argv[] ) {
printf( "== NaturalPoint Motive API Calibration Sample Application =======---\n" );
printf( "== (C) NaturalPoint, Inc.\n\n" );
printf( "Initializing NaturalPoint Devices\n" );
if( TT_Initialize() != NPRESULT_SUCCESS )
{
printf( "Unable to license Motive API\n" );
return 1;
}
// Do an update to pick up any recently-arrived cameras.
TT_Update();
// List all detected cameras.
printf( "Cameras:\n" );
for( int i = 0; i < TT_CameraCount(); i++)
{
printf( "\t%s\n", TT_CameraName(i) );
}
printf("\n");
//== lets set our wand settings ==--
cCameraCalibrationSettings settings;
settings.WandLength = 0.250; // wand length = 250mm
settings.WandCenterOffset = 0.0875; // wand center offset = 87.5mm
if( TT_SetCalibrationSettings( settings ) != NPRESULT_SUCCESS )
{
printf( "Unable to set camera calibration settings.\n\n" );
}
if( TT_CalibrationSettings( settings ) == NPRESULT_SUCCESS )
{
//== fetch & print default wand settings ==--
printf( "Wand Length = %.1fmm\n", settings.WandLength * 1000 );
printf( "Wand Center Offset = %.1fmm\n", settings.WandCenterOffset * 1000 );
}
else
{
printf( "Unable to fetch camera calibration settings.\n\n" );
}
printf( "\n" );
printf( "Press 1: Start Wanding\n" );
printf( "Press 2: Start Calculation\n" );
printf( "Press 3: Apply Calibration\n" );
printf( "Press 4: Reset\n" );
printf( "\n" );
int frameCounter = 0;
bool done = false;
while( !done )
{
if( _kbhit() )
{
char c = _getch();
if( c == '1' )
{
printf( "Start Wanding: " );
if( TT_StartCalibrationWanding() )
{
printf( "Success\n" );
}
else
{
printf( "Failed\n" );
}
}
if( c == '2' )
{
printf( "Start Solving: " );
if( TT_CameraCalibrationSolve() )
{
printf( "Success\n" );
}
else
{
printf( "Failed\n" );
}
}
if( c == '3' )
{
printf( "Apply Calibration: " );
if( TT_CameraCalibrationApplyResult() )
{
printf( "Success\n" );
}
else
{
printf( "Failed\n" );
}
}
if( c == '4' )
{
printf( "Reset Calibration: " );
if( TT_CameraCalibrationReset() )
{
printf( "Success\n" );
}
else
{
printf( "Failed\n" );
}
}
}
if( TT_Update() == NPRESULT_SUCCESS )
{
frameCounter++;
if( (frameCounter%100) == 0 )
{
//== every 100 frames print ongoing sample and calibration state information ==--
printf( "Frame[%5d] Markers[%3d] Calibration State[%s] ", frameCounter, TT_FrameMarkerCount(), CalibrationStateString( TT_CalibrationState()).c_str() );
if( TT_CalibrationState() == TT_CameraCalibration_Sampling )
{
for( int index = 0; index < TT_CameraCount(); index++ )
{
printf( "%d ", TT_CameraCalibrationSamples( index ) );
}
printf( "\n\nWand Location\n" );
printf( "-----------------------\n" );
float points[ 6 ];
for( int index = 0; index < TT_CameraCount(); index++ )
{
bool wandPresent = TT_CameraWandLocation( index, points );
printf( "Camera #%d: ", index );
if( wandPresent )
{
printf( "[Present ] " );
for( int pointIndex = 0; pointIndex < 6; pointIndex += 2 )
{
printf( "%.1f,%.1f ", points[ pointIndex ], points[ pointIndex + 1 ] );
}
}
else
{
printf( "[Not Present] " );
}
printf( "\n" );
}
printf( "\n" );
}
printf( "\n" );
}
}
Sleep(2);
}
printf( "Shutting down NaturalPoint Motive API\n" );
CheckResult( TT_Shutdown() );
printf( "Complete\n" );
while( !_kbhit() )
{
Sleep(20);
}
return 0;
}
void CheckResult( NPRESULT result ) //== CheckResult function will display errors and ---
//== exit application after a key is pressed =====---
{
if( result!= NPRESULT_SUCCESS)
{
// Treat all errors as failure conditions.
printf( "Error: %s\n\n(Press any key to continue)\n", TT_GetResultString(result) );
Sleep(20);
exit(1);
}
}
//== To apply ground plane, call TT_SetGroundPlane(). Specify the vertical offset from the marker centers in meters.
TTAPI bool TT_SetGroundPlane( float verticalOffset );