| OpenCV 5.0.0alpha Open Source Computer Vision

Loading...
Searching...
No Matches
Upscaling images: single-output

In this tutorial you will learn how to use the 'dnn_superres' interface to upscale an image via pre-trained neural networks. It works in C++ and Python.

# Building

When building OpenCV, run the following command to build all the contrib module:

cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules/

Or only build the dnn_superres module:

cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules/dnn_superres

Or make sure you check the dnn_superres module in the GUI version of CMake: cmake-gui.

# Source Code of the sample

You can run the sample code by doing

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

Example:

/home/opencv/build/bin/example_dnn_superres_dnn_superres /home/image.png edsr 2 /home/EDSR_x2.pb
1// This file is part of OpenCV project.
2// It is subject to the license terms in the LICENSE file found in the top-level directory
3// of this distribution and at http://opencv.org/license.html.
4
5#include <iostream>
6
7#include <opencv2/dnn_superres.hpp>
8
9#include <opencv2/imgproc.hpp>
10#include <opencv2/highgui.hpp>
11
12 using namespace std;
13 using namespace cv;
14 using namespace dnn;
15 using namespace dnn_superres;
16
17 int main(int argc, char *argv[])
18{
19 // Check for valid command line arguments, print usage
20 // if insufficient arguments were given.
21 if ( argc < 4 ) {
22 cout << "usage: Arg 1: image | Path to image" << endl;
23 cout << "\t Arg 2: algorithm | bilinear, bicubic, edsr, espcn, fsrcnn or lapsrn" << endl;
24 cout << "\t Arg 3: scale | 2, 3 or 4 \n";
25 cout << "\t Arg 4: path to model file \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 // Load the image
38 Mat img = cv::imread(img_path);
39 Mat original_img(img);
40 if ( img.empty() )
41 {
42 std::cerr << "Couldn't load image: " << img << "\n";
43 return -2;
44 }
45
46 //Make dnn super resolution instance
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 << "Algorithm not recognized. \n";
66 }
67
68 if ( img_new.empty() )
69 {
70 std::cerr << "Upsampling failed. \n";
71 return -3;
72 }
73 cout << "Upsampling succeeded. \n";
74
75 // Display image
76 cv::namedWindow("Initial Image", WINDOW_AUTOSIZE);
77 cv::imshow("Initial Image", img_new);
78 //cv::imwrite("./saved.jpg", img_new);
79 cv::waitKey(0);
80
81 return 0;
82}
cv::Mat
n-dimensional dense array class
Definition mat.hpp:951
cv::Mat::empty
bool empty() const
Returns true if the array has no elements.
cv::Size_
Template class for specifying the size of an image or rectangle.
Definition types.hpp:338
dnn_superres.hpp
cv::imshow
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
cv::waitKey
int waitKey(int delay=0)
Waits for a pressed key.
cv::namedWindow
void namedWindow(const String &winname, int flags=WINDOW_AUTOSIZE)
Creates a window.
cv::imread
CV_EXPORTS_W Mat imread(const String &filename, int flags=IMREAD_COLOR_BGR)
Loads an image from a file.
highgui.hpp
main
int main(int argc, char *argv[])
Definition highgui_qt.cpp:3
imgproc.hpp
cv
Definition core.hpp:107
std
STL namespace.

# Explanation

1. Set header and namespaces

   #include <opencv2/dnn_superres.hpp>
   using namespace std;
   using namespace cv;
   using namespace dnn;
   using namespace dnn_superres;

   If you want you can set the namespace like the code above.

2. Create the Dnn Superres object

   DnnSuperResImpl sr;

   This is just to create the object, register the custom dnn layers and get access to the class functions.

3. Read the model

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

   This reads the TensorFlow model from the .pb file. Here 'path' is one of the pre-trained Tensorflow models' path file. You can download the models from OpenCV's GitHub, in the 'dnn_superres' module.

4. Set the model

   sr.setModel("fsrcnn", 2);

   Depending on the model you want to run, you have to set the algorithm and upscale factor. This is to know the desired algorithm and scale, even if you change the .pb file's name. For example: if you chose FSRCNN_x2.pb, your algorithm and scale will be 'fsrcnn' and 2, respectively. (Other algorithm options include "edsr", "espcn" and "lapsrn".)

5. Upscale an image

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

   Now we can upscale any image. Load an image via the standard 'imread' function and create a new Mat for the destination image. Then simple upscale. Your upscaled image is located in 'img_new'.

# An example in python

import cv2
from cv2 import dnn_superres
# Create an SR object - only function that differs from c++ code
sr = dnn_superres.DnnSuperResImpl_create()
# Read image
image = cv2.imread('./image.png')
# Read the desired model
path = "EDSR_x4.pb"
sr.readModel(path)
# Set the desired model and scale to get correct pre- and post-processing
sr.setModel("edsr", 4)
# Upscale the image
result = sr.upsample(image)
# Save the image
cv2.imwrite("./upscaled.png", result)

Original:

Upscaled Image via FSRCNN:

Upscaled Image via Bicubic Interpolation: