RealSense SDK 开发笔记 (三)获取R200的图像(OpenCV Mat)
来源:互联网 发布:mac 不能玩炉石传说么 编辑:程序博客网 时间:2024/05/29 12:18
(转载请注明出处)
由于上合会议期间外面的快递无法到达市内,F200这些天多半是回不来了。。。
然后就等着我写SR300的吧科科~
上一节的代码的目的是了解SDK的蛋疼,也对手里的摄像头信息有个了解,当我们熟(麻)悉(木)之后很多信息就没必要管了,这节实(不)用(再)为(装)主(哔~),获取R200的彩色、深度和红外帧的数据,转换成Mat类型并显示出来。
看代码吧,到手即用(逃):
查找设备(获取并初始化指定摄像头的Device接口)
这个函数可以和SenseManager配合使用。
初始化SenseManager里面的模块之后,得益于Intel的渣调教,我们不得不自己动手再调一下曝光啥的。
根据iuid查找:
PXCCapture::Device* RealSense::ImplSeek(pxcUID iuid){ cout << "目标IUID:" << iuid << endl; PXCCapture *Capture; for (uint_fast8_t idx = 0; idx<UINT_FAST8_MAX; idx += 1) { PXCSession::ImplDesc Impl = {}; Impl.group = PXCSession::IMPL_GROUP_SENSOR; Impl.subgroup = PXCSession::IMPL_SUBGROUP_VIDEO_CAPTURE; 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; dinfo = { 0 }; retStatus = Capture->QueryDeviceInfo(idx, &dinfo); if (retStatus < PXC_STATUS_NO_ERROR) { cout << "详细信息:获取失败" << endl; continue; } 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;// 不嫌蛋疼的也可以拿它认 if (Impl.iuid != iuid) continue; cout << "======================================================================================" << endl; wcout << "√!找到了匹配的" << Capture->DeviceModelToString(dinfo.model)<<" "; device = Capture->CreateDevice(idx); return device; } if (device == NULL) { cout << "\n没有匹配的设备,"; } return NULL;}
暂时遇到一个问题:R200动不动就无法正常读出来信息(这几天解决)
被M$坑完再被Intel坑=_=|||
初始化视频流格式
void StreamInit(int Profile_idx, PXCCapture::Device *dstDevice, bool Dualeye){ PXCCapture::Device::StreamProfileSet ProfileSet = {}; if (Dualeye) { PXCCapture::StreamType scope = PXCCapture::STREAM_TYPE_COLOR | PXCCapture::STREAM_TYPE_DEPTH | PXCCapture::STREAM_TYPE_LEFT | PXCCapture::STREAM_TYPE_RIGHT; dstDevice->QueryStreamProfileSet(scope, Profile_idx, &ProfileSet); ProfileSet.color.options = ProfileSet.depth.options = ProfileSet.right.options = ProfileSet.left.options = PXCCapture::Device::STREAM_OPTION_STRONG_STREAM_SYNC; } else { PXCCapture::StreamType scope = PXCCapture::STREAM_TYPE_COLOR | PXCCapture::STREAM_TYPE_DEPTH | PXCCapture::STREAM_TYPE_IR; dstDevice->QueryStreamProfileSet(scope, Profile_idx, &ProfileSet); ProfileSet.color.options = ProfileSet.depth.options = ProfileSet.ir.options = PXCCapture::Device::STREAM_OPTION_STRONG_STREAM_SYNC; } if (dstDevice->IsStreamProfileSetValid(&ProfileSet)) { dstDevice->SetStreamProfileSet(&ProfileSet); cout << "Ready" << endl; } else cout << "Bad ProfileSet" << endl;}/*@Profile_idx:根据上节查询的代码,找到对应的索引号即可@*dstDevice:对应操作的设备@Dualeye:是否是R200(我偷懒了,本应该自动判断的)渣代码渣风格,建议自己写一遍*/
获取帧数据
这里擅自写了一个结构体(浪费资源):
struct Frames{ Mat Color; Mat Depth; Mat IR; Mat IR_;};
由于R200有两个红外帧,所以这里第四个是留给R200的。
默认只获取RGBD:
Frames Update(PXCCapture::Device *Device , bool Dualeye = true, PXCCapture::StreamType scope = PXCCapture::STREAM_TYPE_COLOR | PXCCapture::STREAM_TYPE_DEPTH){ PXCCapture::Sample FrameSamples; PXCImage::ImageData color8, deth16, _ir,biol16, bior16; retStatus = Device->ReadStreams(scope, &FrameSamples); if (retStatus < PXC_STATUS_NO_ERROR) exit(0);// 有错直接退出 Frames frames; if (Dualeye) { #pragma region dualeye if (scope & PXCCapture::STREAM_TYPE_COLOR) { FrameSamples.color->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_RGB24, PXCImage::ROTATION_0_DEGREE, PXCImage::OPTION_ANY, &color8); Mat Color(Size(320, 240), CV_8UC3, color8.planes[0]); frames.Color = Color; FrameSamples.color->ReleaseAccess(&color8); } if (scope & PXCCapture::STREAM_TYPE_DEPTH) { FrameSamples.depth->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_DEPTH, PXCImage::ROTATION_0_DEGREE, PXCImage::OPTION_ANY, &deth16); Mat Depth(Size(320, 240), CV_16UC1, deth16.planes[0]); frames.Depth = Depth; FrameSamples.depth->ReleaseAccess(&deth16); } if (scope & PXCCapture::STREAM_TYPE_LEFT) { FrameSamples.left->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_Y16, PXCImage::ROTATION_0_DEGREE, PXCImage::OPTION_ANY, &biol16); Mat StroL(Size(320, 240), CV_16UC1, biol16.planes[0]); frames.IR = StroL; FrameSamples.left->ReleaseAccess(&biol16); } if (scope & PXCCapture::STREAM_TYPE_RIGHT) { FrameSamples.right->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_Y16, PXCImage::ROTATION_0_DEGREE, PXCImage::OPTION_ANY, &bior16); Mat StroR(Size(320, 240), CV_16UC1, bior16.planes[0]); frames.IR_ = StroR; FrameSamples.right->ReleaseAccess(&bior16); } #pragma endregion } else { #pragma region _ if (scope & PXCCapture::STREAM_TYPE_COLOR) { FrameSamples.color->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_RGB24, PXCImage::ROTATION_0_DEGREE, PXCImage::OPTION_ANY, &color8); Mat Color(Size(640, 480), CV_8UC3, color8.planes[0]); frames.Color = Color; FrameSamples.color->ReleaseAccess(&color8); } if (scope & PXCCapture::STREAM_TYPE_DEPTH) { FrameSamples.depth->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_DEPTH, PXCImage::ROTATION_0_DEGREE, PXCImage::OPTION_ANY, &deth16); Mat Depth(Size(640, 480), CV_16UC1, deth16.planes[0]); frames.Depth = Depth; FrameSamples.depth->ReleaseAccess(&deth16); } if (scope & PXCCapture::STREAM_TYPE_IR) { FrameSamples.ir->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_Y16, PXCImage::ROTATION_0_DEGREE, PXCImage::OPTION_ANY, &_ir); Mat _IR(Size(640, 480), CV_16UC1, _ir.planes[0]); frames.IR = _IR; FrameSamples.left->ReleaseAccess(&_ir); } #pragma endregion } FrameSamples.ReleaseImages(); return(frames);}
PXCCapture::Sample 这种结构体里面有名为:*color;*depth;*ir;left;*right;
的PXCImage类型的变量:
对应彩色帧、深度帧、红外帧、双目左红外帧、双目右红外帧的图像数据描述和接口。用ReadStreams来获取StramType包含的类型的图像。
PXCImage::ImageData 这个类型是来描述图像存储信息的(像素格式,首地址,step)。
下面来看看获取图像内容的函数:
AcquireAccess:临时锁定要访问的帧内部数据,并将数据格式化成指定格式,然后告诉ImageData数据的存放信息。
ReleaseAccess:顾名思义,释放刚才锁定的数据内容。
把图像数据取出来:
OpenCV的一行代码即可,如彩色图:
Mat bgr(Size(r, c), CV_8UC3, color8.planes[0])
暴力美学如上,而且Mat拷贝只是复制图像的头数据,时间损失很小。
重载用到的参数依次是Size(行,列)、图像类型、数据起始指针。step在这里是自动的,代表最高维度包含的字节数,图象是二维的,step有两级,一个是行字节数,一个是点字节数。
main函数
/* #define R200_IUID 自己填写 */PXCSession *Session =PXCSession::CreateInstance(); pxcStatus retStatus;int main(){ PXCCapture::Device *R200_Device; // Init Device R200_Device = ImplSeek(R200_IUID); StreamInit(6, R200_Device, true); cout << "Streaming..." << endl; // loop for (;;) { Frames R200_rgbd = Update(R200_Device); //pipeline Mat Depth8 = R200_rgbd.Depth.clone(); (Depth8 /= 15).convertTo(Depth8, CV_8UC1, 1, 20); //show imshow("Depth8", Depth8); imshow("Color", R200_rgbd.Color); waitKey(1); }
程序截图:
至于为什么不用SenseManager
直接看CPU占用率(相同帧率、分辨率):
上述代码:
使用sensemanager的示例程序:
SenseManager给DCM喂了金克拉了?这么吃资源…
8逻辑核i7,可见单核心使用率过半,低压U的流畅度估计好不到哪去。
用了SenseManager的程序关了之后,经常枚举设备信息失败,时不时卡在提交流格式的函数上。
DCM驱动渣,优化渣,不过配上自己的渣算法这点资源损失并不算什么(雾)
等情况足够复杂再用吧。
- RealSense SDK 开发笔记 (三)获取R200的图像(OpenCV Mat)
- 【Opencv学习(三)】获取Mat图像的ROI区域
- RealSense 开发(一):深度图像获取
- RealSense SDK 开发笔记(一)环境配置
- OpenCV学习笔记(三)——Mat,图像的新容器
- OpenCV学习笔记(三)——Mat,图像的新容器
- OpenCV学习笔记(三)——Mat,图像的新容器
- OpenCV学习笔记(三)——Mat,图像的新容器
- OpenCV学习笔记(三)——Mat,图像的新容器
- OpenCV学习笔记(三)——Mat,图像的新容器
- OpenCV学习笔记(三)——Mat,图像的新容器
- OpenCV学习笔记(三)——Mat,图像的新容器
- RealSense SDK 开发笔记 (二)枚举DCM下的摄像机与支持的影像串流
- Ubuntu 16.04 LTS 安装RealSense R200 驱动以及SDK配置+QT+OpenCV
- 从RealSense中提取完整的深度和彩色图像,并存在opencv中的Mat里
- ubuntu14.04利用opencv‘获取realsense图像
- openCV学习笔记(三): 认识Mat
- ros-indigo配置realsense R200的开发套件及遇到问题解决事项
- poj1149 PIGS
- Winsocket编程
- MySQL单列索引和组合索引的区别介绍
- 使用ConcurrentQueue并发集合来设计网络服务器端
- 弘扬的博客,一些基础的和进阶的安卓教程
- RealSense SDK 开发笔记 (三)获取R200的图像(OpenCV Mat)
- Scla富包装器
- Unable to locate appropriate constructor on class [hibernatePojo.ShareResource]
- web研发模式演变史
- vs2013连接mysql配置
- 重新出发吧,少年
- java多线程模拟聊天问题
- bzoj1066【SCOI2007】蜥蜴
- 随意细解:UI -- 数据库