27 #include "Helpers/helpers.h"
30 #include <boost/algorithm/string.hpp>
31 #include <boost/lexical_cast.hpp>
51 bool OpenNIImageProvider::isBackEndInitialized =
false;
54 OpenNIImageProvider::onInitCapturingImageProvider()
58 coloredPoint3DBuffer = NULL;
60 normalizedDepthCells = NULL;
62 isModuleInitialized =
false;
66 uri = getProperty<std::string>(
"DeviceURI").getValue();
68 videoDimension = getProperty<ImageDimension>(
"VideoMode").getValue();
70 frameRate = getProperty<float>(
"FrameRate").getValue();
72 imageType = getProperty<ImageType>(
"ImageType").getValue();
76 ARMARX_INFO <<
"Information: Video Dimension : (" << videoDimension.width <<
","
77 << videoDimension.height <<
")" <<
flush;
85 setImageFormat(videoDimension, imageType, eBayerPatternBg);
87 setImageSyncMode(eCaptureSynchronization);
91 if (!isBackEndInitialized)
93 if (openni::OpenNI::initialize() == openni::STATUS_OK)
95 isBackEndInitialized =
true;
102 << openni::OpenNI::getExtendedError() <<
flush;
108 OpenNIImageProvider::onExitCapturingImageProvider()
112 DestroyDataStructure();
118 OpenNIImageProvider::onStartCapture(
float frameRate)
124 if (isBackEndInitialized)
126 const bool UseAnyDevice = (!uri.length()) || (uri == std::string(
"ANY_DEVICE")) ||
127 (uri == std::string(
"Any")) || (uri == std::string(
"any")) ||
128 (uri == std::string(
"ANY"));
130 const bool LookForDeviceTarget = !UseAnyDevice;
132 bool DeviceTargetFound =
false;
134 openni::Array<openni::DeviceInfo> FoundDevices;
136 openni::OpenNI::enumerateDevices(&FoundDevices);
138 const int TotalDevices = FoundDevices.getSize();
140 ARMARX_INFO <<
"Information: Total openni devices found : " << TotalDevices <<
flush;
144 for (
int i = 0; i < TotalDevices; ++i)
146 const std::string CurrentURI = std::string(FoundDevices[i].getUri());
148 if (LookForDeviceTarget && (uri == CurrentURI))
151 <<
"] Uri = " << CurrentURI <<
flush;
153 DeviceTargetFound =
true;
157 ARMARX_INFO <<
"Information: Available device OpenNI device[" << i
158 <<
"] Uri = " << CurrentURI <<
flush;
162 const int Width = videoDimension.width;
164 const int Height = videoDimension.height;
166 const int Fps = EnsureFPS(
int(round(frameRate)));
168 ARMARX_INFO <<
"Information: Video Dimension : (" << Width <<
"," << Height <<
")"
173 if (LookForDeviceTarget)
175 if (DeviceTargetFound)
177 if (StartDevice(uri.c_str(), Width, Height, Fps))
179 ARMARX_INFO <<
"openni device[" << uri <<
"] started succesfully"
182 if (CreateDataStructures())
184 ARMARX_ERROR <<
"Error: Data structures created succesffully"
198 ARMARX_ERROR <<
"Error: openni device[" << uri <<
"] started failure"
206 ARMARX_ERROR <<
"Error: openni device Uri = " << uri <<
" not found"
214 if (StartDevice(openni::ANY_DEVICE, Width, Height, Fps))
218 if (CreateDataStructures())
256 "Opening cameras failed!");
261 OpenNIImageProvider::onStopCapture()
265 DestroyDataStructure();
269 OpenNIImageProvider::capture(
void** ppImageBuffers)
271 if (!isModuleInitialized)
276 bool succeeded =
false;
278 switch (getImageFormat().type)
284 case visionx::eColoredPointsScan:
285 succeeded = CaptureColoredPoint();
292 ARMARX_ERROR <<
"Error: Image type not supported by OpenNIImageProvider!" <<
flush;
305 ImageFormatInfo imageFormat = getImageFormat();
307 const int BufferSize = imageFormat.dimension.width * imageFormat.dimension.height *
308 imageFormat.bytesPerPixel;
310 memcpy(ppImageBuffers[0], coloredPoint3DBuffer, BufferSize);
356 OpenNIImageProvider::StartDevice(
const char* pDeviceURI,
361 if (isModuleInitialized)
368 if (deviceOpenNI.open(pDeviceURI) != openni::STATUS_OK)
370 ARMARX_ERROR <<
"Error: Cannot open device (" << pDeviceURI <<
") => "
371 << openni::OpenNI::getExtendedError() <<
flush;
376 if (!deviceOpenNI.hasSensor(openni::SENSOR_DEPTH))
378 ARMARX_ERROR <<
"Error: Device (" << pDeviceURI <<
") [ has not depth sensor ]"
384 if (!deviceOpenNI.hasSensor(openni::SENSOR_COLOR))
386 ARMARX_ERROR <<
"Error: Device (" << pDeviceURI <<
") [ has not color sensor ]"
394 if (depthStreamOpenNI.create(deviceOpenNI, openni::SENSOR_DEPTH) != openni::STATUS_OK)
396 ARMARX_ERROR <<
"Error: Cannot create Depth stream on Device (" << pDeviceURI <<
") => "
397 << openni::OpenNI::getExtendedError() <<
flush;
402 if (!depthStreamOpenNI.isValid())
404 ARMARX_ERROR <<
"Error: Cannot create Depth stream on Device (" << pDeviceURI <<
") => "
405 << openni::OpenNI::getExtendedError() <<
flush;
410 openni::VideoMode CurrentDepthStreamMode = depthStreamOpenNI.getVideoMode();
412 ARMARX_INFO <<
"Information: Depth Stream Default Video Dimension : ("
413 << CurrentDepthStreamMode.getResolutionX() <<
","
414 << CurrentDepthStreamMode.getResolutionY() <<
")" <<
flush;
416 ARMARX_INFO <<
"Information: Depth Stream Default Frame Rate : "
417 << CurrentDepthStreamMode.getFps() <<
flush;
419 ARMARX_INFO <<
"Information: Depth Stream Target Video Dimension : (" << Width <<
","
420 << Height <<
")" <<
flush;
422 ARMARX_INFO <<
"Information: Depth Stream Target Frame Rate : " << Fps <<
flush;
424 CurrentDepthStreamMode.setResolution(Width, Height);
426 CurrentDepthStreamMode.setFps(Fps);
428 if (depthStreamOpenNI.setVideoMode(CurrentDepthStreamMode) != openni::STATUS_OK)
430 ARMARX_ERROR <<
"Error: Cannot set Depth stream settings (" << Width <<
"," << Height
431 <<
"," << Fps <<
") Device (" << pDeviceURI <<
") => "
432 << openni::OpenNI::getExtendedError() <<
flush;
437 if (depthStreamOpenNI.start() != openni::STATUS_OK)
439 depthStreamOpenNI.destroy();
441 ARMARX_ERROR <<
"Error: Cannot start Depth stream on Device (" << pDeviceURI <<
") => "
442 << openni::OpenNI::getExtendedError() <<
flush;
447 CurrentDepthStreamMode = depthStreamOpenNI.getVideoMode();
449 ARMARX_INFO <<
"Information: Depth Stream Active Video Dimension : ("
450 << CurrentDepthStreamMode.getResolutionX() <<
","
451 << CurrentDepthStreamMode.getResolutionY() <<
")" <<
flush;
453 ARMARX_INFO <<
"Information: Depth Stream Active Frame Rate : "
454 << CurrentDepthStreamMode.getFps() <<
flush;
456 if (!depthStreamOpenNI.isValid())
458 ARMARX_ERROR <<
"Error: Cannot create Depth stream on Device (" << pDeviceURI <<
") => "
459 << openni::OpenNI::getExtendedError() <<
flush;
466 if (colorStreamOpenNI.create(deviceOpenNI, openni::SENSOR_COLOR) != openni::STATUS_OK)
468 ARMARX_ERROR <<
"Error: Cannot create Color stream on Device (" << pDeviceURI <<
") => "
469 << openni::OpenNI::getExtendedError() <<
flush;
474 if (!colorStreamOpenNI.isValid())
476 ARMARX_ERROR <<
"Error: Cannot create Color stream on Device (" << pDeviceURI <<
") => "
477 << openni::OpenNI::getExtendedError() <<
flush;
482 openni::VideoMode CurrentColorStreamMode = colorStreamOpenNI.getVideoMode();
484 ARMARX_INFO <<
"Information: Color Stream Default Video Dimension : ("
485 << CurrentColorStreamMode.getResolutionX() <<
","
486 << CurrentColorStreamMode.getResolutionY() <<
")" <<
flush;
488 ARMARX_INFO <<
"Information: Color Stream Default Frame Rate : "
489 << CurrentColorStreamMode.getFps() <<
flush;
491 ARMARX_INFO <<
"Information: Color Stream Target Video Dimension : (" << Width <<
","
492 << Height <<
")" <<
flush;
494 ARMARX_INFO <<
"Information: Color Stream Target Frame Rate : " << Fps <<
flush;
496 CurrentColorStreamMode.setResolution(Width, Height);
498 CurrentColorStreamMode.setFps(Fps);
501 if (colorStreamOpenNI.setVideoMode(CurrentColorStreamMode) != openni::STATUS_OK)
503 ARMARX_ERROR <<
"Error: Cannot set Color stream settings (" << Width <<
"," << Height
504 <<
"," << Fps <<
") Device (" << pDeviceURI <<
") => "
505 << openni::OpenNI::getExtendedError() <<
flush;
510 if (colorStreamOpenNI.start() != openni::STATUS_OK)
512 depthStreamOpenNI.destroy();
514 ARMARX_ERROR <<
"Error: Cannot start Color stream on Device (" << pDeviceURI <<
") => "
515 << openni::OpenNI::getExtendedError() <<
flush;
520 CurrentColorStreamMode = colorStreamOpenNI.getVideoMode();
522 ARMARX_INFO <<
"Information: Color Stream Active Video Dimension : ("
523 << CurrentColorStreamMode.getResolutionX() <<
","
524 << CurrentColorStreamMode.getResolutionY() <<
")" <<
flush;
526 ARMARX_INFO <<
"Information: Color Stream Active Frame Rate : "
527 << CurrentColorStreamMode.getFps() <<
flush;
529 if (!colorStreamOpenNI.isValid())
531 ARMARX_ERROR <<
"Error: Cannot create Color stream on Device (" << pDeviceURI <<
") => "
532 << openni::OpenNI::getExtendedError() <<
flush;
539 if (deviceOpenNI.setDepthColorSyncEnabled(
true) != openni::STATUS_OK)
541 ARMARX_WARNING <<
"Warning: Cannot synchronize Depth and Color on Device ("
542 << pDeviceURI <<
") => " << openni::OpenNI::getExtendedError() <<
flush;
545 if (deviceOpenNI.isImageRegistrationModeSupported(
546 openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR))
548 if (deviceOpenNI.setImageRegistrationMode(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR) !=
551 ARMARX_WARNING <<
"Warning: Device supports depth-to-color registration but could "
553 << pDeviceURI <<
") =>" << openni::OpenNI::getExtendedError()
560 isModuleInitialized =
true;
566 OpenNIImageProvider::CreateDataStructures()
568 DestroyDataStructure();
570 const int Width = videoDimension.width;
572 const int Height = videoDimension.height;
574 const int Area = Width * Height;
576 coloredPoint3DBuffer =
new visionx::ColoredPoint3D[
Area];
578 memset(coloredPoint3DBuffer, 0,
sizeof(visionx::ColoredPoint3D) *
Area);
584 InitializeNormalizedDepthCells();
590 OpenNIImageProvider::InitializeNormalizedDepthCells()
592 if (!normalizedDepthCells)
597 const int Width = videoDimension.width;
599 const int Height = videoDimension.height;
601 const float XZFactor = std::tan(depthStreamOpenNI.getHorizontalFieldOfView() / 2.0f) * 2.0f;
603 const float YZFactor = std::tan(depthStreamOpenNI.getVerticalFieldOfView() / 2.0f) * 2.0f;
607 for (
int Y = 0; Y < Height; ++Y)
609 const float NY = (0.5f - (
float(Y) /
float(Height))) * YZFactor;
611 for (
int X = 0; X < Width; ++X, ++pNormalizedDepthCell)
613 pNormalizedDepthCell->
nx = ((
float(X) /
float(Width)) - 0.5f) * XZFactor;
615 pNormalizedDepthCell->
ny = NY;
623 OpenNIImageProvider::StopDevice()
625 if (isModuleInitialized)
627 depthStreamOpenNI.stop();
629 depthStreamOpenNI.destroy();
631 colorStreamOpenNI.stop();
633 colorStreamOpenNI.destroy();
635 deviceOpenNI.close();
637 isModuleInitialized =
false;
645 OpenNIImageProvider::DestroyDataStructure()
647 if (coloredPoint3DBuffer)
649 delete[] coloredPoint3DBuffer;
651 coloredPoint3DBuffer = NULL;
654 if (normalizedDepthCells)
656 delete[] normalizedDepthCells;
658 normalizedDepthCells = NULL;
665 OpenNIImageProvider::CaptureColoredPoint()
667 if (!isModuleInitialized)
672 if (!coloredPoint3DBuffer)
677 if (!normalizedDepthCells)
682 openni::VideoStream* ppStreams[2] = {&depthStreamOpenNI, &colorStreamOpenNI};
684 bool HasBeenCaptured[2] = {
false,
false};
686 while (!(HasBeenCaptured[0] && HasBeenCaptured[1]))
688 int StreamIndex = -1;
690 bool CaptureSuccesfull =
false;
692 for (
int i = 0; i < 3; ++i)
694 if (openni::OpenNI::waitForAnyStream(ppStreams, 2, &StreamIndex, 5000) ==
698 CaptureSuccesfull =
true;
705 << openni::OpenNI::getExtendedError() <<
flush;
709 if (!CaptureSuccesfull)
714 if (!(StreamIndex >= 0) && (StreamIndex <= 1))
719 if (ppStreams[StreamIndex]->readFrame(&frameOpenNI) != openni::STATUS_OK)
728 if (!DispatchDepthFrame())
737 if (!DispatchColorFrame())
748 HasBeenCaptured[StreamIndex] =
true;
782 OpenNIImageProvider::DispatchDepthFrame()
786 visionx::ColoredPoint3D* pColoredPoint3D = coloredPoint3DBuffer;
788 const visionx::ColoredPoint3D*
const pEndColoredPoint3D =
789 coloredPoint3DBuffer + (videoDimension.width * videoDimension.height);
791 uint16_t* pDepthPixel = (uint16_t*)(frameOpenNI.getData());
793 while (pColoredPoint3D < pEndColoredPoint3D)
795 pColoredPoint3D->point.z =
float(*pDepthPixel++);
797 if (pColoredPoint3D->point.z)
799 pColoredPoint3D->point.x = pNormalizedDepthCell->
nx * pColoredPoint3D->point.z;
801 pColoredPoint3D->point.y = pNormalizedDepthCell->
ny * pColoredPoint3D->point.z;
805 pColoredPoint3D->point.x = 0.0f;
807 pColoredPoint3D->point.y = 0.0f;
812 ++pNormalizedDepthCell;
819 OpenNIImageProvider::DispatchColorFrame()
821 visionx::ColoredPoint3D* pColoredPoint3D = coloredPoint3DBuffer;
823 const visionx::ColoredPoint3D*
const pEndColoredPoint3D =
824 coloredPoint3DBuffer + (videoDimension.width * videoDimension.height);
826 unsigned char* pColorPixel = (
unsigned char*)frameOpenNI.getData();
828 while (pColoredPoint3D < pEndColoredPoint3D)
830 pColoredPoint3D->color.r = *pColorPixel++;
832 pColoredPoint3D->color.g = *pColorPixel++;
834 pColoredPoint3D->color.b = *pColorPixel++;
836 pColoredPoint3D->color.a = 0;
845 OpenNIImageProvider::EnsureFPS(
const int FPS)
857 const int DeviationTo30 =
std::abs(FPS - 30);
859 const int DeviationTo15 =
std::abs(FPS - 15);
863 if (DeviationTo30 < DeviationTo15)