API Guides

基础概念

设备

深度相机称为一个设备(Device)。

组件

每个设备包含多个器件,如包括左右红外摄像头、IR激光器、RGB摄像头、激光器等器件,我们称这些器件为组件(Component)。
组件(Component)也可能是虚拟器件,例如depth摄像头、直方图设备等,尽管并不存在这些实体器件,从用户角度看并没有什么区别,用户可以同操作真实存在的器件一样操作这些虚拟器件,完成相应的功能设置。
相机包含的全体组件定义如下,
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。

属性

深度相机设备 或者 不同组件有各种不同的功能参数,SDK 软件工程中称之为属性 (feature)。依据各个feature的特点, SDK 分别为这些属性定义 int、bool、struct 等类型的数据结构。用户可以通过TYGetInt TYSetInt TYGetStruct TYSetStruct 等类似风格的API函数,读取或者写入 深度相机设备或者某个Component的某个feature。
不同Component的feature之间也可以存在联动关系, 例如左IR摄像头的分辨率和右IR摄像头的分辨率始终保持一致。修改组件的一个属性时, 深度相机设备会同步修改另一个组件的同一属性,这种关系称为绑定(binding)。绑定关系可以通过查询feature信息得知。
不同型号、不同版本的深度相机对各个组件和和属性的支持不同,通过软件接口可查询相机设备支持的所有组件和属性。SDK应用示例应用 DumpAllFeatures 能够列出所连接相机的所有组件和属性信息。

以FM810-IX为例,该相机包含的组件、支持的属性,以及属性与组件的隶属关系,请参考下方XML配置描述:

<?xml version="1.0" ?>
<config version="1">
    <comprotocol>1.0</comprotocol>
    <component addr="0x01000000" id="0x80000000" name="device">
            <feature hide="0" id="0x5f00" name="SN" rw="1">207000103630</feature>
            <feature hide="0" id="0x5f01" name="vendor" rw="1">Percipio</feature>
            <feature hide="0" id="0x5f02" name="model" rw="1">FM850-GI-E1</feature>
            <feature addr="0x204" hide="0" id="0x1202" name="frame per trigger" rw="3">1</feature>
            <feature addr="0x208" hide="0" id="0x7523" name="struct trigger mode" rw="3"/>
            <feature absaddr="0x64c" hide="0" id="0x1010" name="persistent IP" rw="3"/>
            <feature absaddr="0x65c" hide="0" id="0x1011" name="persistent netmask" rw="3"/>
            <feature absaddr="0x66c" hide="0" id="0x1012" name="persistent gateway" rw="3"/>
        <feature id="0x1014" addr="0x400020" name="packet delay" rw="3" hide="0" min="0" max="10000" inc="1"></feature>
            <feature hide="0" id="0x4203" name="keep alive onoff" rw="3"/>
            <feature hide="0" id="0x1204" inc="1" max="30000" min="2000" name="keep alive timeout" rw="3"/>
            <feature addr="0x20c" hide="0" id="0x4205" name="cmos sync" rw="3"/>
            <feature addr="0x210" hide="0" id="0x1206" inc="1" max="2600000" min="0" name="trigger delay us" rw="3"/>
            <feature addr="0x214" hide="0" id="0x4207" name="trigger out io" rw="2"/>
            <feature id="0x5fe0" name="device extrinsic" rw="1">0.999952681255 7.60136217579e-05 -0.00972776813563 -0.336485821421 -0.000221031603802 0.999888853739 -0.0149074247776 29.785291942 0.00972555376323 0.0149088695212 0.999841557055 -0.378826934226 0.0 0.0 0.0 1.0</feature>
                <feature id="0x5f03" name="hardware version" rw="1" hide="0">1.3.0</feature>
        <feature id="0x5f04" name="firmware version" rw="1" hide="0">2.1.0</feature>
        <build>
            <hash>model:AM81X_X_X7_F121_DVP;rtl:V1.0.0_0_g90219c318f;kernel:R1.1.1-0-g4444ad1206;tycam:R3.0.7-4527fe5c;gevcam:R1.1.1-0-ga6db8c17</hash>
        </build>
            <config_version>r1.1.1</config_version>
            <tech_model>AM830-GTIS8-47</tech_model>
            <generated_time>2018-10-24T101841</generated_time>
            <calibration_time>2018-10-23T020256</calibration_time>
    </component>
    <component addr="0x02000000" id="0x00010000" name="depth">
            <feature hide="1" id="0x1003" name="intrinsic width" rw="1">1280</feature>
            <feature hide="1" id="0x1004" name="intrinsic height" rw="1">960</feature>
            <feature hide="0" id="0x7000" name="depth intrinsic" rw="1"> 1104.9443713639284 0.0 622.67724609375  0.0 1104.9443713639284 479.1217193603515  0.0 0.0 1.0</feature>
            <feature addr="0x10" hide="0" id="0x1104" name="image width" rw="1"/>
            <feature addr="0x14" hide="0" id="0x1105" name="image height" rw="1"/>
            <feature addr="0x18" hide="0" id="0x3109" name="image mode" rw="3">
                    <entry name="DEPTH16_640x480" value="0x202801e0"/>
                    <entry name="DEPTH16_1280x960" value="0x205003c0"/>
                    <entry name="DEPTH16_320x240" value="0x201400f0"/>
            </feature>
    </component>
    <component addr="0x03000000" id="0x00040000" name="leftIR">
            <feature addr="0x18" hide="0" id="0x3109" name="image mode" rw="1">
                    <entry name="mono8 1280x960" value="0x105003c0"/>
            </feature>
            <feature addr="0x10" hide="0" id="0x1104" name="image width" rw="1">1280</feature>
            <feature addr="0x14" hide="0" id="0x1105" name="image height" rw="1">960</feature>
            <feature hide="1" id="0x1003" name="intrinsic width" rw="1">1280</feature>
            <feature hide="1" id="0x1004" name="intrinsic height" rw="1">960</feature>
            <feature hide="0" id="0x7000" name="intrinsic" rw="1"> 1160.7836634948417 0.0 626.3813885860102  0.0 1160.9506124952643 481.9362930586105  0.0 0.0 1.0</feature>
            <feature hide="0" id="0x7006" name="distortion" rw="1"> -0.2090937211318959  0.4002598371809057  0.0015886459108703148  0.0021725847142336687  0.09247258301599012  0.04501650960020234  0.3086035070066297  0.20138834927631324  -0.004837884769235745  0.0012891597261023644  -0.003680581181205784  0.0013189163946405794</feature>
            <feature addr="0x324" hide="0" id="0x4510" name="undistort" rw="3"/>
            <feature addr="0x304" hide="0" id="0x1301" inc="1" max="1088" min="3" name="exposure time" rw="3" writableAtRun="1"/>
            <feature addr="0x310" hide="0" id="0x1303" inc="1" max="255" min="0" name="gain" rw="3" writableAtRun="1"/>
            <feature addr="0x328" hide="0" id="0x1524" inc="1" max="3" min="0" name="analog gain" rw="3" writableAtRun="1"/>
    </component>
    <component addr="0x04000000" id="0x00080000" name="rightIR">
            <feature addr="0x18" hide="0" id="0x3109" name="image mode" rw="1">
                    <entry name="mono8 1280x960" value="0x105003c0"/>
            </feature>
            <feature addr="0x10" hide="0" id="0x1104" name="image width" rw="1">1280</feature>
            <feature addr="0x14" hide="0" id="0x1105" name="image height" rw="1">960</feature>
            <feature hide="1" id="0x1003" name="intrinsic width" rw="1">1280</feature>
            <feature hide="1" id="0x1004" name="intrinsic height" rw="1">960</feature>
            <feature hide="0" id="0x7000" name="intrinsic" rw="1"> 1153.1756686599747 0.0 645.7794279091883  0.0 1153.247857562341 477.5900542804228  0.0 0.0 1.0</feature>
            <feature hide="0" id="0x7006" name="distortion" rw="1"> 0.09000588948228815  0.4048078233341836  0.002537615602834743  0.00243521069386387  -0.4136313892132548  0.3414723226571538  0.4334024855000957  -0.45811370081414665  -0.006109400262453935  0.001311266546198108  -0.005340532631811117  0.0014391258447545106</feature>
            <feature hide="0" id="0x7001" name="rightIR to leftIR extrinsic" rw="1">  0.999983982368202 -0.004615926942824983 -0.003275396997271765 -78.83403406436271  0.004589377817262036 0.9999569267128814 -0.008067362033506272 -0.28954067451799403  0.0033124942689244548 0.00805220077914965 0.9999620940037328 -1.0014943602949653  0 0 0 1</feature>
            <feature bind="0x00044510"/>
            <feature addr="0x304" hide="0" id="0x1301" inc="1" max="1088" min="3" name="exposure time" rw="3" writableAtRun="1"/>
            <feature addr="0x310" hide="0" id="0x1303" inc="1" max="255" min="0" name="gain" rw="3" writableAtRun="1"/>
            <feature addr="0x328" hide="0" id="0x1524" inc="1" max="3" min="0" name="analog gain" rw="3" writableAtRun="1"/>
    </component>
    <component addr="0x05000000" id="0x00100000" name="RGB">
            <feature addr="0x18" hide="0" id="0x3109" name="image mode" rw="3">
                    <entry name="BAYER8GB_1280x960" value="0x115003c0"/>
            </feature>
            <feature addr="0x10" hide="0" id="0x1104" name="image width" rw="1" volatile="1"/>
            <feature addr="0x14" hide="0" id="0x1105" name="image height" rw="1" volatile="1"/>
            <feature hide="1" id="0x1003" name="intrinsic width" rw="1">1280</feature>
            <feature hide="1" id="0x1004" name="intrinsic height" rw="1">960</feature>
            <feature addr="0x304" hide="0" id="0x1301" inc="1" max="1088" min="3" name="exposure time" rw="3" writableAtRun="1"/>
            <feature hide="0" id="0x7000" name="rgb intrinsic" rw="1"> 1152.92690195  0.0  634.540627076  0.0  1152.75694939  440.080319904  0.0  0.0  1.0</feature>
            <feature hide="0" id="0x7001" name="rgb to leftIR extrinsic" rw="1"> 0.99999518914  0.000830527430246  -0.00298863180135  23.8872194727  -0.000878566337645  0.99986986161  -0.0161086301164  -0.028981499247  0.00297486420644  0.0161111783313  0.999865781051  -0.557470684492  0.0  0.0  0.0  1.0</feature>
            <feature hide="0" id="0x7006" name="distortion" rw="1">0.144952855209  0.388778511355  -0.00155739319143  -0.000416074350025  -0.274502827939  0.40073031408  0.400732028738  -0.254651882242  -0.000425018938173  0.000449264517346  0.00270830941931  -0.00113538552215</feature>
            <feature addr="0x318" hide="0" id="0x1520" inc="1" max="255" min="0" name="r gain" rw="3" writableAtRun="1"/>
            <feature addr="0x31c" hide="0" id="0x1521" inc="1" max="255" min="0" name="g gain" rw="3" writableAtRun="1"/>
            <feature addr="0x320" hide="0" id="0x1522" inc="1" max="255" min="0" name="b gain" rw="3" writableAtRun="1"/>
            <feature addr="0x328" hide="0" id="0x1524" inc="1" max="3" min="0" name="analog gain" rw="3" writableAtRun="1"/>
    </component>
    <component addr="0x07000000" id="0x00400000" name="laser">
            <feature addr="0x500" hide="0" id="0x1500" inc="1" max="100" min="0" name="power" rw="3" writableAtRun="1"/>
            <feature addr="0x504" hide="0" id="0x4501" name="auto ctrl" rw="3"/>
    </component>
    <component addr="0x08000000" id="0x01000000" name="histogram">
    </component>
