mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
moved part of video to contrib/{outflow, bgsegm}; moved matlab to contrib
This commit is contained in:
@@ -1,67 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// Copyright (C) 2014, Advanced Micro Devices, Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "../test_precomp.hpp"
|
||||
#include "opencv2/ts/ocl_test.hpp"
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
namespace cvtest {
|
||||
namespace ocl {
|
||||
|
||||
PARAM_TEST_CASE(UpdateMotionHistory, bool)
|
||||
{
|
||||
double timestamp, duration;
|
||||
bool use_roi;
|
||||
|
||||
TEST_DECLARE_INPUT_PARAMETER(silhouette);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(mhi);
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
use_roi = GET_PARAM(0);
|
||||
}
|
||||
|
||||
virtual void generateTestData()
|
||||
{
|
||||
Size roiSize = randomSize(1, MAX_VALUE);
|
||||
Border silhouetteBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(silhouette, silhouette_roi, roiSize, silhouetteBorder, CV_8UC1, -11, 11);
|
||||
|
||||
Border mhiBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(mhi, mhi_roi, roiSize, mhiBorder, CV_32FC1, 0, 1);
|
||||
|
||||
timestamp = randomDouble(0, 1);
|
||||
duration = randomDouble(0, 1);
|
||||
if (timestamp < duration)
|
||||
std::swap(timestamp, duration);
|
||||
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(silhouette);
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(mhi);
|
||||
}
|
||||
};
|
||||
|
||||
OCL_TEST_P(UpdateMotionHistory, Mat)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
OCL_OFF(cv::updateMotionHistory(silhouette_roi, mhi_roi, timestamp, duration));
|
||||
OCL_ON(cv::updateMotionHistory(usilhouette_roi, umhi_roi, timestamp, duration));
|
||||
|
||||
OCL_EXPECT_MATS_NEAR(mhi, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////// Instantiation /////////////////////////////////////////
|
||||
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Video, UpdateMotionHistory, Values(false, true));
|
||||
|
||||
} } // namespace cvtest::ocl
|
||||
|
||||
#endif // HAVE_OPENCL
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* BackgroundSubtractorGBH_test.cpp
|
||||
*
|
||||
* Created on: Jun 14, 2012
|
||||
* Author: andrewgodbehere
|
||||
*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
class CV_BackgroundSubtractorTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
CV_BackgroundSubtractorTest();
|
||||
protected:
|
||||
void run(int);
|
||||
};
|
||||
|
||||
CV_BackgroundSubtractorTest::CV_BackgroundSubtractorTest()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This test checks the following:
|
||||
* (i) BackgroundSubtractorGMG can operate with matrices of various types and sizes
|
||||
* (ii) Training mode returns empty fgmask
|
||||
* (iii) End of training mode, and anomalous frame yields every pixel detected as FG
|
||||
*/
|
||||
void CV_BackgroundSubtractorTest::run(int)
|
||||
{
|
||||
int code = cvtest::TS::OK;
|
||||
RNG& rng = ts->get_rng();
|
||||
int type = ((unsigned int)rng)%7; //!< pick a random type, 0 - 6, defined in types_c.h
|
||||
int channels = 1 + ((unsigned int)rng)%4; //!< random number of channels from 1 to 4.
|
||||
int channelsAndType = CV_MAKETYPE(type,channels);
|
||||
int width = 2 + ((unsigned int)rng)%98; //!< Mat will be 2 to 100 in width and height
|
||||
int height = 2 + ((unsigned int)rng)%98;
|
||||
|
||||
Ptr<BackgroundSubtractorGMG> fgbg = createBackgroundSubtractorGMG();
|
||||
Mat fgmask;
|
||||
|
||||
if (!fgbg)
|
||||
CV_Error(Error::StsError,"Failed to create Algorithm\n");
|
||||
|
||||
/**
|
||||
* Set a few parameters
|
||||
*/
|
||||
fgbg->setSmoothingRadius(7);
|
||||
fgbg->setDecisionThreshold(0.7);
|
||||
fgbg->setNumFrames(120);
|
||||
|
||||
/**
|
||||
* Generate bounds for the values in the matrix for each type
|
||||
*/
|
||||
double maxd = 0, mind = 0;
|
||||
|
||||
/**
|
||||
* Max value for simulated images picked randomly in upper half of type range
|
||||
* Min value for simulated images picked randomly in lower half of type range
|
||||
*/
|
||||
if (type == CV_8U)
|
||||
{
|
||||
uchar half = UCHAR_MAX/2;
|
||||
maxd = (unsigned char)rng.uniform(half+32, UCHAR_MAX);
|
||||
mind = (unsigned char)rng.uniform(0, half-32);
|
||||
}
|
||||
else if (type == CV_8S)
|
||||
{
|
||||
maxd = (char)rng.uniform(32, CHAR_MAX);
|
||||
mind = (char)rng.uniform(CHAR_MIN, -32);
|
||||
}
|
||||
else if (type == CV_16U)
|
||||
{
|
||||
ushort half = USHRT_MAX/2;
|
||||
maxd = (unsigned int)rng.uniform(half+32, USHRT_MAX);
|
||||
mind = (unsigned int)rng.uniform(0, half-32);
|
||||
}
|
||||
else if (type == CV_16S)
|
||||
{
|
||||
maxd = rng.uniform(32, SHRT_MAX);
|
||||
mind = rng.uniform(SHRT_MIN, -32);
|
||||
}
|
||||
else if (type == CV_32S)
|
||||
{
|
||||
maxd = rng.uniform(32, INT_MAX);
|
||||
mind = rng.uniform(INT_MIN, -32);
|
||||
}
|
||||
else if (type == CV_32F)
|
||||
{
|
||||
maxd = rng.uniform(32.0f, FLT_MAX);
|
||||
mind = rng.uniform(-FLT_MAX, -32.0f);
|
||||
}
|
||||
else if (type == CV_64F)
|
||||
{
|
||||
maxd = rng.uniform(32.0, DBL_MAX);
|
||||
mind = rng.uniform(-DBL_MAX, -32.0);
|
||||
}
|
||||
|
||||
fgbg->setMinVal(mind);
|
||||
fgbg->setMaxVal(maxd);
|
||||
|
||||
Mat simImage = Mat::zeros(height, width, channelsAndType);
|
||||
int numLearningFrames = 120;
|
||||
for (int i = 0; i < numLearningFrames; ++i)
|
||||
{
|
||||
/**
|
||||
* Genrate simulated "image" for any type. Values always confined to upper half of range.
|
||||
*/
|
||||
rng.fill(simImage, RNG::UNIFORM, (mind + maxd)*0.5, maxd);
|
||||
|
||||
/**
|
||||
* Feed simulated images into background subtractor
|
||||
*/
|
||||
fgbg->apply(simImage,fgmask);
|
||||
Mat fullbg = Mat::zeros(simImage.rows, simImage.cols, CV_8U);
|
||||
|
||||
//! fgmask should be entirely background during training
|
||||
code = cvtest::cmpEps2( ts, fgmask, fullbg, 0, false, "The training foreground mask" );
|
||||
if (code < 0)
|
||||
ts->set_failed_test_info( code );
|
||||
}
|
||||
//! generate last image, distinct from training images
|
||||
rng.fill(simImage, RNG::UNIFORM, mind, maxd);
|
||||
|
||||
fgbg->apply(simImage,fgmask);
|
||||
//! now fgmask should be entirely foreground
|
||||
Mat fullfg = 255*Mat::ones(simImage.rows, simImage.cols, CV_8U);
|
||||
code = cvtest::cmpEps2( ts, fgmask, fullfg, 255, false, "The final foreground mask" );
|
||||
if (code < 0)
|
||||
{
|
||||
ts->set_failed_test_info( code );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST(VIDEO_BGSUBGMG, accuracy) { CV_BackgroundSubtractorTest test; test.safe_run(); }
|
||||
@@ -1,500 +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"
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
///////////////////// base MHI class ///////////////////////
|
||||
class CV_MHIBaseTest : public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
CV_MHIBaseTest();
|
||||
|
||||
protected:
|
||||
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
|
||||
void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
|
||||
int prepare_test_case( int test_case_idx );
|
||||
double timestamp, duration, max_log_duration;
|
||||
int mhi_i, mhi_ref_i;
|
||||
double silh_ratio;
|
||||
};
|
||||
|
||||
|
||||
CV_MHIBaseTest::CV_MHIBaseTest()
|
||||
{
|
||||
timestamp = duration = 0;
|
||||
max_log_duration = 9;
|
||||
mhi_i = mhi_ref_i = -1;
|
||||
|
||||
silh_ratio = 0.25;
|
||||
}
|
||||
|
||||
|
||||
void CV_MHIBaseTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high )
|
||||
{
|
||||
cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high );
|
||||
if( i == INPUT && CV_MAT_DEPTH(type) == CV_8U )
|
||||
{
|
||||
low = Scalar::all(cvRound(-1./silh_ratio)+2.);
|
||||
high = Scalar::all(2);
|
||||
}
|
||||
else if( i == mhi_i || i == mhi_ref_i )
|
||||
{
|
||||
low = Scalar::all(-exp(max_log_duration));
|
||||
high = Scalar::all(0.);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CV_MHIBaseTest::get_test_array_types_and_sizes( int test_case_idx,
|
||||
vector<vector<Size> >& sizes, vector<vector<int> >& types )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
|
||||
|
||||
types[INPUT][0] = CV_8UC1;
|
||||
types[mhi_i][0] = types[mhi_ref_i][0] = CV_32FC1;
|
||||
duration = exp(cvtest::randReal(rng)*max_log_duration);
|
||||
timestamp = duration + cvtest::randReal(rng)*30.-10.;
|
||||
}
|
||||
|
||||
|
||||
int CV_MHIBaseTest::prepare_test_case( int test_case_idx )
|
||||
{
|
||||
int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
|
||||
if( code > 0 )
|
||||
{
|
||||
Mat& mat = test_mat[mhi_i][0];
|
||||
mat += Scalar::all(duration);
|
||||
cv::max(mat, 0, mat);
|
||||
if( mhi_i != mhi_ref_i )
|
||||
{
|
||||
Mat& mat0 = test_mat[mhi_ref_i][0];
|
||||
cvtest::copy( mat, mat0 );
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
///////////////////// update motion history ////////////////////////////
|
||||
|
||||
static void test_updateMHI( const Mat& silh, Mat& mhi, double timestamp, double duration )
|
||||
{
|
||||
int i, j;
|
||||
float delbound = (float)(timestamp - duration);
|
||||
for( i = 0; i < mhi.rows; i++ )
|
||||
{
|
||||
const uchar* silh_row = silh.ptr(i);
|
||||
float* mhi_row = mhi.ptr<float>(i);
|
||||
|
||||
for( j = 0; j < mhi.cols; j++ )
|
||||
{
|
||||
if( silh_row[j] )
|
||||
mhi_row[j] = (float)timestamp;
|
||||
else if( mhi_row[j] < delbound )
|
||||
mhi_row[j] = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CV_UpdateMHITest : public CV_MHIBaseTest
|
||||
{
|
||||
public:
|
||||
CV_UpdateMHITest();
|
||||
|
||||
protected:
|
||||
double get_success_error_level( int test_case_idx, int i, int j );
|
||||
void run_func();
|
||||
void prepare_to_validation( int );
|
||||
};
|
||||
|
||||
|
||||
CV_UpdateMHITest::CV_UpdateMHITest()
|
||||
{
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[INPUT_OUTPUT].push_back(NULL);
|
||||
test_array[REF_INPUT_OUTPUT].push_back(NULL);
|
||||
mhi_i = INPUT_OUTPUT; mhi_ref_i = REF_INPUT_OUTPUT;
|
||||
}
|
||||
|
||||
|
||||
double CV_UpdateMHITest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void CV_UpdateMHITest::run_func()
|
||||
{
|
||||
cv::updateMotionHistory( test_mat[INPUT][0], test_mat[INPUT_OUTPUT][0], timestamp, duration);
|
||||
}
|
||||
|
||||
|
||||
void CV_UpdateMHITest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
//CvMat m0 = test_mat[REF_INPUT_OUTPUT][0];
|
||||
test_updateMHI( test_mat[INPUT][0], test_mat[REF_INPUT_OUTPUT][0], timestamp, duration );
|
||||
}
|
||||
|
||||
|
||||
///////////////////// calc motion gradient ////////////////////////////
|
||||
|
||||
static void test_MHIGradient( const Mat& mhi, Mat& mask, Mat& orientation,
|
||||
double delta1, double delta2, int aperture_size )
|
||||
{
|
||||
Point anchor( aperture_size/2, aperture_size/2 );
|
||||
double limit = 1e-4*aperture_size*aperture_size;
|
||||
|
||||
Mat dx, dy, min_mhi, max_mhi;
|
||||
|
||||
Mat kernel = cvtest::calcSobelKernel2D( 1, 0, aperture_size );
|
||||
cvtest::filter2D( mhi, dx, CV_32F, kernel, anchor, 0, BORDER_REPLICATE );
|
||||
kernel = cvtest::calcSobelKernel2D( 0, 1, aperture_size );
|
||||
cvtest::filter2D( mhi, dy, CV_32F, kernel, anchor, 0, BORDER_REPLICATE );
|
||||
|
||||
kernel = Mat::ones(aperture_size, aperture_size, CV_8U);
|
||||
cvtest::erode(mhi, min_mhi, kernel, anchor, 0, BORDER_REPLICATE);
|
||||
cvtest::dilate(mhi, max_mhi, kernel, anchor, 0, BORDER_REPLICATE);
|
||||
|
||||
if( delta1 > delta2 )
|
||||
{
|
||||
std::swap( delta1, delta2 );
|
||||
}
|
||||
|
||||
for( int i = 0; i < mhi.rows; i++ )
|
||||
{
|
||||
uchar* mask_row = mask.ptr(i);
|
||||
float* orient_row = orientation.ptr<float>(i);
|
||||
const float* dx_row = dx.ptr<float>(i);
|
||||
const float* dy_row = dy.ptr<float>(i);
|
||||
const float* min_row = min_mhi.ptr<float>(i);
|
||||
const float* max_row = max_mhi.ptr<float>(i);
|
||||
|
||||
for( int j = 0; j < mhi.cols; j++ )
|
||||
{
|
||||
double delta = max_row[j] - min_row[j];
|
||||
double _dx = dx_row[j], _dy = dy_row[j];
|
||||
|
||||
if( delta1 <= delta && delta <= delta2 &&
|
||||
(fabs(_dx) > limit || fabs(_dy) > limit) )
|
||||
{
|
||||
mask_row[j] = 1;
|
||||
double angle = atan2( _dy, _dx ) * (180/CV_PI);
|
||||
if( angle < 0 )
|
||||
angle += 360.;
|
||||
orient_row[j] = (float)angle;
|
||||
}
|
||||
else
|
||||
{
|
||||
mask_row[j] = 0;
|
||||
orient_row[j] = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CV_MHIGradientTest : public CV_MHIBaseTest
|
||||
{
|
||||
public:
|
||||
CV_MHIGradientTest();
|
||||
|
||||
protected:
|
||||
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
|
||||
double get_success_error_level( int test_case_idx, int i, int j );
|
||||
void run_func();
|
||||
void prepare_to_validation( int );
|
||||
|
||||
double delta1, delta2, delta_range_log;
|
||||
int aperture_size;
|
||||
};
|
||||
|
||||
|
||||
CV_MHIGradientTest::CV_MHIGradientTest()
|
||||
{
|
||||
mhi_i = mhi_ref_i = INPUT;
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[OUTPUT].push_back(NULL);
|
||||
test_array[OUTPUT].push_back(NULL);
|
||||
test_array[REF_OUTPUT].push_back(NULL);
|
||||
test_array[REF_OUTPUT].push_back(NULL);
|
||||
delta1 = delta2 = 0;
|
||||
aperture_size = 0;
|
||||
delta_range_log = 4;
|
||||
}
|
||||
|
||||
|
||||
void CV_MHIGradientTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
CV_MHIBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
|
||||
|
||||
types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_8UC1;
|
||||
types[OUTPUT][1] = types[REF_OUTPUT][1] = CV_32FC1;
|
||||
delta1 = exp(cvtest::randReal(rng)*delta_range_log + 1.);
|
||||
delta2 = exp(cvtest::randReal(rng)*delta_range_log + 1.);
|
||||
aperture_size = (cvtest::randInt(rng)%3)*2+3;
|
||||
//duration = exp(cvtest::randReal(rng)*max_log_duration);
|
||||
//timestamp = duration + cvtest::randReal(rng)*30.-10.;
|
||||
}
|
||||
|
||||
|
||||
double CV_MHIGradientTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int j )
|
||||
{
|
||||
return j == 0 ? 0 : 2e-1;
|
||||
}
|
||||
|
||||
|
||||
void CV_MHIGradientTest::run_func()
|
||||
{
|
||||
cv::calcMotionGradient(test_mat[INPUT][0], test_mat[OUTPUT][0],
|
||||
test_mat[OUTPUT][1], delta1, delta2, aperture_size );
|
||||
//cvCalcMotionGradient( test_array[INPUT][0], test_array[OUTPUT][0],
|
||||
// test_array[OUTPUT][1], delta1, delta2, aperture_size );
|
||||
}
|
||||
|
||||
|
||||
void CV_MHIGradientTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
test_MHIGradient( test_mat[INPUT][0], test_mat[REF_OUTPUT][0],
|
||||
test_mat[REF_OUTPUT][1], delta1, delta2, aperture_size );
|
||||
test_mat[REF_OUTPUT][0] += Scalar::all(1);
|
||||
test_mat[OUTPUT][0] += Scalar::all(1);
|
||||
}
|
||||
|
||||
|
||||
////////////////////// calc global orientation /////////////////////////
|
||||
|
||||
static double test_calcGlobalOrientation( const Mat& orient, const Mat& mask,
|
||||
const Mat& mhi, double timestamp, double duration )
|
||||
{
|
||||
const int HIST_SIZE = 12;
|
||||
int y, x;
|
||||
int histogram[HIST_SIZE];
|
||||
int max_bin = 0;
|
||||
|
||||
double base_orientation = 0, delta_orientation = 0, weight = 0;
|
||||
double low_time, global_orientation;
|
||||
|
||||
memset( histogram, 0, sizeof( histogram ));
|
||||
timestamp = 0;
|
||||
|
||||
for( y = 0; y < orient.rows; y++ )
|
||||
{
|
||||
const float* orient_data = orient.ptr<float>(y);
|
||||
const uchar* mask_data = mask.ptr(y);
|
||||
const float* mhi_data = mhi.ptr<float>(y);
|
||||
for( x = 0; x < orient.cols; x++ )
|
||||
if( mask_data[x] )
|
||||
{
|
||||
int bin = cvFloor( (orient_data[x]*HIST_SIZE)/360 );
|
||||
histogram[bin < 0 ? 0 : bin >= HIST_SIZE ? HIST_SIZE-1 : bin]++;
|
||||
if( mhi_data[x] > timestamp )
|
||||
timestamp = mhi_data[x];
|
||||
}
|
||||
}
|
||||
|
||||
low_time = timestamp - duration;
|
||||
|
||||
for( x = 1; x < HIST_SIZE; x++ )
|
||||
{
|
||||
if( histogram[x] > histogram[max_bin] )
|
||||
max_bin = x;
|
||||
}
|
||||
|
||||
base_orientation = ((double)max_bin*360)/HIST_SIZE;
|
||||
|
||||
for( y = 0; y < orient.rows; y++ )
|
||||
{
|
||||
const float* orient_data = orient.ptr<float>(y);
|
||||
const float* mhi_data = mhi.ptr<float>(y);
|
||||
const uchar* mask_data = mask.ptr(y);
|
||||
|
||||
for( x = 0; x < orient.cols; x++ )
|
||||
{
|
||||
if( mask_data[x] && mhi_data[x] > low_time )
|
||||
{
|
||||
double diff = orient_data[x] - base_orientation;
|
||||
double delta_weight = (((mhi_data[x] - low_time)/duration)*254 + 1)/255;
|
||||
|
||||
if( diff < -180 ) diff += 360;
|
||||
if( diff > 180 ) diff -= 360;
|
||||
|
||||
if( delta_weight > 0 && fabs(diff) < 45 )
|
||||
{
|
||||
delta_orientation += diff*delta_weight;
|
||||
weight += delta_weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( weight == 0 )
|
||||
global_orientation = base_orientation;
|
||||
else
|
||||
{
|
||||
global_orientation = base_orientation + delta_orientation/weight;
|
||||
if( global_orientation < 0 ) global_orientation += 360;
|
||||
if( global_orientation > 360 ) global_orientation -= 360;
|
||||
}
|
||||
|
||||
return global_orientation;
|
||||
}
|
||||
|
||||
|
||||
class CV_MHIGlobalOrientTest : public CV_MHIBaseTest
|
||||
{
|
||||
public:
|
||||
CV_MHIGlobalOrientTest();
|
||||
|
||||
protected:
|
||||
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
|
||||
void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
|
||||
double get_success_error_level( int test_case_idx, int i, int j );
|
||||
int validate_test_results( int test_case_idx );
|
||||
void run_func();
|
||||
double angle, min_angle, max_angle;
|
||||
};
|
||||
|
||||
|
||||
CV_MHIGlobalOrientTest::CV_MHIGlobalOrientTest()
|
||||
{
|
||||
mhi_i = mhi_ref_i = INPUT;
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[INPUT].push_back(NULL);
|
||||
min_angle = max_angle = 0;
|
||||
}
|
||||
|
||||
|
||||
void CV_MHIGlobalOrientTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
CV_MHIBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
|
||||
Size size = sizes[INPUT][0];
|
||||
|
||||
size.width = MAX( size.width, 16 );
|
||||
size.height = MAX( size.height, 16 );
|
||||
sizes[INPUT][0] = sizes[INPUT][1] = sizes[INPUT][2] = size;
|
||||
|
||||
types[INPUT][1] = CV_8UC1; // mask
|
||||
types[INPUT][2] = CV_32FC1; // orientation
|
||||
|
||||
min_angle = cvtest::randReal(rng)*359.9;
|
||||
max_angle = cvtest::randReal(rng)*359.9;
|
||||
if( min_angle >= max_angle )
|
||||
{
|
||||
std::swap( min_angle, max_angle);
|
||||
}
|
||||
max_angle += 0.1;
|
||||
duration = exp(cvtest::randReal(rng)*max_log_duration);
|
||||
timestamp = duration + cvtest::randReal(rng)*30.-10.;
|
||||
}
|
||||
|
||||
|
||||
void CV_MHIGlobalOrientTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high )
|
||||
{
|
||||
CV_MHIBaseTest::get_minmax_bounds( i, j, type, low, high );
|
||||
if( i == INPUT && j == 2 )
|
||||
{
|
||||
low = Scalar::all(min_angle);
|
||||
high = Scalar::all(max_angle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double CV_MHIGlobalOrientTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
|
||||
{
|
||||
return 15;
|
||||
}
|
||||
|
||||
|
||||
void CV_MHIGlobalOrientTest::run_func()
|
||||
{
|
||||
//angle = cvCalcGlobalOrientation( test_array[INPUT][2], test_array[INPUT][1],
|
||||
// test_array[INPUT][0], timestamp, duration );
|
||||
angle = cv::calcGlobalOrientation(test_mat[INPUT][2], test_mat[INPUT][1],
|
||||
test_mat[INPUT][0], timestamp, duration );
|
||||
}
|
||||
|
||||
|
||||
int CV_MHIGlobalOrientTest::validate_test_results( int test_case_idx )
|
||||
{
|
||||
//printf("%d. rows=%d, cols=%d, nzmask=%d\n", test_case_idx, test_mat[INPUT][1].rows, test_mat[INPUT][1].cols,
|
||||
// cvCountNonZero(test_array[INPUT][1]));
|
||||
|
||||
double ref_angle = test_calcGlobalOrientation( test_mat[INPUT][2], test_mat[INPUT][1],
|
||||
test_mat[INPUT][0], timestamp, duration );
|
||||
double err_level = get_success_error_level( test_case_idx, 0, 0 );
|
||||
int code = cvtest::TS::OK;
|
||||
int nz = countNonZero( test_mat[INPUT][1] );
|
||||
|
||||
if( nz > 32 && !(min_angle - err_level <= angle &&
|
||||
max_angle + err_level >= angle) &&
|
||||
!(min_angle - err_level <= angle+360 &&
|
||||
max_angle + err_level >= angle+360) )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "The angle=%g is outside (%g,%g) range\n",
|
||||
angle, min_angle - err_level, max_angle + err_level );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
}
|
||||
else if( fabs(angle - ref_angle) > err_level &&
|
||||
fabs(360 - fabs(angle - ref_angle)) > err_level )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "The angle=%g differs too much from reference value=%g\n",
|
||||
angle, ref_angle );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
}
|
||||
|
||||
if( code < 0 )
|
||||
ts->set_failed_test_info( code );
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
TEST(Video_MHIUpdate, accuracy) { CV_UpdateMHITest test; test.safe_run(); }
|
||||
TEST(Video_MHIGradient, accuracy) { CV_MHIGradientTest test; test.safe_run(); }
|
||||
TEST(Video_MHIGlobalOrient, accuracy) { CV_MHIGlobalOrientTest test; test.safe_run(); }
|
||||
@@ -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::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. */
|
||||
Reference in New Issue
Block a user