[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的流行,区块 ...
随机推荐
- RocketMQ-c#代码
导入包: https://github.com/gaufung/rocketmq-client-dotnet/tree/master using org.apache.rocketmq.client. ...
- django的缓存实例应用
那么多的可配置方法,我们用那个呢. 首先在setting中配置你想要的缓存,我这里就用文件的方式是配置.如图: 第二步: 第三步: 第四步: 实现结果: 总结: 都是指明当前资源的有效期,控制浏览器 ...
- 【Docker】docker安装Jenkins
一.下载镜像 docker pull jenkinsci/jenkins 二.运行Jenkins容器 docker run --name myjenkins -d -p 8580:8080 -p 50 ...
- Linux必知必会--grep
花更少的时间,去验证一件事情:你到底是富翁,还是贫民. --一位历经沧桑的炒客 转自:https://man.linuxde.net/grep grep命令 grep(global search re ...
- Maven之setting.xml 配置详解
文件存放位置 全局配置: ${M2_HOME}/conf/settings.xml 用户配置: ${user.home}/.m2/settings.xml note:用户配置优先于全局配置.${use ...
- dockerhub下载加速
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f5dad4ec.m.daocloud.io syste ...
- MySQL——查询优化|47s到0.1s|我做了什么
前言 这个代码是之前的同事写的,现在我接管了,但是今天早上我打开这个模块的时候发现数据加载异常的缓慢,等了将近一分钟左右数据才显示到页面. 这特么的绝对不正常啊,数据量压根没那么多呀,这特喵的什么情况 ...
- C++中指针形参问题
1.C++指针做形参,会有很多陷阱,很多时候也许并不如我们想的那样.比如我们想通过一个函数改变指针的值: #include<</SPAN>iostream> using nam ...
- bfs与dfs小结
1,bfs适合状态容易存储的题目,如果状态比较难存储,就难以进行记忆化搜索,必然会难以bfs. (比如听说滑雪这个题你用bfs会死得很难看) 2,但是有些题目会很深(比如网格单源最短路),用dfs会跑 ...
- Windbg妙用
计算器 当你在调试,需要做一些从十六进制到十进制的简单转换,一些整数计算你不需要切换到calc.exe,你可以只使用windbg的表达式计算器.假设你得到了一个十六进制的大小,比如说2e903000, ...