SDK 简介
简介
功能说明
Smart Vision SDK为开发者提供:
- 操作获取相机照片数据的API接口。所获相机照片数据用于后续人工智能模型推理。
- IO/TCP信号输出API接口。信号输出可发送NG/Alarm/Alarm Clear信号。
Smart Vision SDK提供了C++和python两种类型的接口。开发者可以根据自身情况选择使用。
开发环境
Smart Vision SDK运行于Aidlux智能相机环境中。
类别 | 要求 |
---|---|
操作系统 | Ubuntu20.04 |
Aidlux | aidlux_2.x.x.x |
支持语言接口 | Python3.8 / Python3.7 / C++ |
限制
只能运行在开发环境所要求的运行条件下。
安装/卸载
可通过应用中心安装或卸载Smart Vision SDK。关于应用中心操作介绍,请参考相应文档。
也可以通过命令在线安装或卸载,例如:
安装:
sudo aid-pkg install smartvision-sdk
卸载:
sudo aid-pkg remove smartvision-sdk
打开相机流程介绍
流程图
流程详细步骤介绍
- 实例化Camera类,创建一个Camera对象。
- 调用Camera对象的Open()函数打开相机(可选择是否带参)。
- 有参模式打开相机需要事先实例化结构体DeviceParam,设置相机配置文件,并将该对象作为入参传入Open()函数。具体可参考有参模式打开相机API接口介绍。关于相机配置文件,请参考相机配置文件。
- 无参模式打开相机则可以直接调用Open()函数,入参仅需要回调函数名。具体可参考无参模式打开相机API接口介绍。
- 如果成功打开相机,则打开流开关。否则退出。
- 设置抓图开关及循环业务流,在循环中持续抓取回调函数中的图片数据。具体可参考代码样例。
- 根据业务需求关闭流开关,退出业务。
- 无参模式即打开相机的时候不需要传入相机配置参数,SDK使用相机当前配置的参数来打开相机。
- 有参模式即打开相机的时候需要传入相机配置参数,SDK使用传入的配置的参数来打开相机。。
- 从使用场景的角度,配置相机可通过SVE界面设置,相对更方便易懂。因此使用无参模式配合SVE界面设置更灵活易用。
- 有参模式可作为后台编程的一种灵活可选项。
日志功能
SDK日志功能分为:
- 打印日志,即控制台输出
- 保存日志,即日志保存到文件
- 动态设置日志等级,即可通过命令动态改变当前日志等级配置(影响文件输出)
- 关闭日志,即关闭日志文件输出
动态修改日志级别
格式:
/opt/aidlux/cpf/aid-rtcm/tools/rtcm_tool <Command> <Module> <Key> <Value>
其中,Command为:set或者'-s'。
Module为smartvisionsdk_<pid>。
Key为log_level。
Value为:
off:关闭日志
err:打印错误日志
warn:打印警告日志
info:打印信息日志
例如:
/opt/aidlux/cpf/aid-rtcm/tools/rtcm_tool set smartvisionsdk_1234 log_level info
其中,查询当前引用smartvision sdk的执行程序的pid可通过以下命令:
/opt/aidlux/cpf/aid-rtcm/tools/rtcm_tool query smartvisionsdk camera_process_id
关于rtcm_tool工具更多用法,请参考其帮助信息。
修改日志文件路径
格式:
/opt/aidlux/cpf/aid-rtcm/tools/rtcm_tool <Command> <Module> <Key> <Value>
其中,Command为:set或者'-s'。
Module为smartvisionsdk_<pid>。
Key为log_file_path。
Value为日志文件路径。如:/home/aidlux/,表示将在/home/aidlux路径下创建日志文件。(注:SDK初始日志默认存储在/tmp/smartvisionsdk/目录下)
例如:
/opt/aidlux/cpf/aid-rtcm/tools/rtcm_tool set smartvisionsdk_1234 log_file_path /home/aidlux/
日志文件路径默认值为应用程序所在路径。
其中,查询当前引用smartvision sdk的执行程序的pid可通过以下命令:
/opt/aidlux/cpf/aid-rtcm/tools/rtcm_tool query smartvisionsdk camera_process_id
关于rtcm_tool工具更多用法,请参考其帮助信息。
查询日志级别配置
格式:
/opt/aidlux/cpf/aid-rtcm/tools/rtcm_tool <Command> <Module> <Key>
其中,Command为:query或者'-q'。
Module为smartvisionsdk_<pid>。
Key为log_level。
例如:
/opt/aidlux/cpf/aid-rtcm/tools/rtcm_tool query smartvisionsdk_1234 log_level
日志保存于应用执行程序同一目录。例如:
$ ls -rlt
-rwxr-xr-x. 1 aidlux aidlux 127032 Jun 21 11:50 demo
-rw-r--r--. 1 aidlux aidlux 919473 Jun 21 13:34 aidclog_smartvisionsdk_logger_115125_429_2024-06-21.aidclog
C++示例代码
#include "smart_vision.hpp"
using namespace std;
using namespace Aidlux::SmartVision;
int stop_sign = 0;
bool data_sign = false;
cv::Mat sdk_frame;
// 回调函数my_get_img_cb定义
int8_t my_get_img_cb(const Image & cap_img, const SVSdkMemfdInfo & mem_info) {
if(data_sign) {
// 将缓冲区中的数据转为sdk_frame Mat对象
yuv_to_bgr(sdk_frame, mem_info.srcSliceHeight, mem_info.srcYPlaneStride, mem_info.planeOffset, (void*)cap_img.data);
data_sign = false;
}
return 0;
}
int main(int argc, char * argv[]) {
Aidlux::SmartVision::Camera camera; // 实例化类Camera
int res = camera.open(my_get_img_cb); // 打开相机
if (res != 0) {
cout << "Opening the camera failed!" << endl;
return -1;
}
camera.start_capture(); // 打开流开关
while(!stop_sign) {
data_sign = true;
while(data_sign && (!stop_sign)) {
usleep(1000);
}
if(stop_sign) {
break;
}
// 业务代码, 处理 回调函数中保存到sdk_frame的数据
// ...
}
camera.stop_capture(); // 关闭流开关
return 0;
}
C++示例代码精解
首先是实例化Camera类
Aidlux::SmartVision::Camera camera;
然后调用open()函数打开相机。
如果是无参设置,则直接传入回调函数名my_get_img_cb。
如果是有参设置,则还需要实例化结构体DeviceParam,并设置相机配置文件名及路径。然后在open()函数中传入DeviceParam实例和回调函数名。
// 无参设置
int res = camera.open(my_get_img_cb);
// 有参设置
DeviceParam device_param;
device_param.cfg_name = "./config.json";
int res = camera.open(device_param, my_get_img_cb);
其次,如果打开相机成功,则调用start_capture函数打开流开关。
接着设计while循环语句,在循环体内,源源不断获取从回调函数中拷贝出来的图像数据。
由于所获数据是YUV原始数据,需要转换为BGR格式,因此需要调用yuv_to_bgr API进行转换。
// sdk_frame为mat对象,转换后的数据存入sdk_frame对象带出。 cap_img.data则为原始数据指针
// mem_info.srcSliceHeight为YUV数据的高度,mem_info.srcYPlaneStride为YUV数据的宽度
yuv_to_bgr(sdk_frame, mem_info.srcSliceHeight, mem_info.srcYPlaneStride, mem_info.planeOffset, (void*)cap_img.data);
转换出来的数据用于AI推理及结果预览等。
最后,当不再需要获取数据的时候,调用stop_capture函数关闭流开关,退出主程序。
Python示例代码
from pysmartvision import smartvisionsdk
import numpy as np
import time
import os
data_sign = False
img_array = []
keep_sign = 1
# 定义回调函数get_img_cb
def get_img_cb(cap_img, mem_info):
global data_sign
global img_array
if (data_sign):
# 获取image数据
im = smartvisionsdk.get_cvimage(cap_img)
print("the image is got successfully")
img_array = np.array(im, copy=True)
data_sign = False
return 0
if __name__ == '__main__':
# 初始化相机
try:
print("instance camera")
# 实例化Camera类
camera_instance = smartvisionsdk.Camera()
# 打开相机
if camera_instance.open(get_img_cb) == 0:
print("camera is opened successfully")
else:
raise ValueError("camera started failed.")
# 打开取流开关
camera_instance.start_capture()
except Exception as e:
print("camera start Error:", e)
raise
try:
while keep_sign:
# 取数据
data_sign = True
count = 0
while (data_sign):
if count >= 10 :
count = 0
print("waiting for the image data in callback function")
else:
time.sleep(0.1)
count += 1
# 业务代码, 处理 回调函数中保存到img_array的数据
...
# 关闭取流开关
camera_instance.stop_capture()
except Exception as e:
print("error:", e)
print("end")
os._exit(0)
Python示例代码精解
首先是实例化Camera类
camera_instance = smartvisionsdk.Camera()
然后调用open()函数打开相机。
如果是无参设置,则直接传入回调函数名my_get_img_cb。
如果是有参设置,则还需要实例化结构体DeviceParam,并设置相机配置文件名及路径。然后在open()函数中传入DeviceParam实例和回调函数名。
// 无参设置
res = camera_instance.open(my_get_img_cb)
// 有参设置
device_param = DeviceParam device_param()
device_param.set_cfgname("./config.json")
res = camera_instance.open(device_param, my_get_img_cb)
其次,如果打开相机成功,则调用start_capture函数打开流开关。
接着设计while
循环语句,在循环体内,源源不断获取从回调函数中拷贝出来的图像数据。而在回调函数中,则通过接口get_cvimage获取图像数据。(注:该图像数据已转为BGR
数据)
im = smartvisionsdk.get_cvimage(cap_img)
所获图像数据用于AI推理等。
最后,当不再需要获取数据的时候,调用stop_capture函数关闭流开关,退出主程序。