首页
  • GM-3568JHF
  • M4-R1
  • M5-R1
  • SC-3568HA
  • M-K1HSE
  • CF-NRS1
  • CF-CRA2
  • 1684XB-32T
  • 1684X-416T
  • C-3568BQ
  • C-3588LQ
  • GC-3568JBAF
  • C-K1BA
商城
  • English
  • 简体中文
首页
  • GM-3568JHF
  • M4-R1
  • M5-R1
  • SC-3568HA
  • M-K1HSE
  • CF-NRS1
  • CF-CRA2
  • 1684XB-32T
  • 1684X-416T
  • C-3568BQ
  • C-3588LQ
  • GC-3568JBAF
  • C-K1BA
商城
  • English
  • 简体中文
  • CF-NRS1

    • 简介

      • 01-产品介绍
      • 02-相关概念
      • 03-MultiVision Studio 介绍
    • 开发

      • 01-ShiMetaPi Hybrid vision SDK 介绍
      • 02-Hybrid_vision_toolkit
      • 03-Hybrid_vision_toolkit API (C++)
      • 04 Hybrid Vision algo
      • 05 Hybrid vision algo API
    • 资源

      • 01-SDK下载
  • CF-CRA2

    • 简介

      • CF-NRS2 简介

API使用说明

Algo SDK 是一款专为evs device 设计的软件开发工具包,提供了算法的功能和简便的操作方式,帮助开发者轻松集成各项功能。

环境配置

请确保您的开发环境中已安装以下必备组件:

  • 操作系统: windows 10 64 位
  • 编译器: 适用于您的操作系统的 C/C++ 编译器
  • 依赖库: 确保安装了必要的库,OpenCV,我们会提供SDK对于的OpenCV版本,自行配置环境变量即可。
  • 开发工具: 如 IDE(Visual Studio 2019等)

建议: 开发路径使用全英文

Algo模块说明

Algo库主要分为三个模块:

  1. OpticalFlow

    • 功能: 该API是基于EVS的光流实现。
  2. HandDetector

    • 功能: 该API是基于EVS的手形检测器实现。
  3. HumanDetector

    • 功能: 该API是基于EVS的人形检测器实现。

Algo目录说明

  • bin目录: 包含所有核心库及依赖库
  • docs目录: 包含接口说明文档
  • include目录: 包含接口头文件
  • lib目录: 包含所有开发库的lib文件
  • models目录: 包含训练模型数据
  • samples_cpp目录: 包含操作设备的简单样例,运行样例需要 OpenCV 环境

注意: 编译样例后运需要把models目录、bin目录下动态库,拷贝到.exe可执行文件同一目录。

1.OpticalFlow

该API是基于EVS的光流实现。

Of函数

Of函数是光流类的初始化构造函数,参数释义如下:

    Of(
    uint16_t width,
    uint16_t height,
    uint8_t scale,
    uint8_t search_radius,
    uint8_t block_dimension);
  • width:EVS图像的宽。
  • height:EVS图像的高。
  • scale:EVS降采样倍数。
  • search_radius:表示的是光流搜索半径大小,通常建议为4。
  • block_dimension:表示的是光流计算相关特征所用的图像大小,通常建议为21,越大越准确但效率降低。

run函数

run函数是运行光流算法的核心函数,参数释义如下:

    int run(
    const cv::Mat& in_img,
    cv::Mat& out_img,
    uint8_t stack_nums = 1);
  • in_img:表示用来计算光流的EVS输入图像。通常0表示没有事件,1和2分别表示正负事件。
  • out_img:表示计算出的光流图像,用CV_8SC2类型来表示。每个像素的两个通道的值分别表示x,y的光流大小,符号表示方向
  • stack_nums:EVS叠帧的数量,默认为1,表示不叠帧,通常事件稀疏需要叠帧。

showOf函数

showOf函数是将run函数得到的光流图像用HVS空间箭头可视化出来,参数释义如下:

    int showOf(
    cv::Mat& of_result,
    cv::Mat& of_mask,
	uint8_t ratio = 2,
    uint8_t step = 2);
  • of_result:表示run函数计算出的光流图像。
  • of_mask:表示将of_result可视化后的光流的结果。
  • ratio:表示将可视化的光流箭头同比放大多少倍。
  • step:表示将可视化的光流箭头稀疏采样多少倍。

用例

// 使用光流算法
#include <AlpOpticalFlow/Of.h>

#include <iostream>
#include <iomanip>
#include <sstream>
#include <chrono>
#include <thread>
#include <ctime>
#include <regex>
#include <filesystem>
#include <fstream>

namespace fs = std::filesystem;
using  namespace ALP;

/**
 * @brief 用于存储和管理程序运行时所需的各种变量
 *
 * 该结构体包含处理 EVS 数据帧所需的成员变量,以及相关的线程和锁。
 */
struct SampleVar
{

    // 保护 EVS 数据帧列表的互斥锁
    std::mutex evs_mutex_;
    // 标记是否关闭数据处理
    bool is_close_ = false;
    // 播放 EVS 数据的线程
    std::unique_ptr<std::thread > evs_thread_;
    // 是否开启 EVS 数据存储
    bool is_evs_show_ = false;
    // evs 图像的宽度
    int evs_width_ = 768;
    // evs 图像的高度
    int evs_height_ = 608;

    std::string evs_image_dir_ = "C:/Users/SMTPC-0430/Desktop/Pic/EVS_RAW";//D:/TestData/Human/20250115161806780/evs_raw

    // 创建光流类
    std::shared_ptr<Of> optical_flow_ = nullptr;
};

std::shared_ptr<SampleVar> var_ = std::make_shared<SampleVar>();


/*
* @brief readRawImage 采用二进制方式读取 .raw 文件,并将其转换为 cv::Mat,以 8-bit 灰度格式解析数据。
*
* 直接使用 cv::imread 读取 .raw 文件会失败,因为它不是标准图片格式。
* 
*/

cv::Mat readRawImage(const std::string& filename, int width, int height)
{
    std::ifstream file(filename, std::ios::binary);
    if (!file) {
        std::cerr << "ERROR: Cannot open file: " << filename << std::endl;
        return cv::Mat();
    }

    cv::Mat image(height, width, CV_8UC1); // 8-bit 单通道灰度图
    image *= 100;
    file.read(reinterpret_cast<char*>(image.data), width * height);

    if (file.gcount() != width * height) {
        std::cerr << "WARNING: File size mismatch: " << filename << std::endl;
        return cv::Mat();
    }

    return image;
}


/**
 * @brief 显示 EVS 图像界面(本地文件版本)
 *
 * 该函数创建一个新的线程来处理和显示本地存储的EVS图像文件。
 * 图像文件将按文件系统顺序循环读取,并计算/显示光流信息。
 */
void displayEVS()
{
    var_->evs_thread_ = std::make_unique<std::thread>([&]()
        {
            var_->is_evs_show_ = true;

            std::vector<std::string> image_files;
            for (const auto& entry : fs::directory_iterator(var_->evs_image_dir_)) {
                if (entry.path().extension() == ".raw") {
                    image_files.push_back(entry.path().string());
                }
            }

            if (image_files.empty()) {
                std::cerr << "ERROR: No image files found in " << var_->evs_image_dir_ << std::endl;
                var_->is_evs_show_ = false;
                return;
            }

            std::sort(image_files.begin(), image_files.end()); // 确保按顺序处理
            size_t frame_index = 0;
            const int frame_delay = 30;

            while (!var_->is_close_) {
                cv::Mat tem = readRawImage(image_files[frame_index], var_->evs_width_, var_->evs_height_);
                if (tem.empty()) {
                    frame_index = (frame_index + 1) % image_files.size();
                    continue;
                }

                cv::Mat out;
                if (!var_->optical_flow_->run(tem, out, 10)) {
                    cv::Mat of_mask;
                    var_->optical_flow_->showOf(out, of_mask, 10, 3);
                    cv::namedWindow("of", cv::WINDOW_FREERATIO);
                    cv::imshow("of", of_mask);
                    cv::waitKey(1);
                }

                frame_index = (frame_index + 1) % image_files.size();
                std::this_thread::sleep_for(std::chrono::milliseconds(frame_delay));
            }

            var_->is_evs_show_ = false;
        });
}




/**
 * @brief 关闭设备
 *
 * 该函数用于关闭 Eiger 设备,停止所有数据流,并释放相关资源。
 */
void closeDevice()
{
    // 等待 EVS 显示线程结束
    if (var_->evs_thread_)
    {
        var_->evs_thread_->join();
        var_->evs_thread_ = nullptr;
    }
}


