跳到主要内容

SDK 简介

简介

功能说明

Smart Vision SDK为开发者提供:

  • 操作获取相机照片数据的API接口。所获相机照片数据用于后续人工智能模型推理。
  • IO/TCP信号输出API接口。信号输出可发送NG/Alarm/Alarm Clear信号。

Smart Vision SDK提供了C++和python两种类型的接口。开发者可以根据自身情况选择使用。

开发环境

Smart Vision SDK运行于Aidlux智能相机环境中。

类别要求
操作系统Ubuntu20.04
Aidluxaidlux_2.x.x.x
支持语言接口Python3.8 / Python3.7 / C++

限制

只能运行在开发环境所要求的运行条件下。

安装/卸载

可通过应用中心安装或卸载Smart Vision SDK。关于应用中心操作介绍,请参考相应文档。

也可以通过命令在线安装或卸载,例如:

安装:
sudo aid-pkg install smartvision-sdk

卸载:
sudo aid-pkg remove smartvision-sdk

打开相机流程介绍

流程图

alt text

流程详细步骤介绍

  1. 实例化Camera类,创建一个Camera对象。
  2. 调用Camera对象的Open()函数打开相机(可选择是否带参)。
  3. 有参模式打开相机需要事先实例化结构体DeviceParam,设置相机配置文件,并将该对象作为入参传入Open()函数。具体可参考有参模式打开相机API接口介绍。关于相机配置文件,请参考相机配置文件
  4. 无参模式打开相机则可以直接调用Open()函数,入参仅需要回调函数名。具体可参考无参模式打开相机API接口介绍。
  5. 如果成功打开相机,则打开流开关。否则退出。
  6. 设置抓图开关及循环业务流,在循环中持续抓取回调函数中的图片数据。具体可参考代码样例。
  7. 根据业务需求关闭流开关,退出业务。
- 无参模式即打开相机的时候不需要传入相机配置参数,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路径下创建日志文件。

例如:
/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函数关闭流开关,退出主程序。