vtk.cpp
#include"Hand3D.hpp"
#include"vtk.hpp"
VTK_MODULE_INIT(vtkRenderingOpenGL2)
int main()
{
Hand3D hand;
HandView vtk;
//hand.KillDCM();
hand.Init();
//PXCHandData::JointData joints[22][3];
vtkSmartPointer renderer =
vtkSmartPointer::New();
vtkSmartPointer renderWindow =
vtkSmartPointer::New();
renderWindow->AddRenderer(renderer);
// An interactor
vtkSmartPointer renderWindowInteractor =
vtkSmartPointer::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->UpdateSize(880,640 );
while (1) {
hand.Update();
auto hl = hand.QueryHandLeft(), hr = hand.QueryHandRight();
auto data = hand.QuerySkeletonPositon(hl);
if (data) {
vtkSmartPointer actors[22];
for (size_t i = 0; i < 22; i++)
{
actors[i] = vtk.createball(data[i].x * 100, data[i].y * 100, data[i].z * 100, 1);
renderer->AddActor(actors[i]);
if (i < 10) {
//cout << "手指关节的信息____________第" << i << " 个关节的位置信息___________" << data->x * 1000 << endl;
}
else
{
//cout << "手指关节的信息____________第" << i << " 个关节的位置信息___________" << data->x * 1000 << endl;
}
}
renderer->SetBackground(0, 0, 0); // Background color white
// Render an image (lights and cameras are created automatically)
renderWindow->Render();
vtkSmartPointer style =
vtkSmartPointer::New();
renderWindowInteractor->SetInteractorStyle(style);
// Begin mouse interaction
//renderWindowInteractor->Start();
//renderWindowInteractor->();
renderWindowInteractor->Disable();
for (size_t i = 0; i < 22; i++){
renderer->RemoveActor(actors[i]);
}
}
}
// //设置圆
// auto actor11 = createball(-12.0, -10.0, 0.0, 2.0);
// auto actor12 = createball(-15.0, -4.0, 0.0, 2.0);
// auto actor13 = createball(-18.0, 3.0, 0.0, 2.0);
// auto actor21 = createball(-6.0, -2.0, 0.0, 2.0);
// auto actor22 = createball(-8.0, 10.0, 0.0, 2.0);
// auto actor23 = createball(-10.0, 25.0, 0.0, 2.0);
// auto actor31 = createball(0.0, 0.0, 0.0, 2.0);
// auto actor32 = createball(0.0, 12.0, 0.0, 2.0);
// auto actor33 = createball(0.0, 27.0, 0.0, 2.0);
// auto actor41 = createball(5.0, -2.0, 0.0, 2.0);
// auto actor42 = createball(7.0, 10.0, 0.0, 2.0);
// auto actor43 = createball(9.0, 23.0, 0.0, 2.0);
// auto actor51 = createball(10.0, -6.0, 0.0, 2.0);
// auto actor52 = createball(12.0, 0.0, 0.0, 2.0);
// auto actor53 = createball(14.0, 10.0, 0.0, 2.0);
// auto actor_ori = createball(0.0, -18.0, 0.0, 2.0);
// //设置线
// auto line_actor10 = createline(-12.0, -10.0, 0.0, 0.0, -18.0, 0.0);
// auto line_actor11 = createline(-12.0, -10.0, 0.0, -15.0, -4.0, 0.0);
// auto line_actor12 = createline(-15.0, -4.0, 0.0, -18.0, 3.0, 0.0);
// auto line_actor20 = createline(-6.0, -2.0, 0.0, 0.0, -18.0, 0.0);
// auto line_actor21 = createline(-6.0, -2.0, 0.0, -8.0, 10.0, 0.0);
// auto line_actor22 = createline(-8.0, 10.0, 0.0, -10.0, 25.0, 0.0);
// auto line_actor30 = createline(0.0, 0.0, 0.0, 0.0, -18.0, 0.0);
// auto line_actor31 = createline(0.0, 0.0, 0.0, 0.0, 12.0, 0.0);
// auto line_actor32 = createline(0.0, 12.0, 0.0, 0.0, 27.0, 0.0);
// auto line_actor40 = createline(5.0, -2.0, 0.0, 0.0, -18.0, 0.0);
// auto line_actor41 = createline(5.0, -2.0, 0.0, 7.0, 10.0, 0.0);
// auto line_actor42 = createline(7.0, 10.0, 0.0, 9.0, 23.0, 0.0);
// auto line_actor50 = createline(10.0, -6.0, 0.0, 0.0, -18.0, 0.0);
// auto line_actor51 = createline(10.0, -6.0, 0.0, 12.0, 0.0, 0.0);
// auto line_actor52 = createline(12.0, 0.0, 0.0, 14.0, 10.0, 0.0);
// /*auto line_actor = createline();
// auto line_actor = createline();
// auto line_actor = createline();
// auto line_actor = createline();
// auto line_actor = createline();*/
//A renderer and render window
// // Add the actors to the scene
// renderer->AddActor(actor11);
// renderer->AddActor(actor12);
// renderer->AddActor(actor13);
// renderer->AddActor(actor21);
// renderer->AddActor(actor22);
// renderer->AddActor(actor23);
// renderer->AddActor(actor31);
// renderer->AddActor(actor32);
// renderer->AddActor(actor33);
// renderer->AddActor(actor41);
// renderer->AddActor(actor42);
// renderer->AddActor(actor43);
// renderer->AddActor(actor51);
// renderer->AddActor(actor52);
// renderer->AddActor(actor53);
// renderer->AddActor(actor_ori);
// renderer->AddActor(line_actor10);
// renderer->AddActor(line_actor11);
// renderer->AddActor(line_actor12);
// renderer->AddActor(line_actor20);
// renderer->AddActor(line_actor21);
// renderer->AddActor(line_actor22);
// renderer->AddActor(line_actor30);
// renderer->AddActor(line_actor31);
// renderer->AddActor(line_actor32);
// renderer->AddActor(line_actor40);
// renderer->AddActor(line_actor41);
// renderer->AddActor(line_actor42);
// renderer->AddActor(line_actor50);
// renderer->AddActor(line_actor51);
// renderer->AddActor(line_actor52);
return EXIT_SUCCESS;
}
vtk.hpp
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace cv;
using namespace std;
class HandView
{
public:
HandView() {
}
vtkSmartPointer createball(float x, float y, float z, int r)
{
vtkSmartPointer sphereSource =
vtkSmartPointer::New();
sphereSource->SetCenter(x, y, z);
sphereSource->SetRadius(r);
sphereSource->Update();
vtkSmartPointer mapper =
vtkSmartPointer::New();
mapper->SetInputConnection(sphereSource->GetOutputPort());
vtkSmartPointer actor =
vtkSmartPointer::New();
actor->SetMapper(mapper);
return actor;
}
vtkSmartPointer createline(double x1, double y1, double z1, double x2, double y2, double z2)
{
vtkSmartPointer lineSource =
vtkSmartPointer::New();
lineSource->SetPoint1(x1, y1, z1);
lineSource->SetPoint2(x2, y2, z2);
lineSource->Update();
// Visualize
vtkSmartPointer mapper =
vtkSmartPointer::New();
mapper->SetInputConnection(lineSource->GetOutputPort());
vtkSmartPointer actor =
vtkSmartPointer::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetLineWidth(4);
return actor;
}
private:
};
hand3d.hpp
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
class Hand3D
{
public:
bool Init() {
sr300_manager = PXCSenseManager::CreateInstance();
sr300_manager->EnableStream(PXCCapture::STREAM_TYPE_COLOR, 960, 540, 60);
sr300_manager->EnableStream(PXCCapture::STREAM_TYPE_DEPTH, 640, 480, 60);
sr300_manager->EnableStream(PXCCapture::STREAM_TYPE_IR, 640, 480, 60);
sr300_manager->EnableHand();
handModule = sr300_manager->QueryHand();
PXCHandConfiguration* handConfig = handModule->CreateActiveConfiguration();
handConfig->SetTrackingMode(PXCHandData::TrackingModeType::TRACKING_MODE_FULL_HAND);
handConfig->EnableStabilizer(true);
handConfig->EnableTrackedJoints(true);
handConfig->EnableNormalizedJoints(true);
handConfig->EnableSegmentationImage(true);
handConfig->ApplyChanges();
handData = handModule->CreateOutput();
sr300_manager->QuerySession()->CreateImpl(&smooth);
for (size_t i = 0; i < 10; i++) {
smoother[i] = smooth->Create1DSpring();
smoother[i]->SmoothValue(0.1);
}
for (size_t i = 0; i < 8; i++) {
smoother_rect[i] = smooth->Create1DSpring(0.3);
smoother[i]->SmoothValue(0.1);
}
auto device = Seek();
projection = device->CreateProjection();
sr300_manager->Init();
//auto device = sr300_manager->QuerySession()->CreateCaptureManager()->QueryDevice();
//auto device = sr300_manager->QueryCaptureManager()->QueryDevice();
yy = 480 - 5 * hist_w;
xx = 640 - 5 * hist_w;
indicator = cv::Mat::zeros(cv::Size(5 * hist_w, 5 * hist_w), CV_8UC3);
canvas = cv::Mat::zeros(cv::Size(640, 480), CV_8UC3);
Update();
//device->SetDeviceAllowProfileChange(true);
device->SetIVCAMLaserPower(16);
cout << device->SetDepthConfidenceThreshold(5);
cout << device->SetIVCAMMotionRangeTradeOff(5);
cout << device->SetIVCAMFilterOption(0);
cout << device->SetIVCAMAccuracy(PXCCapture::Device::IVCAM_ACCURACY_FINEST);
sr300_manager->QuerySession()->CreatePowerManager()->SetState(PXCPowerState::STATE_PERFORMANCE);
return true;
}
int Update() {
// 清零
for (size_t i = 0; i < 3; i++) {
ihand[i] = NULL;
handId[i] = 0;
}
sr300_manager->ReleaseFrame();
// 更新
if (sr300_manager->AcquireFrame(true) < PXC_STATUS_NO_ERROR) return -1;
sample = sr300_manager->QuerySample();
depth = sample->depth;
color = sample->color;
handData->Update();
nHands = handData->QueryNumberOfHands();
for (size_t i = 0; i < nHands; i++) {
auto ret = handData->QueryHandId(PXCHandData::ACCESS_ORDER_NEAR_TO_FAR, i, handId[PXCHandData::BodySideType::BODY_SIDE_UNKNOWN]);//查询所有的手
ret = handData->QueryHandDataById(handId[PXCHandData::BodySideType::BODY_SIDE_UNKNOWN], ihand[PXCHandData::BodySideType::BODY_SIDE_UNKNOWN]);//
auto side = ihand[PXCHandData::BodySideType::BODY_SIDE_UNKNOWN]->QueryBodySide();
ihand[side] = ihand[PXCHandData::BodySideType::BODY_SIDE_UNKNOWN];
handId[side] = handId[PXCHandData::BodySideType::BODY_SIDE_UNKNOWN];
for (size_t i = 0; i < 22; i++) {
// 一根手指
// 归一化关节
ihand[side]->QueryNormalizedJoint((PXCHandData::JointType)i, joints[side][i]);
}
}
colorSight = QueryColorImage();
return nHands;
}
cv::Mat QueryColorImage() {
auto pxcimg = projection->CreateColorImageMappedToDepth(depth, color);
auto info = pxcimg->QueryInfo();
PXCImage::ImageData img_dat;
pxcimg->AcquireAccess(PXCImage::Access::ACCESS_READ, PXCImage::PIXEL_FORMAT_RGB24, &img_dat);
cv::Mat img = cv::Mat(info.height, info.width, CV_8UC3, (void*)img_dat.planes[0], img_dat.pitches[0] / sizeof(uchar)).clone();
pxcimg->ReleaseAccess(&img_dat);
pxcimg->Release();
flip(img, img, 1);
return img + QueryIrImage();
}
cv::Mat QueryIrImage() {
auto pxcimg = sample->ir;
auto info = pxcimg->QueryInfo();
PXCImage::ImageData img_dat;
pxcimg->AcquireAccess(PXCImage::Access::ACCESS_READ, PXCImage::PIXEL_FORMAT_Y8_IR_RELATIVE, &img_dat);
cv::Mat img = cv::Mat(info.height, info.width, CV_8UC1, (void*)img_dat.planes[0], img_dat.pitches[0] / sizeof(uchar));
// cv::normalize(img,img,0,255)
cv::cvtColor(img, img, cv::COLOR_GRAY2BGR);
pxcimg->ReleaseAccess(&img_dat);
flip(img*1.5, img, 1);
return img;
}
cv::Mat QuerySegmentedMask() {///xxx
PXCImage::ImageData img_dat;
color->AcquireAccess(PXCImage::Access::ACCESS_READ, PXCImage::PIXEL_FORMAT_Y8, &img_dat);
cv::Mat img = cv::Mat(360, 640, CV_8UC1, (void*)img_dat.planes[0], img_dat.pitches[0] / sizeof(uchar)).clone();
color->ReleaseAccess(&img_dat);
}
cv::Mat drawIndicator() {
canvas.setTo(0);
draw(ihand[PXCHandData::BodySideType::BODY_SIDE_LEFT]);
draw(ihand[PXCHandData::BodySideType::BODY_SIDE_RIGHT]);
//for (size_t i = 0; i < nHands; i++)
//{
// pxcUID handId;
// auto ret = handData->QueryHandId(PXCHandData::ACCESS_ORDER_NEAR_TO_FAR, i, handId);
// //cout << handId << endl;
// handData->QueryHandDataById(handId, ihand[PXCHandData::BodySideType::BODY_SIDE_UNKNOWN]);
// // 画框
// auto rect = ihand[PXCHandData::BodySideType::BODY_SIDE_UNKNOWN]->QueryBoundingBoxImage();
// rect.x = 640 - rect.x - rect.w;
// auto yy = 480 - 5 * hist_w;
// cout << rect.y << endl;
// if (rect.y > yy) rect.y = yy;
// // 指示器
// cv::Mat ind = canvas(cv::Rect(rect.x, rect.y, 5 * hist_w, 5 * hist_w));
// double *foldedness = QueryFingerFoldedness(handId);
// for (size_t i = 0; i < 5; i++) {
// auto h = (int)(foldedness[i] * indicator.rows);
// rectangle(ind, cv::Rect(i*hist_w, indicator.rows - h, hist_w, h), cv::Scalar(255, 255, 255), -1);
// }
// if (ihand[PXCHandData::BodySideType::BODY_SIDE_UNKNOWN]->QueryBodySide() == PXCHandData::BodySideType::BODY_SIDE_LEFT)flip(ind, ind, 1);
// rectangle(canvas, cv::Rect(rect.x, rect.y, rect.w, rect.h), cv::Scalar(0, 255, ihand[PXCHandData::BodySideType::BODY_SIDE_UNKNOWN]->IsCalibrated() ? 0 : 255), 2);
// // string显示框
//}
return canvas + colorSight;
}
////////////////////////////////////////////////////////////////////////////////////////
PXCHandData::IHand *QueryHandRight() {
return ihand[PXCHandData::BodySideType::BODY_SIDE_RIGHT];
}
PXCHandData::IHand *QueryHandLeft() {
return ihand[PXCHandData::BodySideType::BODY_SIDE_LEFT];
}
PXCHandData::IHand *QueryHandUnknown() {
return ihand[PXCHandData::BodySideType::BODY_SIDE_UNKNOWN];
}
//////////////////////////////////////////////////////////////////////////////////////
//cv::Rect projectRect(PXCRectI32 rect,float z)
//{
// PXCPointF32 p2[2];
// PXCPoint3DF32 p3[2];
// p3[0].x = rect.x;
// p3[0].y = rect.y;
// p3[1].x = p3[0].x+rect.w;
// p3[1].y = p3[0].y + rect.h;
// p3[0].z = p3[1].z = z;
// auto cal = projection->MapDepthToColor(2,p3,p2);
// return cv::Rect(cv::Point(p2[0].x, p2[0].y), cv::Point(p2[1].x, p2[1].y));
//}
// 边界框
cv::Rect QueryHandBoundingBox(PXCHandData::IHand *ihand) {
if (ihand == NULL) return cv::Rect(0, 0, 0, 0);
auto rect = ihand->QueryBoundingBoxImage();
rect.x = 640 - rect.x - rect.w;
return cv::Rect(rect.x, rect.y, rect.w, rect.h);
}
void draw(PXCHandData::IHand *ihand) {
if (ihand == NULL) return;
// 框
auto offset = (ihand->QueryBodySide() == PXCHandData::BodySideType::BODY_SIDE_LEFT) ? 4 : 0;;
auto rect = ihand->QueryBoundingBoxImage();
rect.x = 640 - rect.x - rect.w;
if (rect.y > yy) rect.y = yy;
if (rect.x > xx) rect.x = xx;
//if (rect.x > xx) rect.x = xx;
auto x = smoother_rect[offset + 0]->SmoothValue(rect.x);
auto y = smoother_rect[offset + 1]->SmoothValue(rect.y);
auto w = smoother_rect[offset + 2]->SmoothValue(rect.w);
auto h = smoother_rect[offset + 3]->SmoothValue(rect.h);
auto box = cv::Rect(x, y, w, h);
auto iscalib = ihand->IsCalibrated();
if (iscalib) {
// 指示器
cv::Rect indBox = cv::Rect(x, y + h - 5 * hist_w, 5 * hist_w, 5 * hist_w);
cv::Mat ind;
colorSight(indBox) /= 2;
ind = canvas(indBox);
double *foldedness = QueryFingerFoldedness(ihand);
for (size_t i = 0; i < 5; i++) {
auto h = (int)(foldedness[i] * indicator.rows);
rectangle(ind, cv::Rect(i*hist_w, indicator.rows - h, hist_w, h), cv::Scalar(255 * foldedness[i], 255, 255 - 200 * foldedness[i]), -1);
}
if (ihand->QueryBodySide() == PXCHandData::BodySideType::BODY_SIDE_LEFT)flip(ind, ind, 1);
}
rectangle(canvas, box, cv::Scalar(iscalib ? 255 : 0, 127, iscalib ? 0 : 255), iscalib ? 2 : 15);
//cout << box << endl;
cout << box << endl;
}
// 弯曲度指示器
cv::Mat QueryIndicator(PXCHandData::IHand *ihand) {
indicator.setTo(0);
if (ihand == NULL) return indicator;
double *foldedness = QueryFingerFoldedness(ihand);
for (size_t i = 0; i < 5; i++) {
auto h = (int)(foldedness[i] * indicator.rows);
rectangle(indicator, cv::Rect(i*hist_w, indicator.rows - h, hist_w, h), cv::Scalar(255, 255, 255), -1);
}
if (ihand == NULL) return indicator;
}
PXCPoint3DF32 *QuerySkeletonPositon(PXCHandData::IHand *ihand) {
if (ihand == NULL) return NULL;
auto side = (int)ihand->QueryBodySide();
if (side == PXCHandData::BodySideType::BODY_SIDE_UNKNOWN) return NULL;
for (size_t i = 0; i < 22; i++) {
jointsPosXYZ[i] = joints[side][i].positionWorld;
}
return jointsPosXYZ;
}
double* QueryFingerFoldedness(PXCHandData::IHand *ihand) {
if (ihand == NULL) {
for (size_t i = 0; i < 5; i++)
finger_foldedness[i] = -1;
return finger_foldedness;
}
int offset = ihand->QueryBodySide() == PXCHandData::BodySideType::BODY_SIDE_RIGHT ? 5 : 0;
for (size_t i = 0; i < 5; i++) {
ihand->QueryFingerData((PXCHandData::FingerType)i, finger[i]);
finger_foldedness[i] = smoother[i + offset]->SmoothValue(finger[i].foldedness) / 100.0f;
//cout << finger_foldedness[i] << endl;
}
return finger_foldedness;
}
cv::Point3f QueryMassCenterWorld(PXCHandData::IHand *ihand) {
if (ihand == NULL)return cv::Point3f();
auto worldPos = ihand->QueryMassCenterWorld();
return cv::Point3f(worldPos.x, worldPos.y, worldPos.z);
}
DWORD KillDCM()
{
cout << "正在重启DCM[";
SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO) };
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.lpVerb = TEXT("runas");
sei.lpFile = TEXT("cmd.exe");
sei.nShow = SW_HIDE;
// 停止
sei.lpParameters = TEXT("cmd /c NET STOP RealSenseDCMSR300 & NET START RealSenseDCMSR300");
if (!ShellExecuteEx(&sei)) {
if (GetLastError() == ERROR_CANCELLED)
cout << "访问权限被用户拒绝";
}
DWORD dwExitCode;
GetExitCodeProcess(sei.hProcess, &dwExitCode);
while (dwExitCode == STILL_ACTIVE) {
Sleep(800);
GetExitCodeProcess(sei.hProcess, &dwExitCode);
cout << "=";
}
cout << "]";
CloseHandle(sei.hProcess);
dwExitCode ? cout << "访问错误(" << dwExitCode << ")" << endl : cout << "完成" << endl;
return dwExitCode;
}
PXCCapture::Device* Seek()
{
PXCCapture *Capture;
uint_fast8_t idx = 0, i;
for (;; idx += 1)
{
PXCSession::ImplDesc Impl = {};
Impl.group = PXCSession::IMPL_GROUP_SENSOR;
Impl.subgroup = PXCSession::IMPL_SUBGROUP_VIDEO_CAPTURE;
auto Session = PXCSession::CreateInstance();
auto retStatus = Session->QueryImpl(&Impl, idx, &Impl);
if (retStatus < PXC_STATUS_NO_ERROR) continue;
cout << "--------------------------------------------------------------------------------------" << endl;
wcout << "DCM服务:" << Impl.friendlyName;
cout << " *** IUID是:" << Impl.iuid << endl;
retStatus = Session->CreateImpl(&Impl, &Capture);
if (retStatus < PXC_STATUS_NO_ERROR) continue;
PXCCapture::DeviceInfo dinfo = { 0 };
retStatus = Capture->QueryDeviceInfo(idx, &dinfo);
if (retStatus < PXC_STATUS_NO_ERROR) { cout << "详细信息:获取失败" << endl; break; }
wcout << "详细信息:" << endl;
wcout << " 名称:" << dinfo.name << " 位于DCM设备索引 " << dinfo.didx << endl;
wcout << " 可使用视频流:";
if (dinfo.streams&PXCCapture::STREAM_TYPE_COLOR) cout << "COLOR ";
if (dinfo.streams&PXCCapture::STREAM_TYPE_DEPTH) cout << "DEPTH ";
if (dinfo.streams&PXCCapture::STREAM_TYPE_IR) cout << "IR ";
if (dinfo.streams&PXCCapture::STREAM_TYPE_LEFT) cout << "LEFT";
if (dinfo.streams&PXCCapture::STREAM_TYPE_RIGHT) cout << "RIGHT "; wcout << endl;
wcout << " 固件版本:V" << dinfo.firmware[0] << "." << dinfo.firmware[1] << "." << dinfo.firmware[2] << "." << dinfo.firmware[3] << endl;
wcout << " 序列号:" << dinfo.serial << endl;
wcout << " 设备标识符:" << dinfo.did << endl;
cout << "======================================================================================" << endl;
i = idx;
break;
//wcout << "√!找到了匹配的" << Capture->DeviceModelToString(dinfo.model) << " ";
}
auto device = Capture->CreateDevice(i);
if (device == NULL) { cout << "\n没有匹配设备," << (int)i; }
return device;
}
private:
PXCSenseManager* sr300_manager = NULL;
PXCImage *color, *depth, *segmask = NULL;
PXCCapture::Sample *sample;
PXCHandModule *handModule = NULL;
PXCHandData* handData = NULL;
PXCSmoother *smooth = NULL;
PXCSmoother::Smoother1D* smoother[10];
PXCSmoother::Smoother1D* smoother_rect[8];
PXCHandData::IHand *ihand[3];
pxcUID handId[3];
float handz[3];
pxcUID current_handId = 0;
pxcStatus ihand_update_ret = PXC_STATUS_DATA_UNAVAILABLE;
pxcStatus ihand_update(pxcUID handId) {
return ihand_update_ret = handData->QueryHandDataById(handId, ihand[0]);
}
int hist_w = 20;
int yy = 480 - 5 * hist_w;
int xx = 640 - 5 * hist_w;
cv::Mat indicator;
PXCHandData::FingerData finger[5];
double finger_foldedness[5];
PXCHandData::JointData joints[3][22];
PXCPoint3DF32 jointsPosXYZ[22];
int nHands = 0;
cv::Mat canvas, colorSight;
PXCProjection *projection = NULL;
};