In this tutorial you will learn how to use the 'dnn_superres' interface to upscale an image via a multi-output pre-trained neural network. OpenCVs dnn module supports accessing multiple nodes in one inference, if the names of the nodes are given. Currently there is one model included that is capable of giving more output in one inference run, that is the LapSRN model. LapSRN supports multiple outputs with one forward pass. It can now support 2x, 4x, 8x, and (2x, 4x) and (2x, 4x, 8x) super-resolution. The uploaded trained model files have the following output node names:
- 2x model: NCHW_output
- 4x model: NCHW_output_2x, NCHW_output_4x
- 8x model: NCHW_output_2x, NCHW_output_4x, NCHW_output_8x
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
Run the sample code with the following command
./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
14using namespace dnn_superres;
16int main(
int argc,
char *argv[])
21 cout <<
"usage: Arg 1: image | Path to image" << endl;
22 cout <<
"\t Arg 2: scales in a format of 2,4,8\n";
23 cout <<
"\t Arg 3: output node names in a format of nchw_output_0,nchw_output_1\n";
24 cout <<
"\t Arg 4: path to model file \n";
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]);
34 std::vector<int> scales;
37 std::stringstream ss(scales_str);
39 while (std::getline(ss, token, delim)) {
40 scales.push_back(atoi(token.c_str()));
45 std::vector<String> node_names;
47 std::stringstream ss(output_names_str);
49 while (std::getline(ss, token, delim)) {
50 node_names.push_back(token);
56 Mat original_img(img);
59 std::cerr <<
"Couldn't load image: " << img <<
"\n";
65 int scale = *max_element(scales.begin(), scales.end());
66 std::vector<Mat> outputs;
68 sr.setModel(
"lapsrn", scale);
70 sr.upsampleMultioutput(img, outputs, scales, node_names);
72 for(
unsigned int i = 0; i < outputs.size(); i++)
n-dimensional dense array class
Definition mat.hpp:950
bool empty() const
Returns true if the array has no elements.
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
int waitKey(int delay=0)
Waits for a pressed key.
void namedWindow(const String &winname, int flags=WINDOW_AUTOSIZE)
Creates a window.
CV_EXPORTS_W Mat imread(const String &filename, int flags=IMREAD_COLOR_BGR)
Loads an image from a file.
int main(int argc, char *argv[])
Definition highgui_qt.cpp:3
void scale(cv::Mat &mat, const cv::Mat &range, const T min, const T max)
Definition quality_utils.hpp:90
Explanation
- Set header and namespaces
using namespace std;
using namespace dnn_superres;
Create the Dnn Superres object
Instantiate a dnn super-resolution object.
Read the model
path = "models/LapSRN_x8.pb"
sr.readModel(path);
Read the model from the given path.
Set the model
sr.setModel("lapsrn", 8);
Sets the algorithm and scaling factor. The last (largest) scaling factor should be given here.
Give the node names and scaling factors
std::vector<int> scales{2, 4, 8}
std::vector<int> node_names{'NCHW_output_2x','NCHW_output_4x','NCHW_output_8x'}
Set the scaling factors, and the output node names in the model.
Upscale an image
std::vector<Mat> outputs;
sr.upsampleMultioutput(img, outputs, scales, node_names);
Run the inference. The output images will be stored in a Mat vector.