Merge pull request #708 from sbokov:variational_refinement
commit
30f718d1f0
14 changed files with 2692 additions and 525 deletions
@ -0,0 +1,69 @@ |
||||
/*
|
||||
* By downloading, copying, installing or using the software you agree to this license. |
||||
* If you do not agree to this license, do not download, install, |
||||
* copy or use the software. |
||||
* |
||||
* |
||||
* License Agreement |
||||
* For Open Source Computer Vision Library |
||||
* (3 - clause BSD License) |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without modification, |
||||
* are permitted provided that the following conditions are met : |
||||
* |
||||
* *Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright notice, |
||||
* this list of conditions and the following disclaimer in the documentation |
||||
* and / or other materials provided with the distribution. |
||||
* |
||||
* * Neither the names of the copyright holders nor the names of the contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* This software is provided by the copyright holders and contributors "as is" and |
||||
* any express or implied warranties, including, but not limited to, the implied |
||||
* warranties of merchantability and fitness for a particular purpose are disclaimed. |
||||
* In no event shall copyright holders or contributors be liable for any direct, |
||||
* indirect, incidental, special, exemplary, or consequential damages |
||||
* (including, but not limited to, procurement of substitute goods or services; |
||||
* loss of use, data, or profits; or business interruption) however caused |
||||
* and on any theory of liability, whether in contract, strict liability, |
||||
* or tort(including negligence or otherwise) arising in any way out of |
||||
* the use of this software, even if advised of the possibility of such damage. |
||||
*/ |
||||
|
||||
#include "perf_precomp.hpp" |
||||
|
||||
using std::tr1::tuple; |
||||
using std::tr1::get; |
||||
using namespace perf; |
||||
using namespace testing; |
||||
using namespace cv; |
||||
using namespace cv::optflow; |
||||
|
||||
typedef tuple<Size> DFParams; |
||||
typedef TestBaseWithParam<DFParams> DenseOpticalFlow_DeepFlow; |
||||
|
||||
PERF_TEST_P(DenseOpticalFlow_DeepFlow, perf, Values(szVGA, sz720p)) |
||||
{ |
||||
DFParams params = GetParam(); |
||||
Size sz = get<0>(params); |
||||
|
||||
Mat frame1(sz, CV_8U); |
||||
Mat frame2(sz, CV_8U); |
||||
Mat flow; |
||||
|
||||
randu(frame1, 0, 255); |
||||
randu(frame2, 0, 255); |
||||
|
||||
cv::setNumThreads(cv::getNumberOfCPUs()); |
||||
TEST_CYCLE_N(1) |
||||
{ |
||||
Ptr<DenseOpticalFlow> algo = createOptFlow_DeepFlow(); |
||||
algo->calc(frame1, frame2, flow); |
||||
} |
||||
|
||||
SANITY_CHECK_NOTHING(); |
||||
} |
@ -0,0 +1,103 @@ |
||||
/*
|
||||
* By downloading, copying, installing or using the software you agree to this license. |
||||
* If you do not agree to this license, do not download, install, |
||||
* copy or use the software. |
||||
* |
||||
* |
||||
* License Agreement |
||||
* For Open Source Computer Vision Library |
||||
* (3 - clause BSD License) |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without modification, |
||||
* are permitted provided that the following conditions are met : |
||||
* |
||||
* *Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright notice, |
||||
* this list of conditions and the following disclaimer in the documentation |
||||
* and / or other materials provided with the distribution. |
||||
* |
||||
* * Neither the names of the copyright holders nor the names of the contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* This software is provided by the copyright holders and contributors "as is" and |
||||
* any express or implied warranties, including, but not limited to, the implied |
||||
* warranties of merchantability and fitness for a particular purpose are disclaimed. |
||||
* In no event shall copyright holders or contributors be liable for any direct, |
||||
* indirect, incidental, special, exemplary, or consequential damages |
||||
* (including, but not limited to, procurement of substitute goods or services; |
||||
* loss of use, data, or profits; or business interruption) however caused |
||||
* and on any theory of liability, whether in contract, strict liability, |
||||
* or tort(including negligence or otherwise) arising in any way out of |
||||
* the use of this software, even if advised of the possibility of such damage. |
||||
*/ |
||||
|
||||
#include "perf_precomp.hpp" |
||||
|
||||
using std::tr1::tuple; |
||||
using std::tr1::get; |
||||
using namespace perf; |
||||
using namespace testing; |
||||
using namespace cv; |
||||
using namespace cv::optflow; |
||||
|
||||
void MakeArtificialExample(Mat &dst_frame1, Mat &dst_frame2); |
||||
|
||||
typedef tuple<String, Size> DISParams; |
||||
typedef TestBaseWithParam<DISParams> DenseOpticalFlow_DIS; |
||||
|
||||
PERF_TEST_P(DenseOpticalFlow_DIS, perf, |
||||
Combine(Values("PRESET_ULTRAFAST", "PRESET_FAST", "PRESET_MEDIUM"), Values(szVGA, sz720p, sz1080p))) |
||||
{ |
||||
DISParams params = GetParam(); |
||||
|
||||
// use strings to print preset names in the perf test results:
|
||||
String preset_string = get<0>(params); |
||||
int preset = DISOpticalFlow::PRESET_FAST; |
||||
if (preset_string == "PRESET_ULTRAFAST") |
||||
preset = DISOpticalFlow::PRESET_ULTRAFAST; |
||||
else if (preset_string == "PRESET_FAST") |
||||
preset = DISOpticalFlow::PRESET_FAST; |
||||
else if (preset_string == "PRESET_MEDIUM") |
||||
preset = DISOpticalFlow::PRESET_MEDIUM; |
||||
Size sz = get<1>(params); |
||||
|
||||
Mat frame1(sz, CV_8U); |
||||
Mat frame2(sz, CV_8U); |
||||
Mat flow; |
||||
|
||||
MakeArtificialExample(frame1, frame2); |
||||
|
||||
cv::setNumThreads(cv::getNumberOfCPUs()); |
||||
TEST_CYCLE_N(10) |
||||
{ |
||||
Ptr<DenseOpticalFlow> algo = createOptFlow_DIS(preset); |
||||
algo->calc(frame1, frame2, flow); |
||||
} |
||||
|
||||
SANITY_CHECK_NOTHING(); |
||||
} |
||||
|
||||
void MakeArtificialExample(Mat &dst_frame1, Mat &dst_frame2) |
||||
{ |
||||
int src_scale = 2; |
||||
int OF_scale = 6; |
||||
double sigma = dst_frame1.cols / 300; |
||||
|
||||
Mat tmp(Size(dst_frame1.cols / (int)pow(2, src_scale), dst_frame1.rows / (int)pow(2, src_scale)), CV_8U); |
||||
randu(tmp, 0, 255); |
||||
resize(tmp, dst_frame1, dst_frame1.size(), 0.0, 0.0, INTER_LINEAR); |
||||
resize(tmp, dst_frame2, dst_frame2.size(), 0.0, 0.0, INTER_LINEAR); |
||||
|
||||
Mat displacement_field(Size(dst_frame1.cols / (int)pow(2, OF_scale), dst_frame1.rows / (int)pow(2, OF_scale)), |
||||
CV_32FC2); |
||||
randn(displacement_field, 0.0, sigma); |
||||
resize(displacement_field, displacement_field, dst_frame2.size(), 0.0, 0.0, INTER_CUBIC); |
||||
for (int i = 0; i < displacement_field.rows; i++) |
||||
for (int j = 0; j < displacement_field.cols; j++) |
||||
displacement_field.at<Vec2f>(i, j) += Vec2f((float)j, (float)i); |
||||
|
||||
remap(dst_frame2, dst_frame2, displacement_field, Mat(), INTER_LINEAR, BORDER_REPLICATE); |
||||
} |
@ -0,0 +1,3 @@ |
||||
#include "perf_precomp.hpp" |
||||
|
||||
CV_PERF_TEST_MAIN(optflow) |
@ -0,0 +1,17 @@ |
||||
#ifdef __GNUC__ |
||||
# pragma GCC diagnostic ignored "-Wmissing-declarations" |
||||
# if defined __clang__ || defined __APPLE__ |
||||
# pragma GCC diagnostic ignored "-Wmissing-prototypes" |
||||
# pragma GCC diagnostic ignored "-Wextra" |
||||
# endif |
||||
#endif |
||||
|
||||
#ifndef __OPENCV_PERF_PRECOMP_HPP__ |
||||
#define __OPENCV_PERF_PRECOMP_HPP__ |
||||
|
||||
#include "opencv2/ts.hpp" |
||||
#include "opencv2/imgproc.hpp" |
||||
#include "opencv2/optflow.hpp" |
||||
#include "opencv2/highgui.hpp" |
||||
|
||||
#endif |
@ -0,0 +1,77 @@ |
||||
/*
|
||||
* By downloading, copying, installing or using the software you agree to this license. |
||||
* If you do not agree to this license, do not download, install, |
||||
* copy or use the software. |
||||
* |
||||
* |
||||
* License Agreement |
||||
* For Open Source Computer Vision Library |
||||
* (3 - clause BSD License) |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without modification, |
||||
* are permitted provided that the following conditions are met : |
||||
* |
||||
* *Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright notice, |
||||
* this list of conditions and the following disclaimer in the documentation |
||||
* and / or other materials provided with the distribution. |
||||
* |
||||
* * Neither the names of the copyright holders nor the names of the contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* This software is provided by the copyright holders and contributors "as is" and |
||||
* any express or implied warranties, including, but not limited to, the implied |
||||
* warranties of merchantability and fitness for a particular purpose are disclaimed. |
||||
* In no event shall copyright holders or contributors be liable for any direct, |
||||
* indirect, incidental, special, exemplary, or consequential damages |
||||
* (including, but not limited to, procurement of substitute goods or services; |
||||
* loss of use, data, or profits; or business interruption) however caused |
||||
* and on any theory of liability, whether in contract, strict liability, |
||||
* or tort(including negligence or otherwise) arising in any way out of |
||||
* the use of this software, even if advised of the possibility of such damage. |
||||
*/ |
||||
|
||||
#include "perf_precomp.hpp" |
||||
|
||||
using std::tr1::tuple; |
||||
using std::tr1::get; |
||||
using namespace perf; |
||||
using namespace testing; |
||||
using namespace cv; |
||||
using namespace cv::optflow; |
||||
|
||||
typedef tuple<Size, int, int> VarRefParams; |
||||
typedef TestBaseWithParam<VarRefParams> DenseOpticalFlow_VariationalRefinement; |
||||
|
||||
PERF_TEST_P(DenseOpticalFlow_VariationalRefinement, perf, Combine(Values(szQVGA, szVGA), Values(5, 10), Values(5, 10))) |
||||
{ |
||||
VarRefParams params = GetParam(); |
||||
Size sz = get<0>(params); |
||||
int sorIter = get<1>(params); |
||||
int fixedPointIter = get<2>(params); |
||||
|
||||
Mat frame1(sz, CV_8U); |
||||
Mat frame2(sz, CV_8U); |
||||
Mat flow(sz, CV_32FC2); |
||||
|
||||
randu(frame1, 0, 255); |
||||
randu(frame2, 0, 255); |
||||
flow.setTo(0.0f); |
||||
|
||||
cv::setNumThreads(cv::getNumberOfCPUs()); |
||||
TEST_CYCLE_N(10) |
||||
{ |
||||
Ptr<VariationalRefinement> var = createVariationalFlowRefinement(); |
||||
var->setAlpha(20.0f); |
||||
var->setGamma(10.0f); |
||||
var->setDelta(5.0f); |
||||
var->setSorIterations(sorIter); |
||||
var->setFixedPointIterations(fixedPointIter); |
||||
var->calc(frame1, frame2, flow); |
||||
} |
||||
|
||||
SANITY_CHECK_NOTHING(); |
||||
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,190 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp" |
||||
#include <fstream> |
||||
|
||||
using namespace std; |
||||
using namespace cv; |
||||
using namespace cvtest; |
||||
using namespace optflow; |
||||
|
||||
static string getDataDir() { return TS::ptr()->get_data_path(); } |
||||
|
||||
static bool isFlowCorrect(float u) { return !cvIsNaN(u) && (fabs(u) < 1e9); } |
||||
|
||||
static float calcRMSE(Mat flow1, Mat flow2) |
||||
{ |
||||
float sum = 0; |
||||
int counter = 0; |
||||
const int rows = flow1.rows; |
||||
const int cols = flow1.cols; |
||||
|
||||
for (int y = 0; y < rows; ++y) |
||||
{ |
||||
for (int x = 0; x < cols; ++x) |
||||
{ |
||||
Vec2f flow1_at_point = flow1.at<Vec2f>(y, x); |
||||
Vec2f flow2_at_point = flow2.at<Vec2f>(y, x); |
||||
|
||||
float u1 = flow1_at_point[0]; |
||||
float v1 = flow1_at_point[1]; |
||||
float u2 = flow2_at_point[0]; |
||||
float v2 = flow2_at_point[1]; |
||||
|
||||
if (isFlowCorrect(u1) && isFlowCorrect(u2) && isFlowCorrect(v1) && isFlowCorrect(v2)) |
||||
{ |
||||
sum += (u1 - u2) * (u1 - u2) + (v1 - v2) * (v1 - v2); |
||||
counter++; |
||||
} |
||||
} |
||||
} |
||||
return (float)sqrt(sum / (1e-9 + counter)); |
||||
} |
||||
|
||||
bool readRubberWhale(Mat &dst_frame_1, Mat &dst_frame_2, Mat &dst_GT) |
||||
{ |
||||
const string frame1_path = getDataDir() + "optflow/RubberWhale1.png"; |
||||
const string frame2_path = getDataDir() + "optflow/RubberWhale2.png"; |
||||
const string gt_flow_path = getDataDir() + "optflow/RubberWhale.flo"; |
||||
|
||||
dst_frame_1 = imread(frame1_path); |
||||
dst_frame_2 = imread(frame2_path); |
||||
dst_GT = readOpticalFlow(gt_flow_path); |
||||
|
||||
if (dst_frame_1.empty() || dst_frame_2.empty() || dst_GT.empty()) |
||||
return false; |
||||
else |
||||
return true; |
||||
} |
||||
|
||||
TEST(DenseOpticalFlow_SimpleFlow, ReferenceAccuracy) |
||||
{ |
||||
Mat frame1, frame2, GT; |
||||
ASSERT_TRUE(readRubberWhale(frame1, frame2, GT)); |
||||
float target_RMSE = 0.37f; |
||||
|
||||
Mat flow; |
||||
Ptr<DenseOpticalFlow> algo; |
||||
algo = createOptFlow_SimpleFlow(); |
||||
algo->calc(frame1, frame2, flow); |
||||
ASSERT_EQ(GT.rows, flow.rows); |
||||
ASSERT_EQ(GT.cols, flow.cols); |
||||
EXPECT_LE(calcRMSE(GT, flow), target_RMSE); |
||||
} |
||||
|
||||
TEST(DenseOpticalFlow_DeepFlow, ReferenceAccuracy) |
||||
{ |
||||
Mat frame1, frame2, GT; |
||||
ASSERT_TRUE(readRubberWhale(frame1, frame2, GT)); |
||||
float target_RMSE = 0.35f; |
||||
cvtColor(frame1, frame1, COLOR_BGR2GRAY); |
||||
cvtColor(frame2, frame2, COLOR_BGR2GRAY); |
||||
|
||||
Mat flow; |
||||
Ptr<DenseOpticalFlow> algo; |
||||
algo = createOptFlow_DeepFlow(); |
||||
algo->calc(frame1, frame2, flow); |
||||
ASSERT_EQ(GT.rows, flow.rows); |
||||
ASSERT_EQ(GT.cols, flow.cols); |
||||
EXPECT_LE(calcRMSE(GT, flow), target_RMSE); |
||||
} |
||||
|
||||
TEST(DenseOpticalFlow_SparseToDenseFlow, ReferenceAccuracy) |
||||
{ |
||||
Mat frame1, frame2, GT; |
||||
ASSERT_TRUE(readRubberWhale(frame1, frame2, GT)); |
||||
float target_RMSE = 0.52f; |
||||
|
||||
Mat flow; |
||||
Ptr<DenseOpticalFlow> algo; |
||||
algo = createOptFlow_SparseToDense(); |
||||
algo->calc(frame1, frame2, flow); |
||||
ASSERT_EQ(GT.rows, flow.rows); |
||||
ASSERT_EQ(GT.cols, flow.cols); |
||||
EXPECT_LE(calcRMSE(GT, flow), target_RMSE); |
||||
} |
||||
|
||||
TEST(DenseOpticalFlow_DIS, ReferenceAccuracy) |
||||
{ |
||||
Mat frame1, frame2, GT; |
||||
ASSERT_TRUE(readRubberWhale(frame1, frame2, GT)); |
||||
int presets[] = {DISOpticalFlow::PRESET_ULTRAFAST, DISOpticalFlow::PRESET_FAST, DISOpticalFlow::PRESET_MEDIUM}; |
||||
float target_RMSE[] = {0.86f, 0.74f, 0.49f}; |
||||
cvtColor(frame1, frame1, COLOR_BGR2GRAY); |
||||
cvtColor(frame2, frame2, COLOR_BGR2GRAY); |
||||
|
||||
Ptr<DenseOpticalFlow> algo; |
||||
|
||||
// iterate over presets:
|
||||
for (int i = 0; i < 3; i++) |
||||
{ |
||||
Mat flow; |
||||
algo = createOptFlow_DIS(presets[i]); |
||||
algo->calc(frame1, frame2, flow); |
||||
ASSERT_EQ(GT.rows, flow.rows); |
||||
ASSERT_EQ(GT.cols, flow.cols); |
||||
EXPECT_LE(calcRMSE(GT, flow), target_RMSE[i]); |
||||
} |
||||
} |
||||
|
||||
TEST(DenseOpticalFlow_VariationalRefinement, ReferenceAccuracy) |
||||
{ |
||||
Mat frame1, frame2, GT; |
||||
ASSERT_TRUE(readRubberWhale(frame1, frame2, GT)); |
||||
float target_RMSE = 0.86f; |
||||
cvtColor(frame1, frame1, COLOR_BGR2GRAY); |
||||
cvtColor(frame2, frame2, COLOR_BGR2GRAY); |
||||
|
||||
Ptr<VariationalRefinement> var_ref; |
||||
var_ref = createVariationalFlowRefinement(); |
||||
var_ref->setAlpha(20.0f); |
||||
var_ref->setDelta(5.0f); |
||||
var_ref->setGamma(10.0f); |
||||
var_ref->setSorIterations(25); |
||||
var_ref->setFixedPointIterations(25); |
||||
Mat flow(frame1.size(), CV_32FC2); |
||||
flow.setTo(0.0f); |
||||
var_ref->calc(frame1, frame2, flow); |
||||
ASSERT_EQ(GT.rows, flow.rows); |
||||
ASSERT_EQ(GT.cols, flow.cols); |
||||
EXPECT_LE(calcRMSE(GT, flow), target_RMSE); |
||||
} |
@ -0,0 +1,159 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp" |
||||
#include <fstream> |
||||
|
||||
using namespace std; |
||||
using namespace std::tr1; |
||||
using namespace cv; |
||||
using namespace cvtest; |
||||
using namespace perf; |
||||
using namespace testing; |
||||
using namespace optflow; |
||||
|
||||
typedef tuple<Size> OFParams; |
||||
typedef TestWithParam<OFParams> DenseOpticalFlow_DIS; |
||||
typedef TestWithParam<OFParams> DenseOpticalFlow_VariationalRefinement; |
||||
|
||||
TEST_P(DenseOpticalFlow_DIS, MultithreadReproducibility) |
||||
{ |
||||
double MAX_DIF = 0.01; |
||||
double MAX_MEAN_DIF = 0.001; |
||||
int loopsCount = 2; |
||||
RNG rng(0); |
||||
|
||||
OFParams params = GetParam(); |
||||
Size size = get<0>(params); |
||||
|
||||
for (int iter = 0; iter <= loopsCount; iter++) |
||||
{ |
||||
Mat frame1(size, CV_8U); |
||||
randu(frame1, 0, 255); |
||||
Mat frame2(size, CV_8U); |
||||
randu(frame2, 0, 255); |
||||
|
||||
Ptr<DISOpticalFlow> algo = createOptFlow_DIS(); |
||||
int psz = rng.uniform(4, 16); |
||||
int pstr = rng.uniform(1, psz - 1); |
||||
int grad_iter = rng.uniform(1, 64); |
||||
int var_iter = rng.uniform(0, 10); |
||||
bool use_mean_normalization = !!rng.uniform(0, 2); |
||||
bool use_spatial_propagation = !!rng.uniform(0, 2); |
||||
algo->setFinestScale(0); |
||||
algo->setPatchSize(psz); |
||||
algo->setPatchStride(pstr); |
||||
algo->setGradientDescentIterations(grad_iter); |
||||
algo->setVariationalRefinementIterations(var_iter); |
||||
algo->setUseMeanNormalization(use_mean_normalization); |
||||
algo->setUseSpatialPropagation(use_spatial_propagation); |
||||
|
||||
cv::setNumThreads(cv::getNumberOfCPUs()); |
||||
Mat resMultiThread; |
||||
algo->calc(frame1, frame2, resMultiThread); |
||||
|
||||
cv::setNumThreads(1); |
||||
Mat resSingleThread; |
||||
algo->calc(frame1, frame2, resSingleThread); |
||||
|
||||
EXPECT_LE(cv::norm(resSingleThread, resMultiThread, NORM_INF), MAX_DIF); |
||||
EXPECT_LE(cv::norm(resSingleThread, resMultiThread, NORM_L1), MAX_MEAN_DIF * frame1.total()); |
||||
|
||||
// resulting flow should be within the frame bounds:
|
||||
double min_val, max_val; |
||||
minMaxLoc(resMultiThread, &min_val, &max_val); |
||||
EXPECT_LE(abs(min_val), sqrt(size.height * size.height + size.width * size.width)); |
||||
EXPECT_LE(abs(max_val), sqrt(size.height * size.height + size.width * size.width)); |
||||
} |
||||
} |
||||
|
||||
INSTANTIATE_TEST_CASE_P(FullSet, DenseOpticalFlow_DIS, Values(szODD, szQVGA)); |
||||
|
||||
TEST_P(DenseOpticalFlow_VariationalRefinement, MultithreadReproducibility) |
||||
{ |
||||
double MAX_DIF = 0.01; |
||||
double MAX_MEAN_DIF = 0.001; |
||||
float input_flow_rad = 5.0; |
||||
int loopsCount = 2; |
||||
RNG rng(0); |
||||
|
||||
OFParams params = GetParam(); |
||||
Size size = get<0>(params); |
||||
|
||||
for (int iter = 0; iter <= loopsCount; iter++) |
||||
{ |
||||
Mat frame1(size, CV_8U); |
||||
randu(frame1, 0, 255); |
||||
Mat frame2(size, CV_8U); |
||||
randu(frame2, 0, 255); |
||||
Mat flow(size, CV_32FC2); |
||||
randu(flow, -input_flow_rad, input_flow_rad); |
||||
|
||||
Ptr<VariationalRefinement> var = createVariationalFlowRefinement(); |
||||
var->setAlpha(rng.uniform(1.0f, 100.0f)); |
||||
var->setGamma(rng.uniform(0.1f, 10.0f)); |
||||
var->setDelta(rng.uniform(0.1f, 10.0f)); |
||||
var->setSorIterations(rng.uniform(1, 20)); |
||||
var->setFixedPointIterations(rng.uniform(1, 20)); |
||||
var->setOmega(rng.uniform(1.01f, 1.99f)); |
||||
|
||||
cv::setNumThreads(cv::getNumberOfCPUs()); |
||||
Mat resMultiThread; |
||||
flow.copyTo(resMultiThread); |
||||
var->calc(frame1, frame2, resMultiThread); |
||||
|
||||
cv::setNumThreads(1); |
||||
Mat resSingleThread; |
||||
flow.copyTo(resSingleThread); |
||||
var->calc(frame1, frame2, resSingleThread); |
||||
|
||||
EXPECT_LE(cv::norm(resSingleThread, resMultiThread, NORM_INF), MAX_DIF); |
||||
EXPECT_LE(cv::norm(resSingleThread, resMultiThread, NORM_L1), MAX_MEAN_DIF * frame1.total()); |
||||
|
||||
// resulting flow should be within the frame bounds:
|
||||
double min_val, max_val; |
||||
minMaxLoc(resMultiThread, &min_val, &max_val); |
||||
EXPECT_LE(abs(min_val), sqrt(size.height * size.height + size.width * size.width)); |
||||
EXPECT_LE(abs(max_val), sqrt(size.height * size.height + size.width * size.width)); |
||||
} |
||||
} |
||||
|
||||
INSTANTIATE_TEST_CASE_P(FullSet, DenseOpticalFlow_VariationalRefinement, Values(szODD, szQVGA)); |
@ -1,190 +0,0 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp" |
||||
|
||||
#include <string> |
||||
|
||||
using namespace std; |
||||
|
||||
/* ///////////////////// simpleflow_test ///////////////////////// */ |
||||
|
||||
class CV_SimpleFlowTest : public cvtest::BaseTest |
||||
{ |
||||
public: |
||||
CV_SimpleFlowTest(); |
||||
protected: |
||||
void run(int); |
||||
}; |
||||
|
||||
|
||||
CV_SimpleFlowTest::CV_SimpleFlowTest() {} |
||||
|
||||
static bool readOpticalFlowFromFile(FILE* file, cv::Mat& flow) { |
||||
char header[5]; |
||||
if (fread(header, 1, 4, file) < 4 && (string)header != "PIEH") { |
||||
return false; |
||||
} |
||||
|
||||
int cols, rows; |
||||
if (fread(&cols, sizeof(int), 1, file) != 1|| |
||||
fread(&rows, sizeof(int), 1, file) != 1) { |
||||
return false; |
||||
} |
||||
|
||||
flow = cv::Mat::zeros(rows, cols, CV_32FC2); |
||||
|
||||
for (int i = 0; i < rows; ++i) { |
||||
for (int j = 0; j < cols; ++j) { |
||||
cv::Vec2f flow_at_point; |
||||
if (fread(&(flow_at_point[0]), sizeof(float), 1, file) != 1 || |
||||
fread(&(flow_at_point[1]), sizeof(float), 1, file) != 1) { |
||||
return false; |
||||
} |
||||
flow.at<cv::Vec2f>(i, j) = flow_at_point; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
static bool isFlowCorrect(float u) { |
||||
return !cvIsNaN(u) && (fabs(u) < 1e9); |
||||
} |
||||
|
||||
static float calc_rmse(cv::Mat flow1, cv::Mat flow2) { |
||||
float sum = 0; |
||||
int counter = 0; |
||||
const int rows = flow1.rows; |
||||
const int cols = flow1.cols; |
||||
|
||||
for (int y = 0; y < rows; ++y) { |
||||
for (int x = 0; x < cols; ++x) { |
||||
cv::Vec2f flow1_at_point = flow1.at<cv::Vec2f>(y, x); |
||||
cv::Vec2f flow2_at_point = flow2.at<cv::Vec2f>(y, x); |
||||
|
||||
float u1 = flow1_at_point[0]; |
||||
float v1 = flow1_at_point[1]; |
||||
float u2 = flow2_at_point[0]; |
||||
float v2 = flow2_at_point[1]; |
||||
|
||||
if (isFlowCorrect(u1) && isFlowCorrect(u2) && isFlowCorrect(v1) && isFlowCorrect(v2)) { |
||||
sum += (u1-u2)*(u1-u2) + (v1-v2)*(v1-v2); |
||||
counter++; |
||||
} |
||||
} |
||||
} |
||||
return (float)sqrt(sum / (1e-9 + counter)); |
||||
} |
||||
|
||||
void CV_SimpleFlowTest::run(int) { |
||||
const float MAX_RMSE = 0.6f; |
||||
const string frame1_path = ts->get_data_path() + "optflow/RubberWhale1.png"; |
||||
const string frame2_path = ts->get_data_path() + "optflow/RubberWhale2.png"; |
||||
const string gt_flow_path = ts->get_data_path() + "optflow/RubberWhale.flo"; |
||||
|
||||
cv::Mat frame1 = cv::imread(frame1_path); |
||||
cv::Mat frame2 = cv::imread(frame2_path); |
||||
|
||||
if (frame1.empty()) { |
||||
ts->printf(cvtest::TS::LOG, "could not read image %s\n", frame2_path.c_str()); |
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA); |
||||
return; |
||||
} |
||||
|
||||
if (frame2.empty()) { |
||||
ts->printf(cvtest::TS::LOG, "could not read image %s\n", frame2_path.c_str()); |
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA); |
||||
return; |
||||
} |
||||
|
||||
if (frame1.rows != frame2.rows && frame1.cols != frame2.cols) { |
||||
ts->printf(cvtest::TS::LOG, "images should be of equal sizes (%s and %s)", |
||||
frame1_path.c_str(), frame2_path.c_str()); |
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA); |
||||
return; |
||||
} |
||||
|
||||
if (frame1.type() != 16 || frame2.type() != 16) { |
||||
ts->printf(cvtest::TS::LOG, "images should be of equal type CV_8UC3 (%s and %s)", |
||||
frame1_path.c_str(), frame2_path.c_str()); |
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA); |
||||
return; |
||||
} |
||||
|
||||
cv::Mat flow_gt; |
||||
|
||||
FILE* gt_flow_file = fopen(gt_flow_path.c_str(), "rb"); |
||||
if (gt_flow_file == NULL) { |
||||
ts->printf(cvtest::TS::LOG, "could not read ground-thuth flow from file %s", |
||||
gt_flow_path.c_str()); |
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA); |
||||
return; |
||||
} |
||||
|
||||
if (!readOpticalFlowFromFile(gt_flow_file, flow_gt)) { |
||||
ts->printf(cvtest::TS::LOG, "error while reading flow data from file %s", |
||||
gt_flow_path.c_str()); |
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA); |
||||
return; |
||||
} |
||||
fclose(gt_flow_file); |
||||
|
||||
cv::Mat flow; |
||||
cv::optflow::calcOpticalFlowSF(frame1, frame2, flow, 3, 2, 4); |
||||
|
||||
float rmse = calc_rmse(flow_gt, flow); |
||||
|
||||
ts->printf(cvtest::TS::LOG, "Optical flow estimation RMSE for SimpleFlow algorithm : %lf\n", |
||||
rmse); |
||||
|
||||
if (rmse > MAX_RMSE) { |
||||
ts->printf( cvtest::TS::LOG, |
||||
"Too big rmse error : %lf ( >= %lf )\n", rmse, MAX_RMSE); |
||||
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
|
||||
TEST(Video_OpticalFlowSimpleFlow, accuracy) { CV_SimpleFlowTest test; test.safe_run(); } |
||||
|
||||
/* End of file. */ |
@ -1,146 +0,0 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp" |
||||
|
||||
#include <string> |
||||
|
||||
using namespace std; |
||||
using namespace cv; |
||||
|
||||
/* ///////////////////// sparsetodenseflow_test ///////////////////////// */ |
||||
|
||||
class CV_SparseToDenseFlowTest : public cvtest::BaseTest |
||||
{ |
||||
protected: |
||||
void run(int); |
||||
}; |
||||
|
||||
static bool isFlowCorrect(float u) { |
||||
return !cvIsNaN(u) && (fabs(u) < 1e9); |
||||
} |
||||
|
||||
static float calc_rmse(Mat flow1, Mat flow2) { |
||||
float sum = 0; |
||||
int counter = 0; |
||||
const int rows = flow1.rows; |
||||
const int cols = flow1.cols; |
||||
|
||||
for (int y = 0; y < rows; ++y) { |
||||
for (int x = 0; x < cols; ++x) { |
||||
Vec2f flow1_at_point = flow1.at<Vec2f>(y, x); |
||||
Vec2f flow2_at_point = flow2.at<Vec2f>(y, x); |
||||
|
||||
float u1 = flow1_at_point[0]; |
||||
float v1 = flow1_at_point[1]; |
||||
float u2 = flow2_at_point[0]; |
||||
float v2 = flow2_at_point[1]; |
||||
|
||||
if (isFlowCorrect(u1) && isFlowCorrect(u2) && isFlowCorrect(v1) && isFlowCorrect(v2)) { |
||||
sum += (u1-u2)*(u1-u2) + (v1-v2)*(v1-v2); |
||||
counter++; |
||||
} |
||||
} |
||||
} |
||||
return (float)sqrt(sum / (1e-9 + counter)); |
||||
} |
||||
|
||||
void CV_SparseToDenseFlowTest::run(int) { |
||||
const float MAX_RMSE = 0.6f; |
||||
const string frame1_path = ts->get_data_path() + "optflow/RubberWhale1.png"; |
||||
const string frame2_path = ts->get_data_path() + "optflow/RubberWhale2.png"; |
||||
const string gt_flow_path = ts->get_data_path() + "optflow/RubberWhale.flo"; |
||||
|
||||
Mat frame1 = imread(frame1_path); |
||||
Mat frame2 = imread(frame2_path); |
||||
|
||||
if (frame1.empty()) { |
||||
ts->printf(cvtest::TS::LOG, "could not read image %s\n", frame2_path.c_str()); |
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA); |
||||
return; |
||||
} |
||||
|
||||
if (frame2.empty()) { |
||||
ts->printf(cvtest::TS::LOG, "could not read image %s\n", frame2_path.c_str()); |
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA); |
||||
return; |
||||
} |
||||
|
||||
if (frame1.rows != frame2.rows && frame1.cols != frame2.cols) { |
||||
ts->printf(cvtest::TS::LOG, "images should be of equal sizes (%s and %s)", |
||||
frame1_path.c_str(), frame2_path.c_str()); |
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA); |
||||
return; |
||||
} |
||||
|
||||
if (frame1.type() != 16 || frame2.type() != 16) { |
||||
ts->printf(cvtest::TS::LOG, "images should be of equal type CV_8UC3 (%s and %s)", |
||||
frame1_path.c_str(), frame2_path.c_str()); |
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA); |
||||
return; |
||||
} |
||||
|
||||
Mat flow_gt = optflow::readOpticalFlow(gt_flow_path); |
||||
if(flow_gt.empty()) { |
||||
ts->printf(cvtest::TS::LOG, "error while reading flow data from file %s", |
||||
gt_flow_path.c_str()); |
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA); |
||||
return; |
||||
} |
||||
|
||||
Mat flow; |
||||
optflow::calcOpticalFlowSparseToDense(frame1, frame2, flow); |
||||
|
||||
float rmse = calc_rmse(flow_gt, flow); |
||||
|
||||
ts->printf(cvtest::TS::LOG, "Optical flow estimation RMSE for SparseToDenseFlow algorithm : %lf\n", |
||||
rmse); |
||||
|
||||
if (rmse > MAX_RMSE) { |
||||
ts->printf( cvtest::TS::LOG, |
||||
"Too big rmse error : %lf ( >= %lf )\n", rmse, MAX_RMSE); |
||||
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
|
||||
TEST(Video_OpticalFlowSparseToDenseFlow, accuracy) { CV_SparseToDenseFlowTest test; test.safe_run(); } |
Loading…
Reference in new issue