AI 视觉智能售货柜 RJDVA SDK 使 说明书 RJDVA SDK 说明. RJDVA SDK 于锐捷动态视觉柜 AI 云平台接, 提供相机数据解码 关键帧提取算法 视频硬编码及数据打包与发送 AI 云平台功能. RJDVA SDK 持安卓设备 armeabi-va,arm-v8a 两种 CPU 类型, 前在联发科 MT8A 与瑞芯微 RK88 两款 CPU 通过测试 RJDVA SDK 作时序图 录结构 Headers autobounding.h // ROI 区域自动标定基类 basedatatype.h // 基础数据类型类 bgsegment.h // 背景差分流处理类 bgsubcnt.h // CNT 方法定义基类 cameraautocalib.h // 相机自动标定 ROI 区域类
8 9 0 8 9 0 8 9 cameracfgreader.h // 读取相机配置文件类 cameraframeprocess.h // 图像预处理类 DataPacketSender datapacketsender.h // 数据包发送类 GrpcClient GrpcClient.h // Grpc 客户端类 datapacking.h // 数据打包工具类 datastation.h // 数据中转处理类 decoderprocess.h // 图像解码处理类 encoderprocess.h // 图像编码处理类 hencoder.h // H 编码类 keyframefilter.h // 关键帧处理类 LogUtils.h // 日志类 mjpgdecoder.h // MJpeg 解码类 mogcalculator.h // 背景差分计算类 rjdva_c.h // RJDVA C 语言接口 rjdva.h // RJDVA 基类 shadefile.h // 隐藏配置文件 threadmanager.h // 线程管理基类 Tool.h // 工具类 utility.h // 辅助工具类 videodecoder.h // 视频解码基类 videoencoder.h // 视频编码基类 使 流程及接 说明. RJDVA 初始化在初始化的过程中会将传 的 strinfojson 参数写 到 件中, 因此需要 定的权限, 在调 法之前可以先确保读写权限, 以便后续操作 调 Init 函数执 初始化流程, 函数原型如下 : * @brief 执行算法初始化, 软件启动时调用 * @param strdeviceid - 设备 ID * @param strserveripport - 锐捷 AI 云平台 IP 与 Port 组成的字符串, 如 "0.0.0.0:9999" 8 9 * @param strworkspacepath 工作环境路径 * @param strinfojson - 包含相关信息的 json 格式的字符串内容 * @return 初始化成功返回 true, 失败返回 false bool rjdva_init(const char* strdeviceid, const char* strserverippor, const char* strworkspacepath, const char* strinfojson); strinfojson 说明如下 :
字段名称类别 Host_Smart 接 域名 String appid sercet 对接接 基础字段 ( 有使 平台提供 ) 对接接 基础字段 ( 有使 平台提供 ) String String company 公司名称信息 String keepalive 域名端 String keepalive: 该字段 于将订单信息发送给平台, 实现对订单的全流程监控, 如 需这个业务可以 传 空值 ( 如 :keepalive:"") 或者不传 这个字段亦可 strinfojson 参数示例 : {"Host_Smart":"https://api.xiaomaigui.com/dynamic_vision/notify","appid": "0000000","sercet":"fdeecdfc80c9cbdd","compan y":"ruijie","keepalive":"http://8.8.80.:998"}. 调 开 回调函数, 通知 RJDVA 当前处于购物流程, 并传 订单编号 函数原型如下 : * @brief 开门回调函数, 收到门锁打开信号时调用此函数 * @param strorderid - 订单编号 void rjdva_opendoorcallback(const char* strorderid);. 调 传 相机数据 (MJpeg 数据流, 需解码 ) 的接, 传 相机数据供处理 函数原型如下 : * @brief 开门成功后, 获取相机原始数据写入 * @param vdataframe - 由相机原始数据等信息组成的结构体 * @return 调用成功返回 true, 失败返回 false bool rjdva_pushvdataframe(vdataframe vdataframe);. 调 传 重 数据 ( 所有重 传感器之和, 已去 ) 的接, 传 相机数据供处理 函数原型如下 : * @brief 开门成功后, 获取重力去皮后的数据并写入 * @param gdataframe - 由重力数据等信息组成的结构体 * @return 调用成功返回 true, 失败返回 false bool rjdva_pushgdataframe(gdataframe gdataframe);
. 调 关 回调函数, 通知 RJDVA 购物流程已结束 () 调 关 回调需要在调 开 回调之后, 不然关 回调 法成功执 ; () 关 回调需传 个参数 nstatecode, 作 于将上层捕获到硬件异常信息传递给 SDK, 借此使得之后阶段处理的时候能够有更好的效果, 如果没有此功能传递参数为 0 即可 ; 函数原型如下 : * @brief 关门回调函数, 收到门锁关闭信号时调用此函数 * @param nstatecode - 设备状态码, 用于反馈上层捕获到的异常 ; 若上层不进行异常捕获, 设置为 0 即可 bool rjdva_closedoorcallback( const int nstatecode );. 调 发送数据包接, 将数据包发送 锐捷 AI 云平台 数据包在购物结束后存储在 Init 函数传 的 作环境路径的 DataStation 录下, 由于可能 络异常导致数据发送中断, 建议维护数据包列表, 数据包发送成功后则删除数据包列表中相应项, 否则重新发送数据包 函数原型如下 : 8 * @brief 发送算法数据包至锐捷 AI 云平台 * @param strorderid - 订单编号 * @param strtoken - token 信息 * @param strzippath - ZIP 包保存路径 * @return 调用成功返回 true, 失败返回 false bool rjdva_senddatapacket(const char* strorderid, const char* strtoken, char* strzippath); strzippath 参数说明如下 : 事先声明参数 strzippath, 且这个参数应为空 ( 如 char strzippath;), 将参数传 并且 法执 完成之后, 参数 strzippath 会获得赋值, 以此获取到数据包保存的路径 ;. 相关数据结构定义如下 : 8 9 0 *********************************************************************** ********************** //! \ingroup STRUCTS //! \struct GDATAFRAME //! 重力帧相关信息 *********************************************************************** ********************** typedef struct _gdataframe { float fvalue; // 当前重力值 ( 去皮, 所有重力传感器总和 ) int nframeid; // 帧号 long long lltimestamp; // 当前帧的时间戳 ms
8 9 0 }GDataFrame; *********************************************************************** ********************** //! \ingroup STRUCTS //! \struct VDATAFRAME //! 视觉帧相关数据 *********************************************************************** ********************** typedef struct _vdataframe { unsigned char* pdata; // 当前帧数据指针地址 unsigned int ndatasize; // 当前帧数据大小 int nframeid; // 帧号 long long lltimestamp; // 当前帧的时间戳 ms char strcamerapos[]; // 相机位置信息, 如 TR,DR, 分别代表右上与右下相机 }VDataFrame; 接 调 说明及示例 RJDVA SDK 前 持 C/C++ JAVA 以及 Python 调 C/C++ 接 调 示例如下 : 8 9 0 #include "rjdva_c.h" #ifdef cplusplus extern "C" int main(int argc, char** argv) { #endif rjdva_closedoorcallback(0); return 0; #ifdef cplusplus } #endif JAVA JAVA 调 so 库可以采 JNI 封装的 式, 步骤如下 :. JNI 封装 so 库, 留出接 供上层调. JAVA 上层调 JNI 封装好的 法. 在项 app 录下创建 CMakeLists.txt 另外可以参考相关的调 说明 https://www.sisik.eu/blog/android/ndk/opencv-without-java https://www.cnblogs.com/zhongzhaoxie/p/.html(androidstudio) JNI 接 示例 (native-lib.cpp)
JNIEXPORT void JNICALL Java_eu_sisik_sample_MainActivity_rjdva_CloseDoorCallback( JNIEnv *env, jobject /* this, jint nstatecode) { rjdva_closedoorcallback(nstatecode); } JAVA 调 代码 rjdva_closedoorcallback(0) CMakeLists 件示例 add_library(rdjva_sdk-lib SHARED IMPORTED) set_target_properties( rdjva_sdk-lib PROPERTIES IMPORTED_LOCATION ${RJDVA_LIB_PATH}/${ANDROID_ABI}/libRJDVA.so) target_link_libraries( native-lib rdjva_sdk-lib) Python SDK 包中包含了 个 so 库,python 可以使 ctypes 库来加载 so 库 请根据开发环境选择适配的 so 库, 如 armv 对应的是 位,armv8 对应的是 位 from ctypes import * if name == ' main ': rjdva = cdll.loadlibrary("/path/to/librjdva.so") rjdva.rjdva_closedoorcallback(0) 版本更新记录与下载 上线 期版本号更新说明下载 00-- V0.. RJDVA 调 接 由 C++ 修改为 C RJDVA_ReleaseV0...rar 0-0-09 V0. RK88 版本 RJDVA_ReleaseV0..r ar 0-0-0 V.. 对 Init,SendDataPacket 和 CloseDoorCallback 接 进 修 改, 新增传 参数 RJDVA_ReleaseV.. _RK88.zip 常 问题与解答 (FAQ) SDK 的 作流程是怎么样的? 更详细的 作流程可以参考 档中的时序图, 简单的来说,SDK 作流程如下图 :
在初始化之后需要调 开 回调 rjdva_opendoorcallback 来告知 SDK 开始 成订单 件, 之后 pushdataframe 给 SDK 进 写 数据, 在完成之后需要调 关 回调 rjdva_closedoorcallback 来告知 SDK 订单完成 成最后需要的数据包 下 次需要 成新的订单数据则再调 rjdva_opendoorcallback, 以此循环 控编码怎么传给 SDK? SDK 使 说明 有 参 strdeviceid 双摄像头, 如何传 相机流? 在结构体 _vdataframe 中填 相机位置信息即可,TR 代表上 的相机,DR 代表下 的相机 ( 前暂时采 单侧相机编号 ) 由于 前采 静态 式配置参数, 所以需要按照指定的相机编号进 数据传递, 以免影响数据 成 VDataFrame 结构体传 jpeg 图像的指针和数据 度, 如果 JNI 有和 C 指针对应的数据结构
双摄像头的数据采集,_vDataFrame 的 nframeid 是各 计算, 还是两个累加计算的? 两个摄像头各 从 0 开始计数 对于传 的相机原始数据有什么要求? 因为传 SDK 的数据有做 步解码处理, 所以设计是从相机直接拿到 MJPG 格式的数据传 SDK 即可 ( 建议可以采 VL 去获取相机数据 ) 由于 前采 静态 式配置参数, 所以传递给 SDK 的相机数据需要符合尺 和格式要求, 以免影响数据 成 另外, 为了提 算法准确度, 视频帧率建议 0FPS 前 SDK 持 0*0 和 0*80 两种尺 的图像数据输, 如果有其他尺 的需求可以沟通定制 时序图中的 VL API 是怎么调, 没看到说明?
VL 是 video for linux 的缩写, 是 linux 内部调 相机的 个驱动, 按照 VL 的 API 进 开发即可, 这个官 API 内容基本满 我们的要求, 只要调 caputre 环节就可以了 https://linuxtv.org/downloads/vl-dvb-apis/userspace-api/vl/vl.html 视频数据 定要通过 VL 获取吗? 我们建议是使 VL, 前来说这个是最适合使 的 法, 它是 linux 内核的 法, 效且普适, 通过 VL 法获取相机数据能够达到要求的帧数性能, 并且这个 法是被验证过的 如果有其他 法能够保证性能也可以尝试, 最终能够将数据传给 SDK 即可 8 重 数据, 有时候温差 的情况下传感器会有飘动, 这个影响吗? 我们的算法对重 偏差有 定的容忍度, 我们允许的重 偏差阈值是动态的, 和拿取多重商品有关 重 允许偏差值 = min( 拿取所有商品的重量和 *0.0 + 重 允许的最 偏差值, 重 允许的最 偏差值 ) 重 允许的最 偏差值, 重 允许的最 偏差值, 这两个值可以适当调整, 和称的测试精度有关, 如果称的精度 较低, 可以增加 [0, 0], 但是如果某个重 范围内的商品 较多, 视觉识别不佳的情况下, 可能会牺牲掉部分识别率 9 为什么步骤都是正常但是 成的视频 件没有内容? 在 SDK 内部有静态数据的过滤机制, 如果开发使 的相机捕获到的视频内容没有任何的变化, 便不会有数据被写 到 件中, 如果符合上述情况, 可以尝试在相机前完成 些动作