OpenCV 4.11.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 版本 (cmake-gui) 中确保选中 dnn_superres 模块。

示例代码

您可以通过以下命令运行示例代码:

<opencv_构建目录路径>/bin/example_dnn_superres_dnn_superres <图像路径.png> <算法字符串> <放大倍数> <模型路径.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:算法 | bilinear, bicubic, 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:829
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_BGR)
从文件加载图像。
int main(int argc, char *argv[])
定义 highgui_qt.cpp:3
定义 core.hpp:107
STL命名空间。

解释

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

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

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

  2. 创建Dnn Superres对象

    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放大后的图像:

通过双三次插值放大后的图像: