OpenCV  4.10.0
开源计算机视觉
正在加载...
正在搜索...
无匹配项
图像缩放:多输出

在本教程中,您将学习如何使用“dnn_superres”界面通过多输出预训练神经网络对图像进行缩放。如果给出了节点名称,OpenCV 的 dnn 模块支持在一次推理中访问多个节点。目前包含一个模型,能够在一次推理运行中提供更多输出,即 LapSRN 模型。LapSRN 使用一次前向通路支持多输出。它现在可以支持 2 倍、4 倍、8 倍和 (2 倍、4 倍) 以及 (2 倍、4 倍、8 倍) 的超分辨率。上传的经过训练的模型文件具有以下输出节点名称

  • 2 倍模型:NCHW_output
  • 4 倍模型:NCHW_output_2x,NCHW_output_4x
  • 8 倍模型: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 版本中选中 dnn_superres 模块:cmake-gui。

示例源代码

运行示例代码时,使用以下命令

./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
1// 此文件是 OpenCV 项目的一部分。
2// 它受此发布包中顶级目录中的许可证条款约束,网址为 https://opencv.ac.cn/license.html。
3//
4
5#include <iostream>
6#include <sstream>
8
9#include <opencv2/imgproc.hpp>
10#include <opencv2/highgui.hpp>
11
12using namespace std;
13using namespace cv;
14using namespace dnn_superres;
15
16int main(int argc, char *argv[])
17{
18 // 检查有效的命令行参数,如果给出的参数不足,则打印使用说明。
19 // if insufficient arguments were given.
20 if (argc < 4) {
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";
25 return -1;
26 }
27
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]);
32
33 // 解析缩放因子
34 std::vector<int> scales;
35 char delim = ',';
36 {
37 std::stringstream ss(scales_str);
38 std::string token;
39 while (std::getline(ss, token, delim)) {
40 scales.push_back(atoi(token.c_str()));
41 }
42 }
43
44 // 解析输出节点名称
45 std::vector<String> node_names;
46 {
47 std::stringstream ss(output_names_str);
48 std::string token;
49 while (std::getline(ss, token, delim)) {
50 node_names.push_back(token);
51 }
52 }
53
54 // 加载图像
55 Mat img = cv::imread(img_path);
56 Mat original_img(img);
57 if (img.empty())
58 {
59 std::cerr << "无法加载图像: " << img << "\n";
60 return -2;
61 }
62
63 //创建 dnn 超分辨率实例
64 DnnSuperResImpl sr;
65 int scale = *max_element(scales.begin(), scales.end());
66 std::vector<Mat> outputs;
67 sr.readModel(path);
68 sr.setModel("lapsrn", scale);
69
70 sr.upsampleMultioutput(img, outputs, scales, node_names);
71
72 for(unsigned int i = 0; i < outputs.size(); i++)
73 {
74 cv::namedWindow("上采样图像", WINDOW_AUTOSIZE);
75 cv::imshow("上采样图像", outputs[i]);
76 //cv::imwrite("./saved.jpg", img_new);
77 cv::waitKey(0);
78 }
79
80 return 0;
81}
n 维稠密数组类
定义 mat.hpp:812
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)
从文件中加载图像。
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
与磁盘上的文件关联的文件存储的“黑匣子”表示。
定义 core.hpp:102
STL 命名空间。

说明

  1. 设置头和命名空间
    using namespace std;
    using namespace cv;
    using namespace dnn_superres;
  2. 创建 Dnn Superres 对象

    DnnSuperResImpl sr;

    实例化 dnn 超分辨率对象。

  3. 读取模型

    path = "models/LapSRN_x8.pb"
    sr.readModel(path);

    从给定路径读取模型。

  4. 设置模型

    sr.setModel("lapsrn", 8);

    设置算法和缩放因子。这里应给出最后一个(最大的)缩放因子。

  5. 给出节点名称和缩放因子

    std::vector<int> scales{2, 4, 8}
    std::vector<int> node_names{'NCHW_output_2x','NCHW_output_4x','NCHW_output_8x'}

    设置缩放因子和模型中的输出节点名称。

  6. 上调图像

    Mat img = cv::imread(img_path);
    std::vector<Mat> outputs;
    sr.upsampleMultioutput(img, outputs, scales, node_names);

    运行推理。输出图像将存储在 Mat 向量中。