26 #include "Helpers/helpers.h"
29 #include <boost/algorithm/string.hpp>
30 #include <boost/lexical_cast.hpp>
51 bool OpenNIImageProvider::isBackEndInitialized =
false;
53 void OpenNIImageProvider::onInitCapturingImageProvider()
57 coloredPoint3DBuffer = NULL;
59 normalizedDepthCells = NULL;
61 isModuleInitialized =
false;
65 uri = getProperty<std::string>(
"DeviceURI").getValue();
67 videoDimension = getProperty<ImageDimension>(
"VideoMode").getValue();
69 frameRate = getProperty<float>(
"FrameRate").getValue();
71 imageType = getProperty<ImageType>(
"ImageType").getValue();
75 ARMARX_INFO <<
"Information: Video Dimension : (" << videoDimension.width <<
"," << videoDimension.height <<
")" <<
flush;
83 setImageFormat(videoDimension, imageType, eBayerPatternBg);
85 setImageSyncMode(eCaptureSynchronization);
89 if (!isBackEndInitialized)
91 if (openni::OpenNI::initialize() == openni::STATUS_OK)
93 isBackEndInitialized =
true;
100 ARMARX_ERROR <<
"Error: While intializing OpenNI : " << openni::OpenNI::getExtendedError() <<
flush;
105 void OpenNIImageProvider::onExitCapturingImageProvider()
109 DestroyDataStructure();
114 void OpenNIImageProvider::onStartCapture(
float frameRate)
120 if (isBackEndInitialized)
122 const bool UseAnyDevice = (!uri.length()) || (uri == std::string(
"ANY_DEVICE")) || (uri == std::string(
"Any")) || (uri == std::string(
"any")) || (uri == std::string(
"ANY"));
124 const bool LookForDeviceTarget = !UseAnyDevice;
126 bool DeviceTargetFound =
false;
128 openni::Array<openni::DeviceInfo> FoundDevices;
130 openni::OpenNI::enumerateDevices(&FoundDevices);
132 const int TotalDevices = FoundDevices.getSize();
134 ARMARX_INFO <<
"Information: Total openni devices found : " << TotalDevices <<
flush;
138 for (
int i = 0 ; i < TotalDevices ; ++i)
140 const std::string CurrentURI = std::string(FoundDevices[i].getUri());
142 if (LookForDeviceTarget && (uri == CurrentURI))
144 ARMARX_INFO <<
"Target found: openni device[" << i <<
"] Uri = " << CurrentURI <<
flush;
146 DeviceTargetFound =
true;
150 ARMARX_INFO <<
"Information: Available device OpenNI device[" << i <<
"] Uri = " << CurrentURI <<
flush;
154 const int Width = videoDimension.width;
156 const int Height = videoDimension.height;
158 const int Fps = EnsureFPS(
int(round(frameRate)));
160 ARMARX_INFO <<
"Information: Video Dimension : (" << Width <<
"," << Height <<
")" <<
flush;
164 if (LookForDeviceTarget)
166 if (DeviceTargetFound)
168 if (StartDevice(uri.c_str(), Width, Height, Fps))
172 if (CreateDataStructures())
201 if (StartDevice(openni::ANY_DEVICE, Width, Height, Fps))
205 if (CreateDataStructures())
249 void OpenNIImageProvider::onStopCapture()
253 DestroyDataStructure();
257 bool OpenNIImageProvider::capture(
void** ppImageBuffers)
259 if (!isModuleInitialized)
264 bool succeeded =
false;
266 switch (getImageFormat().type)
272 case visionx::eColoredPointsScan:
273 succeeded = CaptureColoredPoint();
280 ARMARX_ERROR <<
"Error: Image type not supported by OpenNIImageProvider!" <<
flush;
293 ImageFormatInfo imageFormat = getImageFormat();
295 const int BufferSize = imageFormat.dimension.width * imageFormat.dimension.height * imageFormat.bytesPerPixel;
297 memcpy(ppImageBuffers[0], coloredPoint3DBuffer, BufferSize);
343 bool OpenNIImageProvider::StartDevice(
const char* pDeviceURI,
const int Width,
const int Height,
const int Fps)
345 if (isModuleInitialized)
352 if (deviceOpenNI.open(pDeviceURI) != openni::STATUS_OK)
354 ARMARX_ERROR <<
"Error: Cannot open device (" << pDeviceURI <<
") => " << openni::OpenNI::getExtendedError() <<
flush;
359 if (!deviceOpenNI.hasSensor(openni::SENSOR_DEPTH))
361 ARMARX_ERROR <<
"Error: Device (" << pDeviceURI <<
") [ has not depth sensor ]" <<
flush;
366 if (!deviceOpenNI.hasSensor(openni::SENSOR_COLOR))
368 ARMARX_ERROR <<
"Error: Device (" << pDeviceURI <<
") [ has not color sensor ]" <<
flush;
375 if (depthStreamOpenNI.create(deviceOpenNI, openni::SENSOR_DEPTH) != openni::STATUS_OK)
377 ARMARX_ERROR <<
"Error: Cannot create Depth stream on Device (" << pDeviceURI <<
") => " << openni::OpenNI::getExtendedError() <<
flush;
382 if (!depthStreamOpenNI.isValid())
384 ARMARX_ERROR <<
"Error: Cannot create Depth stream on Device (" << pDeviceURI <<
") => " << openni::OpenNI::getExtendedError() <<
flush;
389 openni::VideoMode CurrentDepthStreamMode = depthStreamOpenNI.getVideoMode();
391 ARMARX_INFO <<
"Information: Depth Stream Default Video Dimension : (" << CurrentDepthStreamMode.getResolutionX() <<
"," << CurrentDepthStreamMode.getResolutionY() <<
")" <<
flush;
393 ARMARX_INFO <<
"Information: Depth Stream Default Frame Rate : " << CurrentDepthStreamMode.getFps() <<
flush;
395 ARMARX_INFO <<
"Information: Depth Stream Target Video Dimension : (" << Width <<
"," << Height <<
")" <<
flush;
397 ARMARX_INFO <<
"Information: Depth Stream Target Frame Rate : " << Fps <<
flush;
399 CurrentDepthStreamMode.setResolution(Width, Height);
401 CurrentDepthStreamMode.setFps(Fps);
403 if (depthStreamOpenNI.setVideoMode(CurrentDepthStreamMode) != openni::STATUS_OK)
405 ARMARX_ERROR <<
"Error: Cannot set Depth stream settings (" << Width <<
"," << Height <<
"," << Fps <<
") Device (" << pDeviceURI <<
") => " << openni::OpenNI::getExtendedError() <<
flush;
410 if (depthStreamOpenNI.start() != openni::STATUS_OK)
412 depthStreamOpenNI.destroy();
414 ARMARX_ERROR <<
"Error: Cannot start Depth stream on Device (" << pDeviceURI <<
") => " << openni::OpenNI::getExtendedError() <<
flush;
419 CurrentDepthStreamMode = depthStreamOpenNI.getVideoMode();
421 ARMARX_INFO <<
"Information: Depth Stream Active Video Dimension : (" << CurrentDepthStreamMode.getResolutionX() <<
"," << CurrentDepthStreamMode.getResolutionY() <<
")" <<
flush;
423 ARMARX_INFO <<
"Information: Depth Stream Active Frame Rate : " << CurrentDepthStreamMode.getFps() <<
flush;
425 if (!depthStreamOpenNI.isValid())
427 ARMARX_ERROR <<
"Error: Cannot create Depth stream on Device (" << pDeviceURI <<
") => " << openni::OpenNI::getExtendedError() <<
flush;
434 if (colorStreamOpenNI.create(deviceOpenNI, openni::SENSOR_COLOR) != openni::STATUS_OK)
436 ARMARX_ERROR <<
"Error: Cannot create Color stream on Device (" << pDeviceURI <<
") => " << openni::OpenNI::getExtendedError() <<
flush;
441 if (!colorStreamOpenNI.isValid())
443 ARMARX_ERROR <<
"Error: Cannot create Color stream on Device (" << pDeviceURI <<
") => " << openni::OpenNI::getExtendedError() <<
flush;
448 openni::VideoMode CurrentColorStreamMode = colorStreamOpenNI.getVideoMode();
450 ARMARX_INFO <<
"Information: Color Stream Default Video Dimension : (" << CurrentColorStreamMode.getResolutionX() <<
"," << CurrentColorStreamMode.getResolutionY() <<
")" <<
flush;
452 ARMARX_INFO <<
"Information: Color Stream Default Frame Rate : " << CurrentColorStreamMode.getFps() <<
flush;
454 ARMARX_INFO <<
"Information: Color Stream Target Video Dimension : (" << Width <<
"," << Height <<
")" <<
flush;
456 ARMARX_INFO <<
"Information: Color Stream Target Frame Rate : " << Fps <<
flush;
458 CurrentColorStreamMode.setResolution(Width, Height);
460 CurrentColorStreamMode.setFps(Fps);
463 if (colorStreamOpenNI.setVideoMode(CurrentColorStreamMode) != openni::STATUS_OK)
465 ARMARX_ERROR <<
"Error: Cannot set Color stream settings (" << Width <<
"," << Height <<
"," << Fps <<
") Device (" << pDeviceURI <<
") => " << openni::OpenNI::getExtendedError() <<
flush;
470 if (colorStreamOpenNI.start() != openni::STATUS_OK)
472 depthStreamOpenNI.destroy();
474 ARMARX_ERROR <<
"Error: Cannot start Color stream on Device (" << pDeviceURI <<
") => " << openni::OpenNI::getExtendedError() <<
flush;
479 CurrentColorStreamMode = colorStreamOpenNI.getVideoMode();
481 ARMARX_INFO <<
"Information: Color Stream Active Video Dimension : (" << CurrentColorStreamMode.getResolutionX() <<
"," << CurrentColorStreamMode.getResolutionY() <<
")" <<
flush;
483 ARMARX_INFO <<
"Information: Color Stream Active Frame Rate : " << CurrentColorStreamMode.getFps() <<
flush;
485 if (!colorStreamOpenNI.isValid())
487 ARMARX_ERROR <<
"Error: Cannot create Color stream on Device (" << pDeviceURI <<
") => " << openni::OpenNI::getExtendedError() <<
flush;
494 if (deviceOpenNI.setDepthColorSyncEnabled(
true) != openni::STATUS_OK)
496 ARMARX_WARNING <<
"Warning: Cannot synchronize Depth and Color on Device (" << pDeviceURI <<
") => " << openni::OpenNI::getExtendedError() <<
flush;
499 if (deviceOpenNI.isImageRegistrationModeSupported(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR))
501 if (deviceOpenNI.setImageRegistrationMode(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR) != openni::STATUS_OK)
503 ARMARX_WARNING <<
"Warning: Device supports depth-to-color registration but could not be enabled (" << pDeviceURI <<
") =>" << openni::OpenNI::getExtendedError() <<
flush;
509 isModuleInitialized =
true;
514 bool OpenNIImageProvider::CreateDataStructures()
516 DestroyDataStructure();
518 const int Width = videoDimension.width;
520 const int Height = videoDimension.height;
522 const int Area = Width * Height;
524 coloredPoint3DBuffer =
new visionx::ColoredPoint3D[
Area];
526 memset(coloredPoint3DBuffer, 0,
sizeof(visionx::ColoredPoint3D)*
Area);
532 InitializeNormalizedDepthCells();
537 bool OpenNIImageProvider::InitializeNormalizedDepthCells()
539 if (!normalizedDepthCells)
544 const int Width = videoDimension.width;
546 const int Height = videoDimension.height;
548 const float XZFactor = std::tan(depthStreamOpenNI.getHorizontalFieldOfView() / 2.0f) * 2.0f;
550 const float YZFactor = std::tan(depthStreamOpenNI.getVerticalFieldOfView() / 2.0f) * 2.0f;
554 for (
int Y = 0 ; Y < Height ; ++Y)
556 const float NY = (0.5f - (
float(Y) /
float(Height))) * YZFactor;
558 for (
int X = 0 ; X < Width ; ++X, ++pNormalizedDepthCell)
560 pNormalizedDepthCell->
nx = ((
float(X) /
float(Width)) - 0.5f) * XZFactor;
562 pNormalizedDepthCell->
ny = NY;
569 bool OpenNIImageProvider::StopDevice()
571 if (isModuleInitialized)
573 depthStreamOpenNI.stop();
575 depthStreamOpenNI.destroy();
577 colorStreamOpenNI.stop();
579 colorStreamOpenNI.destroy();
581 deviceOpenNI.close();
583 isModuleInitialized =
false;
590 bool OpenNIImageProvider::DestroyDataStructure()
592 if (coloredPoint3DBuffer)
594 delete[] coloredPoint3DBuffer;
596 coloredPoint3DBuffer = NULL;
599 if (normalizedDepthCells)
601 delete[] normalizedDepthCells;
603 normalizedDepthCells = NULL;
609 bool OpenNIImageProvider::CaptureColoredPoint()
611 if (!isModuleInitialized)
616 if (!coloredPoint3DBuffer)
621 if (!normalizedDepthCells)
626 openni::VideoStream* ppStreams[2] = {&depthStreamOpenNI, &colorStreamOpenNI};
628 bool HasBeenCaptured[2] = {
false,
false};
630 while (!(HasBeenCaptured[0] && HasBeenCaptured[1]))
632 int StreamIndex = -1;
634 bool CaptureSuccesfull =
false;
636 for (
int i = 0; i < 3; ++i)
638 if (openni::OpenNI::waitForAnyStream(ppStreams, 2, &StreamIndex, 5000) == openni::STATUS_OK)
641 CaptureSuccesfull =
true;
647 ARMARX_WARNING <<
"Warning: Capturing Try not succesfull ->" << openni::OpenNI::getExtendedError() <<
flush;
651 if (!CaptureSuccesfull)
656 if (!(StreamIndex >= 0) && (StreamIndex <= 1))
661 if (ppStreams[StreamIndex]->readFrame(&frameOpenNI) != openni::STATUS_OK)
670 if (!DispatchDepthFrame())
679 if (!DispatchColorFrame())
690 HasBeenCaptured[StreamIndex] =
true;
723 bool OpenNIImageProvider::DispatchDepthFrame()
727 visionx::ColoredPoint3D* pColoredPoint3D = coloredPoint3DBuffer;
729 const visionx::ColoredPoint3D*
const pEndColoredPoint3D = coloredPoint3DBuffer + (videoDimension.width * videoDimension.height);
731 uint16_t* pDepthPixel = (uint16_t*)(frameOpenNI.getData());
733 while (pColoredPoint3D < pEndColoredPoint3D)
735 pColoredPoint3D->point.z =
float(*pDepthPixel++);
737 if (pColoredPoint3D->point.z)
739 pColoredPoint3D->point.x = pNormalizedDepthCell->
nx * pColoredPoint3D->point.z;
741 pColoredPoint3D->point.y = pNormalizedDepthCell->
ny * pColoredPoint3D->point.z;
745 pColoredPoint3D->point.x = 0.0f;
747 pColoredPoint3D->point.y = 0.0f;
752 ++pNormalizedDepthCell;
759 bool OpenNIImageProvider::DispatchColorFrame()
761 visionx::ColoredPoint3D* pColoredPoint3D = coloredPoint3DBuffer;
763 const visionx::ColoredPoint3D*
const pEndColoredPoint3D = coloredPoint3DBuffer + (videoDimension.width * videoDimension.height);
765 unsigned char* pColorPixel = (
unsigned char*) frameOpenNI.getData();
767 while (pColoredPoint3D < pEndColoredPoint3D)
769 pColoredPoint3D->color.r = *pColorPixel++;
771 pColoredPoint3D->color.g = *pColorPixel++;
773 pColoredPoint3D->color.b = *pColorPixel++;
775 pColoredPoint3D->color.a = 0;
783 int OpenNIImageProvider::EnsureFPS(
const int FPS)
795 const int DeviationTo30 =
std::abs(FPS - 30);
797 const int DeviationTo15 =
std::abs(FPS - 15);
801 if (DeviationTo30 < DeviationTo15)