[E2E_L9]GOMFCTemplate的融合进阶
在前面出现的融合方法中,最突出的问题就是每次运算,都需要将整个推断的过程全部操作一遍,这样肯定是费时间的——所以我们需要将能够独立的地方独立出来,但是这个过中非常容易出现溢出的错误——经过一段时间的尝试,终于得到了相对稳定的结果,这里将结果记录下来:
// 用于推断的函数
Mat CGOMfcTemplate2Dlg::IEInfer(Mat m_mainframe)
{
//初始化IE
// --------------------------- 1.为IE准备插件-------------------------------------
InferencePlugin plugin(PluginDispatcher().getSuitablePlugin(TargetDevice::eCPU));
plugin.AddExtension(std::make_shared<Extensions::Cpu::CpuExtensions>());//Extension,useful
// --------------------------- 2.读取IR模型(xml和bin)---------------------------------
CNNNetReader networkReader;
networkReader.ReadNetwork("./road-segmentation-adas-0001.xml");
networkReader.ReadWeights("./road-segmentation-adas-0001.bin");
CNNNetwork network = networkReader.getNetwork();
// --------------------------- 3. 准备输入输出的------------------------------------------
InputsDataMap inputInfo(network.getInputsInfo());//获得输入信息
if (inputInfo.size() != 1) throw std::logic_error("错误,该模型应该为单输入");
auto lrInputInfoItem = inputInfo["data"]; //开始读入
int w = static_cast<int>(lrInputInfoItem->getTensorDesc().getDims()[3]); //模型要求的输入大小
int h = static_cast<int>(lrInputInfoItem->getTensorDesc().getDims()[2]);
network.setBatchSize(1);//只有1副图片,故BatchSize = 1
//准备输出数据
OutputsDataMap outputInfo(network.getOutputsInfo());//获得输出信息
std::string firstOutputName;
for (auto &item : outputInfo) {
if (firstOutputName.empty()) {
firstOutputName = item.first;
}
DataPtr outputData = item.second;
if (!outputData) {
throw std::logic_error("错误的格式,请检查!");
}
item.second->setPrecision(Precision::FP32);
}
// --------------------------- 4. 读取模型 ------------------------------------------(目视第4步骤最消耗时间)
ExecutableNetwork executableNetwork = plugin.LoadNetwork(network, {});
// --------------------------- 5. 创建推断 -------------------------------------------------
infer_request = executableNetwork.CreateInferRequest();
// --------------------------- 6. 将数据塞入模型 -------------------------------------------------
Blob::Ptr lrInputBlob = infer_request.GetBlob("data"); //data这个名字是我看出来的,实际上这里可以更统一一些
matU8ToBlob<float_t>(m_mainframe, lrInputBlob, 0);//重要的转换函数,第3个参数是batchSize,应该是自己+1的
// --------------------------- 7. 推断结果 -------------------------------------------------
infer_request.Infer();//多张图片多次推断
// --------------------------- 8. 处理结果-------------------------------------------------------
const Blob::Ptr outputBlob = infer_request.GetBlob(firstOutputName);
const auto outputData = outputBlob->buffer().as<PrecisionTrait<Precision::FP32>::value_type*>();
size_t numOfImages = outputBlob->getTensorDesc().getDims()[0];
size_t numOfChannels = outputBlob->getTensorDesc().getDims()[1];
h = outputBlob->getTensorDesc().getDims()[2];
w = outputBlob->getTensorDesc().getDims()[3];
size_t nunOfPixels = w * h; //写在内存里的结果,还是要拼出来的
std::vector<cv::Mat> imgPlanes{ cv::Mat(h, w, CV_32FC1, &(outputData[0])),
cv::Mat(h, w, CV_32FC1, &(outputData[nunOfPixels])),
cv::Mat(h, w, CV_32FC1, &(outputData[nunOfPixels * 2])) };
for (auto & img : imgPlanes) //本来是平的
img.convertTo(img, CV_8UC1, 255);
cv::Mat resultImg;
cv::merge(imgPlanes, resultImg);
return resultImg;
}

