包含了讀取Realsens感應器的串流(彩色影像、深度影像、IR圖)
以及將擷取到的影像使用OpenCV的library顯示及儲存
--
#include <iostream>
#include <direct.h>
#include <string>
#include <time.h>
#include "opencv2\opencv.hpp"
#include "librealsense\pxcsensemanager.h"
cv::Mat PXCImage2CVMat(PXCImage *pxcImage, PXCImage::PixelFormat format)
{
PXCImage::ImageData data;
pxcImage->AcquireAccess(PXCImage::ACCESS_READ, format, &data);
int width = pxcImage->QueryInfo().width;
int height = pxcImage->QueryInfo().height;
if (!format)
format = pxcImage->QueryInfo().format;
int type = 0;
if (format == PXCImage::PIXEL_FORMAT_Y8) //讀IR
type = CV_8UC1;
else if (format == PXCImage::PIXEL_FORMAT_RGB24) //讀彩色
type = CV_8UC3;
else if (format == PXCImage::PIXEL_FORMAT_DEPTH_F32) //比較容易看懂的深度圖(黑白黑白區隔)
type = CV_32FC1;
else if (format == PXCImage::PIXEL_FORMAT_DEPTH) //一般的深度圖
type = CV_16UC1;
else if (format == PXCImage::PIXEL_FORMAT_DEPTH_RAW) //千層麵深度圖
type = CV_16UC1;
cv::Mat ocvImage = cv::Mat(cv::Size(width, height), type, data.planes[0]);
pxcImage->ReleaseAccess(&data);
return ocvImage;
}
int main()
{
PXCSession *session = PXCSession::CreateInstance();
PXCSenseManager *sm = PXCSenseManager::CreateInstance();
cv::Size frameSize = cv::Size(640, 480);
float frameRate = 60;
cv::Mat frameColor = cv::Mat::zeros(frameSize, CV_8UC3);
cv::Mat frameDepth = cv::Mat::zeros(frameSize, CV_8UC1);
cv::Mat frameIR = cv::Mat::zeros(frameSize, CV_8UC1);
//啟動串流
sm->EnableStream(PXCCapture::STREAM_TYPE_COLOR, frameSize.width, frameSize.height, frameRate);
sm->EnableStream(PXCCapture::STREAM_TYPE_DEPTH, frameSize.width, frameSize.height, frameRate);
sm->EnableStream(PXCCapture::STREAM_TYPE_IR, frameSize.width, frameSize.height, frameRate);
sm->Init();
//設定資料夾名稱
std::string folderName = ".\\data";
std::string colorFileName = folderName + "\\color";
std::string depthFileName = folderName + "\\depth";
std::string irFileName = folderName + "\\IR";
//新增資料夾
_mkdir(folderName.c_str());
_mkdir((colorFileName).c_str());
_mkdir((depthFileName).c_str());
_mkdir((irFileName).c_str());
clock_t startTime;
startTime = clock();
bool storeImg = false;
for (;;)
{
if (sm->AcquireFrame(true) < PXC_STATUS_NO_ERROR)
{
std::cout << "No input Frame" << std::endl;
break;
}
PXCCapture::Sample *sample;
sample = sm->QuerySample();
if (sample->color)
{
frameColor = PXCImage2CVMat(sample->color, PXCImage::PIXEL_FORMAT_RGB24);
}
if (sample->depth)
{
//frameDepth = PXCImage2CVMat(sample->depth, PXCImage::PIXEL_FORMAT_DEPTH_F32);
//frameDepth = PXCImage2CVMat(sample->depth, PXCImage::PIXEL_FORMAT_DEPTH_RAW);
frameDepth = PXCImage2CVMat(sample->depth, PXCImage::PIXEL_FORMAT_DEPTH);
}
if (sample->ir)
{
frameIR = PXCImage2CVMat(sample->ir, PXCImage::PIXEL_FORMAT_Y8);
}
cv::imshow("color", frameColor);
cv::imshow("Depth", frameDepth);
cv::imshow("ir", frameIR);
if (cv::waitKey(27) == 13) //按下Enter開始不斷儲存照片直到下次按下Enter為止
{
storeImg = !storeImg;
if (storeImg)
{
std::cout << "START CAPTURE" << std::endl;
}
else
{
std::cout << "FINISHED CAPTURE" << std::endl;
}
}
if (storeImg) //儲存圖片
{
clock_t nowsTime = clock() - startTime;
std::cout << "Time : " << ((float)nowsTime) / CLOCKS_PER_SEC << "(sec)" << std::endl;
float nowsTime_str = ((float)nowsTime) / CLOCKS_PER_SEC;
cv::imwrite(colorFileName + "\\" + std::to_string(nowsTime_str) + ".png", frameColor);
cv::imwrite(depthFileName + "\\" + std::to_string(nowsTime_str) + ".png", frameDepth);
cv::imwrite(irFileName + "\\" + std::to_string(nowsTime_str) + ".png", frameIR);
}
sm->ReleaseFrame();
}
system("pause");
return 0;
}
--
實驗結果
這張圖是run下去後會應該會跑出的畫面
從左至右分別是 彩色影像、IR圖、深度圖
深度圖因為本身就很難用肉眼辨識的關係會覺得一團黑
實際上圖是有些微變化的 ( 讀取圖像數值的話就知道了!)
--
如果旨在看得見或是有其他用途的話
可以把我中間程式碼註解掉的這段程式碼拿來用看看 (三選一的意思)
frameDepth = PXCImage2CVMat(sample->depth, PXCImage::PIXEL_FORMAT_DEPTH_F32);
frameDepth = PXCImage2CVMat(sample->depth, PXCImage::PIXEL_FORMAT_DEPTH_RAW);
frameDepth = PXCImage2CVMat(sample->depth, PXCImage::PIXEL_FORMAT_DEPTH);
其中
PIXEL_FORMAT_DEPTH_F32
PIXEL_FORMAT_DEPTH_RAW
PIXEL_FORMAT_DEPTH
是讀取深度圖的不同方法
我平時在做3D投射是需要使用最下面這個 PIXEL_FORMAT_DEPTH
下圖是三種方式的比較
右下角為IR圖 (因為IR圖和深度圖是可以相對應的, 所以放在一起比較)
No comments:
Post a Comment