OpenCV4入门139:获取网络各层信息

索引地址:系列索引

数据通过神经网络训练好后,我们使用OpenCV读取并使用。

以下为OpenCV源码中modules/dnn/src/dnn.cpp中第5333行开始的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Net readNet(const String& _model, const String& _config, const String& _framework)
{
String framework = toLowerCase(_framework);
String model = _model;
String config = _config;
const std::string modelExt = model.substr(model.rfind('.') + 1);
const std::string configExt = config.substr(config.rfind('.') + 1);
if (framework == "caffe" || modelExt == "caffemodel" || configExt == "caffemodel" ||
modelExt == "prototxt" || configExt == "prototxt")
{
if (modelExt == "prototxt" || configExt == "caffemodel")
std::swap(model, config);
return readNetFromCaffe(config, model);
}
if (framework == "tensorflow" || modelExt == "pb" || configExt == "pb" ||
modelExt == "pbtxt" || configExt == "pbtxt")
{
if (modelExt == "pbtxt" || configExt == "pb")
std::swap(model, config);
return readNetFromTensorflow(model, config);
}
if (framework == "torch" || modelExt == "t7" || modelExt == "net" ||
configExt == "t7" || configExt == "net")
{
return readNetFromTorch(model.empty() ? config : model);
}
if (framework == "darknet" || modelExt == "weights" || configExt == "weights" ||
modelExt == "cfg" || configExt == "cfg")
{
if (modelExt == "cfg" || configExt == "weights")
std::swap(model, config);
return readNetFromDarknet(config, model);
}
if (framework == "dldt" || modelExt == "bin" || configExt == "bin" ||
modelExt == "xml" || configExt == "xml")
{
if (modelExt == "xml" || configExt == "bin")
std::swap(model, config);
return readNetFromModelOptimizer(config, model);
}
if (framework == "onnx" || modelExt == "onnx")
{
return readNetFromONNX(model);
}
CV_Error(Error::StsError, "Cannot determine an origin framework of files: " +
model + (config.empty() ? "" : ", " + config));
}

readNet是一个通用的加载神经网络结果文件的接口,同时也表明了OpenCV所支持的网络模型。

框架模型格式配置文件
caffecaffemoelprototxt
tensorflowpbpbtxt
torcht7net
darknetweightcfg
dldtbinxml
onnxbinxml

我们来测试一下读取模型文件并输出各层信息,使用darknet的weight文件:

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <iostream>

using namespace cv;
using namespace cv::dnn;
using namespace std;

int main(int argc, char** argv) {
string bin_model = "yolov3.weights";
string protxt = "yolov3.cfg";

//加载网络文件
Net net = dnn::readNet(bin_model, protxt);

// 获取各层信息
vector<String> layer_names = net.getLayerNames();
for (size_t i = 0; i < layer_names.size(); i++) {
int id = net.getLayerId(layer_names[i]);
auto layer = net.getLayer(id);
printf("layer id:%d, type: %s, name:%s \n", id, layer->type.c_str(), layer->name.c_str());
}
return 0;
}

输出为:

1
2
3
4
5
6
7
8
layer id:1, type: Convolution, name:conv_0
layer id:2, type: BatchNorm, name:bn_0
layer id:3, type: ReLU, name:leaky_1
layer id:4, type: Convolution, name:conv_1
...
layer id:252, type: Convolution, name:conv_105
layer id:253, type: Permute, name:permute_106
layer id:254, type: Region, name:yolo_106