OpenCV 4.12.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 文件中的许可条款的约束
3// 此发行版以及 https://opencv.ac.cn/license.html。
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 << "usage: Arg 1: image | 图像路径" << endl;
23 cout << "\t Arg 2: algorithm | bilinear, bicubic, edsr, espcn, fsrcnn 或 lapsrn" << endl;
24 cout << "\t Arg 3: scale | 2, 3 或 4 \n";
25 cout << "\t Arg 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:830
cv::getTickFrequency
double getTickFrequency()
用于指定图像或矩形大小的模板类。
Definition 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 超分辨率处理后的图像:

通过双三次插值超分辨率处理后的图像: