← Xvisio SDK 深度
← Xvisio 功能介绍和快速启动
← Xvisio SDK 文档主页
Xvisio SeerSense™ GR45 系列模组以及Xvisio SeerLens™ One glass Pro会使用到此类型模组,其他产品可以参考对应的数据手册来确认 TOF Camera 类型。PMD 类型 TOF Camera 使用的也是 iTOF 算法 ,波长为940nm 。
Xvisio SDK 提供了三种模式以应对不同的应用场景, 设置了模式后会自动适配对应的频率模式、帧率、曝光时间:
工作模式 | 频率模式 | 帧率 | 曝光时间 | 描述 |
---|---|---|---|---|
短距 | 单频 | 30fps | 250us | 适用在测距距离1米内,需要快速刷新的工作场景,例如手势或人脸识别等 |
中距 | 双频 | 15fps | 450us | 适用在测距距离2米内,需要快速刷新的工作场景,例如物体扫描和检测等 |
远距 | 双频 | 5fps | 1200us | 适用在测距距离4米内,刷新率要求不高的工作场景,例如三维重建等 |
工作模式类型定义:
enum class DistanceMode { Short = 0, Middle, Long };
设置 API 示例:
device->tofCamera()->setDistanceMode(TofCamera::DistanceMode::Short);
Xvisio SDK 提供一个设置接口用来设置数据流模式,不同的模式对应不同的数据流类型或组合。
数据流模式 | 描述 |
---|---|
DepthOnly | 只输出深度数据流 |
CloudOnly | 只输出点云数据流(相机坐标系) |
DepthAndCloud | 同时输出深度和点云数据流(相机坐标系) |
None | 无数据流输出 |
CloudOnLeftHandSlam | 只输出点云数据流,但坐标系转换为SLAM坐标系(左手) |
定义:
enum class StreamMode { DepthOnly = 0, CloudOnly, DepthAndCloud, None, CloudOnLeftHandSlam};
设置 API 示例:
device->tofCamera()->setStreamMode(TofCamera::StreamMode::DepthAndCloud);
Xvisio SDK 不开放 PMD 类型 TOF Camera 的“调制频率”设置接口,只能通过设置 “工作模式”来选择对应的单双频模式。
Xvisio SDK 不开放 PMD 类型 TOF Camera 的分辨率设置,目前固定为 224 * 172 。
可以设置帧率,范围在5-30 fps ,不同的帧率对应的曝光时间请查看表格:
帧率 | 曝光时间 |
---|---|
5fps | 2000us |
10fps | 1080us |
15fps | 720us |
20fps | 540us |
25fps | 440us |
30fps | 360us |
用户根据使用场景和需求选择不同模式和设置。
设置 API 示例:
device->tofCamera()->setFramerate(30.0f);
传参的帧率值为 float 型,范围在 5-30 。
PMD 类型 TOF的数据量比较小,这里列出 30fps 下的不同数据类型带宽:
数据 | 带宽 |
---|---|
深度 | 35.2Mbps |
点云 | 105.8Mbps |
IR | 17.6Mbps |
PMD 类型的 TOF 可以使能或关闭 IR 数据流输出,默认 IR 数据流不输出。
这个设置使用 hid 命令来设置,IR 使用命令: “0x02,0x10,0xf5,0x02,0x01”,IR 关闭命令: “0x02,0x10,0xf5,0x02,0x00” 。
设置 API 示例:
std::vector<unsigned char> result(63);
bool bOK = device->hidWriteAndRead({0x02,0x10,0xf5,0x02,0x01}, result);
if(bOK)
std::cout << "Enable IR successfully" << std::endl;
else
std::cout << "Enable IR failed" << std::endl;
PMD 类型的 TOF 深度数据和点云数据是32位深度数据,单位米,同时也能够支持 IR 灰度数据。
/**
* @brief An image provided by a TOF camera.
* @note There are two manufacturers of TOF camera, Pmd and sony.
* Pmd TOF depth type is Depth_32,sony TOF depth type is Depth_16.
* Cloud type just use for Pmd point cloud,the coordinate system of the point cloud is the camera coordinate system, and the data unit is meters.
* Length, width and depth are in meters use Pmd TOF.
* Length, width and depth are in metmillimeterers use sony TOF.
*/
struct DepthImage {
enum class Type { Depth_16 = 0, Depth_32, IR, Cloud, Raw, Eeprom, IQ };
Type type = Type::Depth_32;
std::size_t width = 0; //!< width of the image (in pixel)
std::size_t height = 0; //!< height of the image (in pixel)
double confidence = 0.0; //!< confidence of depth [0.0,1.0]
std::shared_ptr<const std::uint8_t> data = nullptr; //! image of depth
unsigned int dataSize = 0;
double hostTimestamp = std::numeric_limits<double>::infinity(); //!< host timestamp of the physical measurement (in second based on the `std::chrono::steady_clock`).
std::int64_t edgeTimestampUs = (std::numeric_limits<std::int64_t>::min)(); //!< timestamp of the physical measurement (in microsecond based on edge clock).
/**
* @brief Convert to a #xv::RgbImage
*/
RgbImage toRgb() const;
};
说明:
使用注册回调方式获取 DepthImage,接口调用流程如下所示:
Xvisio SDK 提供了 API 可以把深度数据转换为点云数据格式。
第3章里介绍了如果在 DepthImage里直接获取到点云数据,这种方式由 Xvisio 设备在设备端计算好点云上报的。同时也支持本章介绍的通过 API 可以把深度数据转换为点云数据格式。
这两种方式都可以使用,用户可以选择其一。
/**
* @brief A point cloud of 3D points.
*/
struct PointCloud {
double hostTimestamp = std::numeric_limits<double>::infinity(); //!< host timestamp of ? (in second based on the `std::chrono::steady_clock`).
std::int64_t edgeTimestampUs = (std::numeric_limits<std::int64_t>::min)(); //!< timestamp of ? (in microsecond based on edge clock).
std::vector<Vector3f> points;
};
说明:
转换 PointCloud 必须要先获取 DepthImage,然后再调用接口做转换,流程如下:
device->tofCamera()->depthImageToPointCloud(tofDepthImage)
定义 Xvisio Device
std::shared_ptr<xv::Device> device = nullptr;
读取 device_list,超时 10 秒(推荐值,也可以缩短)
auto device_list = xv::getDevices(10., "");
判断获取的 devices 是否为空,为空则失败
if (device_list.empty())`
{
LOG(LOG_Function,"initDevice faiiled:Timeout for device detection.");
return false;
}
获取 device (这里只针对单设备,多设备请参考相应文档描述)
device = device_list.begin()->second;
注册回调,回调定义里获取深度数据或者 IR 数据 、点云数据
int tofId = -1;
tofId = device->tofCamera()->registerCallback([&](xv::DepthImage const & tofDepthImage){
if (tof.type == xv::DepthImage::Type::Depth_16 ) {
//Operation on tofDepthImage
//...
//point cloud process
if(enableDevMap["tof_point_cloud"])
{
auto points = device->tofCamera()->depthImageToPointCloud(tofDepthImage)->points;
for (auto iter = points.begin(); iter != points.end();iter++)
{
auto point = *iter;
printf(buff, "x=%f ,y=%f ,z=%f\n", point[0], point[1], point[2]);
//...
}
}
}
else if(tof.type == xv::DepthImage::Type::IR )
{
//Operation on tofDepthImage
//...
}
else if(tof.type == xv::DepthImage::Type::Cloud )
{
//Operation on tofDepthImage
//...
}
});
TOF 启动
//start tof
device->tofCamera()->start();
TOF 停止
此处用到的 tofId 是注册callback时赋值。
device->tofCamera()->unregisterCallback(tofId);
device->tofCamera()->stop();