</config>
属性定义如下:
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_INT_NTP_SERVER_IP            = 0x0016 | 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;

深度图

深度图为空间中物体的某个点到垂直于左摄像头光轴并通过镜头光心平面(深度相机光学零点)的垂直距离。
深度图是深度摄像头捕捉到的所有点的深度数据构成的矩阵。深度图中每个深度数据占用2Byte,单位为毫米。没有深度信息的点值为0。为直观的体现不同距离数值,SDK示例程序把深度数据渲染成不同的颜色。

深度图定义

SDK 深度图定义

深度图数据格式

深度图数据格式

点云图

通过测量仪器得到的物体外观表面的点数据集合是点云。使用深度摄像头得到的点云信息为三维坐标(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);

数据接收

深度相机通过USB或者以太网接口输出深度数据, 上位机通过 SDK 的 FetchFrame (主动获取)API获取深度图像数据。
深度相机的数据输出 与 上位机之间通过 FRAME BUFFER QUEUE 进行缓冲。在 QUEUE 中的 FRAME BUFFER 全部被占用的情况下, 深度相机会停止数据发送。上位机获取图像数据后,应及时调用 TYEnqueueBuffer 归还FRAME BUFFER, 防止相机发送的图像数据流被阻塞。如果上位机接收或者数据处理能力低于深度相机的图像输出能力, 可使用软件触发或者硬件触发的方式限制图像计算和输出的帧率,同时也可以降低相机功耗。SDK 例程 SimpleView_Callback 和 SimpleView_FetchFrame 分别提供了在独立应用线程进行图像应用处理 和 直接在图像收取线程中进行图像应用处理的两种框架示例。

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_INT_NTP_SERVER_IP = 0x0016 | TY_FEATURE_INT,

网络相机的NTP服务器IP地址,默认使用时间服务器为 cn.ntp.org.cn

  • 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*)&param, 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*)&param, 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*)&param, 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*)&param, sizeof(param)));
}
  • TY_INT_TRIGGER_DELAY_US = 0x0206 | TY_FEATURE_INT,

延迟触发。深度相机设备 收到触发指令或者硬件触发信号后,延时 TY_INT_TRIGGER_DELAY_US 时间后进行图像采集, 单位是微秒。最大延迟时间1300000微秒。

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时,该属性不能使用。

Note

  1. 各种触发模式的硬件连接方式请参考 外部触发工作模式

  2. 软件实现请参考SDK的Sample例程。

链路监测

  • 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

模拟曝光增益。红外或者彩色摄像头组件的模拟曝光增益设置。不同光学传感器、不同帧率配置下的可调增益范围不同。

AEC/AGC 的控制策略
AEC/AGC 都是基于亮度进行调节的,AEC 调节曝光时间,AGC 调节增益值,最终使图像亮度落在设定亮度阈值范围内。
在整个 AEC/AGC 过程中,不是独立的调整 sensor 的曝光时间或者增益,调整策略为: 曝光时间优先,曝光时间已经最长无法继续调整时,调整增益。
以当前图像过暗的情况为例,调整的先后顺序为: 1不开启任何增益,直到曝光时间达到上限; 2曝光时间达到上限后,再开始调整增益。需要明确指出的是, 增益开启, 将导致噪声呈倍数放大; 而曝光时间加大,则有助于提升信噪比。反之,当图像过亮时,则优先关闭增益,当所有增益关闭,图像仍旧过亮,才会降低曝光时间.

红外投射器控制

  • 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 初始化设备对象等数据结构。

打开设备

1 获取设备列表
初次获取设备信息时可以通过 selectDevice() 查询已连接的设备。
对于USB接口的深度相机设备,初次获取设备信息时可以通过该函数查询已连接的设备数量,并获得所有已连接的列表。在已知设备ID的情况下,或者网络设备,可以不调用该函数查询。
2 打开设备
TYOpenDevice
TYOpenDeviceWithIP
对于USB设备可以通过TYOpenDevice()打开设备。对于网络设备可以通过TYOpenDeviceWithIP()打开设备。

配置组件(component)

1 查询设备的component 状态
TYGetComponentIDs 获取设备支持的组件信息。
TYGetEnabledComponents 获取设备已经打开的组件信息。
2 配置 component
TYEnableComponents
TYDisableComponents

每个设备打开后都必须使能或者配置各个组件,默认情况下只有虚拟组件TY_COMPONENT_DEVICE是使能状态。多个设备可以通过 位或 方式同时使能。

int32_t componentIDs = TY_COMPONENT_DEPTH_CAM | TY_COMPONENT_RGB_CAM;
TYEnableComponents(hDevice, componentIDs);

配置属性(feature)

查询指定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);

分配深度数据存储空间

按照实际查询函数返回的 framebuffer 的大小分配两组 Buffer 空间,并传递给底层驱动缓冲队列,作为数据获取的通道。

驱动内部维护一个缓冲队列(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:主触发模式

相机工作在 触发模式,通过触发输出接口、以指定的频率持续发送硬件触发信号,相机自身和其他被触发相机按照该信号频率输出图像。

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)));

Note

  1. 在主触发模式下,(不连接其他从触发模式相机)该相机可以按照指定的帧率平滑的输出图像。该功能可以用来指定相机的出图帧率,适用于需要特定帧率接收图像或者图像数据处理能力有限的平台。

启动深度采集

TYStartCapture | 如果深度相机工作在触发接入模式(TY_TRIGGER_MODE_TRIG_SLAVE)下,可以使用软件触发接口函数TYSendSoftTrigger(),通过USB或者以太网发送指令,控制相机图像采集的时机。

获取帧数据

TYFetchFrame | 主动获取深度数据模式下,应用可调用该接口获取深度数据。注意回调函数模式下不需要调用。 | 获取数据后,用户程序进行运算处理时,应采用独立线程,避免堵塞图像获取线程的运转。

停止采集

TYStopCapture 停止图像数据采集,相机停止深度数据计算和输出。

关闭设备

TYCloseDevice关闭设备,TYCloseInterface释放占用的接口。

释放API

TYDeinitLib释放API后,需要释放分配的内存资源,避免内存泄露。