API Guides¶
基础概念¶
设备¶
深度相机称为一个设备(Device)。
组件¶
typedef enum TY_DEVICE_COMPONENT_LIST
{
TY_COMPONENT_DEVICE = 0x80000000, ///< Abstract component stands for whole device, always enabled
TY_COMPONENT_DEPTH_CAM = 0x00010000, ///< Depth camera
TY_COMPONENT_IR_CAM_LEFT = 0x00040000, ///< Left IR camera
TY_COMPONENT_IR_CAM_RIGHT = 0x00080000, ///< Right IR camera
TY_COMPONENT_RGB_CAM_LEFT = 0x00100000, ///< Left RGB camera
TY_COMPONENT_RGB_CAM_RIGHT = 0x00200000, ///< Right RGB camera
TY_COMPONENT_LASER = 0x00400000, ///< Laser
TY_COMPONENT_IMU = 0x00800000, ///< Inertial Measurement Unit
TY_COMPONENT_BRIGHT_HISTO = 0x01000000, ///< virtual component for brightness histogram of ir
TY_COMPONENT_RGB_CAM = TY_COMPONENT_RGB_CAM_LEFT ///< Some device has only one RGB camera, map it to left
}TY_DEVICE_COMPONENT_LIST;
TY_COMPONENT_DEVICE 作为抽象设备,代表独立深度相机设备实体,以下简称*深度相机设备*。通过该组件可以控制相机的工作模式、曝光同步模式 等属性。
TY_COMPONENT_DEPTH_CAM、 TY_COMPONENT_IR_CAM_LEFT、 TY_COMPONENT_IR_CAM_RIGHT、 TY_COMPONENT_RGB_CAM_LEFT 和 TY_COMPONENT_RGB_CAM_RIGHT 分别代表 深度摄像头组件、左红外摄像头组件、右红外摄像头组件、左彩色摄像头组件 和 右彩色摄像头组件。深度相机设备仅有一个RGB摄像头组件的情况下,TY_COMPONENT_RGB_CAM 默认代表 TY_COMPONENT_RGB_CAM_LEFT。
属性¶
typedef enum TY_FEATURE_ID_LIST
{
TY_STRUCT_CAM_INTRINSIC = 0x0000 | TY_FEATURE_STRUCT,
TY_STRUCT_EXTRINSIC_TO_LEFT_IR = 0x0001 | TY_FEATURE_STRUCT,
TY_STRUCT_CAM_DISTORTION = 0x0006 | TY_FEATURE_STRUCT,
TY_STRUCT_CAM_CALIB_DATA = 0x0007 | TY_FEATURE_STRUCT,
TY_INT_PERSISTENT_IP = 0x0010 | TY_FEATURE_INT,
TY_INT_PERSISTENT_SUBMASK = 0x0011 | TY_FEATURE_INT,
TY_INT_PERSISTENT_GATEWAY = 0x0012 | TY_FEATURE_INT,
TY_BOOL_GVSP_RESEND = 0x0013 | TY_FEATURE_BOOL,
TY_INT_PACKET_DELAY = 0x0014 | TY_FEATURE_INT,
TY_INT_ACCEPTABLE_PERCENT = 0x0015 | TY_FEATURE_INT,
TY_STRUCT_CAM_STATISTICS = 0x00ff | TY_FEATURE_STRUCT,
TY_INT_WIDTH_MAX = 0x0100 | TY_FEATURE_INT,
TY_INT_HEIGHT_MAX = 0x0101 | TY_FEATURE_INT,
TY_INT_OFFSET_X = 0x0102 | TY_FEATURE_INT,
TY_INT_OFFSET_Y = 0x0103 | TY_FEATURE_INT,
TY_INT_WIDTH = 0x0104 | TY_FEATURE_INT,
TY_INT_HEIGHT = 0x0105 | TY_FEATURE_INT,
TY_ENUM_IMAGE_MODE = 0x0109 | TY_FEATURE_ENUM,
TY_FLOAT_SCALE_UNIT = 0x010a | TY_FEATURE_FLOAT,
TY_ENUM_TRIGGER_ACTIVATION = 0x0201 | TY_FEATURE_ENUM,
TY_INT_FRAME_PER_TRIGGER = 0x0202 | TY_FEATURE_INT,
TY_STRUCT_TRIGGER_PARAM = 0x0523 | TY_FEATURE_STRUCT,
TY_BOOL_KEEP_ALIVE_ONOFF = 0x0203 | TY_FEATURE_BOOL,
TY_INT_KEEP_ALIVE_TIMEOUT = 0x0204 | TY_FEATURE_INT,
TY_BOOL_CMOS_SYNC = 0x0205 | TY_FEATURE_BOOL,
TY_INT_TRIGGER_DELAY_US = 0x0206 | TY_FEATURE_INT,
TY_BOOL_TRIGGER_OUT_IO = 0x0207 | TY_FEATURE_BOOL,
TY_BOOL_AUTO_EXPOSURE = 0x0300 | TY_FEATURE_BOOL,
TY_INT_EXPOSURE_TIME = 0x0301 | TY_FEATURE_INT,
TY_BOOL_AUTO_GAIN = 0x0302 | TY_FEATURE_BOOL,
TY_INT_GAIN = 0x0303 | TY_FEATURE_INT,
TY_BOOL_AUTO_AWB = 0x0304 | TY_FEATURE_BOOL,
TY_INT_LASER_POWER = 0x0500 | TY_FEATURE_INT,
TY_BOOL_LASER_AUTO_CTRL = 0x0501 | TY_FEATURE_BOOL,
TY_BOOL_UNDISTORTION = 0x0510 | TY_FEATURE_BOOL,
TY_BOOL_BRIGHTNESS_HISTOGRAM = 0x0511 | TY_FEATURE_BOOL,
TY_BOOL_DEPTH_POSTPROC = 0x0512 | TY_FEATURE_BOOL,
TY_INT_R_GAIN = 0x0520 | TY_FEATURE_INT,
TY_INT_G_GAIN = 0x0521 | TY_FEATURE_INT,
TY_INT_B_GAIN = 0x0522 | TY_FEATURE_INT,
TY_INT_ANALOG_GAIN = 0x0524 | TY_FEATURE_INT,
}TY_FEATURE_ID_LIST;
属性的数据结构示例:
1,depth camera、ir camera、rgb camera 等组件的可使用的分辨率定义如下:
typedef enum TY_RESOLUTION_MODE_LIST
{
TY_RESOLUTION_MODE_160x120 = (160<<12)+120, ///< 0x000a0078
TY_RESOLUTION_MODE_240x320 = (240<<12)+320, ///< 0x000f0140
TY_RESOLUTION_MODE_320x180 = (320<<12)+180, ///< 0x001400b4
TY_RESOLUTION_MODE_320x200 = (320<<12)+200, ///< 0x001400c8
TY_RESOLUTION_MODE_320x240 = (320<<12)+240, ///< 0x001400f0
TY_RESOLUTION_MODE_480x640 = (480<<12)+640, ///< 0x001e0280
TY_RESOLUTION_MODE_640x360 = (640<<12)+360, ///< 0x00280168
TY_RESOLUTION_MODE_640x400 = (640<<12)+400, ///< 0x00280190
TY_RESOLUTION_MODE_640x480 = (640<<12)+480, ///< 0x002801e0
TY_RESOLUTION_MODE_960x1280 = (960<<12)+1280, ///< 0x003c0500
TY_RESOLUTION_MODE_1280x720 = (1280<<12)+720, ///< 0x005002d0
TY_RESOLUTION_MODE_1280x800 = (1280<<12)+800, ///< 0x00500320
TY_RESOLUTION_MODE_1280x960 = (1280<<12)+960, ///< 0x005003c0
TY_RESOLUTION_MODE_2592x1944 = (2592<<12)+1944, ///< 0x00a20798
}TY_RESOLUTION_MODE_LIST;
2,各个camera组件支持的图像格式如下:
typedef enum TY_PIXEL_FORMAT_LIST{
TY_PIXEL_FORMAT_UNDEFINED = 0,
TY_PIXEL_FORMAT_MONO = (TY_PIXEL_8BIT | (0x0 << 24)),
TY_PIXEL_FORMAT_BAYER8GB = (TY_PIXEL_8BIT | (0x1 << 24)),
TY_PIXEL_FORMAT_DEPTH16 = (TY_PIXEL_16BIT | (0x0 << 24)),
TY_PIXEL_FORMAT_YVYU = (TY_PIXEL_16BIT | (0x1 << 24)),
TY_PIXEL_FORMAT_YUYV = (TY_PIXEL_16BIT | (0x2 << 24)),
TY_PIXEL_FORMAT_RGB = (TY_PIXEL_24BIT | (0x0 << 24)),
TY_PIXEL_FORMAT_BGR = (TY_PIXEL_24BIT | (0x1 << 24)),
TY_PIXEL_FORMAT_JPEG = (TY_PIXEL_24BIT | (0x2 << 24)),
TY_PIXEL_FORMAT_MJPG = (TY_PIXEL_24BIT | (0x3 << 24)),
}TY_PIXEL_FORMAT_LIST;
3,常用光学参数数据结构如下,可使用 TYGetStruct 函数读取:
typedef struct TY_VECT_3F
{
float x;
float y;
float z;
}TY_VECT_3F;
/// [fx, 0, cx,
/// 0, fy, cy,
/// 0, 0, 1]
typedef struct TY_CAMERA_INTRINSIC
{
float data[3*3];
}TY_CAMERA_INTRINSIC;
/// [r11, r12, r13, t1,
/// r21, r22, r23, t2,
/// r31, r32, r33, t3,
/// 0, 0, 0, 1]
typedef struct TY_CAMERA_EXTRINSIC
{
float data[4*4];
}TY_CAMERA_EXTRINSIC;
///camera distortion parameters
typedef struct TY_CAMERA_DISTORTION
{
float data[12];///<k1,k2,p1,p2,k3,k4,k5,k6,s1,s2,s3,s4
}TY_CAMERA_DISTORTION;
typedef struct TY_CAMERA_CALIB_INFO
{
int32_t intrinsicWidth;
int32_t intrinsicHeight;
TY_CAMERA_INTRINSIC intrinsic; // TY_STRUCT_CAM_INTRINSIC
TY_CAMERA_EXTRINSIC extrinsic; // TY_STRUCT_EXTRINSIC_TO_LEFT_IR
TY_CAMERA_DISTORTION distortion; // TY_STRUCT_CAM_DISTORTION
}TY_CAMERA_CALIB_INFO;
深度图¶
深度图定义
深度图数据格式

