ReconstructMe SDK  2.6.43-0
Real-time 3D reconstruction engine


This short example shows how to use ReconstructMe SDK together with markers to intuitively position the reconstruction volume. The example reproduces what is shown in our preview video below.

Boost is only used to generate examples and is not necessary for working with this SDK.

#include <boost/test/unit_test.hpp>
#include <stdio.h>
#include <conio.h>
#include <iostream>
BOOST_AUTO_TEST_CASE(marker_detection) {
puts("Key mapping");
puts("s: start scanning. Marker needs to be fully visible in sensor.");
puts("x: done scanning");
puts("All keys need to be pressed with the command line in the foreground");
// Create a new context
// Create a license object
reme_error_t e = reme_license_authenticate(c, l, "license.txt.sgn");
// Create options
// Specify the volume dimensions. We set it in such a way that
// when the marker is detected and it becomes the origin of the world,
// the volume floats centric above the marker and cuts away floor data.
reme_options_set_int(c, o, "volume.minimum_corner.x", -200);
reme_options_set_int(c, o, "volume.minimum_corner.y", -200);
reme_options_set_int(c, o, "volume.minimum_corner.z", 2);
reme_options_set_int(c, o, "volume.maximum_corner.x", 200);
reme_options_set_int(c, o, "volume.maximum_corner.y", 200);
reme_options_set_int(c, o, "volume.maximum_corner.z", 402);
reme_options_set_bool(c, o, "data_integration.use_colors", true);
// Compile for OpenCL device using defaults
// Create a new volume
// Create a new sensor. For marker detection depth to aux alignment should be enabled,
// which it is by default.
reme_sensor_create(c, "openni;mskinect;file", true, &s);
// Create a marker detector attached to the sensor.
reme_options_set_real(c, o, "marker_size", 90.f);
// Use color in rendering volume image
reme_options_set(c, o, "shade_mode", "SHADE_COLORS");
// Create viewer and start reconstruction
reme_viewer_t viewer;
reme_viewer_create_image(c, "This is ReconstructMe SDK", &viewer);
reme_image_t volume, aux;
reme_image_create(c, &volume);
reme_viewer_add_image(c, viewer, aux);
reme_viewer_add_image(c, viewer, volume);
bool done = false;
bool scan = false;
bool first = false;
float marker_pos[16];
while (!done && REME_SUCCESS(reme_sensor_grab(c, s))) {
if (_kbhit()) {
char k = _getch();
switch (k) {
case 'x':
done = true;
case 's':
scan = !scan;
first = scan;
if (!scan) {
// When not yet scanning we search for the marker
int nmarkers = 0;
reme_marker_detector_find(c, md, &nmarkers);
// When we have at least one marker found, we just remember its position
// and mark it in the image for debug viewing.
if (nmarkers > 0) {
reme_marker_detector_get_position(c, md, 0, marker_pos);
} else {
if (first) {
// Scanning just started, use remembered marker pose to position camera.
float inv_marker_pos[16];
reme_transform_invert(c, marker_pos, inv_marker_pos);
reme_sensor_set_position(c, s, inv_marker_pos);
first = false;
} else {
// Scanning is already running for a while, do the standard reme thing.
reme_viewer_update(c, viewer);
// Close and destroy the sensor, it is not needed anymore
// Create surface from volume
// Remove small unconnected parts
// Fill holes and make mesh watertight
// Prepare to cut the bottom of the surface
reme_csg_create(c, v, &csg);
// Keep the color volume, but clear the geometric volume.
reme_volume_reset_selectively(c, v, true, false);
// Insert the watertight mesh
// Cut with plane at height 0, parallel to xy.
float cut_plane[4] = {0, 0, 1, 0};
// In case anything is sticking out of the volume (e.g on top), close it now.
// Generate the final mesh.
// Save mesh
reme_surface_save_to_file(c, m, "test.ply");
// Visualize resulting surface
reme_viewer_t viewer_surface;
reme_viewer_create_surface(c, m, "This is ReconstructMeSDK", &viewer_surface);
reme_viewer_wait(c, viewer_surface);
// Print pending errors
// Make sure to release all memory acquired
// Image to hold marker template image
reme_image_t marker;
reme_image_create(c, &marker);
// Marker detector that supplies template image. Note that
// the marker detector need to be a valid one.
// Save image for later printing.
reme_image_save_to_file(c, marker, "marker_213.png");
// Display marker inline for debugging purposes.
reme_viewer_create_image(c, "Marker Viewer", &v);
reme_viewer_add_image(c, v, marker);