本教程将介绍如何使用 'dnn_superres' 接口通过多输出预训练神经网络来提升图像分辨率。OpenCV 的 dnn 模块支持在一次推理中访问多个节点,前提是给出这些节点的名称。目前包含一个能够在一轮推理中提供多个输出的模型,即 LapSRN 模型。LapSRN 支持使用一次前向传递进行多输出。它现在支持 2x、4x、8x 以及 (2x, 4x) 和 (2x, 4x, 8x) 超分辨率。上传的训练模型文件具有以下输出节点名称:
- 2x 模型:NCHW_output
- 4x 模型:NCHW_output_2x, NCHW_output_4x
- 8x 模型:NCHW_output_2x, NCHW_output_4x, NCHW_output_8x
构建
构建 OpenCV 时,运行以下命令以构建所有 contrib 模块:
cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules/
或者只构建 dnn_superres 模块:
cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules/dnn_superres
或者确保在 CMake 的 GUI 版本 (cmake-gui) 中选中 dnn_superres 模块。
示例源代码
使用以下命令运行示例代码:
./bin/example_dnn_superres_dnn_superres_multioutput path/to/image.png 2,4 NCHW_output_2x,NCHW_output_4x \
path/to/opencv_contrib/modules/dnn_superres/models/LapSRN_x4.pb
14using namespace dnn_superres;
16int main(
int argc,
char *argv[])
21 cout <<
"用法:参数 1:图像 | 图像路径" << endl;
22 cout <<
"\t 参数 2:比例因子,格式为 2,4,8\n";
23 cout <<
"\t 参数 3:输出节点名称,格式为 nchw_output_0,nchw_output_1\n";
24 cout <<
"\t 参数 4:模型文件路径 \n";
28 string img_path = string(argv[1]);
29 string scales_str = string(argv[2]);
30 string output_names_str = string(argv[3]);
31 std::string path = string(argv[4]);
34 std::vector<int> scales;
37 std::stringstream ss(scales_str);
39 while (std::getline(ss, token, delim)) {
40 scales.push_back(atoi(token.c_str()));
45 std::vector<String> node_names;
47 std::stringstream ss(output_names_str);
49 while (std::getline(ss, token, delim)) {
50 node_names.push_back(token);
56 Mat original_img(img);
59 std::cerr <<
"无法加载图像:" << img <<
"\n";
65 int scale = *max_element(scales.begin(), scales.end());
66 std::vector<Mat> outputs;
68 sr.setModel(
"lapsrn", scale);
70 sr.upsampleMultioutput(img, outputs, scales, node_names);
72 for(
unsigned int i = 0; i < outputs.size(); i++)
bool empty() const
如果数组没有元素,则返回true。
void imshow(const String &winname, InputArray mat)
在指定的窗口中显示图像。
int waitKey(int delay=0)
等待按键按下。
void namedWindow(const String &winname, int flags=WINDOW_AUTOSIZE)
创建一个窗口。
CV_EXPORTS_W Mat imread(const String &filename, int flags=IMREAD_COLOR_BGR)
从文件中加载图像。
int main(int argc, char *argv[])
定义 highgui_qt.cpp:3
void scale(cv::Mat &mat, const cv::Mat &range, const T min, const T max)
定义 quality_utils.hpp:90
解释
- 设置头文件和命名空间
using namespace dnn_superres;
创建Dnn Superres对象
实例化一个dnn超分辨率对象。
读取模型
path = "models/LapSRN_x8.pb"
sr.readModel(path);
从给定路径读取模型。
设置模型
sr.setModel("lapsrn", 8);
设置算法和缩放因子。这里应该给出最后一个(最大)缩放因子。
给出节点名称和缩放因子
std::vector<int> scales{2, 4, 8}
std::vector<int> node_names{'NCHW_output_2x','NCHW_output_4x','NCHW_output_8x'}
设置缩放因子和模型中的输出节点名称。
上采样图像
std::vector<Mat> outputs;
sr.upsampleMultioutput(img, outputs, scales, node_names);
运行推理。输出图像将存储在Mat向量中。