ExecutableNetwork executableNetwork = plugin.LoadNetwork(network, {});
infer_request.Infer();//多张图片多次推断


CNNNetwork CGOMfcTemplate2Dlg::IENetWork(string strXML, string strBIN)
{
CNNNetReader networkReader;
networkReader.ReadNetwork(strXML);
networkReader.ReadWeights(strBIN);
CNNNetwork network = networkReader.getNetwork();
return network;
}
string CGOMfcTemplate2Dlg::IENetSetup(CNNNetwork network)
{
InputsDataMap inputInfo(network.getInputsInfo());//获得输入信息
BlobMap inputBlobs; //保持所有输入的blob数据
if (inputInfo.size() != 1) throw std::logic_error("错误,该模型应该为单输入");
auto lrInputInfoItem = inputInfo["data"]; //开始读入
int h = static_cast<int>(lrInputInfoItem->getTensorDesc().getDims()[2]);
int w = static_cast<int>(lrInputInfoItem->getTensorDesc().getDims()[3]); //模型要求的输入大小
network.setBatchSize(1);//只有1副图片,故BatchSize = 1
//准备输出数据
OutputsDataMap outputInfo(network.getOutputsInfo());//获得输出信息
std::string firstOutputName;
for (auto &item : outputInfo) {
if (firstOutputName.empty()) {
firstOutputName = item.first;
}
DataPtr outputData = item.second;
if (!outputData) {
throw std::logic_error("错误的格式,请检查!");
}
item.second->setPrecision(Precision::FP32);
}
return firstOutputName;
}
InferencePlugin CGOMfcTemplate2Dlg::IEplugin(CNNNetwork network)
{
InferencePlugin plugin(PluginDispatcher().getSuitablePlugin(TargetDevice::eCPU));
plugin.AddExtension(std::make_shared<Extensions::Cpu::CpuExtensions>());//Extension,useful
return plugin;
}
ExecutableNetwork CGOMfcTemplate2Dlg::getNetWork(InferencePlugin plugin, CNNNetwork network)
{
ExecutableNetwork executableNetwork = plugin.LoadNetwork(network, {});
return executableNetwork;
}

