Path: blob/master/modules/superres/test/test_superres.cpp
16344 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.13// Copyright (C) 2009, Willow Garage Inc., all rights reserved.14// Third party copyrights are property of their respective owners.15//16// Redistribution and use in source and binary forms, with or without modification,17// are permitted provided that the following conditions are met:18//19// * Redistribution's of source code must retain the above copyright notice,20// this list of conditions and the following disclaimer.21//22// * Redistribution's in binary form must reproduce the above copyright notice,23// this list of conditions and the following disclaimer in the documentation24// and/or other materials provided with the distribution.25//26// * The name of the copyright holders may not be used to endorse or promote products27// derived from this software without specific prior written permission.28//29// This software is provided by the copyright holders and contributors "as is" and30// any express or implied warranties, including, but not limited to, the implied31// warranties of merchantability and fitness for a particular purpose are disclaimed.32// In no event shall the Intel Corporation or contributors be liable for any direct,33// indirect, incidental, special, exemplary, or consequential damages34// (including, but not limited to, procurement of substitute goods or services;35// loss of use, data, or profits; or business interruption) however caused36// and on any theory of liability, whether in contract, strict liability,37// or tort (including negligence or otherwise) arising in any way out of38// the use of this software, even if advised of the possibility of such damage.39//40//M*/4142#include "test_precomp.hpp"43#include "cvconfig.h"44#include "../src/input_array_utility.hpp"45#include "opencv2/ts/ocl_test.hpp"4647namespace opencv_test {4849#ifdef HAVE_VIDEO_INPUT5051namespace {5253class AllignedFrameSource : public cv::superres::FrameSource54{55public:56AllignedFrameSource(const cv::Ptr<cv::superres::FrameSource>& base, int scale);5758void nextFrame(cv::OutputArray frame);59void reset();6061private:62cv::Ptr<cv::superres::FrameSource> base_;6364cv::Mat origFrame_;65int scale_;66};6768AllignedFrameSource::AllignedFrameSource(const cv::Ptr<cv::superres::FrameSource>& base, int scale) :69base_(base), scale_(scale)70{71CV_Assert( base_ );72}7374void AllignedFrameSource::nextFrame(cv::OutputArray frame)75{76base_->nextFrame(origFrame_);7778if (origFrame_.rows % scale_ == 0 && origFrame_.cols % scale_ == 0)79cv::superres::arrCopy(origFrame_, frame);80else81{82cv::Rect ROI(0, 0, (origFrame_.cols / scale_) * scale_, (origFrame_.rows / scale_) * scale_);83cv::superres::arrCopy(origFrame_(ROI), frame);84}85}8687void AllignedFrameSource::reset()88{89base_->reset();90}9192class DegradeFrameSource : public cv::superres::FrameSource93{94public:95DegradeFrameSource(const cv::Ptr<cv::superres::FrameSource>& base, int scale);9697void nextFrame(cv::OutputArray frame);98void reset();99100private:101cv::Ptr<cv::superres::FrameSource> base_;102103cv::Mat origFrame_;104cv::Mat blurred_;105cv::Mat deg_;106double iscale_;107};108109DegradeFrameSource::DegradeFrameSource(const cv::Ptr<cv::superres::FrameSource>& base, int scale) :110base_(base), iscale_(1.0 / scale)111{112CV_Assert( base_ );113}114115static void addGaussNoise(cv::OutputArray _image, double sigma)116{117int type = _image.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);118cv::Mat noise(_image.size(), CV_32FC(cn));119cvtest::TS::ptr()->get_rng().fill(noise, cv::RNG::NORMAL, 0.0, sigma);120121cv::addWeighted(_image, 1.0, noise, 1.0, 0.0, _image, depth);122}123124static void addSpikeNoise(cv::OutputArray _image, int frequency)125{126cv::Mat_<uchar> mask(_image.size(), 0);127128for (int y = 0; y < mask.rows; ++y)129for (int x = 0; x < mask.cols; ++x)130if (cvtest::TS::ptr()->get_rng().uniform(0, frequency) < 1)131mask(y, x) = 255;132133_image.setTo(cv::Scalar::all(255), mask);134}135136void DegradeFrameSource::nextFrame(cv::OutputArray frame)137{138base_->nextFrame(origFrame_);139140cv::GaussianBlur(origFrame_, blurred_, cv::Size(5, 5), 0);141cv::resize(blurred_, deg_, cv::Size(), iscale_, iscale_, cv::INTER_NEAREST);142143addGaussNoise(deg_, 10.0);144addSpikeNoise(deg_, 500);145146cv::superres::arrCopy(deg_, frame);147}148149void DegradeFrameSource::reset()150{151base_->reset();152}153154double MSSIM(cv::InputArray _i1, cv::InputArray _i2)155{156const double C1 = 6.5025;157const double C2 = 58.5225;158159const int depth = CV_32F;160161cv::Mat I1, I2;162_i1.getMat().convertTo(I1, depth);163_i2.getMat().convertTo(I2, depth);164165cv::Mat I2_2 = I2.mul(I2); // I2^2166cv::Mat I1_2 = I1.mul(I1); // I1^2167cv::Mat I1_I2 = I1.mul(I2); // I1 * I2168169cv::Mat mu1, mu2;170cv::GaussianBlur(I1, mu1, cv::Size(11, 11), 1.5);171cv::GaussianBlur(I2, mu2, cv::Size(11, 11), 1.5);172173cv::Mat mu1_2 = mu1.mul(mu1);174cv::Mat mu2_2 = mu2.mul(mu2);175cv::Mat mu1_mu2 = mu1.mul(mu2);176177cv::Mat sigma1_2, sigma2_2, sigma12;178179cv::GaussianBlur(I1_2, sigma1_2, cv::Size(11, 11), 1.5);180sigma1_2 -= mu1_2;181182cv::GaussianBlur(I2_2, sigma2_2, cv::Size(11, 11), 1.5);183sigma2_2 -= mu2_2;184185cv::GaussianBlur(I1_I2, sigma12, cv::Size(11, 11), 1.5);186sigma12 -= mu1_mu2;187188cv::Mat t1, t2;189cv::Mat numerator;190cv::Mat denominator;191192// t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))193t1 = 2 * mu1_mu2 + C1;194t2 = 2 * sigma12 + C2;195numerator = t1.mul(t2);196197// t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))198t1 = mu1_2 + mu2_2 + C1;199t2 = sigma1_2 + sigma2_2 + C2;200denominator = t1.mul(t2);201202// ssim_map = numerator./denominator;203cv::Mat ssim_map;204cv::divide(numerator, denominator, ssim_map);205206// mssim = average of ssim map207cv::Scalar mssim = cv::mean(ssim_map);208209if (_i1.channels() == 1)210return mssim[0];211212return (mssim[0] + mssim[1] + mssim[3]) / 3;213}214215class SuperResolution : public testing::Test216{217public:218template <typename T>219void RunTest(cv::Ptr<cv::superres::SuperResolution> superRes);220};221222template <typename T>223void SuperResolution::RunTest(cv::Ptr<cv::superres::SuperResolution> superRes)224{225const std::string inputVideoName = cvtest::TS::ptr()->get_data_path() + "car.avi";226const int scale = 2;227const int iterations = 100;228const int temporalAreaRadius = 2;229230ASSERT_FALSE( superRes.empty() );231232const int btvKernelSize = superRes->getKernelSize();233234superRes->setScale(scale);235superRes->setIterations(iterations);236superRes->setTemporalAreaRadius(temporalAreaRadius);237238cv::Ptr<cv::superres::FrameSource> goldSource(new AllignedFrameSource(cv::superres::createFrameSource_Video(inputVideoName), scale));239cv::Ptr<cv::superres::FrameSource> lowResSource(new DegradeFrameSource(240cv::makePtr<AllignedFrameSource>(cv::superres::createFrameSource_Video(inputVideoName), scale), scale));241242// skip first frame243cv::Mat frame;244245lowResSource->nextFrame(frame);246goldSource->nextFrame(frame);247248cv::Rect inner(btvKernelSize, btvKernelSize, frame.cols - 2 * btvKernelSize, frame.rows - 2 * btvKernelSize);249250superRes->setInput(lowResSource);251252double srAvgMSSIM = 0.0;253const int count = 10;254255cv::Mat goldFrame;256T superResFrame;257for (int i = 0; i < count; ++i)258{259goldSource->nextFrame(goldFrame);260ASSERT_FALSE( goldFrame.empty() );261262superRes->nextFrame(superResFrame);263ASSERT_FALSE( superResFrame.empty() );264265const double srMSSIM = MSSIM(goldFrame(inner), superResFrame);266267srAvgMSSIM += srMSSIM;268}269270srAvgMSSIM /= count;271272EXPECT_GE( srAvgMSSIM, 0.5 );273}274275TEST_F(SuperResolution, BTVL1)276{277RunTest<cv::Mat>(cv::superres::createSuperResolution_BTVL1());278}279280#if defined(HAVE_CUDA) && defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING) && defined(HAVE_OPENCV_CUDAFILTERS)281282TEST_F(SuperResolution, BTVL1_CUDA)283{284RunTest<cv::Mat>(cv::superres::createSuperResolution_BTVL1_CUDA());285}286287#endif288289} // namespace290291#ifdef HAVE_OPENCL292293namespace ocl {294295OCL_TEST_F(SuperResolution, BTVL1)296{297RunTest<cv::UMat>(cv::superres::createSuperResolution_BTVL1());298}299300} // namespace opencv_test::ocl301302#endif303304#endif // HAVE_VIDEO_INPUT305306} // namespace307308309