44 #include <XnCppWrapper.h> 45 #include <opencv2/opencv.hpp> 46 #include <boost/thread.hpp> 47 #include <sys/times.h> 52 using namespace boost;
65 ImgContext (
const Mat & img) : image (img), is_new (false)
79 void writeImages ()
const;
83 vector< boost::shared_ptr<OpenNIDevice> >
devices_;
93 , selected_device_ (0)
97 for (vector<unsigned>::const_iterator indexIt = device_indices.begin (); indexIt != device_indices.end (); ++indexIt)
101 cout <<
"Index out of range." << driver.
getNumberDevices () <<
" devices found." << endl;
106 cout <<
devices_.size () + 1 <<
". device on bus: " << (int)device->getBus () <<
" @ " << (int)device->getAddress ()
107 <<
" with serial number: " << device->getSerialNumber () <<
" " 108 << device->getVendorName () <<
" : " << device->getProductName () << endl;
111 const int width = 640;
112 const int height = 480;
113 XnMapOutputMode mode;
118 if (device->hasImageStream())
120 if (!device->isImageModeSupported (mode))
122 cout <<
"image stream mode " << mode.nXRes <<
" x " << mode.nYRes <<
" @ " << mode.nFPS <<
" not supported" << endl;
125 namedWindow (
string (device->getConnectionString ()) +
"RGB", WINDOW_AUTOSIZE);
126 namedWindow (
string (device->getConnectionString ()) +
"Gray", WINDOW_AUTOSIZE);
131 if (device->hasDepthStream())
133 if (!device->isDepthModeSupported (mode))
135 cout <<
"depth stream mode " << mode.nXRes <<
" x " << mode.nYRes <<
" @ " << mode.nFPS <<
" not supported" << endl;
138 namedWindow (
string (device->getConnectionString ()) +
"Depth", WINDOW_AUTOSIZE);
145 gettimeofday (×tamp, NULL);
155 for (map<string, ImageContext*>::iterator imageIt =
rgb_images_.begin (); imageIt !=
rgb_images_.end (); ++imageIt)
157 delete imageIt->second;
160 for (map<string, ImageContext*>::iterator imageIt =
gray_images_.begin (); imageIt !=
gray_images_.end (); ++imageIt)
162 delete imageIt->second;
167 delete imageIt->second;
173 cout <<
"write images" << endl;
174 static unsigned index = 0;
177 cout <<
"locking rgb images..." << flush;
178 map<string, ImageContext*>::const_iterator imageIt;
180 imageIt->second->lock.lock ();
182 cout <<
"done\nlocking gray images..." << flush;
184 imageIt->second->lock.lock ();
188 cout <<
"locking rgb images..." << flush;
192 sprintf (file_name,
"rgb_%03u.png", index);
193 imwrite (file_name, imageIt->second->image);
198 sprintf (file_name,
"gray_%03u.png", index);
199 imwrite (file_name, imageIt->second->image);
210 imageIt->second->lock.unlock ();
213 imageIt->second->lock.unlock ();
221 gettimeofday (×tamp, NULL);
223 double now = timestamp.tv_sec + timestamp.tv_usec * 0.000001;
234 unique_lock<mutex> rgb_lock (rgb_image_context->
lock);
235 unsigned char* rgb_buffer = (
unsigned char*)(rgb_image_context->
image.data + (rgb_image_context->
image.cols >> 2) * rgb_image_context->
image.elemSize () +
236 (rgb_image_context->
image.rows >> 2) * rgb_image_context->
image.step);
237 image->fillRGB (rgb_image_context->
image.cols >> 1, rgb_image_context->
image.rows >> 1, rgb_buffer, rgb_image_context->
image.step);
259 rgb_image_context->
is_new =
true;
262 unique_lock<mutex> gray_lock (gray_image_context->
lock);
264 unsigned char* gray_buffer = (
unsigned char*)(gray_image_context->
image.data + (gray_image_context->
image.cols >> 2) +
265 (gray_image_context->
image.rows >> 2) * gray_image_context->
image.step);
266 image->fillGrayscale (gray_image_context->
image.cols >> 1, gray_image_context->
image.rows >> 1, gray_buffer, gray_image_context->
image.step);
268 gray_image_context->
is_new =
true;
275 gettimeofday (×tamp, NULL);
282 unique_lock<mutex> depth_lock (depth_image_context->
lock);
283 float* buffer = (
float*)(depth_image_context->
image.data + (depth_image_context->
image.cols >> 2) *
sizeof(float) +
284 (depth_image_context->
image.rows >> 2) * depth_image_context->
image.step );
285 depth->fillDepthImage (depth_image_context->
image.cols >> 1, depth_image_context->
image.rows >> 1, buffer, depth_image_context->
image.step);
287 depth_image_context->
is_new =
true;
297 for (map<string, ImageContext*>::iterator imageIt =
rgb_images_.begin (); imageIt !=
rgb_images_.end (); ++imageIt)
299 if (imageIt->second->is_new && imageIt->second->lock.try_lock ())
302 cvtColor (imageIt->second->image, bgr_image, CV_RGB2BGR);
303 imshow (imageIt->first +
"RGB", bgr_image);
304 imageIt->second->is_new =
false;
305 imageIt->second->lock.unlock ();
309 for (map<string, ImageContext*>::iterator imageIt =
gray_images_.begin (); imageIt !=
gray_images_.end (); ++imageIt)
311 if (imageIt->second->is_new && imageIt->second->lock.try_lock ())
313 imshow (imageIt->first +
"Gray", imageIt->second->image);
314 imageIt->second->is_new =
false;
315 imageIt->second->lock.unlock ();
321 if (imageIt->second->is_new && imageIt->second->lock.try_lock ())
324 imageIt->second->image.convertTo (gray_image, CV_8UC1, 25.5);
325 imshow (imageIt->first +
"Depth", gray_image);
326 imageIt->second->is_new =
false;
327 imageIt->second->lock.unlock ();
331 unsigned char key = waitKey (30) & 0xFF;
405 cout <<
"exception caught: " << exception.
what () << endl;
411 cout <<
"unknown exception caught" << endl;
417 int main (
int argc,
char** argv)
422 cout <<
"Usage: " << argv[0] <<
" (<device-index>)+" << endl;
425 for (
unsigned deviceIdx = 0; deviceIdx < driver.
getNumberDevices (); ++deviceIdx)
427 cout <<
"Device: " << deviceIdx <<
", vendor: " << driver.
getVendorName (deviceIdx) <<
", product: " << driver.
getProductName (deviceIdx)
428 <<
", connected: " << (int)driver.
getBus (deviceIdx) <<
" @ " << (int)driver.
getAddress (deviceIdx) <<
", serial number: \'" << driver.
getSerialNumber (deviceIdx) <<
"\'" << endl;
432 cout <<
"No devices connected." << endl;
436 vector <unsigned> device_indices;
437 for (
int argIdx = 1; argIdx < argc; ++argIdx)
439 unsigned deviceIdx = (unsigned)atoi (argv[argIdx]);
444 cout <<
"Device index out of range. " << driver.
getNumberDevices () <<
" devices found." << endl;
445 for (
unsigned deviceIdx = 0; deviceIdx < driver.
getNumberDevices (); ++deviceIdx)
447 cout <<
"Device: " << deviceIdx <<
", vendor: " << driver.
getVendorName (deviceIdx) <<
", product: " 448 << driver.
getProductName (deviceIdx) <<
", connected: " << (int)driver.
getBus (deviceIdx) <<
" @ " 453 cout <<
"No devices connected." << endl;
456 device_indices.push_back ((
unsigned)deviceIdx);
459 cout <<
"<1,2,3...> to select device" << endl;
460 cout <<
"<I> to start or stop image stream of selected device" << endl;
461 cout <<
"<D> to start or stop depth stream of selected device" << endl;
462 cout <<
"<R> to turn on or off registration for selected device" << endl;
463 cout <<
"<S> to turn on or off synchronization for selected device" << endl;
464 cout <<
"<C> to turn on or off image cropping for selected device" << endl;
465 cout <<
"<W> write current images" << endl;
466 cout <<
"<Q> to quit application" << endl;
469 return example.
run ();
unsigned char getBus(unsigned index) const
const char * getSerialNumber(unsigned index) const
unsigned selected_device_
virtual const char * what() const
const char * getProductName(unsigned index) const
const char * getVendorName(unsigned index) const
map< string, ImageContext * > depth_images_
Driver class implemented as Singleton. This class contains the xn::Context object used by all devices...
void imageCallback(const sensor_msgs::ImageConstPtr &msg)
MyOpenNIExample::ImgContext ImageContext
unsigned getNumberDevices() const
vector< boost::shared_ptr< OpenNIDevice > > devices_
MyOpenNIExample(const vector< unsigned > &device_indices)
void depthCallback(boost::shared_ptr< DepthImage > depth, void *cookie)
int main(int argc, char **argv)
boost::shared_ptr< OpenNIDevice > getDeviceByIndex(unsigned index) const
map< string, ImageContext * > gray_images_
const char * getConnectionString() const
returns the connectionstring for current device, which has following format vendorID/productID@BusID/...
Class representing an astract device for Primesense or MS Kinect devices.
void imageCallback(boost::shared_ptr< Image > image, void *cookie)
ImgContext(const Mat &img)
map< string, ImageContext * > rgb_images_
unsigned char getAddress(unsigned index) const
void run(ClassLoader *loader)