Shimeta EVS SDK 库
简介
这是一个从Shimeta EVS相机获取EVS事件数据和APS图像数据的SDK库。该库封装了USB设备的操作,提供了简单易用的API接口,使用户能够方便地获取和处理来自设备的事件流和图像数据。
功能特点
- 检测USB设备连接状态
- 获取EVS事件数据(通过回调函数处理实时事件)
- 获取APS图像数据(通过回调函数处理实时图像)
编译安装
依赖项
- libusb-1.0
- OpenCV 4.x
安装依赖项
在Ubuntu上,您可以使用以下命令安装依赖项:
sudo apt-get update
sudo apt-get install libusb-1.0-0-dev libopencv-dev
使用方法
基本用法
工作文件夹下创建get_started.cpp,以下是一个简单的示例程序,展示如何使用SDK库获取EVS事件数据并进行计时:
#include "evs_aps_sdk.h"
#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>
#include <iomanip>
// 全局变量用于控制程序运行和统计
std::atomic<bool> running(true);
std::atomic<int> total_frames(0);
std::chrono::steady_clock::time_point start_time;
// EVS事件回调函数
void onEVSEvent(const std::vector<EVSEvent>& events) {
// 增加帧计数
total_frames++;
std::cout << "收到事件数组,包含 " << events.size() << " 个事件" << std::endl;
}
int main() {
// 记录启动时间
start_time = std::chrono::steady_clock::now();
// 创建SDK设备实例
EVSAPSDevice device(0x1d6b, 0x0105);
// 打开设备
if (!device.open()) {
std::cerr << "无法打开设备,请检查连接或权限" << std::endl;
return 1;
}
std::cout << "设备已成功打开" << std::endl;
// 启动EVS事件捕获
if (!device.startEVSCapture(onEVSEvent)) {
std::cerr << "启动EVS捕获失败" << std::endl;
device.close();
return 1;
}
std::cout << "EVS数据捕获已启动" << std::endl;
std::cout << "按'q'键退出程序" << std::endl;
// 主循环
char input;
while (running && std::cin.get(input)) {
if (input == 'q') {
running = false;
break;
}
}
std::cout << "正在停止数据捕获..." << std::endl;
// 停止捕获
device.stopEVSCapture();
// 关闭设备
device.close();
// 计算运行时间并打印统计信息
auto end_time = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::duration<double>>(end_time - start_time);
std::cout << "\n运行统计信息:" << std::endl;
std::cout << "总运行时间: " << std::fixed << std::setprecision(3) << duration.count() << " 秒" << std::endl;
std::cout << "接收总帧数: " << total_frames << std::endl;
std::cout << "程序已退出" << std::endl;
return 0;
}
进阶用法
创建工作目录下创建example_usage.cpp,以下示例展示了更复杂的功能,包括图像处理和显示:
#include "evs_aps_sdk.h"
#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>
// 全局变量用于控制程序运行
std::atomic<bool> running(true);
// 用于存储和更新EVS图像
cv::Mat evs_image(APX_K2_EVS_HEIGHT, APX_K2_EVS_WIDTH, CV_8UC3, cv::Scalar(0, 0, 0));
std::mutex evs_mutex;
// EVS事件回调函数
void onEVSEvent(const std::vector<EVSEvent>& events) {
// 清空画布重新绘制
std::lock_guard<std::mutex> lock(evs_mutex);
evs_image = cv::Mat(APX_K2_EVS_HEIGHT, APX_K2_EVS_WIDTH, CV_8UC3, cv::Scalar(0, 0, 0));
// 更新EVS图像
for (const auto& event : events) {
if (event.x < APX_K2_EVS_WIDTH && event.y < APX_K2_EVS_HEIGHT) {
// 根据事件极性设置像素颜色
if (event.polarity == 0) {
evs_image.at<cv::Vec3b>(event.y, event.x) = cv::Vec3b(235, 206, 135);
} else {
evs_image.at<cv::Vec3b>(event.y, event.x) = cv::Vec3b(255, 255, 255);
}
}
}
}
// APS图像回调函数
void onAPSImage(const cv::Mat& image) {
}
int main() {
// 创建SDK设备实例 (使用与原示例相同的设备ID)
EVSAPSDevice device(0x1d6b, 0x0105);
// 打开设备
if (!device.open()) {
std::cerr << "无法打开设备,请检查连接或权限" << std::endl;
return 1;
}
std::cout << "设备已成功打开" << std::endl;
// 启动EVS事件捕获
if (!device.startEVSCapture(onEVSEvent)) {
std::cerr << "启动EVS捕获失败" << std::endl;
device.close();
return 1;
}
// 启动APS图像捕获
if (!device.startAPSCapture(onAPSImage)) {
std::cerr << "启动APS捕获失败" << std::endl;
device.stopEVSCapture();
device.close();
return 1;
}
std::cout << "EVS和APS数据捕获已启动" << std::endl;
std::cout << "按'q'键退出程序" << std::endl;
// 主循环:显示合并的图像
while (running) {
// 获取最新的图像
cv::Mat current_evs_image;
cv::Mat aps_image = device.getLatestAPSImage();
// 获取当前EVS图像的副本
{
std::lock_guard<std::mutex> lock(evs_mutex);
current_evs_image = evs_image.clone();
}
if (!current_evs_image.empty() && !aps_image.empty()) {
// 水平连接两个图像
cv::Mat combined_image;
cv::hconcat(std::vector<cv::Mat>{evs_image, aps_image}, combined_image);
// 显示并排的图像
cv::imshow("EVS和APS图像", combined_image);
// 捕获按键事件
int key = cv::waitKey(1);
if (key == 'q') { // 如果按下'q'键,则退出程序
running = false;
break;
}
}
//短暂休眠,减少CPU使用率
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
std::cout << "正在停止数据捕获..." << std::endl;
// 停止捕获
device.stopEVSCapture();
device.stopAPSCapture();
// 关闭设备
device.close();
std::cout << "程序已退出" << std::endl;
return 0;
}
链接库文件
在您的项目中使用Shimeta EVS SDK库,需要将libevs_aps_sdk.so
库文件和头文件添加到您的项目中。以下是详细步骤:
复制SDK文件
- 将
libevs_aps_sdk.so
复制到您项目的lib目录 - 将SDK头文件复制到您项目的include目录
- 将
设置CMake配置
工作文件下创建CMakeLists.txt,以下是一个完整的CMakeLists.txt示例:
cmake_minimum_required(VERSION 3.10)
project(example_usage)
# 设置C++标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 查找依赖包
find_package(OpenCV REQUIRED)
# 添加头文件路径
include_directories(
${CMAKE_SOURCE_DIR}/include
${OpenCV_INCLUDE_DIRS}
)
# 添加库文件路径
link_directories(${CMAKE_SOURCE_DIR}/lib)
# 添加可执行文件
add_executable(example_usage example_usage.cpp)
# 链接库文件
target_link_libraries(example_usage
evs_aps_sdk
${OpenCV_LIBS}
usb-1.0
)
运行示例程序
工作文件夹下执行如下指令,编译并运行示例程序
mkdir build && cd build
cmake ..
make
./example_usage
如果出现报错no match devices found说明设备未成功连接
将设备连接到主机后,运行程序出现Cannot open device:LIBUSB_EERROR_ACCESS这是由于未赋予权限导致的,执行下述指令即可
sudo chmod -R 777 /dev/bus/usb
示例程序运行截图
API参考
EVSAPSDevice类
构造函数
EVSAPSDevice(uint16_t vendor_id, uint16_t product_id);
vendor_id
: USB设备厂商IDproduct_id
: USB设备产品ID
设备管理
bool open();
打开USB设备,返回是否成功。
bool isOpen() const;
检查设备是否已打开。
void close();
关闭USB设备。
EVS事件捕获
bool startEVSCapture(EVSEventCallback callback);
启动EVS事件数据采集,通过回调函数处理事件。
void stopEVSCapture();
停止EVS事件数据采集。
APS图像捕获
bool startAPSCapture(APSImageCallback callback);
启动APS图像数据采集,通过回调函数处理图像。
void stopAPSCapture();
停止APS图像数据采集。
获取最新图像
cv::Mat getLatestAPSImage() const;
获取最新的APS图像。