18 #include <vtkPolyData.h> 19 #include <vtkCellArray.h> 20 #include <vtkPoints.h> 21 #include <vtkSmartPointer.h> 22 #include <vtkFloatArray.h> 23 #include <vtkPointData.h> 31 template<
class Interface>
34 if (pInterfaceToRelease !=
nullptr)
36 pInterfaceToRelease->Release();
37 pInterfaceToRelease =
nullptr;
43 class KinectV2Controller::KinectV2ControllerPrivate
46 KinectV2ControllerPrivate();
47 ~KinectV2ControllerPrivate();
50 IKinectSensor* m_pKinectSensor;
51 IMultiSourceFrameReader* m_pMultiSourceFrameReader;
52 ICoordinateMapper* m_pCoordinateMapper;
53 RGBQUAD* m_pColorRGBX;
55 bool m_ConnectionCheck;
57 int m_DepthCaptureWidth;
58 int m_DepthCaptureHeight;
60 int m_RGBCaptureWidth;
61 int m_RGBCaptureHeight;
62 size_t m_RGBBufferSize;
63 size_t m_DepthBufferSize;
65 CameraSpacePoint* m_CameraCoordinates;
66 ColorSpacePoint* m_ColorPoints;
67 vtkSmartPointer<vtkPolyData> m_PolyData;
69 double m_TriangulationThreshold;
70 bool m_GenerateTriangularMesh;
73 KinectV2Controller::KinectV2ControllerPrivate::KinectV2ControllerPrivate():
74 m_pKinectSensor(
nullptr),
75 m_pMultiSourceFrameReader(
nullptr),
76 m_pCoordinateMapper(
nullptr),
77 m_pColorRGBX(
nullptr),
78 m_ConnectionCheck(
false),
79 m_DepthCaptureWidth(512),
80 m_DepthCaptureHeight(424),
81 m_RGBCaptureWidth(1920),
82 m_RGBCaptureHeight(1080),
83 m_RGBBufferSize(1920*1080*3),
84 m_DepthBufferSize(
sizeof(
float)*512*424),
85 m_CameraCoordinates(
nullptr),
86 m_ColorPoints(
nullptr),
88 m_TriangulationThreshold(0.0),
89 m_GenerateTriangularMesh(
false)
92 m_pColorRGBX =
new RGBQUAD[m_RGBCaptureWidth * m_RGBCaptureHeight];
94 m_CameraCoordinates =
new CameraSpacePoint[m_DepthCaptureWidth * m_DepthCaptureHeight];
95 m_ColorPoints =
new ColorSpacePoint[m_DepthCaptureWidth * m_DepthCaptureHeight];
96 m_PolyData = vtkSmartPointer<vtkPolyData>::New();
99 KinectV2Controller::KinectV2ControllerPrivate::~KinectV2ControllerPrivate()
101 MITK_INFO <<
"~KinectV2ControllerPrivate";
116 if (!d->m_ConnectionCheck)
119 d->m_ConnectionCheck =
true;
121 hr = GetDefaultKinectSensor(&d->m_pKinectSensor);
125 d->m_ConnectionCheck =
false;
129 hr = d->m_pKinectSensor->get_CoordinateMapper(&d->m_pCoordinateMapper);
132 d->m_ConnectionCheck =
false;
134 hr = d->m_pKinectSensor->Open();
137 if (!d->m_pKinectSensor || FAILED(hr))
139 d->m_ConnectionCheck =
false;
144 MITK_INFO <<
"Kinect 2 succesfully connected";
147 return d->m_ConnectionCheck;
153 if((d->m_ConnectionCheck) && (d->m_pMultiSourceFrameReader))
159 HRESULT hr = d->m_pKinectSensor->OpenMultiSourceFrameReader(
160 FrameSourceTypes::FrameSourceTypes_Depth | FrameSourceTypes::FrameSourceTypes_Color | FrameSourceTypes::FrameSourceTypes_Infrared,
161 &d->m_pMultiSourceFrameReader);
162 if (SUCCEEDED(hr) && (d->m_pMultiSourceFrameReader))
164 MITK_INFO <<
"KinectV2 MultiFrameReader initialized";
179 if(d->m_pKinectSensor)
181 d->m_pKinectSensor->Close();
185 d->m_ConnectionCheck =
false;
201 MITK_ERROR <<
"Unable to initialize MultiFrameReader";
204 IMultiSourceFrame* pMultiSourceFrame =
nullptr;
205 IDepthFrame* pDepthFrame =
nullptr;
209 static DWORD lastTime = 0;
210 DWORD currentTime = GetTickCount();
212 if(
unsigned int(currentTime - lastTime) > 33 )
214 hr = d->m_pMultiSourceFrameReader->AcquireLatestFrame(&pMultiSourceFrame);
215 lastTime = currentTime;
220 IDepthFrameReference* pDepthFrameReference =
nullptr;
222 hr = pMultiSourceFrame->get_DepthFrameReference(&pDepthFrameReference);
225 hr = pDepthFrameReference->AcquireFrame(&pDepthFrame);
232 UINT nDepthBufferSize = 0;
233 UINT16 *pDepthBuffer =
nullptr;
237 hr = pDepthFrame->AccessUnderlyingBuffer(&nDepthBufferSize, &pDepthBuffer);
241 UINT pointCount = d->m_DepthCaptureWidth * d->m_DepthCaptureHeight;
242 d->m_pCoordinateMapper->MapDepthFrameToCameraSpace(pointCount, pDepthBuffer, pointCount, d->m_CameraCoordinates);
243 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
244 vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
245 vtkSmartPointer<vtkFloatArray> textureCoordinates = vtkSmartPointer<vtkFloatArray>::New();
246 textureCoordinates->SetNumberOfComponents(2);
247 textureCoordinates->Allocate(pointCount);
249 d->m_pCoordinateMapper->MapDepthFrameToColorSpace(pointCount, pDepthBuffer, pointCount, d->m_ColorPoints);
251 for(
int i = 0; i < d->m_DepthCaptureHeight*d->m_DepthCaptureWidth; ++i)
253 vtkIdType
id = points->InsertNextPoint(d->m_CameraCoordinates[i].X, d->m_CameraCoordinates[i].Y, d->m_CameraCoordinates[i].Z);
254 vertices->InsertNextCell(1);
255 vertices->InsertCellPoint(
id);
256 distances[i] =
static_cast<float>(*pDepthBuffer);
259 ColorSpacePoint colorPoint = d->m_ColorPoints[i];
261 int colorInDepthX = (int)(floor(colorPoint.X + 0.5));
262 int colorInDepthY = (int)(floor(colorPoint.Y + 0.5));
264 float xNorm =
static_cast<float>(colorInDepthX)/d->m_RGBCaptureWidth;
265 float yNorm = static_cast<float>(colorInDepthY)/d->m_RGBCaptureHeight;
268 if ( colorInDepthX >= 0 && colorInDepthX < d->m_RGBCaptureWidth && colorInDepthY >= 0 && colorInDepthY < d->m_RGBCaptureHeight )
270 textureCoordinates->InsertTuple2(
id, xNorm, yNorm);
273 d->m_PolyData = vtkSmartPointer<vtkPolyData>::New();
274 d->m_PolyData->SetPoints(points);
275 d->m_PolyData->SetVerts(vertices);
276 d->m_PolyData->GetPointData()->SetTCoords(textureCoordinates);
286 if( hr != -1 && !SUCCEEDED(hr) )
290 MITK_DEBUG <<
"HR result false in KinectV2Controller::GetDistances()";
299 MITK_ERROR <<
"Unable to initialize MultiFrameReader";
302 IMultiSourceFrame* pMultiSourceFrame =
nullptr;
303 IColorFrame* pColorFrame =
nullptr;
307 static DWORD lastTime = 0;
308 DWORD currentTime = GetTickCount();
310 if(
unsigned int(currentTime - lastTime) > 33 )
312 hr = d->m_pMultiSourceFrameReader->AcquireLatestFrame(&pMultiSourceFrame);
313 lastTime = currentTime;
316 ColorImageFormat imageFormat = ColorImageFormat_None;
317 UINT nColorBufferSize = 0;
318 RGBQUAD *pColorBuffer =
nullptr;
322 hr = pColorFrame->get_RawColorImageFormat(&imageFormat);
327 if (imageFormat == ColorImageFormat_Bgra)
329 hr = pColorFrame->AccessRawUnderlyingBuffer(&nColorBufferSize, reinterpret_cast<BYTE**>(&pColorBuffer));
331 else if (d->m_pColorRGBX)
333 pColorBuffer = d->m_pColorRGBX;
334 nColorBufferSize = d->m_RGBCaptureWidth * d->m_RGBCaptureHeight *
sizeof(RGBQUAD);
335 hr = pColorFrame->CopyConvertedFrameDataToArray(nColorBufferSize, reinterpret_cast<BYTE*>(pColorBuffer), ColorImageFormat_Bgra);
343 for(
int i = 0; i < d->m_RGBBufferSize; i+=3)
346 rgb[i+0] = pColorBuffer->rgbRed;
347 rgb[i+1] = pColorBuffer->rgbGreen;
348 rgb[i+2] = pColorBuffer->rgbBlue;
356 if( hr != -1 && !SUCCEEDED(hr) )
360 MITK_DEBUG <<
"HR result false in KinectV2Controller::GetRgb()";
368 MITK_ERROR <<
"Unable to initialize MultiFrameReader";
372 IMultiSourceFrame* pMultiSourceFrame =
nullptr;
373 IDepthFrame* pDepthFrame =
nullptr;
374 IColorFrame* pColorFrame =
nullptr;
375 IInfraredFrame* pInfraRedFrame =
nullptr;
379 static DWORD lastTime = 0;
380 DWORD currentTime = GetTickCount();
382 if(
unsigned int(currentTime - lastTime) > 33 )
384 hr = d->m_pMultiSourceFrameReader->AcquireLatestFrame(&pMultiSourceFrame);
385 lastTime = currentTime;
390 IDepthFrameReference* pDepthFrameReference =
nullptr;
392 hr = pMultiSourceFrame->get_DepthFrameReference(&pDepthFrameReference);
395 hr = pDepthFrameReference->AcquireFrame(&pDepthFrame);
402 IColorFrameReference* pColorFrameReference =
nullptr;
404 hr = pMultiSourceFrame->get_ColorFrameReference(&pColorFrameReference);
407 hr = pColorFrameReference->AcquireFrame(&pColorFrame);
414 IInfraredFrameReference* pInfraredFrameReference =
nullptr;
416 hr = pMultiSourceFrame->get_InfraredFrameReference(&pInfraredFrameReference);
419 hr = pInfraredFrameReference->AcquireFrame(&pInfraRedFrame);
426 UINT nDepthBufferSize = 0;
427 UINT16 *pDepthBuffer =
nullptr;
428 UINT16 *pInfraRedBuffer =
nullptr;
430 ColorImageFormat imageFormat = ColorImageFormat_None;
431 UINT nColorBufferSize = 0;
432 RGBQUAD *pColorBuffer =
nullptr;
436 hr = pDepthFrame->AccessUnderlyingBuffer(&nDepthBufferSize, &pDepthBuffer);
440 hr = pInfraRedFrame->AccessUnderlyingBuffer(&nDepthBufferSize, &pInfraRedBuffer);
444 UINT pointCount = d->m_DepthCaptureWidth * d->m_DepthCaptureHeight;
445 d->m_pCoordinateMapper->MapDepthFrameToCameraSpace(pointCount, pDepthBuffer, pointCount, d->m_CameraCoordinates);
446 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
447 vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
448 vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
450 const double meterfactor = 1000.0;
452 vtkSmartPointer<vtkFloatArray> textureCoordinates = vtkSmartPointer<vtkFloatArray>::New();
453 vtkSmartPointer<vtkIdList> vertexIdList = vtkSmartPointer<vtkIdList>::New();
454 vertexIdList->Allocate(pointCount);
455 vertexIdList->SetNumberOfIds(pointCount);
456 for(
unsigned int i = 0; i < pointCount; ++i)
458 vertexIdList->SetId(i, 0);
461 std::vector<bool> isPointValid;
462 isPointValid.resize(pointCount);
465 vertexIdList->Allocate(pointCount);
466 vertexIdList->SetNumberOfIds(pointCount);
467 textureCoordinates->SetNumberOfComponents(2);
468 textureCoordinates->Allocate(pointCount);
470 d->m_pCoordinateMapper->MapDepthFrameToColorSpace(pointCount, pDepthBuffer, pointCount, d->m_ColorPoints);
472 for(
int j = 0; j < d->m_DepthCaptureHeight; ++j)
474 for(
int i = 0; i < d->m_DepthCaptureWidth; ++i)
476 unsigned int pixelID = i+j*d->m_DepthCaptureWidth;
477 unsigned int inverseid = (d->m_DepthCaptureWidth - i - 1) + j*d->m_DepthCaptureWidth;
479 distances[inverseid] = static_cast<float>(*pDepthBuffer);
480 amplitudes[inverseid] =
static_cast<float>(*pInfraRedBuffer);
484 if (d->m_CameraCoordinates[pixelID].Z<=
mitk::eps)
486 isPointValid[pixelID] =
false;
490 isPointValid[pixelID] =
true;
499 vertexIdList->SetId(pixelID, points->InsertNextPoint(-d->m_CameraCoordinates[pixelID].X*meterfactor, -d->m_CameraCoordinates[pixelID].Y*meterfactor, d->m_CameraCoordinates[pixelID].Z*meterfactor));
501 if (d->m_GenerateTriangularMesh)
503 if((i >= 1) && (j >= 1))
517 vtkIdType xy = pixelID;
518 vtkIdType x_1y = pixelID-1;
519 vtkIdType xy_1 = pixelID-d->m_DepthCaptureWidth;
520 vtkIdType x_1y_1 = xy_1-1;
523 vtkIdType xyV = vertexIdList->GetId(xy);
524 vtkIdType x_1yV = vertexIdList->GetId(x_1y);
525 vtkIdType xy_1V = vertexIdList->GetId(xy_1);
526 vtkIdType x_1y_1V = vertexIdList->GetId(x_1y_1);
528 if (isPointValid[xy]&&isPointValid[x_1y]&&isPointValid[x_1y_1]&&isPointValid[xy_1])
530 double pointXY[3], pointX_1Y[3], pointXY_1[3], pointX_1Y_1[3];
532 points->GetPoint(xyV, pointXY);
533 points->GetPoint(x_1yV, pointX_1Y);
534 points->GetPoint(xy_1V, pointXY_1);
535 points->GetPoint(x_1y_1V, pointX_1Y_1);
538 if( (
mitk::Equal(d->m_TriangulationThreshold, 0.0)) || ((vtkMath::Distance2BetweenPoints(pointXY, pointX_1Y) <= d->m_TriangulationThreshold)
539 && (vtkMath::Distance2BetweenPoints(pointXY, pointXY_1) <= d->m_TriangulationThreshold)
540 && (vtkMath::Distance2BetweenPoints(pointX_1Y, pointX_1Y_1) <= d->m_TriangulationThreshold)
541 && (vtkMath::Distance2BetweenPoints(pointXY_1, pointX_1Y_1) <= d->m_TriangulationThreshold)))
543 polys->InsertNextCell(3);
544 polys->InsertCellPoint(x_1yV);
545 polys->InsertCellPoint(xyV);
546 polys->InsertCellPoint(x_1y_1V);
548 polys->InsertNextCell(3);
549 polys->InsertCellPoint(x_1y_1V);
550 polys->InsertCellPoint(xyV);
551 polys->InsertCellPoint(xy_1V);
556 vertices->InsertNextCell(1);
557 vertices->InsertCellPoint(xyV);
565 vertices->InsertNextCell(1);
566 vertices->InsertCellPoint(vertexIdList->GetId(pixelID));
569 ColorSpacePoint colorPoint = d->m_ColorPoints[pixelID];
571 int colorInDepthX = (int)(floor(colorPoint.X + 0.5));
572 int colorInDepthY = (int)(floor(colorPoint.Y + 0.5));
574 float xNorm = -
static_cast<float>(colorInDepthX)/d->m_RGBCaptureWidth;
575 float yNorm = static_cast<float>(colorInDepthY)/d->m_RGBCaptureHeight;
578 if ( colorInDepthX >= 0 && colorInDepthX < d->m_RGBCaptureWidth && colorInDepthY >= 0 && colorInDepthY < d->m_RGBCaptureHeight )
580 textureCoordinates->InsertTuple2(vertexIdList->GetId(pixelID), xNorm, yNorm);
584 textureCoordinates->InsertTuple2(vertexIdList->GetId(pixelID), 0, 0);
590 d->m_PolyData = vtkSmartPointer<vtkPolyData>::New();
591 d->m_PolyData->SetPoints(points);
592 d->m_PolyData->SetVerts(vertices);
593 d->m_PolyData->SetPolys(polys);
594 d->m_PolyData->GetPointData()->SetTCoords(textureCoordinates);
604 hr = pColorFrame->get_RawColorImageFormat(&imageFormat);
609 if (imageFormat == ColorImageFormat_Bgra)
611 hr = pColorFrame->AccessRawUnderlyingBuffer(&nColorBufferSize, reinterpret_cast<BYTE**>(&pColorBuffer));
613 else if (d->m_pColorRGBX)
615 pColorBuffer = d->m_pColorRGBX;
616 nColorBufferSize = d->m_RGBCaptureWidth * d->m_RGBCaptureHeight *
sizeof(RGBQUAD);
617 hr = pColorFrame->CopyConvertedFrameDataToArray(nColorBufferSize, reinterpret_cast<BYTE*>(pColorBuffer), ColorImageFormat_Bgra);
625 for(
int j = 0; j < d->m_RGBCaptureHeight; ++j)
627 for(
int i = 0; i < d->m_RGBCaptureWidth; ++i)
631 unsigned int id = ((d->m_RGBCaptureWidth - i - 1) + j*d->m_RGBCaptureWidth)*3;
633 rgb[
id+0] = pColorBuffer->rgbRed;
634 rgb[
id+1] = pColorBuffer->rgbGreen;
635 rgb[
id+2] = pColorBuffer->rgbBlue;
648 if( hr != -1 && !SUCCEEDED(hr) )
652 MITK_DEBUG <<
"HR result false in KinectV2Controller::GetAllData()";
660 MITK_ERROR <<
"Unable to initialize MultiFrameReader";
664 IMultiSourceFrame* pMultiSourceFrame =
nullptr;
665 IInfraredFrame* pInfraRedFrame =
nullptr;
669 static DWORD lastTime = 0;
670 DWORD currentTime = GetTickCount();
672 if(
unsigned int(currentTime - lastTime) > 33 )
674 hr = d->m_pMultiSourceFrameReader->AcquireLatestFrame(&pMultiSourceFrame);
675 lastTime = currentTime;
680 IInfraredFrameReference* pInfraredFrameReference =
nullptr;
682 hr = pMultiSourceFrame->get_InfraredFrameReference(&pInfraredFrameReference);
685 hr = pInfraredFrameReference->AcquireFrame(&pInfraRedFrame);
692 UINT nDepthBufferSize = 0;
693 UINT16 *pInfraRedBuffer =
nullptr;
697 hr = pInfraRedFrame->AccessUnderlyingBuffer(&nDepthBufferSize, &pInfraRedBuffer);
701 for(
int i = 0; i < d->m_DepthCaptureHeight*d->m_DepthCaptureWidth; ++i)
703 amplitudes[i] =
static_cast<float>(*pInfraRedBuffer);
715 if( hr != -1 && !SUCCEEDED(hr) )
719 MITK_DEBUG <<
"HR result false in KinectV2Controller::GetAmplitudes()";
725 return d->m_RGBCaptureWidth;
730 return d->m_RGBCaptureHeight;
735 return d->m_DepthCaptureWidth;
740 return d->m_DepthCaptureHeight;
745 return d->m_PolyData;
750 d->m_GenerateTriangularMesh = flag;
755 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
int GetRGBCaptureWidth() const
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
vtkSmartPointer< vtkPolyData > GetVtkPolyData()
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.
int GetDepthCaptureHeight() const
virtual bool CloseCameraConnection()
closes the connection to the camera
int GetDepthCaptureWidth() const
MITKCORE_EXPORT const ScalarType eps