市场上各种深度摄像头测试之OPT8241
来源:互联网 发布:打条码软件 编辑:程序博客网 时间:2024/06/06 02:56
简要介绍
- ToF,即time of flight,不同于二维图像来推算三维信息,而是通过红外光在空气中的飞行时间,计算出目标体的距离。
- 相关文档:http://www.ti.com.cn/product/cn/OPT8241/technicaldocuments
- 系统要求: Win7/Ubuntu 14.04 64 bit PC 2GB RAM Minimum of 500MB free
space
资源下载
官方资源下载:http://www.ti.com/tool/opt8241-cdk-evm
使用官方软件就能使用该摄像头,若想下载SDK源码进行编译,参考以下资源:
cmake:http://www.cmake.org/download/
git:http://git-scm.com/download/win
CySuiteUSB:http://www.cypress.com/?rID=34870
QT:http://download.qt.io/official_releases/qt/5.4/5.4.2/qt-opensource-windows-x86-msvc2013_64-5.4.2.exe.mirrorlist
PCL:https://github.com/3dtof/pcl/releases/tag/1.7.2
- 说明:
1、PCL官网不提供1.7之后的版本下载,这仅提供了1.7.2的链接,若需要其他版本可自行Google或百度下载大牛编译好的pcl
2、PCL和QT是必须支持你的编译环境的,另外源码仅支持64位编译,若环境不是64位将会报错,故下载请注意
源码编译过程
- 默认安装完上述软件后(记得提示加环境变量的就加),下载源码:https://github.com/3dtof/voxelsdk
GitHub里也有教程,单个人不认为是用来编译源码的,自行斟酌 - 在源码目录中,Voxel文件夹下新建文件夹CyAPI,将安装后的CySuiteUSB文件夹中的CyAPI.lib和CyAPI.h拷贝到该目录
打开命令行,进入到源码目录下
cd voxel-sdk mkdir build cd build set
CMAKE_PREFIX_PATH=%CWD%;%CMAKE_PREFIX_PATH% cmake-gui ..看到cmake图形界面,点击Configure,选择相应的编译环境,等待完成,若报错,请在图形界面中对应项手动选择路径,具体如下:
如果它找不到PCL, 将PCL_DIR设为PCL的安装目录下版本号文件夹的一个cmake目录。 再点一下configure
如果找不到VTK,设置CMAKE_PREFIX_PATH为vtk-6.1。
如果找不到QT,设置Qt5Widgets_DIR为Qt5Widgets文件夹所在绝对路径说明:一般来说,cmake会自动寻找相应路径,保证PCL和QT的全能找到就可以,什么openNI之类貌似没影响
- 最后点击Generate,就能在build目录下看到项目文件
编译完成后需要在环境变量中添加VOXEL_SDK_PATH这个环境变量为build文件夹所在路径,否则编译运行后会提示找不到设备。 - 之后在PATH当中添加%VOXEL_SDK_PATH%\bin和%VOXEL_SDK_PATH%\lib即可。如果没有添加这两个环境变量,会出现找不到dll文件而无法运行程序
- 最后一步,打开项目文件,重新生成解决方案,确保x64的Release配置无误,生成ALL_BUILD即可。
说明:本人试过debug和release两种模式下的环境配置,然而debug始终会中断,无法调试,最终只能选择release下进行之后的操作
深度数据分析
opt8241的图像有以下种类:
raw/phase/ambient/amplitude/flags/depth/pointcloud/vxl
depth:深度
pointcloud:点云
其他:不知道图像格式:
320 * 240 每个像素4个字节32bit 【12bit相位数据 12bit振幅数据 4bit环境数据
4bit标记数据(某一个官网文档看到的,不知道翻译的对不对,也不知道是不是如此)】
深度图获取
- 源码sdk自带命令控制(一堆,说几个个人需要用到的): help 可看见所有命令及其作用 profilelist
列举所有模式,短距,中距,长距。。。 profileselect id 选择对应id模式 filterlist
列举所有滤波器(这样翻译不知对不对) 。 。 。 save type num filename
:存储num帧type类型的图像数据到文件中,文件名为filename 这里只说深度图的存储:
_saveFile.write((char *)f->depth.data(),
代码中是将深度数据和另一种数据都存到文件,一帧大小为320 * 240 * 4 * 2
sizeof(float)*f->size.width*f->size.height); _saveFile.write((char
*)f->amplitude.data(), sizeof(float)*f->size.width*f->size.height);
取出深度图就只需要文件中每一帧数据的前一半- opencv取深度图:
opencv配置:http://blog.csdn.net/wzw_ice/article/details/77159741 - 个人处理【未成功】: 在源码中的存储深度文件函数中加入以下代码
里面包含了各种尝试,得出的结果始终不对。猜测原因:源图像数据是float类型32位存储,使用Mat存了数据之后放入png格式时,数据丢失导致结果错误
float * depthData = (float*)f->depth.data(); cv::Mat depth(f->size.height, f->size.width, CV_32FC1, depthData); //short int * depthtmp; //cvConvertScale(depthData, depthtmp,255,0); //cv::Mat depthf(f->size.height, f->size.width, CV_8UC1, depthtmp); //IplImage iplimg = depth; //IplImage* outimg = cvCreateImage(cvSize(iplimg.width,iplimg.height),32,1); //cvConvertScale(&iplimg, outimg,1.0/(256*256-1)); //cv::Mat outmat=cv::cvarrToMat(outimg); //cv::imwrite("./b.bmp", outmat); //cvReleaseImage(&outimg); cv::Mat depthImage = depth * 1000; depth.convertTo(depthImage, CV_16UC1); cv::imwrite("./depth.png",depth); cv::imwrite("./depthtmp.png", depthImage); std::cout << f->id << "##" << f->amplitude.data() << "##" << f->depth.data() << "##" << f->timestamp << "##" << std::endl;
5、 最终方案:直接读取sdk存储的文件,对文件进行读处理,对读到的每个像素的数据进行处理之后再用opencv存为png
void depthAmp2png(const std::string & filePath, const std::string & depthPath){ FILE * pFile; long lSize; char * buffer; size_t result; cout << filePath << " " << depthPath; /* 若要一个byte不漏地读入整个文件,只能采用二进制方式打开 */ pFile = fopen(filePath.c_str(), "rb"); if (pFile == NULL) { fputs("File error", stderr); exit(1); } /* 获取文件大小 */ fseek(pFile, 0, SEEK_END); lSize = ftell(pFile); cout << endl << lSize; rewind(pFile); /* 分配内存存储整个文件 */ buffer = (char*)malloc(sizeof(char)*lSize); if (buffer == NULL) { fputs("Memory error", stderr); exit(2); } /* 将文件拷贝到buffer中 */ result = fread(buffer, 1, lSize, pFile); if (result != lSize) { fputs("Reading error", stderr); exit(3); } fclose(pFile); //to png file float * bufferFloat = (float *)buffer; int vertexSize = 320 * 240; int imageSize = lSize / vertexSize / 4 / 2; int strideOfImageChar = 320 * 240 * 4; for (int index = 0; index < imageSize; index++) { cv::Mat depthMat = cv::Mat::zeros(240, 320, CV_32FC1); //cv::Mat amplitude = cv::Mat::zeros(320, 240, CV_32FC1); memcpy(depthMat.data, buffer + (index * 2) *strideOfImageChar, strideOfImageChar); //memcpy(amplitude.data, buffer + (index * 2 + 1) *strideOfImageChar, strideOfImageChar); std::string depthFilePath = depthPath + std::to_string(index) + ".png"; //std::string colorFilePath = depthPath + std::to_string(index) + "_visual.png"; //std::string amplitudePath = depthPath + std::to_string(index) + ".png"; ////2)visual depth image //cv::Mat recolorDepth; //cv::Mat grayImage; //float max = 2.4; //float min = 1.7; //double alpha = 225.0 / (max - min); //depthMat.convertTo(grayImage, CV_8UC1, alpha, -alpha *min);// expand your range to 0..255. Similar to histEq(); ////grayImage = restrictDepthImg(grayImage); //cv::applyColorMap(grayImage, recolorDepth, cv::COLORMAP_JET);// this is great. It converts your grayscale image into a tone-mapped one, much more pleasing for the eye function is found in contrib module, so include contrib.hpp and link accordingly depthMat = depthMat * 1000; depthMat.convertTo(depthMat, CV_16UC1); if (!cv::imwrite(depthFilePath, depthMat)) { cout << "error:" << depthFilePath << " raw data is shorter than header specify!"; } //if (!cv::imwrite(colorFilePath, recolorDepth)) //{ // LOG_ERROR << colorFilePath << " raw data is shorter than header specify!"; //} //if (!cv::imwrite(amplitudePath, amplitude)) //{ // LOG_ERROR << amplitudePath << " raw data is shorter than header specify!"; //} }}
- 市场上各种深度摄像头测试之OPT8241
- 市场上各种深度摄像头测试之华捷艾米A100
- 市场上各种深度摄像头测试之Kinect V2
- 市场上各种深度摄像头测试之Kinect V1(第一代)
- 深度摄像头之gmapping构图
- opencv中各种摄像头速度测试
- 三维像素库Voxel-SDK在VS2015上的配置方法(配套硬件OPT8241)
- 深度学习之Matlab 转C++在iOS上测试CNN手型识别
- OpenGL核心技术之深度测试
- 摄像头之自动曝光,自动增益,图像深度 概念
- 深度学习之各种优化算法
- 深度学习之各种优化算法
- usb摄像头在s3c6410平台上的测试
- usb摄像头在s3c6410平台上的测试
- android 摄像头切换---但在电视上测试失败
- OpenResty上各种测试用例实操(1)
- ROS 教程之 vision : 用各种摄像头获取图像
- ROS 教程之 vision : 用各种摄像头获取图像
- Java编程思想读书笔记——对象导论
- Java GC 变量含义(S0 S1 E O P YGC YGCT FGC FGCT GCT)
- Java Math类取整
- DelayQueue使用示例
- OpenCV——findContours函数的使用(基于Mat轮廓处理基础)
- 市场上各种深度摄像头测试之OPT8241
- Winform 刷新闪烁
- unity中EventSystem射线检测结果的排序规则
- redis集群实现(五) sentinel的架构与raft协议
- SpringMVC笔记——SSM框架搭建简单实例
- Java——反射机制
- bootstrap中table隐藏后显示问题
- 隐藏滚动条
- SQLSERVER CDC 功能