C++中使用OPENCV对深度学习的特征图进行可视化
//需要先在运行目录下创建文件夹opencv_layers
#include <iostream>
#include <unistd.h>
#include <opencv4/opencv2/opencv.hpp>
#include <opencv4/opencv2/dnn.hpp>
#include <opencv4/opencv2/dnn/dnn.hpp> using namespace std; /*
equal list opencv_conv*relu = pycaffe_conv* */ int main(int argc, char *argv[])
{
//// SHOULD BE 4.*.*
cerr<<"WORKING IN OPENCV_VERSION "<<CV_VERSION<<'\n';
cv::Mat src = cv::imread("src.jpg"); string cfg ="deploy.prototxt";
string weights ="net_iter_25000.caffemodel";
cv::dnn::Net net = cv::dnn::readNetFromCaffe(cfg,weights); if(net.empty()){
cerr<<"loaded net failed.\n";
return -;
} cv::Mat inputBlob = cv::dnn::blobFromImage(src, /.F, cv::Size(, ), cv::Scalar(), false, false);
net.setInput(inputBlob,"data"); vector<cv::String> outputname=net.getLayerNames();
outputname.insert(outputname.begin(),"data");
cv::dnn::MatShape netInputSize = {,,,};
vector<cv::dnn::MatShape> netlastSize;
vector<vector<cv::dnn::MatShape> >layerSizes;
for(size_t i=;i<outputname.size();++i){
vector<cv::dnn::MatShape>inputLayerSize;
vector<cv::dnn::MatShape>outputLayerSize;
net.getLayerShapes(netInputSize,i,inputLayerSize,outputLayerSize);
cerr<<"layer <<"<<outputname[i]<<">> size [\n";
for(size_t j=;j<inputLayerSize.size();++j){
cerr<<"\t["<<inputLayerSize[j][];for(size_t k=;k<inputLayerSize[j].size();++k)cerr<<" x "<<inputLayerSize[j][k];cerr<<"]\n";
}
cerr<<"\tto\n";
for(size_t j=;j<outputLayerSize.size();++j){
cerr<<"\t["<<outputLayerSize[j][];for(size_t k=;k<outputLayerSize[j].size();++k)cerr<<" x "<<outputLayerSize[j][k];cerr<<"]\n";
}
cerr<<"]\n";
layerSizes.push_back(outputLayerSize);
netlastSize=inputLayerSize;
} vector<vector<cv::Mat> > outputBlob;
try{
cerr<<"\nNet forward ";
net.forward(outputBlob, outputname);
cerr<<"done\n\n";
}catch(exception e){
cerr << e.what() << '\n';
} string selectLayer="conv4"; for(size_t i=;i<outputname.size();++i){ for(size_t j=;j<outputBlob[i].size();++j){
try{ cv::Mat blob;
cv::normalize(outputBlob[i][j], blob, , , cv::NORM_MINMAX); cerr<<"blob dim = "<<blob.size.dims()<<" with type "<<blob.type()<<'\n';
//b * c * w * h
//b * w * h
//b * w
cerr<<"blob shape ["<<blob.size.p[];for(size_t k=;k<blob.size.dims();++k)cerr<<" x "<<blob.size.p[k];cerr<<"]\n";
cerr<<"real shape ["<<layerSizes[i][j][];for(size_t k=;k<layerSizes[i][j].size();++k)cerr<<" x "<<layerSizes[i][j][k];cerr<<"]\n"; cv::Mat saveimg;
float* data=(float*)blob.data;
string savepath;
int s[]={}; switch(blob.size.dims()){
case :
saveimg.create(layerSizes[i][j][],,CV_8UC1);
for(size_t pi=; pi<layerSizes[i][j][]; ++pi){
saveimg.data[pi]=data[pi];
}
savepath = "opencv_layers/layer_"+strip(outputname[i],"/")+".jpg";
cv::imwrite(savepath,saveimg);
saveimg.release();
break;
case :
s[]=layerSizes[i][j][];
s[]=layerSizes[i][j][];
saveimg.create(layerSizes[i][j][],layerSizes[i][j][],CV_8UC1);
for(size_t pi=; pi<s[]*s[]; ++pi){
saveimg.data[pi]=(uchar)data[pi];
}
savepath = "opencv_layers/layer_"+strip(outputname[i],"/")+".jpg";
cv::imwrite(savepath,saveimg);
saveimg.release();
break;
case :
s[]=layerSizes[i][j][];
s[]=layerSizes[i][j][];
s[]=s[]*s[];
s[]=ceil(sqrt(layerSizes[i][j][]));
s[]=;
saveimg=cv::Mat::zeros((s[]+)*s[],(s[]+)*s[],CV_8UC1);
fprintf(stderr,"saveimg <%d,%d> for %d\n",saveimg.rows,saveimg.cols,layerSizes[i][j][]);
for(size_t wy=; wy<s[]; ++wy){
for(size_t wx=; wx<s[]; ++wx){
if(s[]>=layerSizes[i][j][])break;
s[]=;
for(size_t py=; py<s[]; ++py){
for(size_t px=; px<s[]; ++px){
saveimg.data[(wy*(s[]+)+py)*s[]*(s[]+)+wx*(s[]+)+px]=(uchar)data[s[]*s[]+s[]];
++s[];
}
}
++s[];
}
} savepath = "opencv_layers/layer_"+strip(outputname[i],"/")+".jpg";
cv::imwrite(savepath,saveimg);
saveimg.release();
break;
default:
cerr<<" exordinary dim\n";
break;
}
cerr<<"save to "<<savepath<<'\n'; blob.release();
}catch(exception e){
cerr<<" escape beacuse "<<e.what()<<'\n';
}
}
} fprintf(stderr, "float %d, double %d\n",sizeof(float),sizeof(double));
//blob <CV_32FC1,5> float
fprintf(stderr, "type list : <CV_8UC1,%d> <CV_8UC3,%d> <CV_16FC1,%d> <CV_16FC3,%d> <CV_16SC1,%d> <CV_16SC3,%d> <CV_32FC1,%d> <CV_32SC1,%d> ",
CV_8UC1,CV_8UC3,CV_16FC1,CV_16FC3,CV_16SC1,CV_16SC3,CV_32FC1,CV_32SC1);
return ;
}
C++中使用OPENCV对深度学习的特征图进行可视化的更多相关文章
- Opencv调用深度学习模型
https://blog.csdn.net/lovelyaiq/article/details/79929393 https://blog.csdn.net/qq_29462849/article/d ...
- 语义分割:基于openCV和深度学习(二)
语义分割:基于openCV和深度学习(二) Semantic segmentation in images with OpenCV 开始吧-打开segment.py归档并插入以下代码: Semanti ...
- 语义分割:基于openCV和深度学习(一)
语义分割:基于openCV和深度学习(一) Semantic segmentation with OpenCV and deep learning 介绍如何使用OpenCV.深度学习和ENet架构执行 ...
- 蛋白质组DIA深度学习之谱图预测
目录 1. 简介 2. 近几年发表的主要工具 1.DeepRT 2.Prosit 3. DIANN 4.DeepDIA 1. 简介 基于串联质谱的蛋白质组学大部分是依赖于数据库(database se ...
- Android中AdapterView/Adapter的深度学习
BaseAdapter的深度学习 博主工作了几年,也用了几年的ListView等AdapterView控件,但关于Adapter的一些问题并没有深入下去,终于有时间学习总结下关于BaseAdapter ...
- 使用VS+OpenCV调用深度学习模型
最近项目有个任务,要在windows环境下用VS+OpenCV实现caffe模型的调用,于是在网上找了几个相关的博客跑了几个demo练练手.这些博客写得都很详细,但是有些细节由于版本更新的问题,配置的 ...
- 人工智能之基于Opencv与深度学习的计算机视觉实战课程
https://www.bilibili.com/video/av66375362 imagewatch:https://blog.csdn.net/iracer/article/details/83 ...
- 深度学习原理与框架-Tensorboard可视化展示(代码) 1.tf.reuse_default_graph(进行结构图的重置) 2.tf.summary.FileWriter(writer实例化) 3. write.add_graph(graph的写入) 4. tf.summary.merge_all(将summary进行合并) 5.write.add_summary(将所有summary)
1. tf.reuse_default_graph() # 对graph结构图进行清除和重置操作 2.tf.summary.FileWriter(path)构造writer实例化,以便进行后续的gra ...
- 华为云ModelArts图深度学习,学习知识还能考取微认证
作为人工智能最前沿的技术之一,图深度学习被公认是人工智能认识世界实现因果推理的关键,也是深度学习未来发展的方向.但深度学习对图数据模型的支持性差一直是众多研究者难以攻克的难点,因此图深度学习在实际生产 ...
随机推荐
- Spring Boot常用的注解
@SpringBootApplication:包含@Configuration.@EnableAutoConfiguration.@ComponentScan通常用在主类上.由于大量项目都会在主要的配 ...
- C# 安全性
一.标识和Principal static void Main(string[] args) { AppDomain.CurrentDomain.SetPrincipalPolicy(System.S ...
- C#第一章 第一个C#程序
第一个C#程序 namespace 是C#中组织代码的方式,它的作用那个类似java中的包 using 在Java中作用如果导入其他包 应该是用import关键字而在C#中应使用using关键字来引用 ...
- 数据结构---Set和Map
1.Set数据结构 Set本质上是一个没有重复数据,但是具有irerator接口可以遍历的一种集合. Set本身也是一种数据结构的构造函数. 1.Set的初始化 var obj = new Set(参 ...
- sql server 函数学习
sql server 创建函数 资料 https://docs.microsoft.com/zh-cn/sql/relational-databases/user-defined-functions/ ...
- Laravel API Errors and Exceptions: How to Return Responses
Laravel API Errors and Exceptions: How to Return Responses February 13, 2019 API-based projects are ...
- PRIMARY KEY,key,unique key
主键索引(必须指定为“PRIMARY KEY”,没有PRIMARY Index). 唯一索引(unique index,一般写成unique key). 普通索引(index,只有这一种才是纯粹的in ...
- Win 7 x64 + Visual Studio 2015为WinXP编译可执行程序
造冰箱的大熊猫@cnblogs 2019/9/5 本文承接<Win7下使用Visual Studio为WinXP编译可执行文件>一文. - 在64位Win7(开发机)上,编写基于C的Win ...
- docker容器中查看容器linux版本
root@dae5aecea3dd:~# cat /etc/issue Ubuntu LTS \n \l
- xml详解
https://www.cnblogs.com/zhao1949/p/5652167.html https://www.cnblogs.com/cb0327/p/4967782.html