MindX SDK简介

MindX是一款针对昇腾系列AI芯片的软件开发工具包(SDK),它提供了一系列的API和工具,帮助开发者对昇腾系列AI芯片进行开发和优化。提供了一系列的部署工具,可以将优化后的AI模型部署到昇腾AI芯片上,进行实时推理,实现低延迟、高性能的AI应用。其突出特点是使用流程编排进行开发。

总的来说,MindX SDK为开发者提供了一套完整的开发环境和工具,帮助开发者轻松地进行昇腾系列AI芯片的开发、优化和部署,实现高性能、低功耗的AI应用。
在这里插入图片描述

插件的Buffer与Metadata

Plugin表示业务流程中的基础模块,通过Element的串接构建成一个Stream。Buffer用于内部挂载解码前后的视频、图像数据,是Element之间传递的数据结构,同时也允许用户挂载元数据(Metadata),用于存放结构化数据(如目标检测结果)或过程数据(如缩放后的图像)。如下图,Metadata依附于buffer。
在这里插入图片描述
在这里插入图片描述

自定义插件

Init初始化接口

virtual APP_ERROR Init(std::map<std::string, std::shared_ptr<void>>& configParamMap) = 0;

插件json版:该插件名为mxpi_webpushstream0

"mxpi_webpushstream0": {
    "props": {
        "dataSourceCoordinate": "mxpi_objectpostprocessor0",
        "channelId": "0",
        "deviceId": "0"
    },
    "factory": "mxpi_webpushstream",
    "next": "fakesink0"
},

获取基础资源,获取控件的基本属性(“props”),读取的原始属性都是字符串,需要进行转换,也可以读取本地自定义的配置文件:

APP_ERROR WebPushStream::Init(std::map<std::string, std::shared_ptr<void>>& configParamMap)
{
     for (const auto& kv : configParamMap) {
        const std::string& key = kv.first;
        std::cout<<key;
     }
    channelId_ = *std::static_pointer_cast<uint>(configParamMap["channelId"]);
    if (channelId_ == -1) {
        LogInfo << "Failed to read the channelId";
        return APP_ERR_COMM_INIT_FAIL;
    }
    coordinateDataSource_ = *std::static_pointer_cast<std::string>(configParamMap["dataSourceCoordinate"]);
    if (coordinateDataSource_ == "") {
        LogInfo << "Failed to read the dataSourceCoordinate";
        return APP_ERR_COMM_INIT_FAIL;
    }
    if (!schedulerRun_) {
        Scheduler::GetInstance()->Run("./config/web.config");
        schedulerRun_ = true;
    }

    return APP_ERR_OK;
}

DeInit资源释放接口

用于自定义资源的释放

APP_ERROR WebPushStream::DeInit()
{
    Scheduler::GetInstance()->Stop();
    return APP_ERR_OK;
}

Process插件入口

插件之间传递的数据统一采用protobuf定义,具体的数据格式参考Metadata和Metadata proto文件。相应的输入数据通过protobuf解析,输出结果通过protobuf组装。
std::vector<MxpiBuffer *>& mxpiBuffer代表插件的入参。mxpiBuffer[0]代表插件入口0端口的buffer,mxpiBuffer[1]代表插件入口1端口的buffer;

