diff --git a/modules/README.md b/modules/README.md index 25007370f76..3f8dc5e42a3 100644 --- a/modules/README.md +++ b/modules/README.md @@ -22,7 +22,7 @@ $ cmake -D OPENCV_EXTRA_MODULES_PATH=/modules -D BUILD_opencv_ + +Usage: +-# From link above download `BSDS300-images.tgz`. +-# Unpack. +-# To load data run: +~~~ +./opencv/build/bin/example_datasets_sr_bsds -p=/home/user/path_to_unpacked_folder/ +~~~ + +### DIV2K dataset: DIVerse 2K + +Implements loading dataset: + +"DIV2K dataset: DIVerse 2K": + +Usage: +-# From link above download 'Train data (HR images)' or any other of the dataset files. +-# Unpack. +-# To load data run: +~~~ +./opencv/build/bin/example_datasets_sr_div2k -p=/home/user/path_to_unpacked_folder/folder_containing_the_images/ +~~~ + +### The General-100 Dataset + +Implements loading dataset: + +"General-100 dataset contains 100 bmp-format images (with no compression). +We used this dataset in our FSRCNN ECCV 2016 paper. The size of these 100 images ranges from 710 x 704 (large) to 131 x 112 (small). +They are all of good quality with clear edges but fewer smooth regions (e.g., sky and ocean), thus are very suitable for the super-resolution training.": + + +Usage: +-# From link above download `General-100.zip`. +-# Unpack. +-# To load data run: +~~~ +./opencv/build/bin/example_datasets_sr_general100 -p=/home/user/path_to_unpacked_folder/ +~~~ + @defgroup datasets_tr Text Recognition ### The Chars74K Dataset diff --git a/modules/datasets/include/opencv2/datasets/sr_bsds.hpp b/modules/datasets/include/opencv2/datasets/sr_bsds.hpp new file mode 100644 index 00000000000..c319323dd53 --- /dev/null +++ b/modules/datasets/include/opencv2/datasets/sr_bsds.hpp @@ -0,0 +1,41 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_DATASETS_SR_BSDS_HPP +#define OPENCV_DATASETS_SR_BSDS_HPP + +#include +#include + +#include "opencv2/datasets/dataset.hpp" + +#include + +namespace cv +{ +namespace datasets +{ + +//! @addtogroup datasets_sr +//! @{ + +struct SR_bsdsObj : public Object +{ + std::string imageName; +}; + +class CV_EXPORTS SR_bsds : public Dataset +{ +public: + virtual void load(const std::string &path) CV_OVERRIDE = 0; + + static Ptr create(); +}; + +//! @} + +} +} + +#endif \ No newline at end of file diff --git a/modules/datasets/include/opencv2/datasets/sr_div2k.hpp b/modules/datasets/include/opencv2/datasets/sr_div2k.hpp new file mode 100644 index 00000000000..9e2c0253bea --- /dev/null +++ b/modules/datasets/include/opencv2/datasets/sr_div2k.hpp @@ -0,0 +1,41 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_DATASETS_SR_DIV2K_HPP +#define OPENCV_DATASETS_SR_DIV2K_HPP + +#include +#include + +#include "opencv2/datasets/dataset.hpp" + +#include + +namespace cv +{ +namespace datasets +{ + +//! @addtogroup datasets_sr +//! @{ + +struct SR_div2kObj : public Object +{ + std::string imageName; +}; + +class CV_EXPORTS SR_div2k : public Dataset +{ +public: + virtual void load(const std::string &path) CV_OVERRIDE = 0; + + static Ptr create(); +}; + +//! @} + +} +} + +#endif \ No newline at end of file diff --git a/modules/datasets/include/opencv2/datasets/sr_general100.hpp b/modules/datasets/include/opencv2/datasets/sr_general100.hpp new file mode 100644 index 00000000000..8b2d18903f8 --- /dev/null +++ b/modules/datasets/include/opencv2/datasets/sr_general100.hpp @@ -0,0 +1,41 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_DATASETS_SR_GENERAL100_HPP +#define OPENCV_DATASETS_SR_GENERAL100_HPP + +#include +#include + +#include "opencv2/datasets/dataset.hpp" + +#include + +namespace cv +{ +namespace datasets +{ + +//! @addtogroup datasets_sr +//! @{ + +struct SR_general100Obj : public Object +{ + std::string imageName; +}; + +class CV_EXPORTS SR_general100 : public Dataset +{ +public: + virtual void load(const std::string &path) CV_OVERRIDE = 0; + + static Ptr create(); +}; + +//! @} + +} +} + +#endif \ No newline at end of file diff --git a/modules/datasets/samples/sr_bsds.cpp b/modules/datasets/samples/sr_bsds.cpp new file mode 100644 index 00000000000..75c7d7cb5f3 --- /dev/null +++ b/modules/datasets/samples/sr_bsds.cpp @@ -0,0 +1,50 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#include "opencv2/datasets/sr_bsds.hpp" + +#include + +#include + +#include +#include + +using namespace std; +using namespace cv; +using namespace cv::datasets; + +int main(int argc, char *argv[]) +{ + const char *keys = + "{ help h usage ? | | show this message }" + "{ path p |true| path to dataset (images, iids_train.txt, iids_test.txt) }"; + CommandLineParser parser(argc, argv, keys); + string path(parser.get("path")); + if (parser.has("help") || path=="true") + { + parser.printMessage(); + return -1; + } + + Ptr dataset = SR_bsds::create(); + dataset->load(path); + + // *************** + // Dataset train & test contain names of appropriate images. + // For example, let's output full path & name for first train and test images. + // And dataset sizes. + printf("train size: %u\n", (unsigned int)dataset->getTrain().size()); + printf("test size: %u\n", (unsigned int)dataset->getTest().size()); + + SR_bsdsObj *example1 = static_cast(dataset->getTrain()[0].get()); + string fullPath(path + "images/train/" + example1->imageName + ".jpg"); + printf("first train image: %s\n", fullPath.c_str()); + + SR_bsdsObj *example2 = static_cast(dataset->getTest()[0].get()); + fullPath = path + "images/test/" + example2->imageName + ".jpg"; + printf("first test image: %s\n", fullPath.c_str()); + + return 0; +} \ No newline at end of file diff --git a/modules/datasets/samples/sr_div2k.cpp b/modules/datasets/samples/sr_div2k.cpp new file mode 100644 index 00000000000..d28b846a57e --- /dev/null +++ b/modules/datasets/samples/sr_div2k.cpp @@ -0,0 +1,47 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#include "opencv2/datasets/sr_div2k.hpp" + +#include + +#include + +#include +#include + +using namespace std; +using namespace cv; +using namespace cv::datasets; + +int main(int argc, char *argv[]) +{ + const char *keys = + "{ help h usage ? | | show this message }" + "{ path p |true| path to dataset (Div2k dataset folder containing the images) }"; + CommandLineParser parser(argc, argv, keys); + string path(parser.get("path")); + if (parser.has("help") || path=="true") + { + parser.printMessage(); + return -1; + } + + Ptr dataset = SR_div2k::create(); + dataset->load(path); + + // *************** + // Dataset contains all images. + // For example, let's output dataset size; first image name; and second image full path. + printf("dataset size: %u\n", (unsigned int)dataset->getTrain().size()); + + SR_div2kObj *example = static_cast(dataset->getTrain()[0].get()); + printf("first image name: %s\n", example->imageName.c_str()); + + SR_div2kObj *example2 = static_cast(dataset->getTrain()[1].get()); + string fullPath = path + "/" + example2->imageName.c_str(); + printf("second image full path: %s\n", fullPath.c_str()); + + return 0; +} \ No newline at end of file diff --git a/modules/datasets/samples/sr_general100.cpp b/modules/datasets/samples/sr_general100.cpp new file mode 100644 index 00000000000..c1ffd6a41a2 --- /dev/null +++ b/modules/datasets/samples/sr_general100.cpp @@ -0,0 +1,47 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#include "opencv2/datasets/sr_general100.hpp" + +#include + +#include + +#include +#include + +using namespace std; +using namespace cv; +using namespace cv::datasets; + +int main(int argc, char *argv[]) +{ + const char *keys = + "{ help h usage ? | | show this message }" + "{ path p |true| path to dataset (General-100 dataset folder) }"; + CommandLineParser parser(argc, argv, keys); + string path(parser.get("path")); + if (parser.has("help") || path=="true") + { + parser.printMessage(); + return -1; + } + + Ptr dataset = SR_general100::create(); + dataset->load(path); + + // *************** + // Dataset contains all images. + // For example, let's output dataset size; first image name; and second image full path. + printf("dataset size: %u\n", (unsigned int)dataset->getTrain().size()); + + SR_general100Obj *example = static_cast(dataset->getTrain()[0].get()); + printf("first image name: %s\n", example->imageName.c_str()); + + SR_general100Obj *example2 = static_cast(dataset->getTrain()[1].get()); + string fullPath = path + "/" + example2->imageName.c_str(); + printf("second image full path: %s\n", fullPath.c_str()); + + return 0; +} \ No newline at end of file diff --git a/modules/datasets/src/sr_bsds.cpp b/modules/datasets/src/sr_bsds.cpp new file mode 100644 index 00000000000..aa59c019a1e --- /dev/null +++ b/modules/datasets/src/sr_bsds.cpp @@ -0,0 +1,74 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#include "opencv2/datasets/sr_bsds.hpp" +#include "opencv2/datasets/util.hpp" + +namespace cv +{ +namespace datasets +{ + +using namespace std; + +class SR_bsdsImp CV_FINAL : public SR_bsds +{ +public: + SR_bsdsImp() {} + //SR_bsdsImp(const string &path); + virtual ~SR_bsdsImp() {} + + virtual void load(const string &path) CV_OVERRIDE; + +private: + void loadDataset(const string &path); + + void loadDatasetPart(const string &fileName, vector< Ptr > &dataset_); +}; + +void SR_bsdsImp::loadDatasetPart(const string &fileName, vector< Ptr > &dataset_) +{ + ifstream infile(fileName.c_str()); + string imageName; + while (infile >> imageName) + { + Ptr curr(new SR_bsdsObj); + curr->imageName = imageName; + dataset_.push_back(curr); + } +} + +/*SR_bsdsImp::SR_bsdsImp(const string &path) +{ + loadDataset(path); +}*/ + +void SR_bsdsImp::load(const string &path) +{ + loadDataset(path); +} + +void SR_bsdsImp::loadDataset(const string &path) +{ + train.push_back(vector< Ptr >()); + test.push_back(vector< Ptr >()); + validation.push_back(vector< Ptr >()); + + string trainName(path + "iids_train.txt"); + string testName(path + "iids_test.txt"); + + // loading train + loadDatasetPart(trainName, train.back()); + + // loading test + loadDatasetPart(testName, test.back()); +} + +Ptr SR_bsds::create() +{ + return Ptr(new SR_bsdsImp); +} + +} +} \ No newline at end of file diff --git a/modules/datasets/src/sr_div2k.cpp b/modules/datasets/src/sr_div2k.cpp new file mode 100644 index 00000000000..3e5700161f9 --- /dev/null +++ b/modules/datasets/src/sr_div2k.cpp @@ -0,0 +1,62 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#include "opencv2/datasets/sr_div2k.hpp" +#include "opencv2/datasets/util.hpp" + +namespace cv +{ +namespace datasets +{ + +using namespace std; + +class SR_div2kImp CV_FINAL : public SR_div2k +{ +public: + SR_div2kImp() {} + //SR_div2kImp(const string &path); + virtual ~SR_div2kImp() {} + + virtual void load(const string &path) CV_OVERRIDE; + +private: + void loadDataset(const string &path); +}; + +/*SR_div2kImp::SR_div2kImp(const string &path) +{ + loadDataset(path); +}*/ + +void SR_div2kImp::load(const string &path) +{ + loadDataset(path); +} + +void SR_div2kImp::loadDataset(const string &path) +{ + train.push_back(vector< Ptr >()); + test.push_back(vector< Ptr >()); + validation.push_back(vector< Ptr >()); + + vector fileNames; + getDirList(path, fileNames); + for (vector::iterator it=fileNames.begin(); it!=fileNames.end(); ++it) + { + string &imageName = *it; + Ptr curr(new SR_div2kObj); + curr->imageName = imageName; + train.back().push_back(curr); + + } +} + +Ptr SR_div2k::create() +{ + return Ptr(new SR_div2kImp); +} + +} +} \ No newline at end of file diff --git a/modules/datasets/src/sr_general100.cpp b/modules/datasets/src/sr_general100.cpp new file mode 100644 index 00000000000..c0ad6df87e8 --- /dev/null +++ b/modules/datasets/src/sr_general100.cpp @@ -0,0 +1,62 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#include "opencv2/datasets/sr_general100.hpp" +#include "opencv2/datasets/util.hpp" + +namespace cv +{ +namespace datasets +{ + +using namespace std; + +class SR_general100Imp CV_FINAL : public SR_general100 +{ +public: + SR_general100Imp() {} + //SR_general100Imp(const string &path); + virtual ~SR_general100Imp() {} + + virtual void load(const string &path) CV_OVERRIDE; + +private: + void loadDataset(const string &path); +}; + +/*SR_general100Imp::SR_general100Imp(const string &path) +{ + loadDataset(path); +}*/ + +void SR_general100Imp::load(const string &path) +{ + loadDataset(path); +} + +void SR_general100Imp::loadDataset(const string &path) +{ + train.push_back(vector< Ptr >()); + test.push_back(vector< Ptr >()); + validation.push_back(vector< Ptr >()); + + vector fileNames; + getDirList(path, fileNames); + for (vector::iterator it=fileNames.begin(); it!=fileNames.end(); ++it) + { + string &imageName = *it; + Ptr curr(new SR_general100Obj); + curr->imageName = imageName; + train.back().push_back(curr); + + } +} + +Ptr SR_general100::create() +{ + return Ptr(new SR_general100Imp); +} + +} +} \ No newline at end of file diff --git a/modules/dnn_superres/README.md b/modules/dnn_superres/README.md index 1e71f938197..b47772b049a 100644 --- a/modules/dnn_superres/README.md +++ b/modules/dnn_superres/README.md @@ -40,7 +40,7 @@ Trained models can be downloaded from [here](https://github.com/fannymonori/TF-E - Advantage: It is tiny and fast, and still performs well. - Disadvantage: Perform worse visually than newer, more robust models. - Speed: < 0.01 sec for every scaling factor on 256x256 images on an Intel i7-9700K CPU. -- Original paper: [Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network]() [2] +- Original paper: [Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network](https://arxiv.org/pdf/1707.02921.pdf) [2] #### FSRCNN @@ -66,11 +66,11 @@ Trained models can be downloaded from [here](https://github.com/fannymonori/TF-L - Advantage: The model can do multi-scale super-resolution with one forward pass. It can now support 2x, 4x, 8x, and [2x, 4x] and [2x, 4x, 8x] super-resolution. - Disadvantage: It is slower than ESPCN and FSRCNN, and the accuracy is worse than EDSR. - Speed: < 0.1 sec for every scaling factor on 256x256 images on an Intel i7-9700K CPU. -- Original paper: [Deep laplacian pyramid networks for fast and accurate super-resolution]() [4] +- Original paper: [Deep laplacian pyramid networks for fast and accurate super-resolution](https://arxiv.org/pdf/1707.02921.pdf) [4] ### Benchmarks -Comparing different algorithms. Scale x4 on monarch.png. +Comparing different algorithms. Scale x4 on monarch.png (768x512 image). | | Inference time in seconds (CPU)| PSNR | SSIM | | ------------- |:-------------------:| ---------:|--------:| @@ -82,6 +82,8 @@ Comparing different algorithms. Scale x4 on monarch.png. | Nearest neighbor |**0.00014** |23.5628 |0.81741 | | Lanczos |0.00101 |25.9115 |0.87057 | +Refer to the benchmarks located in the tutorials for more detailed benchmarking. + ### References [1] Bee Lim, Sanghyun Son, Heewon Kim, Seungjun Nah, and Kyoung Mu Lee, **"Enhanced Deep Residual Networks for Single Image Super-Resolution"**, 2nd NTIRE: New Trends in Image Restoration and Enhancement workshop and challenge on image super-resolution in conjunction with **CVPR 2017**. [[PDF](http://openaccess.thecvf.com/content_cvpr_2017_workshops/w12/papers/Lim_Enhanced_Deep_Residual_CVPR_2017_paper.pdf)] [[arXiv](https://arxiv.org/abs/1707.02921)] [[Slide](https://cv.snu.ac.kr/research/EDSR/Presentation_v3(release).pptx)] @@ -90,4 +92,4 @@ Comparing different algorithms. Scale x4 on monarch.png. [3] Chao Dong, Chen Change Loy, Xiaoou Tang. **"Accelerating the Super-Resolution Convolutional Neural Network"**, in Proceedings of European Conference on Computer Vision **ECCV 2016**. [[PDF](http://personal.ie.cuhk.edu.hk/~ccloy/files/eccv_2016_accelerating.pdf)] [[arXiv](https://arxiv.org/abs/1608.00367)] [[Project Page](http://mmlab.ie.cuhk.edu.hk/projects/FSRCNN.html)] -[4] Lai, W. S., Huang, J. B., Ahuja, N., and Yang, M. H., **"Deep laplacian pyramid networks for fast and accurate super-resolution"**, In Proceedings of the IEEE conference on computer vision and pattern recognition **CVPR 2017**. [[PDF](http://openaccess.thecvf.com/content_cvpr_2017/papers/Lai_Deep_Laplacian_Pyramid_CVPR_2017_paper.pdf)] [[arXiv](https://arxiv.org/abs/1710.01992)] [[Project Page](http://vllab.ucmerced.edu/wlai24/LapSRN/)] \ No newline at end of file +[4] Lai, W. S., Huang, J. B., Ahuja, N., and Yang, M. H., **"Deep laplacian pyramid networks for fast and accurate super-resolution"**, In Proceedings of the IEEE conference on computer vision and pattern recognition **CVPR 2017**. [[PDF](http://openaccess.thecvf.com/content_cvpr_2017/papers/Lai_Deep_Laplacian_Pyramid_CVPR_2017_paper.pdf)] [[arXiv](https://arxiv.org/abs/1710.01992)] [[Project Page](http://vllab.ucmerced.edu/wlai24/LapSRN/)] diff --git a/modules/dnn_superres/perf/perf_dnn_superres.cpp b/modules/dnn_superres/perf/perf_dnn_superres.cpp index d8e61157a83..2576b544243 100644 --- a/modules/dnn_superres/perf/perf_dnn_superres.cpp +++ b/modules/dnn_superres/perf/perf_dnn_superres.cpp @@ -27,20 +27,21 @@ PERF_TEST_P(dnn_superres, upsample, testing::Combine(MODEL, IMAGES)) string model_filename = get<1>(model); int scale = get<2>(model); - string model_path = getDataPath( TEST_DIR + "/" + model_filename ); - string image_path = getDataPath( image_name ); + string model_path = cvtest::findDataFile(TEST_DIR + "/" + model_filename); + string image_path = cvtest::findDataFile(image_name); DnnSuperResImpl sr; sr.readModel(model_path); sr.setModel(model_name, scale); Mat img = imread(image_path); + ASSERT_FALSE(img.empty()) << image_path; - Mat img_new(img.rows * scale, img.cols * scale, CV_8UC3); + Mat result; - declare.in(img, WARMUP_RNG).out(img_new).iterations(10); + TEST_CYCLE() { sr.upsample(img, result); } - TEST_CYCLE() { sr.upsample(img, img_new); } + ASSERT_FALSE(result.empty()); SANITY_CHECK_NOTHING(); } diff --git a/modules/dnn_superres/samples/dnn_superres.cpp b/modules/dnn_superres/samples/dnn_superres.cpp new file mode 100644 index 00000000000..77f28a55079 --- /dev/null +++ b/modules/dnn_superres/samples/dnn_superres.cpp @@ -0,0 +1,82 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#include + +#include + +#include +#include + +using namespace std; +using namespace cv; +using namespace dnn; +using namespace dnn_superres; + +int main(int argc, char *argv[]) +{ + // Check for valid command line arguments, print usage + // if insufficient arguments were given. + if ( argc < 4 ) { + cout << "usage: Arg 1: image | Path to image" << endl; + cout << "\t Arg 2: algorithm | bilinear, bicubic, edsr, espcn, fsrcnn or lapsrn" << endl; + cout << "\t Arg 3: scale | 2, 3 or 4 \n"; + cout << "\t Arg 4: path to model file \n"; + return -1; + } + + string img_path = string(argv[1]); + string algorithm = string(argv[2]); + int scale = atoi(argv[3]); + string path = ""; + + if( argc > 4) + path = string(argv[4]); + + // Load the image + Mat img = cv::imread(img_path); + Mat original_img(img); + if ( img.empty() ) + { + std::cerr << "Couldn't load image: " << img << "\n"; + return -2; + } + + //Make dnn super resolution instance + DnnSuperResImpl sr; + + Mat img_new; + + if( algorithm == "bilinear" ){ + resize(img, img_new, Size(), scale, scale, 2); + } + else if( algorithm == "bicubic" ) + { + resize(img, img_new, Size(), scale, scale, 3); + } + else if( algorithm == "edsr" || algorithm == "espcn" || algorithm == "fsrcnn" || algorithm == "lapsrn" ) + { + sr.readModel(path); + sr.setModel(algorithm, scale); + sr.upsample(img, img_new); + } + else{ + std::cerr << "Algorithm not recognized. \n"; + } + + if ( img_new.empty() ) + { + std::cerr << "Upsampling failed. \n"; + return -3; + } + cout << "Upsampling succeeded. \n"; + + // Display image + cv::namedWindow("Initial Image", WINDOW_AUTOSIZE); + cv::imshow("Initial Image", img_new); + //cv::imwrite("./saved.jpg", img_new); + cv::waitKey(0); + + return 0; +} \ No newline at end of file diff --git a/modules/dnn_superres/src/precomp.hpp b/modules/dnn_superres/src/precomp.hpp index a41f52326ff..cf1c4493569 100644 --- a/modules/dnn_superres/src/precomp.hpp +++ b/modules/dnn_superres/src/precomp.hpp @@ -6,8 +6,11 @@ #include #include +#include #include -#include +#include +#include +#include #include "opencv2/core.hpp" #include diff --git a/modules/dnn_superres/test/test_dnn_superres.cpp b/modules/dnn_superres/test/test_dnn_superres.cpp index 4370dd32fc6..6645040bddc 100644 --- a/modules/dnn_superres/test/test_dnn_superres.cpp +++ b/modules/dnn_superres/test/test_dnn_superres.cpp @@ -44,12 +44,22 @@ void runSingleModel(std::string algorithm, int scale, std::string model_filename ASSERT_EQ(new_rows, result.rows); } -TEST(CV_DnnSuperResSingleOutputTest, accuracy) +TEST(CV_DnnSuperResSingleOutputTest, accuracy_espcn_2) { - //x2 runSingleModel("espcn", 2, "ESPCN_x2.pb"); } +TEST(CV_DnnSuperResSingleOutputTest, accuracy_fsrcnn_2) +{ + runSingleModel("fsrcnn", 2, "FSRCNN_x2.pb"); +} + +TEST(CV_DnnSuperResSingleOutputTest, accuracy_fsrcnn_3) +{ + runSingleModel("fsrcnn", 3, "FSRCNN_x3.pb"); +} + + /****************************************************************************************\ * Test multi output models * \****************************************************************************************/ @@ -101,4 +111,4 @@ TEST(CV_DnnSuperResMultiOutputTest, accuracy) runMultiModel("lapsrn", 4, "LapSRN_x4.pb", scales_4x, names_4x); } -}} \ No newline at end of file +}} diff --git a/modules/dnn_superres/tutorials/table_of_content_dnn_superres.markdown b/modules/dnn_superres/tutorials/table_of_content_dnn_superres.markdown index 61f1e3df2bc..ce7c81d9e7a 100644 --- a/modules/dnn_superres/tutorials/table_of_content_dnn_superres.markdown +++ b/modules/dnn_superres/tutorials/table_of_content_dnn_superres.markdown @@ -1,5 +1,11 @@ Super Resolution using CNNs {#tutorial_table_of_content_dnn_superres} -============================ +=========================== + +- @subpage tutorial_dnn_superres_upscale_image_single + + *Author:* Xavier Weber + + How to upscale images using the 'dnn_superres' interface: single-output - @subpage tutorial_dnn_superres_upscale_image_multi diff --git a/modules/dnn_superres/tutorials/upscale_image_single/images/bicubicOutput.jpg b/modules/dnn_superres/tutorials/upscale_image_single/images/bicubicOutput.jpg new file mode 100644 index 00000000000..0d834452932 Binary files /dev/null and b/modules/dnn_superres/tutorials/upscale_image_single/images/bicubicOutput.jpg differ diff --git a/modules/dnn_superres/tutorials/upscale_image_single/images/fsrcnnOutput.jpg b/modules/dnn_superres/tutorials/upscale_image_single/images/fsrcnnOutput.jpg new file mode 100644 index 00000000000..ce36c8d58e3 Binary files /dev/null and b/modules/dnn_superres/tutorials/upscale_image_single/images/fsrcnnOutput.jpg differ diff --git a/modules/dnn_superres/tutorials/upscale_image_single/images/input.jpg b/modules/dnn_superres/tutorials/upscale_image_single/images/input.jpg new file mode 100644 index 00000000000..6fbc335e692 Binary files /dev/null and b/modules/dnn_superres/tutorials/upscale_image_single/images/input.jpg differ diff --git a/modules/dnn_superres/tutorials/upscale_image_single/upscale_image_single.markdown b/modules/dnn_superres/tutorials/upscale_image_single/upscale_image_single.markdown new file mode 100644 index 00000000000..7b42e652f53 --- /dev/null +++ b/modules/dnn_superres/tutorials/upscale_image_single/upscale_image_single.markdown @@ -0,0 +1,66 @@ +Upscaling images: single-output {#tutorial_dnn_superres_upscale_image_single} +=========================== + +In this tutorial you will learn how to use the 'dnn_superres' interface to upscale an image via pre-trained neural networks. + +Building +---- + +When building OpenCV, run the following command to build the 'dnn_superres' module: + +```make +cmake -DOPENCV_EXTRA_MODULES_PATH=/modules -Dopencv_dnn_superres=ON +``` + +Or make sure you check the dnn_superres module in the GUI version of CMake: cmake-gui. + +Source Code of the sample +----------- + +@includelineno dnn_superres/samples/dnn_superres.cpp + +Explanation +----------- + +-# **Set header and namespaces** + @code{.cpp} + #include + using namespace std; + using namespace cv; + using namespace dnn; + using namespace dnn_superres; + @endcode + + If you want you can set the namespace like the code above. +-# **Create the Dnn Superres object** + @code{.cpp} + DnnSuperResImpl sr; + @endcode + + This is just to create the object, register the custom dnn layers and get access to the class functions. +-# **Read the model** + @code{.cpp} + path = "models/FSRCNN_x2.pb" + sr.readModel(path); + @endcode + + 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. +-# **Set the model** + @code{.cpp} + sr.setModel("fsrcnn", 2); + @endcode + + 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".) +-# **Upscale an image** + @code{.cpp} + Mat img = cv::imread(img_path); + Mat img_new; + sr.upsample(img, img_new); + @endcode + + 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'. + +Original: ![](images/input.jpg) +Upscaled Image via FSRCNN: ![](images/fsrcnnOutput.jpg) +Upscaled Image via Bicubic Interpolation: ![](images/bicubicOutput.jpg) \ No newline at end of file