API 详解

库加载与卸载

调用 Camport SDK 控制相机获取图像前,首先应完成 Camport SDK 库的加载动作,退出应用前应完成库文件的卸载操作。

inline TY_STATUS    TYInitLib                 (void);
TY_CAPI             TYDeinitLib               (void);

获取 Camport 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 的设备状态。每一台 Percipio 相机拥有独立的设备 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, TY_FW_ERRORCODE* outFwErrorcode);

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, bool reboot);

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];///<device serial number
    char                vendorName[32];
    char                userDefinedName[32];
    char                modelName[32];///<device model name
    TY_VERSION_INFO     hardwareVersion; ///<deprecated
    TY_VERSION_INFO     firmwareVersion;///<deprecated
    union {
      TY_DEVICE_NET_INFO netInfo;
      TY_DEVICE_USB_INFO usbInfo;
    };
    char                buildHash[256];
    char                configVersion[256];
    char                reserved[256];
}TY_DEVICE_BASE_INFO;

打开设备的一般操作如下:

LOGD("Init lib");
ASSERT_OK( TYInitLib() );
TY_VERSION_INFO ver;
ASSERT_OK( TYLibVersion(&ver) );
LOGD("     - lib version: %d.%d.%d", ver.major, ver.minor, ver.patch);

std::vector<TY_DEVICE_BASE_INFO> selected;
ASSERT_OK( selectDevice(TY_INTERFACE_ALL, ID, IP, 1, selected) );
ASSERT(selected.size() > 0);
TY_DEVICE_BASE_INFO& selectedDev = selected[0];

ASSERT_OK( TYOpenInterface(selectedDev.iface.id, &hIface) );
ASSERT_OK( TYOpenDevice(hIface, selectedDev.id, &handle) );

其中, selectDevice 函数封装如下:

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

关闭设备的一般操作如下:

ASSERT_OK( TYCloseDevice(hDevice));
ASSERT_OK( TYCloseInterface(hIface) );

组件控制

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

TYEnqueueBuffer 把分配的帧缓冲推入缓冲队列。

TY_CAPI             TYEnqueueBuffer           (TY_DEV_HANDLE hDevice, void* buffer, uint32_t bufferSize);

TYClearBufferQueue 清空帧缓冲区的缓冲队列。在系统运行过程中,动态调整组件个数时,需要清除 SDK 内部的缓冲队列,并重新申请和推入缓冲队列。

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

对时设定

TY_ENUM_TIME_SYNC_TYPE = 0x0211 | TY_FEATURE_ENUM,

TY_BOOL_TIME_SYNC_READY = 0x0212 | TY_FEATURE_BOOL,

设置深度相机对时类型,枚举型属性。确认对时设置,布尔型属性。深度相机支持与 HOST、NTP 服务器、 PTP 服务器或 CAN 对时。

小技巧

设置 NTP 对时后,需配置 NTP 服务器,配置方法请参见 网络配置

定义:

typedef enum TY_TIME_SYNC_TYPE_LIST
{
    TY_TIME_SYNC_TYPE_NONE = 0,
    TY_TIME_SYNC_TYPE_HOST = 1,
    TY_TIME_SYNC_TYPE_NTP = 2,
    TY_TIME_SYNC_TYPE_PTP = 3,
    TY_TIME_SYNC_TYPE_CAN = 4,
    TY_TIME_SYNC_TYPE_PTP_MASTER = 5,
}TY_TIME_SYNC_TYPE_LIST;
typedef int32_t TY_TIME_SYNC_TYPE;

操作:通过 TYSetEnum() 的接口设置对时类型,再通过读取 TY_BOOL_TIME_SYNC_READY 确认是否完成对时。

示例:设置对时类型为与 HOST 对时。设置该对时类型后,主机自动下发当前时间,随后每隔 6s下发对时一次。

LOGD("Set type of time sync mechanism");
ASSERT_OK(TYSetEnum(hDevice, TY_COMPONENT_DEVICE, TY_ENUM_TIME_SYNC_TYPE, TY_TIME_SYNC_TYPE_HOST));
LOGD("Wait for time sync ready");
while (1) {
    bool sync_ready;
    ASSERT_OK(TYGetBool(hDevice, TY_COMPONENT_DEVICE, TY_BOOL_TIME_SYNC_READY, &sync_ready));
    if (sync_ready) {
        break;
    }
    MSLEEP(10);
}

工作模式配置

TY_STRUCT_TRIGGER_PARAM = 0x0523 | TY_FEATURE_STRUCT,

深度相机的工作模式配置。结构体属性。定义如下:

typedef 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_SIG_PASS    = 18,
    TY_TRIGGER_MODE_PER_PASS    = 19,
    TY_TRIGGER_MODE_TIMER_LIST  = 20,
    TY_TRIGGER_MODE_TIMER_PERIOD= 21,
}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;

//@see sample SimpleView_TriggerMode, only for TY_TRIGGER_MODE_SIG_PASS/TY_TRIGGER_MODE_PER_PASS
typedef struct TY_TRIGGER_PARAM_EX
{
    TY_TRIGGER_MODE   mode;
    union
    {
        struct
        {
            int8_t    fps;
            int8_t    duty;
            int32_t   laser_stream;
            int32_t   led_stream;
            int32_t   led_expo;
            int32_t   led_gain;
        };
        struct
        {
            int32_t   ir_gain[2];
        };
        int32_t   rsvd[32];
    };
}TY_TRIGGER_PARAM_EX;

//@see sample SimpleView_TriggerMode, only for TY_TRIGGER_MODE_TIMER_LIST
  • 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,多台从设备(相机)工作在模式 1,以实现多台深度相机级联触发,同时采集图像。

    主设备收到上位机发送的软件触发信号后,通过硬件 TRIG_OUT 接口输出触发信号,同时触发自身采集并输出深度图;从设备收到主设备的硬件触发信号后,采集并输出深度图。

    LOGD("=== Set trigger mode");
    if (((strcmp(selected[i].id, list[0]) == 0) && (list.size() > 0))
            || ((count == 0) && (list.size() == 0))) {
        LOGD("=== set master device, id: %s", cams[count].sn);
        cams[count].tag = std::string(cams[count].sn) + "_master";
        TY_TRIGGER_PARAM param;
        param.mode = TY_TRIGGER_MODE_M_SIG;
        ASSERT_OK(TYSetStruct(cams[count].hDev, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, (void*)&param, sizeof(param)));
    } else {
        cams[count].tag = std::string(cams[count].sn) + "_slave";
        TY_TRIGGER_PARAM param;
        param.mode = TY_TRIGGER_MODE_SLAVE;
        ASSERT_OK(TYSetStruct(cams[count].hDev, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, (void*)&param, sizeof(param)));
    }
    
  • TY_TRIGGER_MODE_M_PER 配置主设备(相机)工作在模式 3,多台从设备(相机)工作在模式 1,以实现多台深度相机按照设置的帧率级联触发,同时采集图像。

    主设备按照设置的帧率,通过硬件 TRIG_OUT 接口输出触发信号,同时触发自身采集并输出深度图;从设备收到主设备的硬件触发信号后,采集并输出深度图。

    备注

    1. 设置的帧率不能超过相机处理能力,即工作模式 0 且 TY_BOOL_CMOS_SYNC=false 下相机的出图帧率。

    2. 在工作模式 3 下(不连接从设备),主设备可以按照设置的帧率平滑的输出图像,适用于需要特定帧率接收图像或者图像数据处理能力有限的平台。

    LOGD("=== Set trigger mode");
    
    if (((strcmp(selected[i].id, list[0]) == 0) && (list.size() > 0))
        || ((count == 0) && (list.size() == 0))) {
        LOGD("=== set master device");
        cams[count].tag = std::string(cams[count].sn) + "_master";
        TY_TRIGGER_PARAM param;
        param.mode = TY_TRIGGER_MODE_M_PER;
        param.fps = 5;
        ASSERT_OK(TYSetStruct(cams[count].hDev, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, (void*)&param, sizeof(param)));
    }
    else {
        cams[count].tag = std::string(cams[count].sn) + "_slave";
        TY_TRIGGER_PARAM param;
        param.mode = TY_TRIGGER_MODE_SLAVE;
        ASSERT_OK(TYSetStruct(cams[count].hDev, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, (void*)&param, sizeof(param)));
    }
    
  • TY_TRIGGER_MODE_SIG_PASS 配置深度相机工作在模式 18,相机每接收到一次软触发指令或硬触发信号后,便按照设置的帧率,以 1+duty 的方式采集一轮图像并输出图像数据(1:出 1 次泛光;duty:出 duty 次激光)。

    备注

    设置的帧率不能超过相机处理能力,即工作模式 0 且 TY_BOOL_CMOS_SYNC=false 下相机的出图帧率。

    LOGD("=== Set trigger to trig mode 18");
    TY_TRIGGER_PARAM_EX trigger;
    trigger.mode = TY_TRIGGER_MODE_SIG_PASS;
    trigger.fps = 10;           // [1, 15]
    trigger.duty = duty;
    trigger.laser_stream = TY_COMPONENT_DEPTH_CAM | TY_COMPONENT_RGB_CAM;
    trigger.led_stream = TY_COMPONENT_IR_CAM_LEFT | TY_COMPONENT_RGB_CAM;
    trigger.led_expo = 1088;    // [3, 1088]
    trigger.led_gain = 32;      // [0, 255]
    ASSERT_OK(TYSetStruct(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM_EX, &trigger, sizeof(trigger)));
    
  • TY_TRIGGER_MODE_PER_PASS 配置深度相机工作在模式 19,相机接收到一次软触发或者硬触发信号后,便按照设置的帧率,以 1+duty 的方式连续采集图像并输出图像数据(1:出 1 次泛光;duty:出 duty 次激光)。

    备注

    设置的帧率不能超过相机处理能力,即工作模式 0 且 TY_BOOL_CMOS_SYNC=false 下相机的出图帧率。

    LOGD("=== Set trigger to trig mode 19");
    TY_TRIGGER_PARAM_EX trigger;
    trigger.mode = TY_TRIGGER_MODE_PER_PASS;
    trigger.fps = 10;           // [1, 15]
    trigger.duty = duty;
    trigger.laser_stream = TY_COMPONENT_DEPTH_CAM | TY_COMPONENT_RGB_CAM;
    trigger.led_stream = TY_COMPONENT_IR_CAM_LEFT | TY_COMPONENT_RGB_CAM;
    trigger.led_expo = 1088;    // [3,1088]
    trigger.led_gain = 32;      // [0, 255]
    ASSERT_OK(TYSetStruct(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM_EX, &trigger, sizeof(trigger)));
    
  • TY_TRIGGER_MODE_TIMER_LIST 配置深度相机工作在模式 20(列表式定时触发模式),相机根据设置的触发开始时间(start_time_us)、触发次数(offset_us_count)和每两帧的时间间隔数组(offset_us_list[ ]),定时采集(1 + offset_us_count)张图像并输出图像数据。此工作模式要求相机先启动 PTP 对时,详情请参考 对时设定

    定义:

    typedef struct TY_TRIGGER_TIMER_LIST
    {
        uint64_t  start_time_us; // 0 for disable
        uint32_t  offset_us_count; // length of offset_us_list
        uint32_t  offset_us_list[50]; // used in TY_TRIGGER_MODE_TIMER_LIST mode
    }TY_TRIGGER_TIMER_LIST;
    

    操作:

    1. 通过 TY_TRIGGER_MODE_TIMER_LIST 配置深度相机工作在模式 20。

      LOGD("=== Set trigger to trig mode 20");
      TY_TRIGGER_PARAM trigger;
      trigger.mode = TY_TRIGGER_MODE_TIMER_LIST;
      ASSERT_OK(TYSetStruct(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, &trigger, sizeof(trigger)));
      
    2. 通过 TY_TRIGGER_TIMER_LIST 设置一个列表触发定时器,offset_us_count ≤ 50。

      LOGD("=== Set trigger timer list");
      TY_TRIGGER_TIMER_LIST list_timer;
      list_timer.start_time_us = (getSystemTime() + 3000) * 1000;
      list_timer.offset_us_count = 4;
      list_timer.offset_us_list[0] = 1000000;
      list_timer.offset_us_list[1] = 1000000;
      list_timer.offset_us_list[2] = 1000000;
      list_timer.offset_us_list[3] = 1000000;
      ASSERT_OK(TYSetStruct(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_TIMER_LIST, &list_timer, sizeof(list_timer)));
      
    3. 若需关闭列表触发定时器,则将 start_time_us 设置为 0。

      TY_TRIGGER_TIMER_LIST list_timer;
      list_timer.start_time_us = 0;
      ASSERT_OK(TYSetStruct(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_TIMER_LIST, & list_timer, sizeof(list_timer)));
      
  • TY_TRIGGER_MODE_TIMER_PERIOD 配置深度相机工作在模式 21(周期式定时触发模式),相机根据设置触发开始时间(start_time_us)、触发次数(trigger_count)和触发时间间隔(peroid_us),每间隔 peroid_us 采集⼀帧图像,共采集 trigger_count 张图像并输出图像数据。此工作模式要求相机先启动 PTP 对时,详情请参考 对时设定

    定义:

    typedef struct TY_TRIGGER_TIMER_PERIOD
    {
        uint64_t  start_time_us; // 0 for disable
        uint32_t  trigger_count;
        uint32_t  period_us; // used in TY_TRIGGER_MODE_TIMER_PERIOD mode
    }TY_TRIGGER_TIMER_PERIOD;
    

    操作:

    1. 通过 TY_TRIGGER_MODE_TIMER_PERIOD 配置深度相机工作在模式 21。

      LOGD("=== Set trigger to trig mode 21");
      TY_TRIGGER_PARAM trigger;
      trigger.mode = TY_TRIGGER_MODE_TIMER_PERIOD;
      ASSERT_OK(TYSetStruct(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, &trigger, sizeof(trigger)));
      
    2. 通过 TY_TRIGGER_TIMER_PERIOD 设置一个周期触发定时器。

      TY_TRIGGER_TIMER_PERIOD period_timer;
      period_timer.start_time_us = (getSystemTime() + 3000) * 1000;
      period_timer.trigger_count = 10;
      period_timer.period_us = 1000000;
      ASSERT_OK(TYSetStruct(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_TIMER_PERIOD, &period_timer, sizeof(period_timer)));
      
    3. 若需关闭周期触发定时器,则将 start_time_us 设置为 0。

      TY_TRIGGER_TIMER_PERIOD period_timer;
      period_timer.start_time_us = 0;
      ASSERT_OK(TYSetStruct(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_TIMER_PERIOD, & period_timer, sizeof(period_timer)));
      

启停管理

TYStartCapture 设备组件、组件特性功能配置完成后,调用该接口启动设备,开始图像采集和计算输出,运行结束后调用 TYStopCapture 停止图像采集操作。

TY_CAPI             TYStartCapture            (TY_DEV_HANDLE hDevice);
TY_CAPI             TYStopCapture             (TY_DEV_HANDLE hDevice);

软件触发

TYSendSoftTrigger 相机设备工作于模式 1、模式 2 时(请参考 工作模式 ),可以使用软件触发接口函数 TYSendSoftTrigger(),通过 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 获取深度图像数据。

深度相机的数据输出与上位机之间通过 frameBuffer Queue 进行缓冲。在 Queue 中的 frameBuffer 全部被占用的情况下,深度相机会停止数据发送。为避免相机发送的图像数据流被阻塞,上位机获取图像数据后,应及时调用 TYEnqueueBuffer 归还 frameBuffer。

如果上位机接收或者数据处理能力低于深度相机的图像输出能力,可使用软件触发或者硬件触发的方式限制图像计算和输出的帧率,同时也可以降低相机功耗。SDK 示例程序 SimpleView_Callback 和 SimpleView_FetchFrame 分别提供了在独立应用线程进行图像应用处理和直接在图像收取线程中进行图像应用处理的两种框架示例。

FetchFrame 数据接收函数,输入设备句柄并在指定的时间内等待有效数据帧,指定时间内没有收到数据帧,函数会返回并报告错误状态。

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 对应属性的信息。

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 privilege
    bool            writableAtRun;      ///< feature can be written while capturing
    char            reserved0[1];
    TY_COMPONENT_ID componentID;        ///< owner of this feature
    TY_FEATURE_ID   featureID;          ///< feature unique id
    char            name[32];           ///< describe string
    int32_t         bindComponentID;    ///< component ID current feature bind to
    int32_t         bindFeatureID;      ///< feature ID current feature bind to
    char            reserved[252];
}TY_FEATURE_INFO;

属性分类操作接口

属性操作 API 通常包含的输入参数有相机句柄 hDevice、属性所属组件的 ID componentID、待操作属性 ID featureID、待接收或者写入的数据参数, 依据不同的属性类型选择不同的操作 API,即遵循相机、组件、属性的隶属关系和属性类型进行操作。

组件属性的数据类型共有 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);

属性说明

不同型号的 Percipio 深度相机拥有不同的属性配置,通过遍历深度相机的组件和属性列表,可以获取产品准确的配置信息。建议使用 SDK 示例程序 DumpAllFeatures 遍历设备支持的属性。

组件光学参数

  • TY_STRUCT_CAM_INTRINSIC = 0x0000 | TY_FEATURE_STRUCT,

    红外图像传感器组件、彩色图像传感器组件、深度图像传感器组件的内参。结构体型属性,数据结构为 3x3 浮点数组。定义如下:

    ///  a 3x3 matrix
    /// |.|.|.|
    /// | --|---|---|
    /// | 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 浮点数组。定义如下:

    /// a 4x4 matrix
    ///  |.|.|.|.|
    ///  |---|----|----|---|
    ///  |r11| r12| r13| t1|
    ///  |r21| r22| r23| t2|
    ///  |r31| r32| r33| t3|
    ///  | 0 |   0|   0|  1|
    // 该参数用于初始坐标系中的坐标点向新的坐标系转换
    // R11  R12  R13  T1分别为x在新的坐标系中x y z三轴的旋转系数及偏移量
    // R21  R22  R23  T2分别为y在新的坐标系中x y z三轴的旋转系数及偏移量
    // R31  R32  R33  T3分别为z在新的坐标系中x y z三轴的旋转系数及偏移量
    typedef struct TY_CAMERA_EXTRINSIC
    {
        float data[4*4];
    }TY_CAMERA_EXTRINSIC;
    
    [r11, r12, r13, t1,
     r21, r22, r23, t2,
     r31, r32, r33, t3,
     0,   0,   0,  1]
    
  • TY_STRUCT_CAM_DISTORTION = 0x0006 | TY_FEATURE_STRUCT,

    红外图像传感器或者彩色图像传感器组件的光学畸变参数。结构体型属性,数据结构为 12 个元素的浮点数组。定义如下:

    // k1 k2 k3 k4 k5 k6是基于理想模型的径向畸变系数
    // p1 p2 为切向畸变系数
    // s1 s2 s3 s4 为薄棱镜畸变系数
    ///camera distortion parameters
    typedef struct TY_CAMERA_DISTORTION
    {
        float data[12];///<Definition is compatible with opencv3.0+ :k1,k2,p1,p2,k3,k4,k5,k6,s1,s2,s3,s4
    }TY_CAMERA_DISTORTION;
    
  • TY_STRUCT_CAM_CALIB_DATA = 0x0007 | TY_FEATURE_STRUCT,

    红外图像传感器组件、彩色图像传感器组件的标定参数组合,可获取内参数据、外参数据和畸变数据。结构体内包含相机出厂前标定的标定尺寸,内参,外参,畸变参数。该标定参数是在特定分辨率下标定计算出来的,与图像的分辨率存在转换关系。SDK 提供的相关 API 会根据实际图像分辨率自动调整输出的参数。

    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;
    

    示例:获取标定参数,详情请参考 SDK 示例程序 SimpleView_Registration。

    struct CallbackData {
      int             index;
      TY_ISP_HANDLE   IspHandle;
      TY_DEV_HANDLE   hDevice;
      DepthRender*    render;
      DepthViewer*    depthViewer;
      bool            needUndistort;
    
      float           scale_unit;
    
      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 网关。

    const char * newIP = "0.0.0.0";
    const char * newNetmask = "0.0.0.0";
    const char * newGateway = "0.0.0.0";
    
    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(hDevice, 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(hDevice, 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(hDevice, 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

    网络上两个物理数据包的发送间隔,用于降低网络数据发送拥塞程度。默认为 100 微秒。

  • TY_INT_PACKET_SIZE = 0x0017 | TY_FEATURE_INT,

    网络深度相机数据传输时,分组发送到链路上最大传输单元的大小,范围 100 ~ 1500,默认为 1500。

  • TY_INT_ACCEPTABLE_PERCENT = 0x0015 | TY_FEATURE_INT,

    网络深度相机的丢包率阈值。若上位机收取的图像数据百分比低于丢包率阈值时,则丢弃该帧数据;反之,则输出该帧图像数据。

  • TY_INT_NTP_SERVER_IP = 0x0016 | TY_FEATURE_INT,

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

    以 192.168.2.117 为例,转换 IP 地址:

    uint32_t ntp_server = (192<<24)|(168<<16)|(2<<8)|117;
    
  • TY_STRUCT_CAM_STATISTICS = 0x00ff | TY_FEATURE_STRUCT,

    网络深度相机统计数据信息。结构体型属性,定义如下:

    typedef struct TY_CAMERA_STATISTICS
    {
        uint64_t   packetReceived;
        uint64_t   packetLost;
        uint64_t   imageOutputed;
        uint64_t   imageDropped;
        uint8_t   rsvd[1024];
    }TY_CAMERA_STATISTICS;
    

触发设置

  • TY_INT_FRAME_PER_TRIGGER = 0x0202 | TY_FEATURE_INT,

    深度相机接收到一次软触发指令或者硬件触发信号后,输出的图像的帧数量。默认输出 1 帧。

  • TY_INT_TRIGGER_DELAY_US = 0x0206 | TY_FEATURE_INT,

    延迟触发。深度相机收到硬件触发信号后,延时设置的延迟时间后进行图像采集,单位是微秒。最大延迟时间 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, the maximum value is 1.3s
    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 输出控制。在深度相机工作在模式 1 时,可以通过该属性控制触发输出接口工作在普通 IO 模式。

    • 若相机触发输出信号默认为高电平,该值设置为 false 时,输出信号默认为高电平;该值设置为 true 时,输出信号默认为低电平。

    • 若相机触发输出信号默认为低电平,该值设置为 false 时,输出信号默认为低电平;该值设置为 true 时,输出信号默认为高电平。

    深度相机工作在模式 2 或者模式 3 时,该属性不能使用。

备注

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

  2. 软件实现请参考 SDK 示例程序 SimpleView_TriggerMode1。

链路监测

  • TY_BOOL_KEEP_ALIVE_ONOFF = 0x0203 | TY_FEATURE_BOOL

    深度相机状态保持。SDK 与相机维持通信状态保持机制。默认为 true。一旦发生连接异常,将激活 TYRegisterEventCallback 注册的回调函数。用户可在回调函数中进行重连等异常处理操作,重连示例代码请参见 回调函数注册

  • TY_INT_KEEP_ALIVE_TIMEOUT = 0x0204 | TY_FEATURE_INT

    深度相机状态保持时间设置。在该时间内未收到状态保持数据包,则判定系统与设备的连接出现异常。单位是毫秒。USB 相机默认是 15 秒,网络相机默认 3 秒。

曝光设置

  • TY_BOOL_AUTO_AWB = 0x0304 | TY_FEATURE_BOOL,

    自动白平衡控制。自动白平衡功能适用于彩色图像传感器,通过调整 R、G、B 三个通道的数字增益值实现色彩空间的平衡。若要手动设置 R、G、B 三个通道的数字增益,需先关闭自动白平衡功能,否则自动白平衡功能会与手动设置的 R、G、B 通道数字增益冲突,影响图像效果。

  • TY_BOOL_AUTO_EXPOSURE = 0x0300 | TY_FEATURE_BOOL,

    自动曝光控制。图像传感器组件的自动曝光开关。部分深度相机的光学组件支持图像自动曝光。

  • TY_INT_EXPOSURE_TIME = 0x0301 | TY_FEATURE_INT,

    曝光时间。红外或者彩色图像传感器组件的曝光时间设置。可使用 TYGetIntRange 接口查询曝光时间的最大值和最小值。通过 API 设置曝光时间前,如果图像传感器支持自动曝光设置,需要关闭自动曝光设置功能。

    //shutdown the Auto Exposure time function of the rgb image
    ASSERT_OK(TYSetBool(hDevice, TY_COMPONENT_RGB_CAM, TY_BOOL_AUTO_EXPOSURE, false));
    
    //Adjust the Exposure time of the rgb image
    TY_INT_RANGE range;
    ASSERT_OK(TYGetIntRange(hDevice, TY_COMPONENT_RGB_CAM, TY_INT_EXPOSURE_TIME, &range));
    int32_t tmp;
    ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_RGB_CAM, TY_INT_EXPOSURE_TIME, (range.min + range.max) / 2));
    ASSERT_OK(TYGetInt(hDevice, TY_COMPONENT_RGB_CAM, TY_INT_EXPOSURE_TIME, &tmp));
    if (tmp != (range.min + range.max) / 2)
    {
        LOGD("set rgb image exposure time failed");
    }
    
  • TY_BOOL_AUTO_GAIN = 0x0302 | TY_FEATURE_BOOL,

    自动增益控制。彩色图像传感器组件的自动增益调整开关。部分深度相机的光学组件允许自动调整增益。

  • TY_INT_ANALOG_GAIN = 0x0524 | TY_FEATURE_INT,

    模拟曝光增益。红外或者彩色图像传感器组件的模拟曝光增益设置。不同光学传感器、不同帧率配置下的增益可调范围不同。通过 API 设置彩色图像传感器组件的模拟曝光增益时,需要先关闭自动增益调整功能。

    ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_IR_CAM_LEFT, TY_INT_ANALOG_GAIN, 4));
    
    //shutdown the Auto Gain function of the RGB image
    ASSERT_OK(TYSetBool(hDevice, TY_COMPONENT_RGB_CAM, TY_BOOL_AUTO_GAIN, false));
    ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_RGB_CAM, TY_INT_ANALOG_GAIN, 4));
    
  • 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));
    
  • TY_INT_R_GAIN = 0x0520 | TY_FEATURE_INT,

  • TY_INT_G_GAIN = 0x0521 | TY_FEATURE_INT,

  • TY_INT_B_GAIN = 0x0522 | TY_FEATURE_INT,

    彩色传感器数字曝光增益。彩色图像传感器模组的数字曝光增益需要通过 R、G、B 三通道独立设置。通过 API 设置增益时,如果传感器支持 AWB 设置,需要先关闭 AWB 功能。

    //shutdown the AWB function of the RGB image
    ASSERT_OK(TYSetBool(hDevice, TY_COMPONENT_RGB_CAM, TY_BOOL_AUTO_AWB, false));
    
    ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_RGB_CAM, TY_INT_R_GAIN, 2));
    ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_RGB_CAM, TY_INT_G_GAIN, 2));
    ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_RGB_CAM, TY_INT_B_GAIN, 2));
    

自动曝光ROI

TY_STRUCT_AEC_ROI

设置图像传感器的 AEC/AGC 配置的统计范围,图像传感器将依据该范围内的图像数据特征自动调整曝光时间和增益,实现更好的图像效果。

下面代码将图像左上角 100*100 的区域设置为 ROI 区域,AEC 仅统计该区域:

TY_AEC_ROI_PARAM aec_roi_param;
aec_roi_param.x = 0;
aec_roi_param.y = 0;
aec_roi_param.w = 100;
aec_roi_param.h = 100;
TYSetStruct(hDevice, TY_COMPONENT_RGB_CAM, TY_STRUCT_AEC_ROI, &aec_roi_param, sizeof(TY_AEC_ROI_PARAM));

图像集成时间

TY_INT_CAPTURE_TIME_US

该接口用于读取触发模式下相机实际的图像集成时间,单位为微秒。

相机在接收到触发信号后,进入曝光阶段,持续 CAPTURE_TIME_US 时间。此时,相机视野内的物体应保持静止,否则会影响图像质量。曝光阶段结束后,相机进入数据处理阶段,此时,相机视野内的物体可以运动,不会影响已拍摄的图像。

因此,用户可以先读取相机实际的图像集成时间,从而确定物体(如机器手)运动的时间点,以避免在曝光期间进入相机视野,影响相机成像。

读取 capture_time 的示例:

int32_t capture_time;
TYGetInt(hDevice, TY_COMPONENT_DEVICE, TY_INT_CAPTURE_TIME_US, &capture_time);
printf("get capture time %d\n", capture_time);

图像同步

TY_BOOL_CMOS_SYNC = 0x0205 | TY_FEATURE_BOOL,

双目深度计算使用的左、右两幅图像曝光完全同步时,可以获得最好的深度图数据;当左、右两幅红外图像曝光不完全同步,时间相差较小时,也可以输出深度图像数据,数据精度稍差。左右图像完全同步时,图像输出帧率低于不完全同步时图像输出帧率。依据实际使用场景对深度图质量和帧率的需要,可以通过该布尔型属性对相机的工作配置进行修改。

bool tmp;
ASSERT_OK(TYSetBool(hDevice, TY_COMPONENT_DEVICE, TY_BOOL_CMOS_SYNC, false));
ASSERT_OK(TYGetBool(hDevice, TY_COMPONENT_DEVICE, TY_BOOL_CMOS_SYNC, &tmp));
if (tmp != false) {
   LOGD("==set TY_BOOL_CMOS_SYNC failed !");
}

数据流异步

TY_ENUM_STREAM_ASYNC

深度相机的红外图像、彩色图像和深度图像数据输出时,支持立即输出已获取到的图像数据。如 -IX 系列及 PS 系列产品,红外和彩色图像获取时间较早,深度数据计算时间较长,可以先输出红外和彩色数据,供上位机进行必要的计算。

typedef enum TY_STREAM_ASYNC_MODE_LIST
{
    TY_STREAM_ASYNC_OFF         = 0,
    TY_STREAM_ASYNC_DEPTH       = 1,
    TY_STREAM_ASYNC_RGB         = 2,
    TY_STREAM_ASYNC_DEPTH_RGB   = 3,
    TY_STREAM_ASYNC_ALL         = 0xff,
}TY_STREAM_ASYNC_MODE_LIST;

ASSERT_OK(TYSetEnum(hDevice, TY_COMPONENT_DEVICE, TY_ENUM_STREAM_ASYNC, TY_STREAM_ASYNC_ALL));

图像格式设置与处理

图像的格式和分辨率是 ENUM 类型。SDK 头文件中枚举了相机支持的各种图像格式和分辨率。不同相机支持的具体格式不同,可以通过 API 进行查询和设置。

  • TY_ENUM_IMAGE_MODE = 0x0109 | TY_FEATURE_ENUM,

    示例:获取彩色图像支持的图像格式。

    uint32_t n;
    ASSERT_OK(TYGetEnumEntryCount(hDevice, TY_COMPONENT_RGB_CAM, TY_ENUM_IMAGE_MODE, &n));
    LOGD("===         %14s: entry count %d", "", n);
    if (n > 0) {
        std::vector<TY_ENUM_ENTRY> entry(n);
        ASSERT_OK(TYGetEnumEntryInfo(hDevice, TY_COMPONENT_RGB_CAM, TY_ENUM_IMAGE_MODE, &entry[0], n, &n));
        for (uint32_t i = 0; i < n; i++) {
            LOGD("===         %14s:     value(%d), desc(%s)", "", entry[i].value, entry[i].description);
        }
    }
    

    示例:设置彩色图格式为 BAYER8GB,分辨率为 1280*960。

    LOGD("=== Configure feature, set resolution to 1280x960.");
    ASSERT_OK(TYSetEnum(hDevice, TY_COMPONENT_RGB_CAM, TY_ENUM_IMAGE_MODE, TY_PIXEL_FORMAT_BAYER8GB|TY_RESOLUTION_MODE_1280x960));
    

    或者使用图像格式的组合定义 TY_IMAGE_MODE_format_resolution 来配置彩色图像传感器的输出图像格式:

    LOGD("=== Configure feature, set resolution to 1280x960.");
    ASSERT_OK(TYSetEnum(hDevice, TY_COMPONENT_RGB_CAM, TY_ENUM_IMAGE_MODE, TY_IMAGE_MODE_BAYER8GB_1280x960));
    

    示例:设置深度图为 1280x960 格式。

    std::vector<TY_ENUM_ENTRY> image_mode_list(n);
    ASSERT_OK(TYGetEnumEntryInfo(hDevice, TY_COMPONENT_DEPTH_CAM, TY_ENUM_IMAGE_MODE, &image_mode_list[0], n, &n));
    for (int idx = 0; idx < image_mode_list.size(); idx++)
    {
    
        //try to select a 1280x960 resolution
        if (TYImageWidth(image_mode_list[idx].value) == 1280 || TYImageHeight(image_mode_list[idx].value) == 960)
        {
            LOGD("Select Depth Image Mode: %s", image_mode_list[idx].description);
            int err = TYSetEnum(hDevice, TY_COMPONENT_DEPTH_CAM, TY_ENUM_IMAGE_MODE, image_mode_list[idx].value);
            ASSERT(err == TY_STATUS_OK || err == TY_STATUS_NOT_PERMITTED);
            break;
        }
    }
    
  • TY_FLOAT_SCALE_UNIT = 0x010a | TY_FEATURE_FLOAT,

    深度测量值的计算系数。默认值为 1.0,即深度图中每个像素的数据值是实际测得的距离(单位是毫米);当设定值不为 1.0 时,深度图中每个像素的数据值与该系数的乘积可得到实际测得的距离(单位是毫米)。

    该值会影响到最终的深度计算结果。若设定值过小,可能会导致深度计算出现误差。若设定值过大,可能会降低深度计算的精度。

    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,即红外图像传感器组件默认输出未做畸变矫正的图像数据。

    bool hasUndistortSwitch;
    ASSERT_OK( TYHasFeature(hDevice, TY_COMPONENT_IR_CAM_LEFT, TY_BOOL_UNDISTORTION, &hasUndistortSwitch) );
    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),设备会统计并输出左、右红外图像的亮度直方图。

    示例,详情请参考 SDK 示例程序 SimpleView_FetchHisto:

    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 ir cam");
    componentIDs |= TY_COMPONENT_IR_CAM_RIGHT| TY_COMPONENT_IR_CAM_LEFT;
    ASSERT_OK( TYEnableComponents(hDevice, componentIDs) );
    

激光器设置

  • TY_BOOL_LASER_AUTO_CTRL = 0x0501 | TY_FEATURE_BOOL,

    激光器自动调整功能开关,布尔型属性,默认为 true,即深度相机依据深度计算需要,自动开关红外激光器。具体规则如下:

    • TY_BOOL_LASER_AUTO_CTRL= true

      • 有深度图输出,激光器便开启,激光亮度通过 TY_INT_LASER_POWER 设置;

      • 无深度图输出,激光器便关闭。

    • TY_BOOL_LASER_AUTO_CTRL= false

      • 有任何图像输出,激光器都开启,激光亮度通过 TY_INT_LASER_POWER 设置。

      备注

      需要注意的是,FM851-E2 部分型号的表现与上述描述有所不同,在 TY_BOOL_LASER_AUTO_CTRL= false,TY_BOOL_CMOS_SYNC = false 且无深度图输出的情况下,激光器会处于关闭状态。

  • TY_INT_LASER_POWER = 0x0500 | TY_FEATURE_INT,

    激光强度设置。整型属性,设置范围 0~100,默认为 100。通过该属性可设置激光强度,从而调节红外图像传感器成像的亮度。 该属性设置为 0 时,激光器关闭。

    示例:关闭激光发射器自动调整功能并将激光强度设置为 90。

    ASSERT_OK(TYSetBool(hDevice, TY_COMPONENT_LASER, TY_BOOL_LASER_AUTO_CTRL, false));
    ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_LASER, TY_INT_LASER_POWER, 90));
    

泛光设置

  • TY_BOOL_FLASHLIGHT = 0x0213 | TY_FEATURE_BOOL,

    泛光功能开关,布尔型属性,默认为 false。通过该属性可开启泛光功能,利用红外泛光进行相机标定。目前只有 PS 系列支持泛光功能。具体规则如下:

    • TY_BOOL_FLASHLIGHT= true

      • 有深度图输出,泛光灯便关闭;

      • 无深度图输出,泛光灯便开启,泛光亮度通过 TY_INT_FLASHLIGHT_INTENSITY 设置。

    • TY_BOOL_FLASHLIGHT= false

      • 泛光灯关闭。

  • TY_INT_FLASHLIGHT_INTENSITY = 0x0214 | TY_FEATURE_INT,

    泛光强度设置。整型属性,设置范围 0~63,默认为 19。开启泛光功能后,依据实际标定场景,通过该属性设置泛光强度。

    备注

    泛光灯自带过热保护功能,当温度过高时,泛光灯自动熄灭。

示例:开启泛光功能并将泛光强度设置为 63。

ASSERT_OK(TYSetBool(hDevice, TY_COMPONENT_DEVICE, TY_BOOL_FLASHLIGHT, true));
ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_DEVICE, TY_INT_FLASHLIGHT_INTENSITY, 63));

SGBM 属性

与测距范围、精度、帧率相关

  • TY_FLOAT_SCALE_UNIT = 0x010a | TY_FEATURE_FLOAT

    属性说明请参见 TY_FLOAT_SCALE_UNIT

  • TY_INT_SGBM_DISPARITY_NUM = 0x0611 | TY_FEATURE_INT

    设置视差搜索范围。匹配窗口在搜索过程中的视差搜索范围,整型属性。

    设定值越大,相机Z方向的测量范围越大,算力会增加。建议设置成 16 的整数倍。

  • TY_INT_SGBM_DISPARITY_OFFSET = 0x0612 | TY_FEATURE_INT

    设置开始搜索的视差值。整型属性。

    设定值越小,Z方向最大测量值(Zmax)越大,即测量范围越远,但设定值下限受景深影响。

  • TY_INT_SGBM_IMAGE_NUM = 0x0610 | TY_FEATURE_INT

    设置用于深度计算的 IR 图像数量。整型属性。

    设定值越大,输出深度图像质量越好,帧率越小。设定值上限受相机算力影响。

  • TY_INT_SGBM_MATCH_WIN_HEIGHT = 0x0613 | TY_FEATURE_INT

    设置视差匹配窗口的高。整型属性。设定值必须为奇数。

  • TY_INT_SGBM_MATCH_WIN_WIDTH = 0x061A | TY_FEATURE_INT

    设置视差匹配窗口的宽。整型属性。设定值必须为奇数。

    视差匹配窗口(MATCH_WIN_HEIGHT * MATCH_WIN_WIDTH)越大,深度图更加平滑,但是精度会降低。视差匹配窗口越小,深度图显示更多细节,但是出现错误匹配的几率越大。

备注

受相机算力影响,IMAGE_NUM 和 MATCH_WIN_HEIGHT 之间存在一个约束。不同型号的相机约束不同,具体请参见相机的 fetch_config.xml 文件

与图像中边缘像素平滑处理相关

  • TY_INT_SGBM_SEMI_PARAM_P1 = 0x0614 | TY_FEATURE_INT

    相邻像素 (+/-1) 约束惩罚参数 P1。

    设定值越大,深度图越平滑。

    防止出现不连续或不合理的深度值,有效抑制噪声和不连续性。

  • TY_INT_SGBM_SEMI_PARAM_P2 = 0x0615 | TY_FEATURE_INT

    周围像素约束惩罚参数 P2。

    设定值越大,深度图越平滑。P2 > P1。

    该参数可以有效地处理纹理丰富区域,减少误匹配的数量。

  • TY_INT_SGBM_SEMI_PARAM_P1_SCALE = 0x061F | TY_FEATURE_INT

    相邻像素 (+/-1) 约束惩罚参数 P1_scale,值越小越平滑。

  • TY_BOOL_SGBM_HFILTER_HALF_WIN = 0x0619 | TY_FEATURE_BOOL

    半搜索滤波开关。

    用于进一步优化深度图,去除噪声和不连续性,对物体边缘点云更友好。

与误匹配相关

  • TY_INT_SGBM_UNIQUE_FACTOR = 0x0616 | TY_FEATURE_INT

    唯一性检查参数 1,即最优与次优匹配点的百分比。

    设定值越大,匹配代价越唯一,值越大错误匹配点过滤掉的越多。

  • TY_INT_SGBM_UNIQUE_ABSDIFF = 0x0617 | TY_FEATURE_INT

    唯一性检查参数 2,即最优与次优匹配点的差值。

    设定值越大,匹配代价越唯一,值越大错误匹配点过滤掉的越多。

  • TY_BOOL_SGBM_LRC = 0x061C | TY_FEATURE_BOOL

    左右一致性检查开关。

    TY_INT_SGBM_LRC_DIFF = 0x061D | TY_FEATURE_INT

    左右一致性检查参数。

    在进行立体匹配时,对于同一物体表面上的像素,左图匹配右图的视差为 LR,右图匹配左图的视差为 RL。当 ABS(LR-RL) < max LRC diff 时,则认为该点是可信匹配点。

    左右一致性检查参数设定值越小,匹配越可靠。

中值滤波

  • TY_BOOL_SGBM_MEDFILTER = 0x061B | TY_FEATURE_BOOL

    中值滤波开关。

    用于消除孤立的噪声点,同时尽可能地保留图像的边缘信息。

    TY_INT_SGBM_MEDFILTER_THRESH = 0x061E | TY_FEATURE_INT

    中值滤波阈值。

    设定值越大,过滤的噪点越多,但也可能会导致深度图的细节信息丢失。

ToF 相机属性

图像质量设置

TY_ENUM_DEPTH_QUALITY = 0x0900 | TY_FEATURE_ENUM,

设置 ToF 深度相机输出的深度图质量。枚举型属性,定义如下:

typedef enum TY_DEPTH_QUALITY_LIST
{
TY_DEPTH_QUALITY_BASIC = 1,
TY_DEPTH_QUALITY_MEDIUM = 2,
TY_DEPTH_QUALITY_HIGH = 4,
}TY_DEPTH_QUALITY_LIST;
  • 深度图质量设置为 BASIC 时,深度值抖动幅度大,输出帧率高。

  • 深度图质量设置为 MEDIUM 时,深度值抖动幅度中等,输出帧率中等。

  • 深度图质量设置为 HIGH 时,深度值抖动幅度小,输出帧率低。

飞点滤波设置

TY_INT_FILTER_THRESHOLD = 0x0901 | TY_FEATURE_INT,

ToF 深度相机飞点滤波阈值。整型属性,范围 [0,100]。默认值为 0,即不加滤波。滤波阈值设置越小,过滤的飞点越多。

备注

滤波阈值设置过小,可能会把大量有效深度信息过滤掉。

示例:将 ToF 深度相机飞点滤波阈值设置为 43。

ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_DEPTH_CAM, TY_INT_FILTER_THRESHOLD, 43));

调制频道设置

TY_INT_TOF_CHANNEL = 0x0902 | TY_FEATURE_INT,

ToF 深度相机调制频道。整型属性。不同调制频道的调制频率不同,互不干扰。如需在同一场景运行多台 ToF 深度相机,首先需确保同系列相机的调制频道不同。

示例:将 ToF 深度相机调制频道设置为 2。

ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_DEPTH_CAM, TY_INT_TOF_CHANNEL, 2));

激光调制光强设置

TY_INT_TOF_MODULATION_THRESHOLD = 0x0903 | TY_FEATURE_INT,

ToF 深度相机接收激光调制光强的阈值,整型属性。小于此阈值的像素点不参与计算深度,即像素点的深度值赋值为 0。

示例:将 ToF 深度相机接收激光调制光强的阈值设置为 300。

ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_DEPTH_CAM, TY_INT_TOF_MODULATION_THRESHOLD, 300));

抖动过滤设置

TY_INT_TOF_JITTER_THRESHOLD = 0x0307 | TY_FEATURE_INT,

ToF 深度相机抖动过滤阈值,整型属性。阈值设置值越大,深度图边缘抖动的深度数据过滤得越少。

示例:将 ToF 深度相机抖动过滤阈值设置为 5。

ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_DEPTH_CAM, TY_INT_TOF_JITTER_THRESHOLD, 5));

高动态范围比设置

TY_INT_TOF_HDR_RATIO = 0x0306 | TY_FEATURE_INT,

高动态范围比阈值,整型属性。设置该阈值前,需将相机工作模式设置为触发模式且深度图质量设置为 HIGH。目前只有 TL460-S1-E1 ToF 深度相机支持高动态范围比功能。

示例:将 TL460-S1-E1 ToF 深度相机的高动态范围比阈值设置为 50。

ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_DEPTH_CAM, TY_INT_TOF_HDR_RATIO, 50));

抗阳光指数设置

TY_INT_TOF_ANTI_SUNLIGHT_INDEX = 0x0906 | TY_FEATURE_INT,

抗阳光指数,整数属性。取值范围:[0,2]。抗阳光指数用于优化 TM260-E2 ToF 深度相机在阳光下的深度成像效果。

若在室内场景或阳光较弱时,建议将该指数设置为 0;在半室外场景或有一定阳光时,设置为 1;在室外场景或阳光强烈时,设置为 2。

示例:将 TM260-E2 ToF 深度相机的抗阳光指数设置为 0。

ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_DEPTH_CAM, TY_INT_TOF_ANTI_SUNLIGHT_INDEX, 0));

斑点滤波器设置

  • TY_INT_MAX_SPECKLE_DIFF = 0x0908 | TY_FEATURE_INT,

    MAX_SPECKLE_DIFF 斑点滤波器聚类阈值,整数属性。取值范围:[100,500]。单位:mm。若相邻像素的深度差值小于该阈值,则认为该相邻像素属于同一个聚类斑点。

  • TY_INT_MAX_SPECKLE_SIZE = 0x0907 | TY_FEATURE_INT,

    MAX_SPECKLE_SIZE 斑点滤波器面积阈值,整数属性。取值范围:[0,200]。单位:像素。面积小于该阈值的聚类斑点会被滤除。

目前仅 TM260-E2 ToF 相机支持斑点滤波器设置。

示例: 将 TM260-E2 ToF 深度相机的斑点滤波器聚类阈值设置为 123,斑点滤波器聚类阈值设置为 148。

ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_DEPTH_CAM, TY_INT_MAX_SPECKLE_DIFF, 123));
ASSERT_OK(TYSetInt(hDevice, TY_COMPONENT_DEPTH_CAM, TY_INT_MAX_SPECKLE_SIZE, 148));

坐标变换

点云数据结构:

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,
                                     int32_t imageW, int32_t imageH,
                                     const uint16_t* depth,
                                     TY_VECT_3F* point3d,
                                     float f_scale_unit = 1.0f);

示例:获取点云数据,详请请参考 SDK 示例程序 SimpleView_Point3D。

struct CallbackData {
    int             index;
    TY_DEV_HANDLE   hDevice;
    TY_ISP_HANDLE   isp_handle;
    TY_CAMERA_CALIB_INFO depth_calib;
    TY_CAMERA_CALIB_INFO color_calib;

};

static void handleFrame(TY_FRAME_DATA* frame, void* userdata) {
    //we only using Opencv Mat as data container.
    //you can allocate memory by yourself.
    CallbackData* pData = (CallbackData*) userdata;
    LOGD("=== Get frame %d", ++pData->index);

    cv::Mat depth, color;
    parseFrame(*frame, &depth, NULL, NULL, &color, isp_handle);
    if(!depth.empty()){
        std::vector<TY_VECT_3F> p3d;
        p3d.resize(depth.size().area());

        ASSERT_OK(TYMapDepthImageToPoint3d(&pData->depth_calib, depth.cols, depth.rows
            , (uint16_t*)depth.data, &p3d[0]));
}

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* point3d, int32_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,
                  float f_scale_unit = 1.0f);

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,
                  float f_scale_unit = 1.0f);

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,
                  float f_scale_unit = 1.0f);

TYMapRGBImageToDepthCoordinate 映射彩色图到深度图坐标。输入深度图标定数据、深度图宽和高、深度图、彩色图标定数据、彩色图宽和高、彩色图,输出映射后的彩色图像数据。

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,
                  float f_scale_unit = 1.0f);

示例:深度图和彩色图之间的坐标映射,详请请参考 SDK 示例程序 SimpleView_Registration。

static void doRegister(const TY_CAMERA_CALIB_INFO& depth_calib
                      , const TY_CAMERA_CALIB_INFO& color_calib
                      , const cv::Mat& depth
                      , const float f_scale_unit
                      , 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>(), f_scale_unit
      )
    );
    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>(), f_scale_unit
      )
    );
  }
}

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,
                  float f_scale_unit = 1.0f);

图像处理

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 噪音过滤系数。