为帮助开发者在没有GPS 或RTK 卫星等应用场景中实现无人机的自动化飞行控制,实现如精准悬停和避障等功能,DJI 开放了无人机视觉感知系统,开发者通过使用OSDK 提供的API 即可获取DJI 无人机视觉感知系统的码流数据,并生成时差图以及点云图,结合图像识别算法,开发出满足特定使用场景需求的应用程序。
说明
- 仅使用Linux 和ROS 系统开发的应用程序支持开发者使用DJI 的高级感知功能。
- 使用DJI OSDK 的高级感知功能时,需使用USB 线接收无人机视觉感知系统的原始图像数据。
为满足开发者使用OSDK 开发的应用程序对获取相机码流的功能,OSDK 提供了获取相机码流的功能,支持获取FPV 相机或获取I 号云台相机H.264 码流和RGB 图像。
说明
- M210 系列无人机支持获取FPV 相机和I 号云台上相机的H.264 码流或RGB 图像;M300 RTK 无人机支持获取FPV 相机和所有云台相机的H.264 码流。
- 由于获取FPV 相机码流和获取I 号云台上相机码流的回调函数在各自独立的线程中运行,OpenCV 的imshow 模块仅支持在一个线程中运行,因此仅支持开发者获取FPV 相机或获取I 号云台相机H.264 码流和RGB 图像。
- 获取相机码流后,请安装FFmpeg 等解码器解码。
- 有关H.264 标准码流的相关参考请参见H.264 码流标准 。
OSDK 支持开发者获取M210 系列和M300 RTK 无人机上I 号云台上相机的码流,开发者或用户可根据实际的使用需求挂载不同型号的相机,根据相机的型号以及相机的工作模式,指定帧速率,获取所需的码流。
说明: 获取FPV 相机和主相机码流的帧速率均为30 FPS。
获取M210 系列和M300 RTK 无人机上相机H.264 码流的流程如下所示:
liveViewSampleCb
函数,用于获取并处理相机H.264 码流。startH264Stream()
接口,指定所需获取码流的相机、接收相机H.264 码流的回调函数和用户信息;liveViewSampleCb
在获取相机H.264 码流后,将对所获得的H.264 码流执行存储、解码及转发等相应的操作。DJI 无人机的视觉感知系统主要由无人机视感知传感器和视觉感知算法构成,在无人机飞行的过程中,感知传感器能够获取周围环境的状态,协助无人机刹车、避障和精确悬停。
说明
- 在悬停期间若无人机受到外部干扰,无人机将会返回到原悬停点。
- 使用立体感知功能时,若无人机与无人机遥控器断开连接,无人机将会悬停。
立体感知功能支持开发者获取的图像类型和分辨率如下所示:
无人机视觉传感器产生的图像主要包含帧索引和时间戳两种元数据。
使用高级视觉功能时,开发者需要调用指定的API 通过USB 接口在应用程序运行的周期内订阅(或退订)相机视觉传感器的图像,并使用回调函数在专用的读取线程内获取订阅的图像。
说明
- 获取无人机视觉传感器图像时,建议安装OpenCV 以显示图像。
- 为避免处理视觉传感器图像的工作阻塞主线程,请创建一个独立的线程处理无人机视觉传感器的图像。 在ROS 系统上使用高级视觉功能时,请使用
ROS services
订阅并通过image_view
显示视觉传感器的图像。
下文以使用KCFcpp 库实现目标跟踪功能的步骤,介绍使用DJI 无人机视觉传感器或相机的图像数据,控制云台的流程和方法,开发者可在合法的使用范围内使用第三方库开发出更为完善的应用程序。
说明
- 使用KCFcpp 库编译目标跟踪的示例代码时,请使用命令
cmake -DADVANCED_SENSING=ON -DTARGET_TRACKING_SAMPLE=ON make
编译该程序。- 从键盘中输入g 后,即可创建KCF跟踪器;选择跟踪新的对象时请输入s,如需退出该程序,请按ESC 键。
为了方便用户指定所需跟踪的目标,OSDK 提供了TrackingUtility
类,用于获取目标对象和跟踪状态。
tracker = new KCFTracker(true, true, false, false); |
目标跟踪算法根据视觉传感器或相机每一帧的图像,确定目标图像的位置并计算目标对象移动的距离(单位:1 px)。
/*获取目标对象*/ |
根据目标对象移动的状态,计算云台所需改变的偏航角度和俯仰角度,并将该角度发送给DJI::OSDK::Gimbal::SpeedData gimbalSpeed;
。
DJI::OSDK::Gimbal::SpeedData gimbalSpeed; |
在主线程中以轮询的方式获取RGB 图像。
vehicle->advancedSensing->startFPVCameraStream()
接口创建一个线程,用于读取相机原始的码流并解码成图像。vehicle->advancedSensing->newFPVCameraImageIsReady()
接口,检查相机码流的状态,若相机中有可用的码流,则调用vehicle->advancedSensing->getFPVCameraImage(fpvImage)
获取该图像。说明: 若开发者安装了OpenCV 库,则可通过
show_rgb
函数调用cv::imshow()
接口显示解码后的RGB 图像。
vehicle->advancedSensing->stopFPVCameraStream()
接口,断开与相机的链接,销毁读取相机码流的线程。通过回调函数的方式获取RGB 图像。
vehicle->advancedSensing->startFPVCameraStream(&show_rgb, NULL)
接口,创建获取相机码流的线程,同时在该接口中注册回调函数show_rgb
,用于处理接收到的码流。vehicle->advancedSensing->stopFPVCameraStream()
接口,断开与相机的连接,销毁读取相机码流的线程。控制应用程序接收指定相机的H.264 码流。
LiveView::LiveViewErrCode startH264Stream(LiveView::LiveViewCameraPosition pos, H264Callback cb, void *userData); |
控制应用程序停止接收相机的H.264 码流。
LiveView::LiveViewErrCode stopH264Stream(LiveView::LiveViewCameraPosition pos); |
基于OSDK 开发的应用程序获取H.264 码流后,开发者即可对所获取的H.264 码流执行所需的操作。
typedef void (*H264Callback)(uint8_t* buf, int bufLen, void* userData); |
说明
- 开发者获取指定相机的H.264 码流后,使用
ffplay FPV.h264
命令即可播放所获取的H.264 文件。- 借助OSDK 提供的Sample (djiosdk-liveview-sample) 获取H.264 码流数据,并将接收到的H.264 码流数据以H.264 文件的形式记录在本地,该文件名为
userData
。- 使用Sample camera-stream-callback-sample和camera-stream-poll-sample 可借助FFMpeg 对H.264 码流解码。开发者可借助Sample 实现所需的功能。
开发者使用Elecard StreamEye Tools,H264Visa等H.264 解码软件,即可解码和分析使用OSDK 获取的H.264 码流,如下为使用Sample djiosdk-liveview-sample 获取DJI 无人机上相机码流的分析结果,该视频均在室内录制,时长为9~10秒。
表1.相机H.264 码流分析结果
M300 FPV | M210 V2 FPV | Z30 | XTS | X7 | H20T | ||
---|---|---|---|---|---|---|---|
Video Stream Type | AVC/H.264 | AVC/H.264 | AVC/H.264 | AVC/H.264 | AVC/H.264 | AVC/H.264 | |
Resolution | 608 x 448 | 608 x 448 | 1280 x 720 | 640 x 512 | 1280 x 720 | 1920 x 1080 | |
Profile | Main:4.1 | Main:4.1 | Main:4.1 | High:5.0 | High:4.0 | High:4.0 | |
Aspect Ratio | 4 x 3 | 4 x 3 | 16 x 9 | 5 x 4 | 16 x 9 | 16 x 9 | |
Interlaced | No | No | No | No | No | No | |
File Size (Bytes) | 867619 | 877819 | 4559469 | 5472872 | 8765755 | 17243162 | |
Frames Count | 271 | 274 | 300 | 240 | 294 | 299 | |
Frame Size | Max | 5095 |
5875 | 34848 | 53368 | 45846 | 71881 |
Avg | 3201 | 3203 | 15198 | 22803 | 29815 | 57669 | |
Min | 1990 | 1456 | 4164 | 11025 | 18532 | 51506 | |
I Frame | Max | 4802 |
4641 | 0 | 51729 | 0 | 0 |
Avg | 4243 | 4117 | 0 | 37054 | 0 | 0 | |
P Frame | Max | 5095 |
5875 | 34848 | 53368 | 45846 | 71881 |
Avg | 3177 | 3183 | 15198 | 22312 | 29815 | 57669 | |
B Frame | Max | 0 |
0 | 0 | 0 | 0 | 0 |
AVG | 0 | 0 | 0 | 0 | 0 | 0 | |
FrameRate | Declared | 30.00 |
30.00 | 0.00 | 25.00 | 25.00 | 30.00 |
Real | 30.00 | 30.00 | 30.00 | 25.37 | 25.39 | 30.00 | |
BitRate (bit/s) | Max | 846960 | 835680 | 3988324 | 5367808 | 6789069 | 14462654 |
Avg | 768240 | 768720 | 3647523 | 4628379 | 6056010 | 13840574 | |
Min | 731040 | 709920 | 3070083 | 4179404 | 5401762 | 13307293 |
受计算平台算力的制约,基于OSDK 开发的应用程序在编解码时可能会出现如下问题:
由于Z30 采用Main Profile技术,使用GDR 编码格式,因此开发者使用OSDK 提供的Sample,无法通过FFMpeg 解码方式解码相机Z30 的H.264 视频流,但开发者可根据实际的开发环境选用其他解码器,如硬件解码器或JM 解码器等对相机Z30 的H.264 码流数据解码。
说明: OSDK暂不支持同时获取和切换支持多种光源的相机的图像,如需切换,请在DJI Pilot 中设置切换相机的图像。