OpenCV  4.10.0
开源计算机视觉
正在加载...
正在搜索...
无匹配项
图像上采样:单输出

本教程将教你如何使用 'dnn_superres' 接口通过预训练的神经网络对图像进行上采样。它适用于 C++ 和 Python。

构建

构建 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。

示例的源代码

你可以通过以下方式运行示例代码

<path_of_your_opencv_build_directory>/bin/example_dnn_superres_dnn_superres <path_to_image.png> <algo_string> <upscale_int> <model_path.pb>

示例

/home/opencv/build/bin/example_dnn_superres_dnn_superres /home/image.png edsr 2 /home/EDSR_x2.pb
1// 此文件是 OpenCV 项目的一部分。
2// 它受此发行版顶层目录中 LICENSE 文件中以及 https://opencv.ac.cn/license.html 中的许可条款的约束。
3//
4
5#include <iostream>
6
8
9#include <opencv2/imgproc.hpp>
10#include <opencv2/highgui.hpp>
11
12using namespace std;
13using namespace cv;
14using namespace dnn;
15using namespace dnn_superres;
16
17int main(int argc, char *argv[])
18{
19 // 检查有效命令行参数,如果给出参数不足则打印用法。
20 //
21 if ( argc < 4 ) {
22 cout << "用法:参数 1:图像 | 图像路径" << endl;
23 cout << "\t 参数 2:算法 | 双线性、双三次、edsr、espcn、fsrcnn 或 lapsrn" << endl;
24 cout << "\t 参数 3:比例 | 2、3 或 4 \n";
25 cout << "\t 参数 4:模型文件路径 \n";
26 return -1;
27 }
28
29 string img_path = string(argv[1]);
30 string algorithm = string(argv[2]);
31 int scale = atoi(argv[3]);
32 string path = "";
33
34 if( argc > 4)
35 path = string(argv[4]);
36
37 // 加载图像
38 Mat img = cv::imread(img_path);
39 Mat original_img(img);
40 if ( img.empty() )
41 {
42 std::cerr << "无法加载图像:" << img << "\n";
43 return -2;
44 }
45
46 // 创建 dnn 超分辨率实例
47 DnnSuperResImpl sr;
48
49 Mat img_new;
50
51 if( algorithm == "bilinear" ){
52 resize(img, img_new, Size(), scale, scale, 2);
53 }
54 else if( algorithm == "bicubic" )
55 {
56 resize(img, img_new, Size(), scale, scale, 3);
57 }
58 else if( algorithm == "edsr" || algorithm == "espcn" || algorithm == "fsrcnn" || algorithm == "lapsrn" )
59 {
60 sr.readModel(path);
61 sr.setModel(algorithm, scale);
62 sr.upsample(img, img_new);
63 }
64 else{
65 std::cerr << "无法识别算法。\n";
66 }
67
68 if ( img_new.empty() )
69 {
70 std::cerr << "上采样失败。\n";
71 return -3;
72 }
73 cout << "上采样成功。\n";
74
75 // 显示图像
76 cv::namedWindow("初始图像", WINDOW_AUTOSIZE);
77 cv::imshow("初始图像", img_new);
78 //cv::imwrite("./saved.jpg", img_new);
79 cv::waitKey(0);
80
81 return 0;
82}
n 维密集数组类
定义 mat.hpp:812
bool empty() const
如果数组没有元素,则返回 true。
用于指定图像或矩形大小的模板类。
定义 types.hpp:335
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
与磁盘上的文件关联的文件存储的“黑盒”表示形式。
定义 core.hpp:102
STL 命名空间。

解释

  1. 设置头文件和命名空间

    using namespace std;
    using namespace cv;
    using namespace dnn;
    using namespace dnn_superres;

    如果你想,你可以像上面的代码一样设置命名空间。

  2. 创建 Dnn 超分辨率对象

    DnnSuperResImpl sr;

    这只是为了创建对象、注册自定义 dnn 层并访问类函数。

  3. 读取模型

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

    这会从 .pb 文件中读取 TensorFlow 模型。这里 'path' 是预训练的 TensorFlow 模型之一的路径文件。你可以在 OpenCV 的 GitHub 中的 'dnn_superres' 模块中下载模型。

  4. 设置模型

    sr.setModel("fsrcnn", 2);

    根据你想要运行的模型,你必须设置算法和上采样因子。这是为了知道所需的算法和比例,即使你更改了 .pb 文件的名称。例如:如果你选择了 FSRCNN_x2.pb,你的算法和比例将分别为 'fsrcnn' 和 2。(其他算法选项包括“edsr”、“espcn”和“lapsrn”。)

  5. 对图像进行上采样

    Mat img = cv::imread(img_path);
    Mat img_new;
    sr.upsample(img, img_new);

    现在我们可以对任何图像进行上采样。通过标准的 'imread' 函数加载图像,并为目标图像创建一个新的 Mat。然后简单地进行上采样。你的上采样图像位于 'img_new' 中。

Python 中的示例

import cv2
from cv2 import dnn_superres
# 创建一个 SR 对象 - 这是与 c++ 代码不同的唯一函数
sr = dnn_superres.DnnSuperResImpl_create()
# 读取图像
image = cv2.imread('./image.png')
# 读取所需的模型
path = "EDSR_x4.pb"
sr.readModel(path)
# 设置所需的模型和比例以获得正确的预处理和后处理
sr.setModel("edsr", 4)
# 对图像进行上采样
result = sr.upsample(image)
# 保存图像
cv2.imwrite("./upscaled.png", result)

原始图像:

通过 FSRCNN 上采样的图像:

通过双三次插值上采样的图像: