22 #include <vtkPolyData.h>
23 #include <vtkCellArray.h>
24 #include <vtkPoints.h>
25 #include <vtkSmartPointer.h>
26 #include <vtkFloatArray.h>
27 #include <vtkPointData.h>
35 template<
class Interface>
38 if (pInterfaceToRelease != NULL)
40 pInterfaceToRelease->Release();
41 pInterfaceToRelease = NULL;
47 class KinectV2Controller::KinectV2ControllerPrivate
50 KinectV2ControllerPrivate();
51 ~KinectV2ControllerPrivate();
54 IKinectSensor* m_pKinectSensor;
55 IMultiSourceFrameReader* m_pMultiSourceFrameReader;
56 ICoordinateMapper* m_pCoordinateMapper;
57 RGBQUAD* m_pColorRGBX;
59 bool m_ConnectionCheck;
61 int m_DepthCaptureWidth;
62 int m_DepthCaptureHeight;
64 int m_RGBCaptureWidth;
65 int m_RGBCaptureHeight;
66 size_t m_RGBBufferSize;
67 size_t m_DepthBufferSize;
69 CameraSpacePoint* m_CameraCoordinates;
70 ColorSpacePoint* m_ColorPoints;
71 vtkSmartPointer<vtkPolyData> m_PolyData;
73 double m_TriangulationThreshold;
74 bool m_GenerateTriangularMesh;
77 KinectV2Controller::KinectV2ControllerPrivate::KinectV2ControllerPrivate():
78 m_pKinectSensor(NULL),
79 m_pMultiSourceFrameReader(NULL),
80 m_pCoordinateMapper(NULL),
82 m_ConnectionCheck(false),
83 m_DepthCaptureWidth(512),
84 m_DepthCaptureHeight(424),
85 m_RGBCaptureWidth(1920),
86 m_RGBCaptureHeight(1080),
87 m_RGBBufferSize(1920*1080*3),
88 m_DepthBufferSize(sizeof(float)*512*424),
89 m_CameraCoordinates(NULL),
92 m_TriangulationThreshold(0.0),
93 m_GenerateTriangularMesh(false)
96 m_pColorRGBX =
new RGBQUAD[m_RGBCaptureWidth * m_RGBCaptureHeight];
98 m_CameraCoordinates =
new CameraSpacePoint[m_DepthCaptureWidth * m_DepthCaptureHeight];
99 m_ColorPoints =
new ColorSpacePoint[m_DepthCaptureWidth * m_DepthCaptureHeight];
103 KinectV2Controller::KinectV2ControllerPrivate::~KinectV2ControllerPrivate()
105 MITK_INFO <<
"~KinectV2ControllerPrivate";
108 KinectV2Controller::KinectV2Controller(): d(new KinectV2ControllerPrivate)
120 if (!d->m_ConnectionCheck)
123 d->m_ConnectionCheck =
true;
125 hr = GetDefaultKinectSensor(&d->m_pKinectSensor);
129 d->m_ConnectionCheck =
false;
133 hr = d->m_pKinectSensor->get_CoordinateMapper(&d->m_pCoordinateMapper);
136 d->m_ConnectionCheck =
false;
138 hr = d->m_pKinectSensor->Open();
141 if (!d->m_pKinectSensor || FAILED(hr))
143 d->m_ConnectionCheck =
false;
148 MITK_INFO <<
"Kinect 2 succesfully connected";
151 return d->m_ConnectionCheck;
157 if((d->m_ConnectionCheck) && (d->m_pMultiSourceFrameReader))
163 HRESULT hr = d->m_pKinectSensor->OpenMultiSourceFrameReader(
164 FrameSourceTypes::FrameSourceTypes_Depth | FrameSourceTypes::FrameSourceTypes_Color | FrameSourceTypes::FrameSourceTypes_Infrared,
165 &d->m_pMultiSourceFrameReader);
166 if (SUCCEEDED(hr) && (d->m_pMultiSourceFrameReader))
168 MITK_INFO <<
"KinectV2 MultiFrameReader initialized";
183 if(d->m_pKinectSensor)
185 d->m_pKinectSensor->Close();
189 d->m_ConnectionCheck =
false;
205 MITK_ERROR <<
"Unable to initialize MultiFrameReader";
208 IMultiSourceFrame* pMultiSourceFrame = NULL;
209 IDepthFrame* pDepthFrame = NULL;
213 static DWORD lastTime = 0;
214 DWORD currentTime = GetTickCount();
216 if(
unsigned int(currentTime - lastTime) > 33 )
218 hr = d->m_pMultiSourceFrameReader->AcquireLatestFrame(&pMultiSourceFrame);
219 lastTime = currentTime;
224 IDepthFrameReference* pDepthFrameReference = NULL;
226 hr = pMultiSourceFrame->get_DepthFrameReference(&pDepthFrameReference);
229 hr = pDepthFrameReference->AcquireFrame(&pDepthFrame);
236 UINT nDepthBufferSize = 0;
237 UINT16 *pDepthBuffer = NULL;
241 hr = pDepthFrame->AccessUnderlyingBuffer(&nDepthBufferSize, &pDepthBuffer);
245 UINT pointCount = d->m_DepthCaptureWidth * d->m_DepthCaptureHeight;
246 d->m_pCoordinateMapper->MapDepthFrameToCameraSpace(pointCount, pDepthBuffer, pointCount, d->m_CameraCoordinates);
250 textureCoordinates->SetNumberOfComponents(2);
251 textureCoordinates->Allocate(pointCount);
253 d->m_pCoordinateMapper->MapDepthFrameToColorSpace(pointCount, pDepthBuffer, pointCount, d->m_ColorPoints);
255 for(
int i = 0; i < d->m_DepthCaptureHeight*d->m_DepthCaptureWidth; ++i)
257 vtkIdType
id = points->InsertNextPoint(d->m_CameraCoordinates[i].X, d->m_CameraCoordinates[i].Y, d->m_CameraCoordinates[i].Z);
258 vertices->InsertNextCell(1);
259 vertices->InsertCellPoint(
id);
260 distances[i] =
static_cast<float>(*pDepthBuffer);
263 ColorSpacePoint colorPoint = d->m_ColorPoints[i];
265 int colorInDepthX = (int)(floor(colorPoint.X + 0.5));
266 int colorInDepthY = (int)(floor(colorPoint.Y + 0.5));
268 float xNorm =
static_cast<float>(colorInDepthX)/d->m_RGBCaptureWidth;
269 float yNorm = static_cast<float>(colorInDepthY)/d->m_RGBCaptureHeight;
272 if ( colorInDepthX >= 0 && colorInDepthX < d->m_RGBCaptureWidth && colorInDepthY >= 0 && colorInDepthY < d->m_RGBCaptureHeight )
274 textureCoordinates->InsertTuple2(
id, xNorm, yNorm);
278 d->m_PolyData->SetPoints(points);
279 d->m_PolyData->SetVerts(vertices);
280 d->m_PolyData->GetPointData()->SetTCoords(textureCoordinates);
290 if( hr != -1 && !SUCCEEDED(hr) )
294 MITK_DEBUG <<
"HR result false in KinectV2Controller::GetDistances()";
303 MITK_ERROR <<
"Unable to initialize MultiFrameReader";
306 IMultiSourceFrame* pMultiSourceFrame = NULL;
307 IColorFrame* pColorFrame = NULL;
311 static DWORD lastTime = 0;
312 DWORD currentTime = GetTickCount();
314 if(
unsigned int(currentTime - lastTime) > 33 )
316 hr = d->m_pMultiSourceFrameReader->AcquireLatestFrame(&pMultiSourceFrame);
317 lastTime = currentTime;
320 ColorImageFormat imageFormat = ColorImageFormat_None;
321 UINT nColorBufferSize = 0;
322 RGBQUAD *pColorBuffer = NULL;
326 hr = pColorFrame->get_RawColorImageFormat(&imageFormat);
331 if (imageFormat == ColorImageFormat_Bgra)
333 hr = pColorFrame->AccessRawUnderlyingBuffer(&nColorBufferSize, reinterpret_cast<BYTE**>(&pColorBuffer));
335 else if (d->m_pColorRGBX)
337 pColorBuffer = d->m_pColorRGBX;
338 nColorBufferSize = d->m_RGBCaptureWidth * d->m_RGBCaptureHeight *
sizeof(RGBQUAD);
339 hr = pColorFrame->CopyConvertedFrameDataToArray(nColorBufferSize, reinterpret_cast<BYTE*>(pColorBuffer), ColorImageFormat_Bgra);
347 for(
int i = 0; i < d->m_RGBBufferSize; i+=3)
350 rgb[i+0] = pColorBuffer->rgbRed;
351 rgb[i+1] = pColorBuffer->rgbGreen;
352 rgb[i+2] = pColorBuffer->rgbBlue;
360 if( hr != -1 && !SUCCEEDED(hr) )
364 MITK_DEBUG <<
"HR result false in KinectV2Controller::GetRgb()";
372 MITK_ERROR <<
"Unable to initialize MultiFrameReader";
376 IMultiSourceFrame* pMultiSourceFrame = NULL;
377 IDepthFrame* pDepthFrame = NULL;
378 IColorFrame* pColorFrame = NULL;
379 IInfraredFrame* pInfraRedFrame = NULL;
383 static DWORD lastTime = 0;
384 DWORD currentTime = GetTickCount();
386 if(
unsigned int(currentTime - lastTime) > 33 )
388 hr = d->m_pMultiSourceFrameReader->AcquireLatestFrame(&pMultiSourceFrame);
389 lastTime = currentTime;
394 IDepthFrameReference* pDepthFrameReference = NULL;
396 hr = pMultiSourceFrame->get_DepthFrameReference(&pDepthFrameReference);
399 hr = pDepthFrameReference->AcquireFrame(&pDepthFrame);
406 IColorFrameReference* pColorFrameReference = NULL;
408 hr = pMultiSourceFrame->get_ColorFrameReference(&pColorFrameReference);
411 hr = pColorFrameReference->AcquireFrame(&pColorFrame);
418 IInfraredFrameReference* pInfraredFrameReference = NULL;
420 hr = pMultiSourceFrame->get_InfraredFrameReference(&pInfraredFrameReference);
423 hr = pInfraredFrameReference->AcquireFrame(&pInfraRedFrame);
430 UINT nDepthBufferSize = 0;
431 UINT16 *pDepthBuffer = NULL;
432 UINT16 *pInfraRedBuffer = NULL;
434 ColorImageFormat imageFormat = ColorImageFormat_None;
435 UINT nColorBufferSize = 0;
436 RGBQUAD *pColorBuffer = NULL;
440 hr = pDepthFrame->AccessUnderlyingBuffer(&nDepthBufferSize, &pDepthBuffer);
444 hr = pInfraRedFrame->AccessUnderlyingBuffer(&nDepthBufferSize, &pInfraRedBuffer);
448 UINT pointCount = d->m_DepthCaptureWidth * d->m_DepthCaptureHeight;
449 d->m_pCoordinateMapper->MapDepthFrameToCameraSpace(pointCount, pDepthBuffer, pointCount, d->m_CameraCoordinates);
454 const double meterfactor = 1000.0;
458 vertexIdList->Allocate(pointCount);
459 vertexIdList->SetNumberOfIds(pointCount);
460 for(
unsigned int i = 0; i < pointCount; ++i)
462 vertexIdList->SetId(i, 0);
465 std::vector<bool> isPointValid;
466 isPointValid.resize(pointCount);
469 vertexIdList->Allocate(pointCount);
470 vertexIdList->SetNumberOfIds(pointCount);
471 textureCoordinates->SetNumberOfComponents(2);
472 textureCoordinates->Allocate(pointCount);
474 d->m_pCoordinateMapper->MapDepthFrameToColorSpace(pointCount, pDepthBuffer, pointCount, d->m_ColorPoints);
476 for(
int j = 0; j < d->m_DepthCaptureHeight; ++j)
478 for(
int i = 0; i < d->m_DepthCaptureWidth; ++i)
480 unsigned int pixelID = i+j*d->m_DepthCaptureWidth;
481 unsigned int inverseid = (d->m_DepthCaptureWidth - i - 1) + j*d->m_DepthCaptureWidth;
483 distances[inverseid] = static_cast<float>(*pDepthBuffer);
484 amplitudes[inverseid] =
static_cast<float>(*pInfraRedBuffer);
488 if (d->m_CameraCoordinates[pixelID].Z<=
mitk::eps)
490 isPointValid[pixelID] =
false;
494 isPointValid[pixelID] =
true;
503 vertexIdList->SetId(pixelID, points->InsertNextPoint(-d->m_CameraCoordinates[pixelID].X*meterfactor, -d->m_CameraCoordinates[pixelID].Y*meterfactor, d->m_CameraCoordinates[pixelID].Z*meterfactor));
505 if (d->m_GenerateTriangularMesh)
507 if((i >= 1) && (j >= 1))
521 vtkIdType xy = pixelID;
522 vtkIdType x_1y = pixelID-1;
523 vtkIdType xy_1 = pixelID-d->m_DepthCaptureWidth;
524 vtkIdType x_1y_1 = xy_1-1;
527 vtkIdType xyV = vertexIdList->GetId(xy);
528 vtkIdType x_1yV = vertexIdList->GetId(x_1y);
529 vtkIdType xy_1V = vertexIdList->GetId(xy_1);
530 vtkIdType x_1y_1V = vertexIdList->GetId(x_1y_1);
532 if (isPointValid[xy]&&isPointValid[x_1y]&&isPointValid[x_1y_1]&&isPointValid[xy_1])
534 double pointXY[3], pointX_1Y[3], pointXY_1[3], pointX_1Y_1[3];
536 points->GetPoint(xyV, pointXY);
537 points->GetPoint(x_1yV, pointX_1Y);
538 points->GetPoint(xy_1V, pointXY_1);
539 points->GetPoint(x_1y_1V, pointX_1Y_1);
542 if( (
mitk::Equal(d->m_TriangulationThreshold, 0.0)) || ((vtkMath::Distance2BetweenPoints(pointXY, pointX_1Y) <= d->m_TriangulationThreshold)
543 && (vtkMath::Distance2BetweenPoints(pointXY, pointXY_1) <= d->m_TriangulationThreshold)
544 && (vtkMath::Distance2BetweenPoints(pointX_1Y, pointX_1Y_1) <= d->m_TriangulationThreshold)
545 && (vtkMath::Distance2BetweenPoints(pointXY_1, pointX_1Y_1) <= d->m_TriangulationThreshold)))
547 polys->InsertNextCell(3);
548 polys->InsertCellPoint(x_1yV);
549 polys->InsertCellPoint(xyV);
550 polys->InsertCellPoint(x_1y_1V);
552 polys->InsertNextCell(3);
553 polys->InsertCellPoint(x_1y_1V);
554 polys->InsertCellPoint(xyV);
555 polys->InsertCellPoint(xy_1V);
560 vertices->InsertNextCell(1);
561 vertices->InsertCellPoint(xyV);
569 vertices->InsertNextCell(1);
570 vertices->InsertCellPoint(vertexIdList->GetId(pixelID));
573 ColorSpacePoint colorPoint = d->m_ColorPoints[pixelID];
575 int colorInDepthX = (int)(floor(colorPoint.X + 0.5));
576 int colorInDepthY = (int)(floor(colorPoint.Y + 0.5));
578 float xNorm = -
static_cast<float>(colorInDepthX)/d->m_RGBCaptureWidth;
579 float yNorm = static_cast<float>(colorInDepthY)/d->m_RGBCaptureHeight;
582 if ( colorInDepthX >= 0 && colorInDepthX < d->m_RGBCaptureWidth && colorInDepthY >= 0 && colorInDepthY < d->m_RGBCaptureHeight )
584 textureCoordinates->InsertTuple2(vertexIdList->GetId(pixelID), xNorm, yNorm);
588 textureCoordinates->InsertTuple2(vertexIdList->GetId(pixelID), 0, 0);
595 d->m_PolyData->SetPoints(points);
596 d->m_PolyData->SetVerts(vertices);
597 d->m_PolyData->SetPolys(polys);
598 d->m_PolyData->GetPointData()->SetTCoords(textureCoordinates);
608 hr = pColorFrame->get_RawColorImageFormat(&imageFormat);
613 if (imageFormat == ColorImageFormat_Bgra)
615 hr = pColorFrame->AccessRawUnderlyingBuffer(&nColorBufferSize, reinterpret_cast<BYTE**>(&pColorBuffer));
617 else if (d->m_pColorRGBX)
619 pColorBuffer = d->m_pColorRGBX;
620 nColorBufferSize = d->m_RGBCaptureWidth * d->m_RGBCaptureHeight *
sizeof(RGBQUAD);
621 hr = pColorFrame->CopyConvertedFrameDataToArray(nColorBufferSize, reinterpret_cast<BYTE*>(pColorBuffer), ColorImageFormat_Bgra);
629 for(
int j = 0; j < d->m_RGBCaptureHeight; ++j)
631 for(
int i = 0; i < d->m_RGBCaptureWidth; ++i)
635 unsigned int id = ((d->m_RGBCaptureWidth - i - 1) + j*d->m_RGBCaptureWidth)*3;
637 rgb[
id+0] = pColorBuffer->rgbRed;
638 rgb[
id+1] = pColorBuffer->rgbGreen;
639 rgb[
id+2] = pColorBuffer->rgbBlue;
652 if( hr != -1 && !SUCCEEDED(hr) )
656 MITK_DEBUG <<
"HR result false in KinectV2Controller::GetAllData()";
664 MITK_ERROR <<
"Unable to initialize MultiFrameReader";
668 IMultiSourceFrame* pMultiSourceFrame = NULL;
669 IInfraredFrame* pInfraRedFrame = NULL;
673 static DWORD lastTime = 0;
674 DWORD currentTime = GetTickCount();
676 if(
unsigned int(currentTime - lastTime) > 33 )
678 hr = d->m_pMultiSourceFrameReader->AcquireLatestFrame(&pMultiSourceFrame);
679 lastTime = currentTime;
684 IInfraredFrameReference* pInfraredFrameReference = NULL;
686 hr = pMultiSourceFrame->get_InfraredFrameReference(&pInfraredFrameReference);
689 hr = pInfraredFrameReference->AcquireFrame(&pInfraRedFrame);
696 UINT nDepthBufferSize = 0;
697 UINT16 *pInfraRedBuffer = NULL;
701 hr = pInfraRedFrame->AccessUnderlyingBuffer(&nDepthBufferSize, &pInfraRedBuffer);
705 for(
int i = 0; i < d->m_DepthCaptureHeight*d->m_DepthCaptureWidth; ++i)
707 amplitudes[i] =
static_cast<float>(*pInfraRedBuffer);
719 if( hr != -1 && !SUCCEEDED(hr) )
723 MITK_DEBUG <<
"HR result false in KinectV2Controller::GetAmplitudes()";
729 return d->m_RGBCaptureWidth;
734 return d->m_RGBCaptureHeight;
739 return d->m_DepthCaptureWidth;
744 return d->m_DepthCaptureHeight;
749 return d->m_PolyData;
754 d->m_GenerateTriangularMesh = flag;
759 this->d->m_TriangulationThreshold = triangulationThreshold * triangulationThreshold;
virtual bool UpdateCamera()
updates the camera. The update function of the hardware interface is called only when new data is ava...
void SetTriangulationThreshold(double triangulationThreshold)
void GetAllData(float *distances, float *amplitudes, unsigned char *rgb)
convenience method for faster access to distance and rgb data
void SafeRelease(Interface *&pInterfaceToRelease)
virtual bool OpenCameraConnection()
opens a connection to the Kinect V2 camera.
void SetGenerateTriangularMesh(bool flag)
void GetAmplitudes(float *amplitudes)
void GetDistances(float *distances)
acquire new distance data from the Kinect camera
DataCollection - Class to facilitate loading/accessing structured data.
bool InitializeMultiFrameReader()
Setup MultiFrameReader of Kinect V2. This reader can acquire different types of data. Here it is used to acquire depth, RGB and infrared images.
void GetRgb(unsigned char *rgb)
acquire new rgb data from the Kinect camera
int GetRGBCaptureHeight() const
int GetRGBCaptureWidth() const
int GetDepthCaptureHeight() const
vtkSmartPointer< vtkPolyData > GetVtkPolyData()
int GetDepthCaptureWidth() const
MITKNEWMODULE_EXPORT bool Equal(mitk::ExampleDataStructure *leftHandSide, mitk::ExampleDataStructure *rightHandSide, mitk::ScalarType eps, bool verbose)
Returns true if the example data structures are considered equal.
virtual bool CloseCameraConnection()
closes the connection to the camera
MITKCORE_EXPORT const ScalarType eps
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.