APP_ERROR WebPushStream::Process(std::vector<MxpiBuffer *>& mxpiBuffer)
{
    MxpiBuffer *streamBuffer = mxpiBuffer[0];
    MxpiBuffer *inferBuffer = mxpiBuffer[1];
    if (streamBuffer) {
        MxTools::MxpiMetadataManager mxpiMetadataManager(*streamBuffer);
        errorInfo_.str("");
        if (mxpiMetadataManager.GetErrorInfo() != nullptr) {
            LogDebug << "Input data is invalid, element(" << elementName_ <<") plugin will not be executed rightly.";
            SendData(0, *streamBuffer);
            return APP_ERR_OK;
        }
        //使用GetHostDataInfo取其接口,用于从MxpiBuffer中获取Host内存相关信息。如果在device侧,用device的相关接口
        //MxpiFrame用于存放帧信息,包括图像数据,详见https://www.hiascend.com/document/detail/zh/mind-   sdk/300/vision/mxvisionug/mxmanufactureug_0575.html#ZH-CN_TOPIC_0000001537875962__table144651455122610
        MxTools::MxpiFrame streamMxpiBuffer = MxpiBufferManager::GetHostDataInfo(*streamBuffer);
        if (!WsManager::GetInstance()->VideoChannelIsAlive(channelId_ + 1)) {
            if (!webDataMap_.empty()) {
                webDataMap_.clear();
            }
            SendData(0, *streamBuffer);
            return APP_ERR_OK;
        }
        //发送至下一个元件的0端口
        SendData(0, *streamBuffer);
        //也可以调用MxpiMetadataManager类的AddMetadata接口,将元数据加载到streamBuffer上。
        //APP_ERROR AddMetadata(const std::string& key, std::shared_ptr<void> metadata);
    }

    if (inferBuffer) {
        MxTools::MxpiMetadataManager mxpiMetadataManager(*inferBuffer);
        //获取buffer上挂载的Metadata,并验证该data的类型,如果类型不对,则返回空指针。
        std::shared_ptr<MxTools::MxpiObjectList> mxpiObjectList = std::static_pointer_cast<MxTools::MxpiObjectList>(
        mxpiMetadataManager.GetMetadataWithType(coordinateDataSource_,"MxpiObjectList"));
        if(mxpiObjectList==nullptr)
         {
           std::cout<<"bad type!!!!!!!!!!!!!!!!!!!!!!!!!!";
         }
         else
         {
           mxpiObjectList->objectvec_size();
         }
        //下面这段代码可获取并打印matedata上的所有key值名,key值通常为插件名,如mxpi_imageresize0,如不包含该key,说明该插件未将对应元数据挂载到buffer上。
         auto re=mxpiMetadataManager.GetAllMetaData();
         for (const auto& kv : re) {
         const std::string& key = kv.first;
         std::cout << "Key: " <<key<< std::endl;
         } 

        errorInfo_.str("");
        if (mxpiMetadataManager.GetErrorInfo() != nullptr) {
            LogDebug << "Input data is invalid, element(" << elementName_ <<") plugin will not be executed rightly.";
            SendData(0, *inferBuffer);
            return APP_ERR_OK;
        }
        MxTools::MxpiFrame streamMxpiBuffer = MxpiBufferManager::GetDeviceDataInfo(*inferBuffer);
        if (!WsManager::GetInstance()->VideoChannelIsAlive(channelId_ + 1) || webDataMap_.empty()) {
            SendData(0, *inferBuffer);
            return APP_ERR_OK;
        }

        SendDataToWeb(inferBuffer);
        SendData(0, *inferBuffer);
    }
    return APP_ERR_OK;
}

DefineProperties接口

这里进行自定义属性的添加:

std::vector<std::shared_ptr<void>> WebPushStream::DefineProperties()
{
    std::vector<std::shared_ptr<void>> properties;
    auto coordinateDataSourceSptr = std::make_shared<ElementProperty<std::string>>(ElementProperty<std::string> {
            STRING, "dataSourceCoordinate", "name", "The coordinate data source", "", "", ""
    });
    auto channelIdSptr = std::make_shared<ElementProperty<uint>>(
            ElementProperty<uint> { UINT, "channelId", "name", "channel id", 0, 0, UINT_MAX });
    properties.push_back(coordinateDataSourceSptr);
    properties.push_back(channelIdSptr);
    return properties;
}

DefineInputPorts接口

自定义插件的接口添加了两个万用接口

MxpiPortInfo WebPushStream::DefineInputPorts()
{
    MxpiPortInfo inputPortInfo;
    std::vector<std::vector<std::string>> value = {{"ANY"}, {"ANY"}};
    GenerateStaticInputPortsInfo(value, inputPortInfo);
    return inputPortInfo;
}
Logo

昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链

更多推荐