int main(int argc, char* argv[])
{
    // 创建光流类
    var_->optical_flow_ = std::make_shared<Of>(var_->evs_width_, var_->evs_height_, 6, 4, 31);
    displayEVS();
    closeDevice();
    return 0;
}

效果

of_flow

2.HandDetector

HandDetector函数

此函数用来构造具有初始手检测器类型的HandDetector对象,参数释义如下:

HandDetector(HandDetectorType type);
  • type: aps or evs Currently only supports HumanDetectorType::evs

detect函数

输入图像进行检测,然后从方框和地标中获取结果,参数释义如下:

int detect  ( const cv::Mat & image,  
  std::vector< cv::Rect > & boxes,  
  std::vector< std::vector< cv::Point2f > > & landmarks ) ;
  • image:输入图像
  • boxes:表示检测到的手部框结果
  • landmarks:表示手的关键点

init函数

初始化函数,参数释义如下:

int init(const std::string& device="cpu");
  • cpu" or "cuda", defalut is "cpu"

用例

#pragma execution_character_set("utf-8")
/**********************************************
* 此样例为播放保存的evs raw数据          *
***********************************************/

//手势检测
#include <ALPML/HandDetector/hand_detector.h>

#include <iostream>
#include <iomanip>
#include <sstream>
#include <chrono>
#include <thread>
#include <ctime>
#include <regex>
#include <filesystem>
#include <fstream>


namespace fs = std::filesystem;
using  namespace ALP;

/**
 * @brief 用于存储和管理程序运行时所需的各种变量
 *
 * 该结构体包含处理 APS 和 EVS 数据帧所需的成员变量,以及相关的线程和锁。
 */
struct SampleVar
{
    // 保护 EVS 数据帧列表的互斥锁
    std::mutex evs_mutex_;
    // 标记是否关闭数据处理
    bool is_close_ = false;
    // 播放 EVS 数据的线程
    std::unique_ptr<std::thread > evs_thread_;
    // 是否开启 EVS 数据存储
    bool is_evs_show_ = false;
    // evs 图像的宽度
    int evs_width_ = 768;
    // evs 图像的高度
    int evs_height_ = 608;
    // WriterFile类的智能指针
    const int play_evs_ = 2;
    // 创建手势检测
    std::shared_ptr<HandDetector> detector_ = nullptr;


    std::string evs_image_dir_ = "C:/Users/SMTPC-0430/Desktop/Pic/EVS_RAW";
};

std::shared_ptr<SampleVar> var_ = std::make_shared<SampleVar>();

/*
* @brief readRawImage 采用二进制方式读取 .raw 文件,并将其转换为 cv::Mat,以 8-bit 灰度格式解析数据。
*
* 直接使用 cv::imread 读取 .raw 文件会失败,因为它不是标准图片格式。
*
*/
cv::Mat readRawImage(const std::string& filename, int width, int height)
{
    std::ifstream file(filename, std::ios::binary);
    if (!file) {
        std::cerr << "ERROR: Cannot open file: " << filename << std::endl;
        return cv::Mat();
    }

    cv::Mat image(height, width, CV_8UC1); // 8-bit 单通道灰度图
    image *= 100;
    file.read(reinterpret_cast<char*>(image.data), width * height);

    if (file.gcount() != width * height) {
        std::cerr << "WARNING: File size mismatch: " << filename << std::endl;
        return cv::Mat();
    }

    return image;
}

/**
 * @brief 显示 EVS 图像界面
 *
 * 该函数创建一个新的线程来处理和显示 EVS 数据帧。
 * 在这个线程中,会从 `var_->evs_frames_` 列表中获取最新的 EVS 数据帧,
 * 并将其转换为 OpenCV 的 Mat 对象进行显示。
 */

void displayEVS()
{
    // 创建一个新的线程来处理 EVS 数据帧的显示
    var_->evs_thread_ = std::make_unique<std::thread>([&]()
        {
            // 开始存储EVS数据
            var_->is_evs_show_ = true;
            std::vector<std::string> image_files;
            for (const auto& entry : fs::directory_iterator(var_->evs_image_dir_)) {
                if (entry.path().extension() == ".raw") {
                    image_files.push_back(entry.path().string());
                }
            }

            if (image_files.empty()) {
                std::cerr << "ERROR: No image files found in " << var_->evs_image_dir_ << std::endl;
                var_->is_evs_show_ = false;
                return;
            }

            std::sort(image_files.begin(), image_files.end()); // 确保按顺序处理
            size_t frame_index = 0;
            const int frame_delay = 15;
            // 主循环,持续处理 EVS 数据直到关闭标志被设置
            while (!var_->is_close_)
            {
                // 获取互斥锁以保护 EVS 数据帧列表
                std::unique_lock<std::mutex> locker(var_->evs_mutex_);



                    const cv::Mat tem = readRawImage(image_files[frame_index], var_->evs_width_, var_->evs_height_);
                    if (tem.empty()) {
                        frame_index = (frame_index + 1) % image_files.size();
                        continue;
                    }

                    if (var_->detector_) {
                        std::vector<cv::Rect> box;
                        std::vector<std::vector<cv::Point2f>> landmarks;
                        cv::Mat image = tem;
                        var_->detector_->detect(image, box, landmarks);
                        cv::cvtColor(image, image, cv::COLOR_GRAY2BGR);
                        image *= 100;
                        for (size_t i = 0; i < box.size(); i++) {
                            cv::rectangle(image, box[i], cv::Scalar(0, 0, 255), 2);
                        }
                        for (auto& landmark : landmarks) {
                            for (auto& point : landmark) {
                                cv::circle(image, point, 2, cv::Scalar(0, 0, 255), 2);
                            }
                        }
                        cv::imshow("image", image);
                        cv::waitKey(25);
                    }
                    frame_index = (frame_index + 1) % image_files.size();
     

            }

            // 停止存储EVS数据
            var_->is_evs_show_ = false;
        });
}


/**
 * @brief 关闭设备
 *
 * 该函数用于关闭 Eiger 设备,停止所有数据流,并释放相关资源。
 */
void closeDevice()
{
    // 等待 EVS 显示线程结束
    if (var_->evs_thread_)
    {
        var_->evs_thread_->join();
        var_->evs_thread_ = nullptr;
    }
}

int main(int argc, char* argv[])
{
    // 创建手势检测
    var_->detector_ = std::make_shared<HandDetector>(HandDetectorType::evs);
    var_->detector_->init("cpu");
    // 启动显示 EVS 图像的线程
    displayEVS();
    closeDevice();
    return 0;
}

效果

hand

3.HumanDetector

HumanDetector函数

此函数用来构造具有初始手检测器类型的HumanDetector对象,参数释义如下:

HumanDetector(HumanDetectorType type);
  • type: aps or evs Currently only supports HumanDetectorType::evs

detect函数

输入要检测的图像,然后从框中获取结果,参数释义如下:

int detect(const cv::Mat& image, std::vector<cv::Rect>& boxes);
  • image:输入图像
  • boxes:输出检测框

init函数

初始化函数,参数释义如下:

int init  ( const std::string & device = "cpu" )
  • device type:"cpu" or "cuda", defalut is "cpu"

用例

#pragma execution_character_set("utf-8")
/**********************************************
*  此样例为播放保存的evs raw数据          *
***********************************************/

// 人形检测
#include <AlpML/HumanDetector/human_detector.h>

#include <iostream>
#include <iomanip>
#include <sstream>
#include <chrono>
#include <thread>
#include <ctime>
#include <regex>
#include <filesystem>
#include <fstream>


namespace fs = std::filesystem;
using  namespace ALP;

/**
 * @brief 用于存储和管理程序运行时所需的各种变量
 *
 * 该结构体包含处理 APS 和 EVS 数据帧所需的成员变量,以及相关的线程和锁。
 */
struct SampleVar
{
    // 保护 EVS 数据帧列表的互斥锁
    std::mutex evs_mutex_;
    // 标记是否关闭数据处理
    bool is_close_ = false;
    // 播放 EVS 数据的线程
    std::unique_ptr<std::thread > evs_thread_;
    // 是否开启 EVS 数据存储
    bool is_evs_show_ = false;
    // evs 图像的宽度
    int evs_width_ = 768;
    // evs 图像的高度
    int evs_height_ = 608;

    const int play_evs_ = 2;