std::string firstOutputName = IENetSetup(network);
InferRequest infer_request = executableNetwork.CreateInferRequest();
Blob::Ptr lrInputBlob = infer_request.GetBlob("data");
matU8ToBlob<float_t>(m_mainframe, lrInputBlob, 0);//重要的转换函数,第3个参数是batchSize,应该是自己+1的
// ---------------------------推断结果 -------------------------------------------------
infer_request.Infer();//多张图片多次推断
// ---------------------------处理结果-------------------------------------------------------
const Blob::Ptr outputBlob = infer_request.GetBlob(firstOutputName);
const auto outputData = outputBlob->buffer().as<PrecisionTrait<Precision::FP32>::value_type*>();
size_t numOfImages = outputBlob->getTensorDesc().getDims()[0];
size_t numOfChannels = outputBlob->getTensorDesc().getDims()[1];
int h = outputBlob->getTensorDesc().getDims()[2];
int w = outputBlob->getTensorDesc().getDims()[3];
size_t nunOfPixels = w * h; //写在内存里的结果,还是要拼出来的
std::vector<cv::Mat> imgPlanes{ cv::Mat(h, w, CV_32FC1, &(outputData[0])),
cv::Mat(h, w, CV_32FC1, &(outputData[nunOfPixels])),
cv::Mat(h, w, CV_32FC1, &(outputData[nunOfPixels * 2])) };
for (auto & img : imgPlanes) //本来是平的
img.convertTo(img, CV_8UC1, 255);
cv::Mat resultImg;
cv::merge(imgPlanes, resultImg);
showImage(resultImg, IDC_PIC); //显示原始图像
//摄像头显示循环,所有关于采集的操作是通过主线程传递控制变量到采集线程,而后由采集线程完成的
DWORD WINAPI CaptureThread(LPVOID lpParameter)
{
CGOMfcTemplate2Dlg* pDlg = (CGOMfcTemplate2Dlg*)lpParameter;
double t_start = (double)cv::getTickCount(); //开始时间
Mat tmpPrydown;
//#pragma omp parallel for
while (true)
{
if (pDlg->b_closeCam)//退出循环
break;
double t = ((double)cv::getTickCount() - t_start) / getTickFrequency();
if (t <= 0.1)//fps =10,主动降低速度
{
Sleep(100);
continue;
}
else
{
t_start = (double)cv::getTickCount();
}
//从directX中获得当前图像并显示出来
IplImage* queryframe = pDlg->cameraDs.QueryFrame();
//在2.0版本中可以强转,在3.0中需要使用函数
Mat camframe = cvarrToMat(queryframe);
pDlg->showImage(camframe, IDC_CAM); //显示原始图像
////根据条件,决定是否采用算法
Mat dst;
Mat img;
Mat tmp;
Mat divideGaussMin;
Mat divideGaussMiddle;
Mat divideGaussMax;
cvtColor(camframe, img, COLOR_BGR2GRAY);
cvtColor(img, img, COLOR_GRAY2BGR);
if (pDlg->bMethod) //这里实现的是灰度转彩色
{
//算法
if (img.empty())
{
return -1;
}
std::string firstOutputName = pDlg->IENetSetup(pDlg->network);
InferRequest infer_request = pDlg->executableNetwork.CreateInferRequest();
Blob::Ptr lrInputBlob = infer_request.GetBlob("data");
matU8ToBlob<float_t>(img, lrInputBlob, 0);//重要的转换函数,第3个参数是batchSize,应该是自己+1的
// ---------------------------推断结果 -------------------------------------------------
infer_request.Infer();//多张图片多次推断
// ---------------------------处理结果-------------------------------------------------------
const Blob::Ptr outputBlob = infer_request.GetBlob(firstOutputName);
const auto outputData = outputBlob->buffer().as<PrecisionTrait<Precision::FP32>::value_type*>();
size_t numOfImages = outputBlob->getTensorDesc().getDims()[0];
size_t numOfChannels = outputBlob->getTensorDesc().getDims()[1];
int h = outputBlob->getTensorDesc().getDims()[2];
int w = outputBlob->getTensorDesc().getDims()[3];
size_t nunOfPixels = w * h; //写在内存里的结果,还是要拼出来的
std::vector<cv::Mat> imgPlanes{ cv::Mat(h, w, CV_32FC1, &(outputData[0])),
cv::Mat(h, w, CV_32FC1, &(outputData[nunOfPixels])),
cv::Mat(h, w, CV_32FC1, &(outputData[nunOfPixels * 2])) };
for (auto & img : imgPlanes) //本来是平的
img.convertTo(img, CV_8UC1, 255);
cv::merge(imgPlanes, dst);
}
else
{
dst = img.clone();
}
pDlg->showImage(dst, IDC_PIC); //显示网络处理图像
}
return 0;
}
附件列表
[E2E_L9]GOMFCTemplate的融合进阶的更多相关文章
- [E2E_L8_1]segmentation_demo道路分割例子和GOMFCTemplate的初步融合
一.来源 模型例子自己带来副图像 二.简化 #include <algorithm> #include <fstream> #include <iomanip ...
- (E2E_L2)GOMfcTemplate在vs2017上的运行并融合Dnn模块
GOMfcTemplate一直运行在VS2012上运行的,并且开发出来了多个产品.在技术不断发展的过程中,出现了一些新的矛盾:1.由于需要使用DNN模块,而这个模块到了4.0以上的OpenCV才支持的 ...
- [BZOI2014]大融合——————线段树进阶
竟然改了不到一小时就改出来了, 可喜可贺 Description Solution 一开始想的是边两侧简单路径之和的乘积,之后发现这是个树形结构,简单路径数就是节点数. 之后的难点就变成了如何求线段树 ...
- C#进阶系列——WebApi 接口参数不再困惑:传参详解
前言:还记得刚使用WebApi那会儿,被它的传参机制折腾了好久,查阅了半天资料.如今,使用WebApi也有段时间了,今天就记录下API接口传参的一些方式方法,算是一个笔记,也希望能帮初学者少走弯路.本 ...
- NLP系列(4)_朴素贝叶斯实战与进阶
作者: 寒小阳 && 龙心尘 时间:2016年2月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/50629608 htt ...
- Ionic APP-Web SPA开发进阶(一)AngularJS全栈工程狮进阶
AngularJS全栈工程狮进阶 前言 学习了一段时间AngularJS,开始接触移动端APP开发.为了响应公司开发需求,采用"Hybrid"混血开发方法.采用Ionic前端框架, ...
- 【进阶3-3期】深度广度解析 call 和 apply 原理、使用场景及实现(转)
这是我在公众号(高级前端进阶)看到的文章,现在做笔记 https://github.com/yygmind/blog/issues/22 call() 和 apply() call() 方法调用一个 ...
- Apollo 1 融合 Spring 的三个入口
前言 Spring 作为 Java 世界非官方标准框架,任何一个中间件想要得到良好的发展,必须完美支持 Spring 的各种特性,即:无缝融入 Spring. Apollo 作为分布式配置中心,服务于 ...
- Scala进阶之路-为什么要学习Scala以及开发环境搭建
Scala进阶之路-为什么要学习Scala以及开发环境搭建 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 最近人工智能和大数据那是相当的火呀,人工智能带动了Python的流行,区块 ...
随机推荐
- Linux指令(时间日期类)
date指令-显示当前日期 基本语法: 1)date (功能描述:显示当前时间) 2)date +%Y (功能描述:显示当前年份) 3)date +%m (功能描述:显示当前月份) 4)date +% ...
- nano的简单笔记
CTRL+c 显示行数信息 ctrl + _ 到某行 alt +m 移动光标功能 alt+y 语法矫正功能
- 2019年牛客多校第二场 H题Second Large Rectangle
题目链接 传送门 题意 求在\(n\times m\)的\(01\)子矩阵中找出面积第二大的内部全是\(1\)的子矩阵的面积大小. 思路 处理出每个位置往左连续有多少个\(1\),然后对每一列跑单调栈 ...
- python笔记36-装饰器之wraps
前言 前面一篇对python装饰器有了初步的了解了,但是还不够完美,领导看了后又提出了新的需求,希望运行的日志能显示出具体运行的哪个函数. __name__和doc __name__用于获取函数的名称 ...
- js中的全局对象
- 写一段程序,删除字符串a中包含的字符串b,举例 输入a = "asdw",b = "sd" 返回 字符串 “aw”;一个容易被忽略的bug
代码如下: public class test{ public static void main(String args[]){ String test=test("sahsjkshabsh ...
- CF622F——自然数幂和模板&&拉格朗日插值
题意 求 $ \displaystyle \sum_{i=1}^n i^k \ mod (1e9+7), n \leq 10^9, k \leq 10^6$. CF622F 分析 易知答案是一个 $k ...
- CDN工作机制
CDN(content delivery network),即内容分布网络,是一种构建在现有Internet上的一种先进的流量分配网络.CDN以缓存网站中的静态数据为主,当用户请求动态内容时,先从CD ...
- Thread线程框架学习
原文:https://www.cnblogs.com/wangkeqin/p/9351299.html Thread线程框架 线程定义:线程可以理解为一个特立独行的函数.其存在的意义,就是并行,避免了 ...
- Linux 重启 PHP-FPM 命令
1. 停止命令 pkill php-fpm 2.重启或启动命令 php-fpm -R