Workspace Calibration

With a workspace calibration you can change the coordinate system of the PointMap by using a calibration pattern as a reference.

Note: This how-to shows how a workspace calibration can be done with the NxLib. When you only want to do it once, you can also use NxView. Simply open the camera that you want to calibrate and choose the “Workspace Calibration” Mode.

To perform a workspace calibration, you will need the following steps.

  • Place a calibration pattern at a known point of your desired coordinate system (e.g. the origin) such that the camera can see it.

  • Take an image with the Capture command.

  • Search for the calibration pattern with the CollectPattern command.

  • Compute the pose of this pattern with the EstimatePatternPose command.

  • Execute the CalibrateWorkspace command. Use the estimated pattern pose from the previous step as the PatternPose parameter and give the desired pose of the calibration pattern in your new coordinate system as the

    DefinedPose parameter.

  • When the command is done, you can continue with grabbing 3D data. The points will now be in your new coordinate system.

Note

The calibration only persists until the camera is closed. To permanently store it on the camera, you can execute the StoreCalibration command with the Link parameter enabled.

Note

  • To get better calibration results, you can take multiple images of the same calibration pattern and use the Average parameter for the EstimatePatternPose command.

  • After mounting a camera at a new position, it might be useful to perform a recalibration. This can be done with the patterns that you collected for the workspace calibration anyway. See this how-to for a code snippet that performs a recalibration and can be inserted into the example code below.

Code Examples

Note

We assume that the camera with serial “1234” is already open. See here for information on how this can be done.

// Turn off the camera's projector so that we can observe the calibration pattern.
NxLibItem()[itmCameras]["1234"][itmParameters][itmCapture][itmProjector] = false;
NxLibItem()[itmCameras]["1234"][itmParameters][itmCapture][itmFrontLight] = true;

// Clear the pattern buffer in case there are any old observations in it.
NxLibCommand(cmdDiscardPatterns).execute();

// Take some images and search for the calibration patterns in them.
for (int i = 0; i < 10; i++) {
	NxLibCommand capture(cmdCapture);
	capture.parameters()[itmCameras] = "1234";
	capture.execute();
	try {
		NxLibCommand collectPattern(cmdCollectPattern);
		collectPattern.parameters()[itmCameras] = "1234";
		collectPattern.execute();
	} catch (NxLibException&) {
		// Could not find any calibration patterns...
	}
}

// You can insert a recalibration here, as you already captured stereo patterns anyway. See here for a
// code snippet that does a recalibration.

// Estimate the position of the calibration pattern. We increase the precision of this step by averaging
// over all of the collected pattern positions.
NxLibCommand estimatePatternPose(cmdEstimatePatternPose);
estimatePatternPose.parameters()[itmAverage] = true;
estimatePatternPose.execute();

// Perform a workspace calibration with the estimated pattern pose as input. At this point you could
// also specify the target location of the calibration pattern with the DefinedPose parameter. Leaving
// it empty will set the calibration pattern to the origin of the new coordinate system.
NxLibCommand calibrateWorkspace(cmdCalibrateWorkspace);
calibrateWorkspace.parameters()[itmCameras] = "1234";
calibrateWorkspace.parameters()[itmPatternPose] << estimatePatternPose.result()[itmPatternPose];
calibrateWorkspace.execute();

// Store the new calibration to the camera's EEPROM.
NxLibCommand storeCalibration(cmdStoreCalibration);
storeCalibration.parameters()[itmCameras] = "1234";
storeCalibration.parameters()[itmLink] = true;
storeCalibration.execute();

// When you compute a point map now, the result will be in workspace coordinates.

Your installation of the NxLib contains an extended version of this example with better error handling and more features in the examples. Before running this example, you should connect a single Ensenso camera to your computer.

* Make a handle referencing the parameter tree root
open_framegrabber( 'Ensenso-NxLib'000000, 'default'0, 'Raw'-1, 'false', 'Item', '/'00RootHandle)

* Open the first available stereo camera
open_framegrabber( 'Ensenso-NxLib'000000, 'default'0, 'Raw'-1, 'false', 'Stereo', ''00Camera)

* Get the serial number of the opened camera
get_framegrabber_param(Camera, 'SerialNumber'SerialNumber)

* For collecting patterns it is necessary to capture with front light enabled
set_framegrabber_param(Camera, 'Parameters/Capture/FrontLight', 'true' )
set_framegrabber_param(Camera, 'Parameters/Capture/Projector', 'false' )

* Clear the pattern buffer in case there are any old observations in it.
set_framegrabber_param(RootHandle, 'do_execute', 'DiscardPatterns' )

* To get a better calibration result we average over multiple captured pattern positions
for Index := 1 to 10 by 1
    try
        * Capture image with open camera
        set_framegrabber_param(RootHandle, 'do_execute', 'Capture' )
        * Try to collect pattern in captured image
        set_framegrabber_param(RootHandle, 'do_execute', 'CollectPattern' )
    catch (Exception)
    endtry
endfor

* You can insert a recalibration here, as you already captured stereo patterns anyway.
set_framegrabber_param(RootHandle, 'do_execute', 'EstimatePatternPose' )

* Get estimated pattern position
get_framegrabber_param(RootHandle, 'exec:Result/PatternPose'PatternPose)

* Execute workspace calibration
set_framegrabber_param(RootHandle, 'exec:Parameters/Cameras', [ 'string'SerialNumber])
set_framegrabber_param(RootHandle, 'exec:Parameters/PatternPose', [ 'apply'PatternPose])
set_framegrabber_param(RootHandle, 'do_execute', 'CalibrateWorkspace' )

* Write the new link into the eeprom of the camera.
* This will overwrite your old link!

set_framegrabber_param(RootHandle, 'exec:Parameters/Cameras', [ 'string'SerialNumber])
set_framegrabber_param(RootHandle, 'exec:Parameters/Link', 'true')
set_framegrabber_param(RootHandle, 'do_execute', 'StoreCalibration')

* When you compute a point map now, the result will be in workspace coordinates
close_framegrabber(Camera)
close_framegrabber(RootHandle)

Note

To check the calibration, there is a code snippet that does a recalibration. See here for a code snippet that does a recalibration.