点云图¶
通过测量仪器得到的物体外观表面的点数据集合是点云。使用深度摄像头得到的点云信息为三维坐标(XYZ)。点云图是深度摄像头捕捉到的所有点的点云信息构成的矩阵。每点为3个float类型x,y,z值。没有深度信息的点值为(0,0,0)。
点云图数据格式

API详解¶
库加载与卸载¶
调用SDK进行相机控制和图像获取前,首先应完成SDK库的加载动作,退出应用前应完成库文件的卸载操作。
inline TY_STATUS TYInitLib (void);
TY_CAPI TYDeinitLib (void);
获取SDK的版本信息。
TY_CAPI TYLibVersion (TY_VERSION_INFO* version);
接口控制¶
Camport SDK同时支持USB深度相机和网络深度相机。发现设备前需要更新主机的USB接口、以太网接口、无线网络接口状态,获取接口句柄,退出应用程序前应释放接口句柄。
更新接口状态。
TY_CAPI TYUpdateInterfaceList ();
获取接口数量。
TY_CAPI TYGetInterfaceNumber (uint32_t* pNumIfaces);
获取接口列表。
TY_CAPI TYGetInterfaceList (TY_INTERFACE_INFO* pIfaceInfos, uint32_t bufferCount, uint32_t* filledCount);
查询接口是否有效。
TY_CAPI TYHasInterface (const char* ifaceID, bool* value);
打开接口。
TY_CAPI TYOpenInterface (const char* ifaceID, TY_INTERFACE_HANDLE* outHandle);
释放接口句柄。
TY_CAPI TYCloseInterface (TY_INTERFACE_HANDLE ifaceHandle);
设备控制¶
TYUpdateDeviceList 更新指定接口上挂载的设备列表。
TY_CAPI TYUpdateDeviceList (TY_INTERFACE_HANDLE ifaceHandle);
TYGetDeviceNumber 获取指定接口上挂载的设备数量。
TY_CAPI TYGetDeviceNumber (TY_INTERFACE_HANDLE ifaceHandle, uint32_t* deviceNumber);
TYGetDeviceList 获取指定接口上挂载的设备列表,bufferCount是按照挂载额设备数量设定的 interface infos array size。
TY_CAPI TYGetDeviceList (TY_INTERFACE_HANDLE ifaceHandle, TY_DEVICE_BASE_INFO* deviceInfos, uint32_t bufferCount, uint32_t* filledDeviceCount);
TYHasDevice 查询指定接口和设备ID的设备状态。每一台图漾相机拥有独立的设备ID。
TY_CAPI TYHasDevice (TY_INTERFACE_HANDLE ifaceHandle, const char* deviceID, bool* value);
TYOpenDevice 打开设备。输入接口句柄和指定的设备ID,获得打开的相机设备的句柄。
TY_CAPI TYOpenDevice (TY_INTERFACE_HANDLE ifaceHandle, const char* deviceID, TY_DEV_HANDLE* outDeviceHandle);
TYOpenDeviceWithIP 在已知指定设备的IP地址时,可以使用该接口打开指定IP地址的网络相机。输入接口句柄和IP地址,获得打开网络相机的句柄。
TY_CAPI TYOpenDeviceWithIP (TY_INTERFACE_HANDLE ifaceHandle, const char* IP, TY_DEV_HANDLE* deviceHandle);
TYGetDeviceInterface 使用已知设备的句柄,查询该设备挂载的接口的句柄。
TY_CAPI TYGetDeviceInterface (TY_DEV_HANDLE hDevice, TY_INTERFACE_HANDLE* pIface);
TYForceDeviceIP 强制设定网络相机的IP地址。 已知网络相机的MAC地址时,可以通过该接口强制相机临时使用指定的IP地址和网关;设备重新启动后,该IP配置失效。
TY_CAPI TYForceDeviceIP (TY_INTERFACE_HANDLE ifaceHandle, const char* MAC, const char* newIP, const char* newNetMask, const char* newGateway);
TYCloseDevice 关闭指定设备。
TY_CAPI TYCloseDevice (TY_DEV_HANDLE hDevice);
TYGetDeviceInfo 输入设备句柄,查询设备信息,如接口、版本、厂商等信息。
TY_CAPI TYGetDeviceInfo (TY_DEV_HANDLE hDevice, TY_DEVICE_BASE_INFO* info);
设备信息包含以下数据,
typedef struct TY_DEVICE_BASE_INFO
{
TY_INTERFACE_INFO iface;
char id[32];
char vendorName[32];
char modelName[32];
TY_VERSION_INFO hardwareVersion;
TY_VERSION_INFO firmwareVersion;
union {
TY_DEVICE_NET_INFO netInfo;
TY_DEVICE_USB_INFO usbInfo;
};
char reserved[256];
}TY_DEVICE_BASE_INFO;
打开设备的一般操作如下
LOGD("Init lib");
TYInitLib();
std::vector<TY_DEVICE_BASE_INFO> selected;
selectDevice(TY_INTERFACE_ALL, ID, IP, 1, selected);
selected.size();
TY_DEVICE_BASE_INFO& selectedDev = selected[0];
TYOpenInterface(selectedDev.iface.id, &hIface);
TYOpenDevice(hIface, selectedDev.id, &hDevice);
其中 select 函数封装如下,
static inline TY_STATUS selectDevice(TY_INTERFACE_TYPE iface
, const std::string& ID, const std::string& IP
, uint32_t deviceNum, std::vector<TY_DEVICE_BASE_INFO>& out)
{
LOGD("Update interface list");
ASSERT_OK( TYUpdateInterfaceList() );
uint32_t n = 0;
ASSERT_OK( TYGetInterfaceNumber(&n) );
LOGD("Got %u interface list", n);
if(n == 0){
LOGE("interface number incorrect");
return TY_STATUS_ERROR;
}
std::vector<TY_INTERFACE_INFO> ifaces(n);
ASSERT_OK( TYGetInterfaceList(&ifaces[0], n, &n) );
ASSERT( n == ifaces.size() );
for(uint32_t i = 0; i < n; i++){
LOGI("Found interface %u:", i);
LOGI(" name: %s", ifaces[i].name);
LOGI(" id: %s", ifaces[i].id);
LOGI(" type: 0x%x", ifaces[i].type);
if(TYIsNetworkInterface(ifaces[i].type)){
LOGI(" MAC: %s", ifaces[i].netInfo.mac);
LOGI(" ip: %s", ifaces[i].netInfo.ip);
LOGI(" netmask: %s", ifaces[i].netInfo.netmask);
LOGI(" gateway: %s", ifaces[i].netInfo.gateway);
LOGI(" broadcast: %s", ifaces[i].netInfo.broadcast);
}
}
out.clear();
std::vector<TY_INTERFACE_TYPE> ifaceTypeList;
ifaceTypeList.push_back(TY_INTERFACE_USB);
ifaceTypeList.push_back(TY_INTERFACE_ETHERNET);
ifaceTypeList.push_back(TY_INTERFACE_IEEE80211);
for(size_t t = 0; t < ifaceTypeList.size(); t++){
for(uint32_t i = 0; i < ifaces.size(); i++){
if(ifaces[i].type == ifaceTypeList[t] && (ifaces[i].type & iface) && deviceNum > out.size()){
TY_INTERFACE_HANDLE hIface;
ASSERT_OK( TYOpenInterface(ifaces[i].id, &hIface) );
ASSERT_OK( TYUpdateDeviceList(hIface) );
uint32_t n = 0;
TYGetDeviceNumber(hIface, &n);
if(n > 0){
std::vector<TY_DEVICE_BASE_INFO> devs(n);
TYGetDeviceList(hIface, &devs[0], n, &n);
for(uint32_t j = 0; j < n; j++){
if(deviceNum > out.size() && ((ID.empty() && IP.empty())
|| (!ID.empty() && devs[j].id == ID)
|| (!IP.empty() && IP == devs[j].netInfo.ip)))
{
if (devs[j].iface.type == TY_INTERFACE_ETHERNET || devs[j].iface.type == TY_INTERFACE_IEEE80211) {
LOGI("*** Select %s on %s, ip %s", devs[j].id, ifaces[i].id, devs[j].netInfo.ip);
} else {
LOGI("*** Select %s on %s", devs[j].id, ifaces[i].id);
}
out.push_back(devs[j]);
}
}
}
TYCloseInterface(hIface);
}
}
}
if(out.size() == 0){
LOGE("not found any device");
return TY_STATUS_ERROR;
}
return TY_STATUS_OK;
}
关闭设备操作如下
TYCloseDevice(hDevice);
TYCloseInterface(hIface);
TYDeinitLib();
组件控制¶
TYGetComponentIDs 查询设备支持的组件
TY_CAPI TYGetComponentIDs (TY_DEV_HANDLE hDevice, int32_t* componentIDs);
TYGetEnabledComponents 查询已使能的组件
TY_CAPI TYGetEnabledComponents (TY_DEV_HANDLE hDevice, int32_t* componentIDs);
TYEnableComponents 使能指定的设备组件
TY_CAPI TYEnableComponents (TY_DEV_HANDLE hDevice, int32_t componentIDs);
TYDisableComponents 关闭指定的设备组件
TY_CAPI TYDisableComponents (TY_DEV_HANDLE hDevice, int32_t componentIDs);
示例,查询并使能左右红外摄像头和彩色摄像头
int32_t allComps;
ASSERT_OK( TYGetComponentIDs(hDevice, &allComps) );
if(allComps & TY_COMPONENT_RGB_CAM && color) {
LOGD("Has RGB camera, open RGB cam");
ASSERT_OK( TYEnableComponents(hDevice, TY_COMPONENT_RGB_CAM) );
}
if (allComps & TY_COMPONENT_IR_CAM_LEFT && ir) {
LOGD("Has IR left camera, open IR left cam");
ASSERT_OK(TYEnableComponents(hDevice, TY_COMPONENT_IR_CAM_LEFT));
}
if (allComps & TY_COMPONENT_IR_CAM_RIGHT && ir) {
LOGD("Has IR right camera, open IR right cam");
ASSERT_OK(TYEnableComponents(hDevice, TY_COMPONENT_IR_CAM_RIGHT));
}
帧缓冲管理¶
TYGetFrameBufferSize 获取当前设备配置需要的帧缓冲空间大小。同一相机设备,工作在不同图像数据输出模式下,需要的帧缓冲区大小不同。
TY_CAPI TYGetFrameBufferSize (TY_DEV_HANDLE hDevice, uint32_t* outSize);
TYEnqueueBuffer 把分配的帧缓冲推入缓冲队列。
TY_CAPI TYEnqueueBuffer (TY_DEV_HANDLE hDevice, void* buffer, uint32_t bufferSize);
TYClearBufferQueue 清空帧缓冲区的缓冲空间。(哪里会被调用到呢?或说哪里会清空队列呢?)
TY_CAPI TYClearBufferQueue (TY_DEV_HANDLE hDevice);
示例: 查询帧缓冲的大小,分配2帧缓冲并推入帧缓冲队列,
uint32_t frameSize;
ASSERT_OK( TYGetFrameBufferSize(hDevice, &frameSize) );
LOGD(" - Allocate & enqueue buffers");
char* frameBuffer[2];
frameBuffer[0] = new char[frameSize];
frameBuffer[1] = new char[frameSize];
LOGD(" - Enqueue buffer (%p, %d)", frameBuffer[0], frameSize);
ASSERT_OK( TYEnqueueBuffer(hDevice, frameBuffer[0], frameSize) );
LOGD(" - Enqueue buffer (%p, %d)", frameBuffer[1], frameSize);
ASSERT_OK( TYEnqueueBuffer(hDevice, frameBuffer[1], frameSize) );
启停管理¶
TYStartCapture 设备组件、组件特性功能配置完成后,调用该接口启动设备,开始图像采集和计算输出,运行结束后调用 TYStopCapture 停止图像采集操作。
TY_CAPI TYStartCapture (TY_DEV_HANDLE hDevice);
TY_CAPI TYStopCapture (TY_DEV_HANDLE hDevice);
软件触发¶
TYSendSoftTrigger 相机设备工作于 模式1或者模式2时(请参考 工作模式介绍 模式1图像有错,网络相机的极限图有错),应用程序调用该接口,通过USB链接或者以太网链接发送触发指令到深度相机设备,设备接收到该指令后进行一次图像采集和深度计算,并输出相应图像数据。
TY_CAPI TYSendSoftTrigger (TY_DEV_HANDLE hDevice);
状态报告¶
设备掉线或者设备License状态异常时,该回调函数可以收到 TY_EVENT_DEVICE_OFFLINE 或 TY_EVENT_LICENSE_ERROR 事件通知。
TY_CAPI TYRegisterEventCallback (TY_DEV_HANDLE hDevice, TY_EVENT_CALLBACK callback, void* userdata);
数据接收¶
FetchFrame 数据接收函数,输入设备句柄并在指定的时间内(Timeout in milliseconds. 0 for infinite)等待有效数据帧, 指定时间内没有收到数据帧,函数会返回并报告错误状态。
TY_CAPI TYFetchFrame (TY_DEV_HANDLE hDevice, TY_FRAME_DATA* frame, int32_t timeout);
属性设置¶
属性有无查询 TYHasFeature 输入设备句柄、组件ID,查询是否支持 featureID 对应的属性。
TY_CAPI TYHasFeature (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, bool* value);
属性信息查询 TYGetFeatureInfo 输入设备句柄、组件ID,查询 featureID 对应属d性的信息。
TY_CAPI TYGetFeatureInfo (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, TY_FEATURE_INFO* featureInfo);
属性的信息包括,访问属性(TY_ACCESS_MODE,读、写)、是否支持图像运行时配置、以及该属性相关联的组件和其他属性ID。
typedef struct TY_FEATURE_INFO
{
bool isValid; ///< true if feature exists, false otherwise
TY_ACCESS_MODE accessMode; ///< feature access mode
bool writableAtRun; ///< feature can be written while capturing
char reserved0[1];
TY_COMPONENT_ID componentID;
TY_FEATURE_ID featureID;
char name[32];
int32_t bindComponentID; ///< component ID current feature bind to
int32_t bindFeatureID; ///< feature ID current feature bind to
char reserved[252];
}TY_FEATURE_INFO;
属性分类 | 组件属性共计有7种,SDK使用同一个API对同一类型的不同属性进行操作。
typedef enum TY_FEATURE_TYPE_LIST
{
TY_FEATURE_INT = 0x1000,
TY_FEATURE_FLOAT = 0X2000,
TY_FEATURE_ENUM = 0x3000,
TY_FEATURE_BOOL = 0x4000,
TY_FEATURE_STRING = 0x5000,
TY_FEATURE_BYTEARRAY = 0x6000,
TY_FEATURE_STRUCT = 0x7000,
}TY_FEATURE_TYPE_LIST;
整型属性操作接口,
TY_CAPI TYGetIntRange (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, TY_INT_RANGE* intRange);
TY_CAPI TYGetInt (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, int32_t* value);
TY_CAPI TYSetInt (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, int32_t value);
浮点型属性操作接口,
TY_CAPI TYGetFloatRange (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, TY_FLOAT_RANGE* floatRange);
TY_CAPI TYGetFloat (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, float* value);
TY_CAPI TYSetFloat (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, float value);
枚举型设备操作接口,
TY_CAPI TYGetEnumEntryCount (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, uint32_t* entryCount);
TY_CAPI TYGetEnumEntryInfo (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, TY_ENUM_ENTRY* entries, uint32_t entryCount, uint32_t* filledEntryCount);
TY_CAPI TYGetEnum (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, int32_t* value);
TY_CAPI TYSetEnum (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, int32_t value);
布尔型属性操作接口,
TY_CAPI TYGetBool (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, bool* value);
TY_CAPI TYSetBool (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, bool value);
字符串型操作接口,
TY_CAPI TYGetStringLength (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, uint32_t* length);
TY_CAPI TYGetString (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, char* buffer, uint32_t bufferSize);
TY_CAPI TYSetString (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, const char* buffer);
结构体型操作接口,
TY_CAPI TYGetStruct (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, void* pStruct, uint32_t structSize);
TY_CAPI TYSetStruct (TY_DEV_HANDLE hDevice, TY_COMPONENT_ID componentID, TY_FEATURE_ID featureID, void* pStruct, uint32_t structSize);
属性说明¶
不同型号的深度相机拥有不同的属性配置, 通过遍历深度相机设备的组件和属性列表,可以获取产品准确的配置信息。参考 SDK 例程 DumpAllFeatures 可遍历设备支持的属性。
组件光学参数
- TY_STRUCT_CAM_INTRINSIC = 0x0000 | TY_FEATURE_STRUCT,
红外摄像头组件、彩色摄像头组件、深度摄像头组件的内参。结构体型属性,数据结构为3x3浮点数组。定义如下,
[fx, 0, cx,
0, fy, cy,
0, 0, 1]
typedef struct TY_CAMERA_INTRINSIC
{
float data[3*3];
}TY_CAMERA_INTRINSIC;
- TY_STRUCT_EXTRINSIC_TO_LEFT_IR = 0x0001 | TY_FEATURE_STRUCT,
组件外参。右侧红外摄像头组件、或者彩色摄像头组件 相对左侧红外摄像头组件的外参数据。结构体型属性,数据结构为4x4浮点数组。定义如下,
[r11, r12, r13, t1,
r21, r22, r23, t2,
r31, r32, r33, t3,
0, 0, 0, 1]
typedef struct TY_CAMERA_EXTRINSIC
{
float data[4*4];
}TY_CAMERA_EXTRINSIC;
- TY_STRUCT_CAM_DISTORTION = 0x0006 | TY_FEATURE_STRUCT,
红外摄像头或者彩色摄像头组件的光学畸变参数。结构体型属性,数据结构为12个元素的浮点数组。定义如下,
typedef struct TY_CAMERA_DISTORTION
{
float data[12];///<k1,k2,p1,p2,k3,k4,k5,k6,s1,s2,s3,s4
}TY_CAMERA_DISTORTION;
- TY_STRUCT_CAM_CALIB_DATA = 0x0007 | TY_FEATURE_STRUCT,
红外摄像头组件、彩色摄像头组件的标定参数组合,可获取内参数据、外参数据和畸变数据。
typedef struct TY_CAMERA_CALIB_INFO
{
int32_t intrinsicWidth;
int32_t intrinsicHeight;
TY_CAMERA_INTRINSIC intrinsic; // TY_STRUCT_CAM_INTRINSIC
TY_CAMERA_EXTRINSIC extrinsic; // TY_STRUCT_EXTRINSIC_TO_LEFT_IR
TY_CAMERA_DISTORTION distortion; // TY_STRUCT_CAM_DISTORTION
}TY_CAMERA_CALIB_INFO;
示例,获取标定参数( 参考例程 SimpleView_Registration)
struct CallbackData {
int index;
TY_DEV_HANDLE hDevice;
DepthRender* render;
DepthViewer* depthViewer;
bool needUndistort;
TY_CAMERA_CALIB_INFO depth_calib;
TY_CAMERA_CALIB_INFO color_calib;
};
CallbackData cb_data;
LOGD("=== Read depth calib info");
ASSERT_OK( TYGetStruct(hDevice, TY_COMPONENT_DEPTH_CAM, TY_STRUCT_CAM_CALIB_DATA
, &cb_data.depth_calib, sizeof(cb_data.depth_calib)) );
LOGD("=== Read color calib info");
ASSERT_OK( TYGetStruct(hDevice, TY_COMPONENT_RGB_CAM, TY_STRUCT_CAM_CALIB_DATA
, &cb_data.color_calib, sizeof(cb_data.color_calib)) );
网络相关属性
- TY_INT_PERSISTENT_IP = 0x0010 | TY_FEATURE_INT,
网络接口深度相机设备 的静态IP地址。
- TY_INT_PERSISTENT_SUBMASK = 0x0011 | TY_FEATURE_INT,
网络接口深度相机设备 的静态IP地址掩码。
- TY_INT_PERSISTENT_GATEWAY = 0x0012 | TY_FEATURE_INT,
网络接口深度相机设备 的静态IP网关。
int32_t ip_i[4];
uint8_t ip_b[4];
int32_t ip32;
sscanf(newIP, "%d.%d.%d.%d", &ip_i[0], &ip_i[1], &ip_i[2], &ip_i[3]);
ip_b[0] = ip_i[0];ip_b[1] = ip_i[1];ip_b[2] = ip_i[2];ip_b[3] = ip_i[3];
ip32 = TYIPv4ToInt(ip_b);
LOGI("Set persistent IP 0x%x(%d.%d.%d.%d)", ip32, ip_b[0], ip_b[1], ip_b[2], ip_b[3]);
ASSERT_OK( TYSetInt(hDev, TY_COMPONENT_DEVICE, TY_INT_PERSISTENT_IP, ip32) );
sscanf(newNetmask, "%d.%d.%d.%d", &ip_i[0], &ip_i[1], &ip_i[2], &ip_i[3]);
ip_b[0] = ip_i[0];ip_b[1] = ip_i[1];ip_b[2] = ip_i[2];ip_b[3] = ip_i[3];
ip32 = TYIPv4ToInt(ip_b);
LOGI("Set persistent Netmask 0x%x(%d.%d.%d.%d)", ip32, ip_b[0], ip_b[1], ip_b[2], ip_b[3]);
ASSERT_OK( TYSetInt(hDev, TY_COMPONENT_DEVICE, TY_INT_PERSISTENT_SUBMASK, ip32) );
sscanf(newGateway, "%d.%d.%d.%d", &ip_i[0], &ip_i[1], &ip_i[2], &ip_i[3]);
ip_b[0] = ip_i[0];ip_b[1] = ip_i[1];ip_b[2] = ip_i[2];ip_b[3] = ip_i[3];
ip32 = TYIPv4ToInt(ip_b);
LOGI("Set persistent Gateway 0x%x(%d.%d.%d.%d)", ip32, ip_b[0], ip_b[1], ip_b[2], ip_b[3]);
ASSERT_OK( TYSetInt(hDev, TY_COMPONENT_DEVICE, TY_INT_PERSISTENT_GATEWAY, ip32) );
- TY_BOOL_GVSP_RESEND = 0x0013 | TY_FEATURE_BOOL,
网络接口深度相机设备 的图像数据流重传开关。默认图像数据流不做重传。
- TY_INT_PACKET_DELAY = 0x0014 | TY_FEATURE_INT, ///< microseconds
网络接口深度相机设备 的数据传输的延时等待时间,用于缓冲网络数据发送雍塞。默认为0微秒。
- TY_INT_ACCEPTABLE_PERCENT = 0x0015 | TY_FEATURE_INT,
网络接口深度相机设备 的丢包率门槛,超过该门槛开启重传。
- TY_STRUCT_CAM_STATISTICS = 0x00ff | TY_FEATURE_STRUCT,
网络接口深度相机设备 统计数据信息。结构体型属性。定义如下,
typedef struct TY_CAMERA_STATISTICS
{
int32_t packetReceived;
int32_t packetLost;
int32_t imageOutputed;
int32_t imageDropped;
uint8_t rsvd[1024];
}TY_CAMERA_STATISTICS;
触发设置
- TY_ENUM_TRIGGER_ACTIVATION = 0x0201 | TY_FEATURE_ENUM,
深度相机设备 的触发信号设定。整型属性。深度相机设备支持下降沿触发和上升沿触发,默认设置是下降沿触发。定义如下,
typedef enum TY_TRIGGER_ACTIVATION_LIST
{
TY_TRIGGER_ACTIVATION_FALLINGEDGE = 0,
TY_TRIGGER_ACTIVATION_RISINGEDGE = 1,
}TY_TRIGGER_ACTIVATION_LIST;
- TY_INT_FRAME_PER_TRIGGER = 0x0202 | TY_FEATURE_INT,
深度相机设备 接收到一次软触发指令或者硬件触发信号 后,输出的图像的帧数量。默认输出1帧。
- TY_STRUCT_TRIGGER_PARAM = 0x0523 | TY_FEATURE_STRUCT,
深度相机设备 的触发模式设置。结构体属性。定义如下,
ypedef enum TY_TRIGGER_MODE_LIST
{
TY_TRIGGER_MODE_OFF = 0,
TY_TRIGGER_MODE_SLAVE = 1,
TY_TRIGGER_MODE_M_SIG = 2,
TY_TRIGGER_MODE_M_PER = 3,
}TY_TRIGGER_MODE_LIST;
typedef int16_t TY_TRIGGER_MODE;
typedef struct TY_TRIGGER_PARAM
{
TY_TRIGGER_MODE mode;
int8_t fps;
int8_t rsvd;
}TY_TRIGGER_PARAM;
—- TY_TRIGGER_MODE_OFF 配置相机设备工作在模式0,连续输出图像数据。
LOGD("=== Disable trigger mode");
TY_TRIGGER_PARAM trigger;
trigger.mode = TY_TRIGGER_MODE_OFF;
ASSERT_OK(TYSetStruct(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, &trigger, sizeof(trigger)));
—- TY_TRIGGER_MODE_SLAVE 配置相机设备工作在模式1,收到触发指令或者硬件触发信号后,进行一次图像采集并输出图像数据。
LOGD("=== Set trigger to slave mode");
TY_TRIGGER_PARAM trigger;
trigger.mode = TY_TRIGGER_MODE_SLAVE;
ASSERT_OK(TYSetStruct(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, &trigger, sizeof(trigger)));
—- TY_TRIGGER_MODE_M_SIG 配置相机设备工作在模式2,收到软件触发信号后,通过硬件TRIGGER OUT接口输出触发信号 并 进行一次图像采集。该模式可以实现多设备同步采集。
LOGD("=== Set trigger mode");
if(0 == i ){
cams[i].tag = std::string(cams[i].sn) + "_master";
TY_TRIGGER_PARAM param;
param.mode = TY_TRIGGER_MODE_M_SIG;
ASSERT_OK(TYSetStruct(cams[i].hDev, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, (void*)¶m, sizeof(param)));
}else{
cams[i].tag = std::string(cams[i].sn) + "_slave";
TY_TRIGGER_PARAM param;
param.mode = TY_TRIGGER_MODE_SLAVE;
ASSERT_OK(TYSetStruct(cams[i].hDev, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, (void*)¶m, sizeof(param)));
}
—- TY_TRIGGER_MODE_M_PER 配置相机设备工作在模式3,相机设备按照 TY_TRIGGER_PARAM 中的帧率设置,通过硬件TRIGGER OUT接口输出触发信号,同时触发自身进行图像采集。该模式可实现多设备同步采集。
LOGD("=== Set trigger mode");
if(0 == i ){
cams[i].tag = std::string(cams[i].sn) + "_master";
TY_TRIGGER_PARAM param;
param.mode = TY_TRIGGER_MODE_M_PER;
param.fps = 30;
ASSERT_OK(TYSetStruct(cams[i].hDev, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, (void*)¶m, sizeof(param)));
}else{
cams[i].tag = std::string(cams[i].sn) + "_slave";
TY_TRIGGER_PARAM param;
param.mode = TY_TRIGGER_MODE_SLAVE;
ASSERT_OK(TYSetStruct(cams[i].hDev, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, (void*)¶m, sizeof(param)));
}
- TY_INT_TRIGGER_DELAY_US = 0x0206 | TY_FEATURE_INT,
延迟触发。深度相机设备 收到触发指令或者硬件触发信号后,延时 TY_INT_TRIGGER_DELAY_US 时间后进行图像采集。单位是微秒。
LOGD("=== Set trigger to slave mode");
TY_TRIGGER_PARAM trigger;
trigger.mode = TY_TRIGGER_MODE_SLAVE;
ASSERT_OK(TYSetStruct(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, &trigger, sizeof(trigger)));
//notice: trigger delay only be enabled in trigger salve mode and only work for hardware trigger.
// delay time unit is microsecond
int32_t time = 1000;
ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_DEVICE, TY_INT_TRIGGER_DELAY_US, time));
- TY_BOOL_TRIGGER_OUT_IO = 0x0207 | TY_FEATURE_BOOL,
触发IO输出控制。在深度相机工作在模式0或者模式1时,可以通过该属性控制触发输出接口工作在普通IO模式。设置该值为True时,输出有效的触发信号( 参考TY_ENUM_TRIGGER_ACTIVATION 属性设置),设置该值为False时,进入无效触发的状态。深度相机设备工作在模式2或者模式3时,该属性不能使用。
链路监测
- TY_BOOL_KEEP_ALIVE_ONOFF = 0x0203 | TY_FEATURE_BOOL,
深度相机状态保持。SDK与相机设备维持通信状态保持机制。默认为TRUE。一旦发生链接异常,将激活TYRegisterEventCallback注册的回调函数。用户可在回调函数中进行重连等异常处理操作。
- TY_INT_KEEP_ALIVE_TIMEOUT = 0x0204 | TY_FEATURE_INT, ///< Keep Alive timeout
深度相机状态保持时间设置。在该时间内未收到状态保持数据包,则判定系统与设备的链接出现异常。单位是秒。USB相机默认是15秒,网络相机默认3秒。
曝光设置
- TY_BOOL_CMOS_SYNC = 0x0205 | TY_FEATURE_BOOL,
双目深度计算使用的左、右两幅图像曝光完全同步时,可以获得最好的深度图数据;当左、右两幅红外图像曝光不完全同步,时间相差较小时,也可以输出深度图像数据,数据精度稍差。左右图像完全同步时,图像输出帧率低于不完全同步时图像输出帧率。依据实际使用场景对深度图质量和帧率的需要,可以通过该布尔型属性对相机的工作配置进行修改。深度相机默认采用完全同步的设置。
- TY_BOOL_AUTO_AWB = 0x0304 | TY_FEATURE_BOOL,
自动白平衡。红外或者彩色摄像头组件的自动白平衡设置。
- TY_BOOL_AUTO_EXPOSURE = 0x0300 | TY_FEATURE_BOOL,
自动曝光开关。红外摄像头组件或者彩色摄像头组件的自动曝光开关。部分型号深度相机的光学组件允许图像自动曝光。
- TY_INT_EXPOSURE_TIME = 0x0301 | TY_FEATURE_INT,
曝光时间。红外或者彩色摄像头组件的曝光时间设置。单位为行曝光时间。不同光学传感器、不同帧率配置下的行曝光时间、可配置范围不同。
- TY_BOOL_AUTO_GAIN = 0x0302 | TY_FEATURE_BOOL,
自动增益。红外摄像头组件或者彩色摄像头组件的自动增益调整开关。部分型号深度相机的光学组件允许自动调整增益。
- TY_INT_GAIN = 0x0303 | TY_FEATURE_INT,
数字曝光增益。红外摄像头组件的数字曝光增益设置。不同光学传感器、不同帧率配置下的可调增益范围不同。
int32_t value;
TY_INT_RANGE range;
// get the range of digital gain
ASSERT_OK(TYGetIntRange(hDevice, TY_COMPONENT_IR_CAM_LEFT, TY_INT_GAIN, &range));
// set the max digital gain
ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_IR_CAM_LEFT, TY_INT_GAIN, range.max));
ASSERT_OK(TYGetInt(hDevice, TY_COMPONENT_IR_CAM_LEFT, TY_INT_GAIN, &value));
- TY_INT_R_GAIN = 0x0520 | TY_FEATURE_INT, ///< Gain of R channel
- TY_INT_G_GAIN = 0x0521 | TY_FEATURE_INT, ///< Gain of G channel
- TY_INT_B_GAIN = 0x0522 | TY_FEATURE_INT, ///< Gain of B channel
彩色摄像头模组的数字曝光增益,可分别为 R、G、B三通道独立设置。
- TY_INT_ANALOG_GAIN = 0x0524 | TY_FEATURE_INT, ///< Analog gain
模拟曝光增益。红外或者彩色摄像头组件的模拟曝光增益设置。不同光学传感器、不同帧率配置下的可调增益范围不同。
红外投射器控制
- TY_INT_LASER_POWER = 0x0500 | TY_FEATURE_INT,
红外激光发射器功率设置。通过该属性可设置红外投射器的补光亮度,从而影响红外传感器成像的亮度。
int32_t value;
TY_INT_RANGE range;
// get the range of laser power
ASSERT_OK(TYGetIntRange(hDevice,TY_COMPONENT_LASER, TY_INT_LASER_POWER, &range));
// set the max power
ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_LASER, TY_INT_LASER_POWER, range.max));
ASSERT_OK(TYGetInt(hDevice, TY_COMPONENT_LASER, TY_INT_LASER_POWER, &value));
- TY_BOOL_LASER_AUTO_CTRL = 0x0501 | TY_FEATURE_BOOL,
红外激光发射器自动调整功能。该属性默认使能,深度相机设备依据深度计算需要,自动开关红外激光发射器。关闭该属性后,可根据需要 调整红外激光发射器功率 来开关红外发激光发射器(功率为0时关闭激光)。
图像配置
- TY_ENUM_IMAGE_MODE = 0x0109 | TY_FEATURE_ENUM,
图像的格式和分辨率。
LOGD("=== Configure feature, set resolution to 640x480.");
int err = TYSetEnum(hDevice, TY_COMPONENT_DEPTH_CAM, TY_ENUM_IMAGE_MODE, TY_IMAGE_MODE_DEPTH16_640x480);
- TY_FLOAT_SCALE_UNIT = 0x010a | TY_FEATURE_FLOAT,
深度测量值的计算系数。该值默认为1,深度图中每个Pixel的数据值是实际测得的距离(单位是毫米);当该值不为1时,深度图中每个Pixel的数据值与该系数的乘积可得到实际测得的距离(单位是毫米)。
float value;
ASSERT_OK(TYGetFloat(hDevice, TY_COMPONENT_DEPTH_CAM, TY_FLOAT_SCALE_UNIT, &value));
- TY_BOOL_UNDISTORTION = 0x0510 | TY_FEATURE_BOOL, ///< Output undistorted image
畸变矫正开关。默认为False,即红外摄像头组件 默认输出未做畸变矫正的图像数据。彩色默认不支持输出未做畸变矫正的图像数据。
// ASSERT_OK( TYSetEnum(hDevice, TY_COMPONENT_IR_CAM_LEFT, TY_ENUM_IMAGE_MODE, TY_IMAGE_MODE_YUYV_640x480) );
bool hasUndistortSwitch, hasDistortionCoef;
ASSERT_OK( TYHasFeature(hDevice, TY_COMPONENT_IR_CAM_LEFT, TY_BOOL_UNDISTORTION, &hasUndistortSwitch) );
ASSERT_OK( TYHasFeature(hDevice, TY_COMPONENT_IR_CAM_LEFT, TY_STRUCT_CAM_DISTORTION, &hasDistortionCoef) );
if (hasUndistortSwitch) {
ASSERT_OK( TYSetBool(hDevice, TY_COMPONENT_IR_CAM_LEFT, TY_BOOL_UNDISTORTION, true) );
- TY_BOOL_BRIGHTNESS_HISTOGRAM = 0x0511 | TY_FEATURE_BOOL,
红外亮度直方图组件使能开关。默认为False,不打开红外亮度直方图组件。使能红外亮度直方图组件(TY_COMPONENT_BRIGHT_HISTO),设备会统计并输出左、右红外图像的亮度直方图。
示例(请参考sample code: SimpleView_FetchFrame),
int32_t allComps, componentIDs = 0;
ASSERT_OK( TYGetComponentIDs(hDevice, &allComps) );
if(allComps & TY_COMPONENT_BRIGHT_HISTO) {
LOGD("=== Has bright histo component");
componentIDs |= TY_COMPONENT_BRIGHT_HISTO;
}
LOGD("=== Configure components, open depth cam");
componentIDs |= TY_COMPONENT_IR_CAM_RIGHT| TY_COMPONENT_IR_CAM_LEFT;
ASSERT_OK( TYEnableComponents(hDevice, componentIDs) );
- TY_BOOL_DEPTH_POSTPROC = 0x0512 | TY_FEATURE_BOOL,
深度图像后处理开关。客户定制版设备具有深度图的平滑滤波功能,仅部分设备支持。
坐标变换¶
点云数据结构,
typedef struct TY_VECT_3F
{
float x;
float y;
float z;
}TY_VECT_3F;
深度图上点描述数据结构,
typedef struct TY_PIXEL_DESC
{
int16_t x; // x coordinate in pixels
int16_t y; // y coordinate in pixels
uint16_t depth; // depth value
uint16_t rsvd;
}TY_PIXEL_DESC;
TYInvertExtrinsic 逆阵转换,输入4x4外参矩阵,输出其逆矩阵。
TY_CAPI TYInvertExtrinsic (const TY_CAMERA_EXTRINSIC* orgExtrinsic,
TY_CAMERA_EXTRINSIC* invExtrinsic);
TYMapDepthToPoint3d 指定深度图上点转换为点云数据, 输入深度相机标定数据、深度图宽高和深度数据点、点数量,输出点云数据。
TY_CAPI TYMapDepthToPoint3d (const TY_CAMERA_CALIB_INFO* src_calib,
uint32_t depthW, uint32_t depthH,
const TY_PIXEL_DESC* depthPixels, uint32_t count,
TY_VECT_3F* point3d);
TYMapPoint3dToDepth 转换点云数据为深度图数据,输入深度相机标定数据,点云数据、点数和目标深度图的宽高,输出深度图上点数据。TYMapDepthToPoint3d 的逆操作。
TY_CAPI TYMapPoint3dToDepth (const TY_CAMERA_CALIB_INFO* dst_calib,
const TY_VECT_3F* point3d, uint32_t count,
uint32_t depthW, uint32_t depthH,
TY_PIXEL_DESC* depth);
TYMapDepthImageToPoint3d 转换深度数据图为点云,输入深度相机的标定数据,深度图宽、高、和深度图,输出点云。数值为0的无效深度点映射为(NAN, NAN, NAN)。
TY_CAPI TYMapDepthImageToPoint3d (const TY_CAMERA_CALIB_INFO* src_calib,
uint32_t imageW, uint32_t imageH,
const uint16_t* depth,
TY_VECT_3F* point3d);
示例,获取点云数据,详请参考 SDK 例程 SimpleView_Point3D 。
LOGD("=== Read depth intrinsic");
TY_CAMERA_CALIB_INFO depth_calib;
ASSERT_OK( TYGetStruct(hDevice, TY_COMPONENT_DEPTH_CAM, TY_STRUCT_CAM_CALIB_DATA
, &depth_calib, sizeof(depth_calib)) );
LOGD("=== parse depth frame");
cv::Mat depth, color;
parseFrame(*frame, &depth, 0, 0, &color);
cv::Mat p3d(depth.size(), CV_32FC3);
ASSERT_OK( TYMapDepthImageToPoint3d(&depth_calib, depth.cols, depth.rows
, depth.ptr<uint16_t>(), p3d.ptr<TY_VECT_3F>()) );
TYMapPoint3dToDepthImage 转换点云为深度图像,输入深度相机的标定数据,点云和点数、深度图宽、高。无效点云(NAN, NAN, NAN)映射为无效深度0。
TY_CAPI TYMapPoint3dToDepthImage (const TY_CAMERA_CALIB_INFO* dst_calib,
const TY_VECT_3F* point3d, uint32_t count,
uint32_t depthW, uint32_t depthH, uint16_t* depth);
TYMapPoint3dToPoint3d 点云坐标转换。输入外参矩阵、点云数据和点数,输出转换后的点云数据。
TY_CAPI TYMapPoint3dToPoint3d (const TY_CAMERA_EXTRINSIC* extrinsic,
const TY_VECT_3F* point3dFrom, uint32_t count,
TY_VECT_3F* point3dTo);
TYMapDepthToColorCoordinate 映射深度数据点到彩色图像坐标。 输入深度图标定数据、深度图宽和高、深度数据点、深度图点数、彩色图标定数据、彩色图宽、高,输出映射后的深度点。
static inline TY_STATUS TYMapDepthToColorCoordinate(
const TY_CAMERA_CALIB_INFO* depth_calib,
uint32_t depthW, uint32_t depthH,
const TY_PIXEL_DESC* depth, uint32_t count,
const TY_CAMERA_CALIB_INFO* color_calib,
uint32_t mappedW, uint32_t mappedH,
TY_PIXEL_DESC* mappedDepth);
TYCreateDepthToColorCoordinateLookupTable 创建深度图到彩色图的坐标查找表。输入深度图标定数据、深度图宽和高、深度图、彩色图标定数据、映射后的深度图宽和高,输出映射后的深度点数据表。
static inline TY_STATUS TYCreateDepthToColorCoordinateLookupTable(
const TY_CAMERA_CALIB_INFO* depth_calib,
uint32_t depthW, uint32_t depthH, const uint16_t* depth,
const TY_CAMERA_CALIB_INFO* color_calib,
uint32_t mappedW, uint32_t mappedH,
TY_PIXEL_DESC* lut);
TYMapDepthImageToColorCoordinate 映射深度数据图到彩色图像坐标。 输入深度图标定数据、深度图宽和高,深度图、彩色图标定数据、彩色图宽和高,输出映射后的深度图。
static inline TY_STATUS TYMapDepthImageToColorCoordinate(
const TY_CAMERA_CALIB_INFO* depth_calib,
uint32_t depthW, uint32_t depthH, const uint16_t* depth,
const TY_CAMERA_CALIB_INFO* color_calib,
uint32_t mappedW, uint32_t mappedH, uint16_t* mappedDepth);
TYMapRGBImageToDepthCoordinate 映射RGB彩色图到深度图坐标。输入深度图标定数据、深度图宽和高、深度图、彩色图标定数据、彩色图宽和高、彩色图,输出映射后的彩色图像数据。
static inline TY_STATUS TYMapRGBImageToDepthCoordinate(
const TY_CAMERA_CALIB_INFO* depth_calib,
uint32_t depthW, uint32_t depthH, const uint16_t* depth,
const TY_CAMERA_CALIB_INFO* color_calib,
uint32_t rgbW, uint32_t rgbH, const uint8_t* inRgb,
uint8_t* mappedRgb);
示例,详请参考 SDK 例程 SimpleView_Registration。
void doRegister(const TY_CAMERA_CALIB_INFO& depth_calib
, const TY_CAMERA_CALIB_INFO& color_calib
, const cv::Mat& depth
, const cv::Mat& color
, bool needUndistort
, cv::Mat& undistort_color
, cv::Mat& out
, bool map_depth_to_color
)
{
// do undistortion
if (needUndistort) {
TY_IMAGE_DATA src;
src.width = color.cols;
src.height = color.rows;
src.size = color.size().area() * 3;
src.pixelFormat = TY_PIXEL_FORMAT_RGB;
src.buffer = color.data;
undistort_color = cv::Mat(color.size(), CV_8UC3);
TY_IMAGE_DATA dst;
dst.width = color.cols;
dst.height = color.rows;
dst.size = undistort_color.size().area() * 3;
dst.buffer = undistort_color.data;
dst.pixelFormat = TY_PIXEL_FORMAT_RGB;
ASSERT_OK(TYUndistortImage(&color_calib, &src, NULL, &dst));
}
else {
undistort_color = color;
}
// do register
if (map_depth_to_color) {
out = cv::Mat::zeros(undistort_color.size(), CV_16U);
ASSERT_OK(
TYMapDepthImageToColorCoordinate(
&depth_calib,
depth.cols, depth.rows, depth.ptr<uint16_t>(),
&color_calib,
out.cols, out.rows, out.ptr<uint16_t>()
)
);
cv::Mat temp;
//you may want to use median filter to fill holes in projected depth image
//or do something else here
cv::medianBlur(out, temp, 5);
out = temp;
}
else {
out = cv::Mat::zeros(depth.size(), CV_8UC3);
ASSERT_OK(
TYMapRGBImageToDepthCoordinate(
&depth_calib,
depth.cols, depth.rows, depth.ptr<uint16_t>(),
&color_calib,
undistort_color.cols, undistort_color.rows, undistort_color.ptr<uint8_t>(),
out.ptr<uint8_t>()
)
);
}
}
TYMapMono8ImageToDepthCoordinate 映射MONO8彩色图到深度图坐标。输入深度图标定数据、深度图宽和高、深度图、MONO8 彩色图标定数据、MONO8 彩色图宽和高、MONO8 彩色图,输出映射后的 MONO8 彩色图像数据。
static inline TY_STATUS TYMapMono8ImageToDepthCoordinate(
const TY_CAMERA_CALIB_INFO* depth_calib,
uint32_t depthW, uint32_t depthH, const uint16_t* depth,
const TY_CAMERA_CALIB_INFO* color_calib,
uint32_t monoW, uint32_t monoH, const uint8_t* inMono,
uint8_t* mappedMono);
图像处理¶
TYUndistortImage 畸变校正,可对摄像头组件输出的图像做畸变处理,支持 TY_PIXEL_FORMAT_MONO ,TY_PIXEL_FORMAT_RGB,TY_PIXEL_FORMAT_BGR 三种数据格式。输入参数为 摄像头标定数据、未矫正原始图像 和 期望的图像内参(输入为NULL则使用摄像头原有内参),输出校正后的图像数据。
TY_CAPI TYUndistortImage (const TY_CAMERA_CALIB_INFO *srcCalibInfo
, const TY_IMAGE_DATA *srcImage
, const TY_CAMERA_INTRINSIC *cameraNewIntrinsic
, TY_IMAGE_DATA *dstImage
);
TYDepthSpeckleFilter 深度图中无效点填充 和 离散点降噪处理,输入深度图 和 滤波参数,输出处理后的深度图。
struct DepthSpeckleFilterParameters {
int max_speckle_size; // blob size smaller than this will be removed
int max_speckle_diff; // Maximum difference between neighbor disparity pixels
};
#define DepthSpeckleFilterParameters_Initializer {150, 64}
TY_CAPI TYDepthSpeckleFilter (TY_IMAGE_DATA* depthImage
, const DepthSpeckleFilterParameters* param
);
TYDepthEnhenceFilter 图像滤波,输入深度图,图像数量,参照图,和滤波系数,输出滤波后的深度数据。
TY_CAPI TYDepthEnhenceFilter (const TY_IMAGE_DATA* depthImages
, int imageNum
, TY_IMAGE_DATA *guide
, TY_IMAGE_DATA *output
, const DepthEnhenceParameters* param
);
struct DepthEnhenceParameters{
float sigma_s; // filter param on space
float sigma_r; // filter param on range
int outlier_win_sz; // outlier filter windows size
float outlier_rate;
};
#define DepthEnhenceParameters_Initializer {10, 20, 10, 0.1f}
sigma_s是空间滤波系数,sigma_r是深度滤波系数,outlier_win_sz是以像素为单位的滤波窗口,outlier_rate噪音过滤系数。
流程说明¶
以SDK示例程序 Simpleview_FetchFrame 为例说明深度相机的配置和图像获取流程。
初始化API¶
TYInitLib 初始化设备对象等数据结构。
打开设备¶
配置组件(component)¶
每个设备打开后都必须使能或者配置各个组件,默认情况下只有虚拟组件TY_COMPONENT_DEVICE是使能状态。多个设备可以通过 位或 方式同时使能。
int32_t componentIDs = TY_COMPONENT_DEPTH_CAM | TY_COMPONENT_RGB_CAM;
TYEnableComponents(hDevice, componentIDs);
配置属性(feature)¶
TYGetFeatureInfo | TYGetFeatureInfo()通过填充结构体TY_FEATURE_INFO来获取指定component的指定feature的信息。如果该component不包含所指定的feature,则TY_FEATURE_INFO中isValid值为false。如果该组件不包含所指定的参数,则 TY_FEATURE_INFO 中 isValid 值为 false。也可以通过 TYGetIntRange 等具体参数类型的 API 接口查询指定功能参数的信息。 | 常用读写feature函数如下,
TYGetIntRange
TYGetInt
TYSetInt
TYGetFloatRange
TYGetFloat
TYSetFloat
TYGetEnumEntryCount
TYGetEnumEntryInfo
TYGetEnum
TYSetEnum
TYGetBool
TYSetBool
TYGetStringLength
TYGetString
TYSetString
TYGetStruct
TYSetStruct
示例 调用TYSetEnum设置设备的深度摄像头输出的数据分辨率属性,
int err = TYSetEnum(hDevice, TY_COMPONENT_DEPTH_CAM, TY_ENUM_IMAGE_MODE, TY_IMAGE_MODE_640x480);
Framebuffer管理¶
首先应指定输出图像的种类、分辨率规格。
LOGD("=== Configure feature, set resolution to 640x480.");
int err = TYSetEnum(cams[i].hDev, TY_COMPONENT_DEPTH_CAM, TY_ENUM_IMAGE_MODE, TY_IMAGE_MODE_DEPTH16_640x480);
ASSERT(err == TY_STATUS_OK || err == TY_STATUS_NOT_PERMITTED);
然后调用API查询当前配置下每个framebuffer的大小
uint32_t frameSize;
ASSERT_OK( TYGetFrameBufferSize(cams[i].hDev, &frameSize) );
LOGD(" - Get size of framebuffer, %d", frameSize);
分配深度数据存储空间
驱动内部维护一个缓冲队列(buffer queue), 每帧数据传出时会将填充好的 buffer 作 dequeue 操作, 并完全传出给用户使用。用户完成该帧图像数据处理后,需做 enqueue 动作以返还该 Buffer 给驱动层缓冲队列。用户需要保证新的一帧数据到来时驱动的缓冲队列 buffer queue 不为空, 否则该帧数据将被丢弃。
LOGD(" - Allocate & enqueue buffers");
cams[i].fb[0] = new char[frameSize];
cams[i].fb[1] = new char[frameSize];
LOGD(" - Enqueue buffer (%p, %d)", cams[i].fb[0], frameSize);
ASSERT_OK( TYEnqueueBuffer(cams[i].hDev, cams[i].fb[0], frameSize) );
LOGD(" - Enqueue buffer (%p, %d)", cams[i].fb[1], frameSize);
ASSERT_OK( TYEnqueueBuffer(cams[i].hDev, cams[i].fb[1], frameSize) );
回调函数注册¶
TYRegisterCallback | 使用回调函数的方式获取图像数据时,需要注册该函数,当图像数据到达后,该回调函数会主动被执行。在使用主动获取模式获取图像时,需要调用该函数注册回调函数为NULL。回调函数的格式请参考API说明和示例。
配置工作模式¶
示例1:设置相机工作在连续模式,
TY_TRIGGER_MODE tyTriggerMode;
tyTriggerMode.mode = TY_TRIGGER_MODE_CONTINUES;
ASSERT_OK(TYSetStruct(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_WORK_MODE, (void*)&tyTriggerMode,sizeof(tyTriggerMode)));
示例2: 如设置相机工作在触发模式。
TY_TRIGGER_MODE tyTriggerMode;
tyTriggerMode.mode = TY_TRIGGER_MODE_TRIG_SLAVE;
ASSERT_OK(TYSetStruct(cams[i].hDev, TY_COMPONENT_DEVICE, TY_STRUCT_WORK_MODE, (void*)&tyTriggerMode, sizeof(tyTriggerMode)));
示例3:设置相机工作在主触发模式,通过触发输出接口、以10HZ的频率持续发送触发信号。
TY_TRIGGER_MODE tyTriggerMode;
tyTriggerMode.mode = TY_TRIGGER_MODE_M_PER;
tyTriggerMode.fps = 10;
ASSERT_OK(TYSetStruct(cams[i].hDev, TY_COMPONENT_DEVICE, TY_STRUCT_WORK_MODE, (void*)&tyTriggerMode, sizeof(tyTriggerMode)));
启动深度采集¶
TYStartCapture | 如果深度相机工作在触发接入模式(TY_TRIGGER_MODE_TRIG_SLAVE)下,可以使用软件触发接口函数TYSendSoftTrigger(),通过USB或者以太网发送指令,控制相机图像采集的时机。
获取帧数据¶
TYFetchFrame | 主动获取深度数据模式下,应用可调用该接口获取深度数据。注意回调函数模式下不需要调用。 | 获取数据后,用户程序进行运算处理时,应采用独立线程,避免堵塞图像获取线程的运转。
停止采集¶
TYStopCapture 停止图像数据采集,相机停止深度数据计算和输出。
关闭设备¶
TYCloseDevice关闭设备,TYCloseInterface释放占用的接口。
释放API¶
TYDeinitLib释放API后,需要释放分配的内存资源,避免内存泄露。