31 #include <opencv2/imgproc/types_c.h> 42 template<
class Interface>
43 inline void SafeRelease(Interface *& pInterfaceToRelease)
45 if (pInterfaceToRelease != NULL)
47 pInterfaceToRelease->Release();
48 pInterfaceToRelease =
NULL;
67 Camera(imageRate, localTransform)
72 pCoordinateMapper_(
NULL),
75 pMultiSourceFrameReader_(
NULL),
85 if (pDepthCoordinates_)
87 delete[] pDepthCoordinates_;
88 pDepthCoordinates_ =
NULL;
91 if (pColorCoordinates_)
93 delete[] pColorCoordinates_;
94 pColorCoordinates_ =
NULL;
110 if (pMultiSourceFrameReader_)
112 pMultiSourceFrameReader_->UnsubscribeMultiSourceFrameArrived(hMSEvent);
113 CloseHandle((HANDLE)hMSEvent);
118 SafeRelease(pMultiSourceFrameReader_);
121 SafeRelease(pCoordinateMapper_);
126 pKinectSensor_->Close();
129 SafeRelease(pKinectSensor_);
135 bool CameraK4W2::init(
const std::string & calibrationFolder,
const std::string & cameraName)
142 hr = GetDefaultKinectSensor(&pKinectSensor_);
152 hr = pKinectSensor_->Open();
156 hr = pKinectSensor_->get_CoordinateMapper(&pCoordinateMapper_);
160 hr = pKinectSensor_->OpenMultiSourceFrameReader(
161 FrameSourceTypes::FrameSourceTypes_Depth | FrameSourceTypes::FrameSourceTypes_Color,
162 &pMultiSourceFrameReader_);
166 hr = pMultiSourceFrameReader_->SubscribeMultiSourceFrameArrived(&hMSEvent);
172 if (!pKinectSensor_ || FAILED(hr))
174 UERROR(
"No ready Kinect found!");
183 CameraIntrinsics intrinsics;
184 hr = pCoordinateMapper_->GetDepthCameraIntrinsics(&intrinsics);
185 if (SUCCEEDED(hr) && intrinsics.FocalLengthX > 0.0f)
189 intrinsics.FocalLengthX,
190 intrinsics.FocalLengthY,
191 intrinsics.PrincipalPointX,
192 intrinsics.PrincipalPointY);
205 if (p.X != -std::numeric_limits<float>::infinity() && p.Y != -std::numeric_limits<float>::infinity())
207 if (firstIndex == -1)
209 firstIndex = depthIndex;
211 lastIndex = depthIndex;
215 UASSERT(firstIndex >= 0 && lastIndex >= 0);
216 float fx, fy, cx, cy;
217 float x1, y1, z1, x2, y2, z2;
219 depthModel.
project(lastIndex - (lastIndex / cDepthWidth)*cDepthWidth, lastIndex / cDepthWidth, 1.0
f, x2, y2, z2);
222 fx = ((uv1.X - uv2.X)*z1*z2) / (x1*z2 - x2*z1);
223 cx = uv1.X - (x1 / z1) * fx;
224 fy = ((uv1.Y - uv2.Y)*z1*z2) / (y1*z2 - y2*z1);
225 cy = uv1.Y - (y1 / z1) * fy;
238 if (!colorCameraModel_.isValidForProjection())
240 UERROR(
"Failed to get camera parameters! Is the camera connected? Try restarting the camera again or use kTypeColor2DepthSD.");
248 UINFO(
"Running kinect device \"%s\"", serial.c_str());
253 UERROR(
"CameraK4W2: RTAB-Map is not built with Kinect for Windows 2 SDK support!");
268 wchar_t uid[255] = { 0 };
270 HRESULT hr = pKinectSensor_->get_UniqueKinectId(255, uid);
273 std::wstring ws(uid);
274 return std::string(ws.begin(), ws.end());
287 if (!pMultiSourceFrameReader_)
295 HANDLE handles[] = {
reinterpret_cast<HANDLE
>(hMSEvent) };
298 while((
UTimer::now()-t < 5.0) && WaitForMultipleObjects(_countof(handles), handles,
false, 5000) == WAIT_OBJECT_0)
300 IMultiSourceFrameArrivedEventArgs* pArgs =
NULL;
302 hr = pMultiSourceFrameReader_->GetMultiSourceFrameArrivedEventData(hMSEvent, &pArgs);
305 IMultiSourceFrameReference * pFrameRef =
NULL;
306 hr = pArgs->get_FrameReference(&pFrameRef);
309 IMultiSourceFrame* pMultiSourceFrame =
NULL;
310 IDepthFrame* pDepthFrame =
NULL;
311 IColorFrame* pColorFrame =
NULL;
313 hr = pFrameRef->AcquireFrame(&pMultiSourceFrame);
316 UERROR(
"Failed getting latest frame.");
319 IDepthFrameReference* pDepthFrameReference =
NULL;
320 hr = pMultiSourceFrame->get_DepthFrameReference(&pDepthFrameReference);
323 hr = pDepthFrameReference->AcquireFrame(&pDepthFrame);
325 SafeRelease(pDepthFrameReference);
327 IColorFrameReference* pColorFrameReference =
NULL;
328 hr = pMultiSourceFrame->get_ColorFrameReference(&pColorFrameReference);
331 hr = pColorFrameReference->AcquireFrame(&pColorFrame);
333 SafeRelease(pColorFrameReference);
335 if (pDepthFrame && pColorFrame)
337 IFrameDescription* pDepthFrameDescription =
NULL;
339 int nDepthHeight = 0;
340 UINT nDepthBufferSize = 0;
341 UINT16 *pDepthBuffer =
NULL;
343 IFrameDescription* pColorFrameDescription =
NULL;
345 int nColorHeight = 0;
346 ColorImageFormat imageFormat = ColorImageFormat_None;
347 UINT nColorBufferSize = 0;
352 hr = pDepthFrame->get_FrameDescription(&pDepthFrameDescription);
354 hr = pDepthFrameDescription->get_Width(&nDepthWidth);
356 hr = pDepthFrameDescription->get_Height(&nDepthHeight);
358 hr = pDepthFrame->AccessUnderlyingBuffer(&nDepthBufferSize, &pDepthBuffer);
362 hr = pColorFrame->get_FrameDescription(&pColorFrameDescription);
364 hr = pColorFrameDescription->get_Width(&nColorWidth);
366 hr = pColorFrameDescription->get_Height(&nColorHeight);
368 hr = pColorFrame->get_RawColorImageFormat(&imageFormat);
371 if (imageFormat == ColorImageFormat_Bgra)
373 hr = pColorFrame->AccessRawUnderlyingBuffer(&nColorBufferSize, reinterpret_cast<BYTE**>(&pColorBuffer));
375 else if (pColorRGBX_)
377 pColorBuffer = pColorRGBX_;
379 hr = pColorFrame->CopyConvertedFrameDataToArray(nColorBufferSize, reinterpret_cast<BYTE*>(pColorBuffer), ColorImageFormat_Bgra);
394 if (pCoordinateMapper_ &&
400 HRESULT hr = pCoordinateMapper_->MapColorFrameToDepthSpace(nDepthWidth * nDepthHeight, (UINT16*)pDepthBuffer, nColorWidth * nColorHeight, pDepthCoordinates_);
403 cv::Mat depth = cv::Mat::zeros(nDepthHeight, nDepthWidth, CV_16UC1);
404 cv::Mat imageColorRegistered = cv::Mat::zeros(nDepthHeight, nDepthWidth, CV_8UC3);
406 for (
int colorIndex = 0; colorIndex < (nColorWidth*nColorHeight); ++colorIndex)
411 if (p.X != -std::numeric_limits<float>::infinity() && p.Y != -std::numeric_limits<float>::infinity())
415 int pixel_x_l, pixel_y_l, pixel_x_h, pixel_y_h;
416 pixel_x_l = nDepthWidth -
static_cast<int>(p.X);
417 pixel_y_l =
static_cast<int>(p.Y);
418 pixel_x_h = pixel_x_l - 1;
419 pixel_y_h = pixel_y_l + 1;
421 const RGBQUAD* pSrc = pColorBuffer + colorIndex;
422 if ((pixel_x_l >= 0 && pixel_x_l < nDepthWidth) && (pixel_y_l >= 0 && pixel_y_l < nDepthHeight))
424 unsigned char * ptr = imageColorRegistered.ptr<
unsigned char>(pixel_y_l, pixel_x_l);
425 ptr[0] = pSrc->rgbBlue;
426 ptr[1] = pSrc->rgbGreen;
427 ptr[2] = pSrc->rgbRed;
428 depth.at<
unsigned short>(pixel_y_l, pixel_x_l) = *(pDepthBuffer + nDepthWidth - pixel_x_l + pixel_y_l*nDepthWidth);
430 if ((pixel_x_l >= 0 && pixel_x_l < nDepthWidth) && (pixel_y_h >= 0 && pixel_y_h < nDepthHeight))
432 unsigned char * ptr = imageColorRegistered.ptr<
unsigned char>(pixel_y_h, pixel_x_l);
433 ptr[0] = pSrc->rgbBlue;
434 ptr[1] = pSrc->rgbGreen;
435 ptr[2] = pSrc->rgbRed;
436 depth.at<
unsigned short>(pixel_y_h, pixel_x_l) = *(pDepthBuffer + nDepthWidth - pixel_x_l + pixel_y_h*nDepthWidth);
438 if ((pixel_x_h >= 0 && pixel_x_h < nDepthWidth) && (pixel_y_l >= 0 && pixel_y_l < nDepthHeight))
440 unsigned char * ptr = imageColorRegistered.ptr<
unsigned char>(pixel_y_l, pixel_x_h);
441 ptr[0] = pSrc->rgbBlue;
442 ptr[1] = pSrc->rgbGreen;
443 ptr[2] = pSrc->rgbRed;
444 depth.at<
unsigned short>(pixel_y_l, pixel_x_h) = *(pDepthBuffer + nDepthWidth - pixel_x_h + pixel_y_l*nDepthWidth);
446 if ((pixel_x_h >= 0 && pixel_x_h < nDepthWidth) && (pixel_y_h >= 0 && pixel_y_h < nDepthHeight))
448 unsigned char * ptr = imageColorRegistered.ptr<
unsigned char>(pixel_y_h, pixel_x_h);
449 ptr[0] = pSrc->rgbBlue;
450 ptr[1] = pSrc->rgbGreen;
451 ptr[2] = pSrc->rgbRed;
452 depth.at<
unsigned short>(pixel_y_h, pixel_x_h) = *(pDepthBuffer + nDepthWidth - pixel_x_h + pixel_y_h*nDepthWidth);
457 CameraIntrinsics intrinsics;
458 pCoordinateMapper_->GetDepthCameraIntrinsics(&intrinsics);
460 intrinsics.FocalLengthX,
461 intrinsics.FocalLengthY,
462 intrinsics.PrincipalPointX,
463 intrinsics.PrincipalPointY,
464 this->getLocalTransform(),
471 UERROR(
"Failed color to depth registration!");
476 HRESULT hr = pCoordinateMapper_->MapDepthFrameToColorSpace(nDepthWidth * nDepthHeight, (UINT16*)pDepthBuffer, nDepthWidth * nDepthHeight, pColorCoordinates_);
479 cv::Mat depthSource(nDepthHeight, nDepthWidth, CV_16UC1, pDepthBuffer);
480 cv::Mat depthRegistered = cv::Mat::zeros(
488 cv::resize(cv::Mat(nColorHeight, nColorWidth, CV_8UC4, pColorBuffer), tmp, cv::Size(), 0.5, 0.5, cv::INTER_AREA);
489 cv::cvtColor(tmp, imageColor, CV_BGRA2BGR);
493 cv::cvtColor(cv::Mat(nColorHeight, nColorWidth, CV_8UC4, pColorBuffer), imageColor, CV_BGRA2BGR);
496 for (
int depthIndex = 0; depthIndex < (nDepthWidth*nDepthHeight); ++depthIndex)
501 if (p.X != -std::numeric_limits<float>::infinity() && p.Y != -std::numeric_limits<float>::infinity())
508 const unsigned short & depth_value = depthSource.at<
unsigned short>(0, depthIndex);
509 int pixel_x_l, pixel_y_l, pixel_x_h, pixel_y_h;
511 pixel_x_l = depthRegistered.cols - p.X;
513 pixel_x_h = pixel_x_l - 1;
514 pixel_y_h = pixel_y_l + 1;
516 if (pixel_x_l >= 0 && pixel_x_l < depthRegistered.cols &&
517 pixel_y_l>0 && pixel_y_l < depthRegistered.rows &&
520 unsigned short & depthPixel = depthRegistered.at<
unsigned short>(pixel_y_l, pixel_x_l);
521 if (depthPixel == 0 || depthPixel > depth_value)
523 depthPixel = depth_value;
526 if (pixel_x_h >= 0 && pixel_x_h < depthRegistered.cols &&
527 pixel_y_h>0 && pixel_y_h < depthRegistered.rows &&
530 unsigned short & depthPixel = depthRegistered.at<
unsigned short>(pixel_y_h, pixel_x_h);
531 if (depthPixel == 0 || depthPixel > depth_value)
533 depthPixel = depth_value;
542 model = model.
scaled(0.5);
546 cv::flip(imageColor, imageColor, 1);
551 UERROR(
"Failed depth to color registration!");
557 SafeRelease(pDepthFrameDescription);
558 SafeRelease(pColorFrameDescription);
561 pFrameRef->Release();
563 SafeRelease(pDepthFrame);
564 SafeRelease(pColorFrame);
565 SafeRelease(pMultiSourceFrame);
575 UERROR(
"CameraK4W2: RTAB-Map is not built with Kinect for Windows 2 SDK support!");
const Transform & getLocalTransform() const
struct _DepthSpacePoint DepthSpacePoint
struct tagRGBQUAD RGBQUAD
static const int cDepthWidth
const cv::Mat & imageRaw() const
#define UASSERT(condition)
virtual SensorData captureImage(CameraInfo *info=0)
CameraK4W2(int deviceId=0, Type type=kTypeDepth2ColorSD, float imageRate=0.0f, const Transform &localTransform=CameraModel::opticalRotation())
static const int cColorWidth
void RTABMAP_EXP fillRegisteredDepthHoles(cv::Mat &depthRegistered, bool vertical, bool horizontal, bool fillDoubleHoles=false)
void project(float u, float v, float depth, float &x, float &y, float &z) const
void uSleep(unsigned int ms)
static const int cDepthHeight
virtual bool init(const std::string &calibrationFolder=".", const std::string &cameraName="")
static const int cColorHeight
struct _ColorSpacePoint ColorSpacePoint
cv::Mat RTABMAP_EXP fillDepthHoles(const cv::Mat &depth, int maximumHoleSize=1, float errorRatio=0.02f)
virtual std::string getSerial() const
virtual bool isCalibrated() const
CameraModel scaled(double scale) const