    std::string evs_image_dir_ = "C:/Users/SMTPC-0430/Desktop/Pic/human/EVS_RAW";//D:/TestData/Human/20250115161806780/evs_raw C:/Users/SMTPC-0430/Desktop/Pic/human/EVS_RAW

    // 创建人形检测类
    std::shared_ptr<ALP::HumanDetector> detector_ = nullptr;
};

std::shared_ptr<SampleVar> var_ = std::make_shared<SampleVar>();

/*
* @brief readRawImage 采用二进制方式读取 .raw 文件,并将其转换为 cv::Mat,以 8-bit 灰度格式解析数据。
*
* 直接使用 cv::imread 读取 .raw 文件会失败,因为它不是标准图片格式。
*
*/
cv::Mat readRawImage(const std::string& filename, int width, int height)
{
    std::ifstream file(filename, std::ios::binary);
    if (!file) {
        std::cerr << "ERROR: Cannot open file: " << filename << std::endl;
        return cv::Mat();
    }

    cv::Mat image(height, width, CV_8UC1); // 8-bit 单通道灰度图
    image *= 100;
    file.read(reinterpret_cast<char*>(image.data), width * height);

    if (file.gcount() != width * height) {
        std::cerr << "WARNING: File size mismatch: " << filename << std::endl;
        return cv::Mat();
    }

    return image;
}

/**
 * @brief 显示 EVS 图像界面
 *
 * 该函数创建一个新的线程来处理和显示 EVS 数据帧。
 * 在这个线程中,会从 `var_->evs_frames_` 列表中获取最新的 EVS 数据帧,
 * 并将其转换为 OpenCV 的 Mat 对象进行显示。
 */
void displayEVS()
{
    // 创建一个新的线程来处理 EVS 数据帧的显示
    var_->evs_thread_ = std::make_unique<std::thread>([&]()
        {
            // 开始存储EVS数据
            var_->is_evs_show_ = true;

            var_->is_evs_show_ = true;
            std::vector<std::string> image_files;
            for (const auto& entry : fs::directory_iterator(var_->evs_image_dir_)) {
                if (entry.path().extension() == ".raw") {
                    image_files.push_back(entry.path().string());
                }
            }

            if (image_files.empty()) {
                std::cerr << "ERROR: No image files found in " << var_->evs_image_dir_ << std::endl;
                var_->is_evs_show_ = false;
                return;
            }

            std::sort(image_files.begin(), image_files.end()); // 确保按顺序处理
            size_t frame_index = 0;
            const int frame_delay = 15;
            // 主循环,持续处理 EVS 数据直到关闭标志被设置
            while (!var_->is_close_)
            {
                // 获取互斥锁以保护 EVS 数据帧列表
                std::unique_lock<std::mutex> locker(var_->evs_mutex_);



                const cv::Mat tem = readRawImage(image_files[frame_index], var_->evs_width_, var_->evs_height_);
                if (tem.empty()) {
                    frame_index = (frame_index + 1) % image_files.size();
                    continue;
                }

                if (var_->detector_)
                {
                    std::vector<cv::Rect> box;
                    cv::Mat image = tem;
                    var_->detector_->detect(image, box);
                    cv::cvtColor(image, image, cv::COLOR_GRAY2BGR);
                    image *= 100;
                    for (size_t i = 0; i < box.size(); i++)
                    {
                        cv::rectangle(image, box[i], cv::Scalar(0, 0, 255), 2);
                    }
                    cv::imshow("image", image);
                    cv::waitKey(25);
                }
                frame_index = (frame_index + 1) % image_files.size();


            }

            // 停止存储EVS数据
            var_->is_evs_show_ = false;
        });

}


/**
 * @brief 关闭设备
 *
 * 该函数用于关闭 Eiger 设备,停止所有数据流,并释放相关资源。
 */
void closeDevice()
{
    // 等待 EVS 显示线程结束
    if (var_->evs_thread_)
    {
        var_->evs_thread_->join();
        var_->evs_thread_ = nullptr;
    }

}


int main(int argc, char* argv[])
{
    // 创建手势检测
    var_->detector_ = std::make_shared<HumanDetector>(HumanDetectorType::evs);
    var_->detector_->init("cpu");
    // 启动显示 EVS 图像的线程
    displayEVS();
    closeDevice();
    return 0;
}

效果

human

在 GitHub 上编辑此页
上次更新:
贡献者: szm