ReconstructMe SDK  2.6.43-0
Real-time 3D reconstruction engine
example_reconstructmesdk_sensor_external.cpp

Content

Shows how to use an existing sensor with ReconstructMe. This allows you to share a sensor resource between your application and ReconstructMe.I n this example we will connect to a sensor using OpenNI and use share its data with ReconstructMe. This example focuses on depth maps. Similar things can be done for auxilary (color) images.

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

#include <boost/test/unit_test.hpp>
#include <OpenNI.h>
BOOST_AUTO_TEST_SUITE(example_reconstructmesdk)
// Test for OpenNI errors
#define OPENNI_ASSERT(expr) \
if (!(expr) == openni::STATUS_OK) \
throw std::runtime_error(openni::OpenNI::getExtendedError());
BOOST_AUTO_TEST_CASE(sensor_external) {
// Create OpenNI sensor to be used as external sensor.
openni::Device ni_dev;
openni::VideoStream ni_depth;
openni::VideoFrameRef ni_depth_frame;
OPENNI_ASSERT(openni::OpenNI::initialize());
OPENNI_ASSERT(ni_dev.open(openni::ANY_DEVICE));
OPENNI_ASSERT(ni_depth.create(ni_dev, openni::SENSOR_DEPTH));
OPENNI_ASSERT(ni_depth.start());
// Create ReconstructMe context
// Create external sensor.
reme_sensor_create(c, "external", false, &s);
// Since we are using an external sensor, we need to tell ReMe about its image size field of view.
int image_width = ni_depth.getVideoMode().getResolutionX();
int image_height = ni_depth.getVideoMode().getResolutionY();
reme_options_set_int(c, o, "depth_stream.image_size.width", image_width);
reme_options_set_int(c, o, "depth_stream.image_size.height", image_height);
// The following intrinsics are based on a Kinect like device. By providing
// intrinsics.width and intrinsics.height ReMe is able to automatically derive intrinsics
// for different stream sizes.
reme_options_set_int(c, o, "depth_stream.intrinsics.width", 640);
reme_options_set_int(c, o, "depth_stream.intrinsics.height", 480);
reme_options_set_real(c, o, "depth_stream.intrinsics.fx", 530);
reme_options_set_real(c, o, "depth_stream.intrinsics.fy", 530);
reme_options_set_real(c, o, "depth_stream.intrinsics.cx", 320);
reme_options_set_real(c, o, "depth_stream.intrinsics.cy", 240);
// Open the sensor like any other sensor.
// In order inform ReMe about external sensor data
reme_image_t raw_depth;
reme_image_create(c, &raw_depth);
// Create a new volume
// Create a viewer
reme_viewer_t viewer;
reme_viewer_create_image(c, "This is ReconstructMe SDK", &viewer);
reme_image_t images_to_show[2];
reme_image_create(c, &images_to_show[0]);
reme_image_create(c, &images_to_show[1]);
reme_viewer_add_image(c, viewer, images_to_show[0]);
reme_viewer_add_image(c, viewer, images_to_show[1]);
// Perform reconstruction while viewer is not closed.
bool viewer_done = false;
while (!viewer_done)
{
// Grab from the real sensor
int index;
openni::VideoStream* streams[] = {&ni_depth};
OPENNI_ASSERT(openni::OpenNI::waitForAnyStream(streams, 1, &index, 500));
OPENNI_ASSERT(ni_depth.readFrame(&ni_depth_frame));
const unsigned short *sensor_pixel = (const unsigned short *)ni_depth_frame.getData();
// ... Potentially modify sensor input before passing to ReMe
// Get hold of raw depth image reference provded by ReMe.
void *virtual_pixel;
int nbytes;
reme_image_get_mutable_bytes(c, raw_depth, &virtual_pixel, &nbytes);
// Copy content
memcpy(virtual_pixel, sensor_pixel, image_width * image_height * sizeof(unsigned short));
// Only need to prepare volume data.
}
// Update the viewer
reme_sensor_get_image(c, s, REME_IMAGE_DEPTH, images_to_show[0]);
reme_sensor_get_image(c, s, REME_IMAGE_VOLUME, images_to_show[1]);
reme_viewer_update(c, viewer);
reme_viewer_is_closed(c, viewer, &viewer_done);
}
reme_viewer_t volume_viewer;
reme_viewer_create_volume(c, v, s, "This is ReconstructMeSDK - Volume", &volume_viewer);
reme_viewer_wait(c, volume_viewer);
}
BOOST_AUTO_TEST_SUITE_END()