1838 lines
		
	
	
		
			49 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1838 lines
		
	
	
		
			49 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*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;
 | |
| 
 | |
| class CV_BaseHistTest : public cvtest::BaseTest
 | |
| {
 | |
| public:
 | |
|     enum { MAX_HIST = 12 };
 | |
| 
 | |
|     CV_BaseHistTest();
 | |
|     ~CV_BaseHistTest();
 | |
|     void clear();
 | |
| 
 | |
| protected:
 | |
|     int read_params( CvFileStorage* fs );
 | |
|     void run_func(void);
 | |
|     int prepare_test_case( int test_case_idx );
 | |
|     int validate_test_results( int test_case_idx );
 | |
|     virtual void init_hist( int test_case_idx, int i );
 | |
| 
 | |
|     virtual void get_hist_params( int test_case_idx );
 | |
|     virtual float** get_hist_ranges( int test_case_idx );
 | |
| 
 | |
|     int max_log_size;
 | |
|     int max_cdims;
 | |
|     int cdims;
 | |
|     int dims[CV_MAX_DIM];
 | |
|     int total_size;
 | |
|     int hist_type;
 | |
|     int hist_count;
 | |
|     int uniform;
 | |
|     int gen_random_hist;
 | |
|     double gen_hist_max_val, gen_hist_sparse_nz_ratio;
 | |
| 
 | |
|     int init_ranges;
 | |
|     int img_type;
 | |
|     int img_max_log_size;
 | |
|     double low, high, range_delta;
 | |
|     CvSize img_size;
 | |
| 
 | |
|     vector<CvHistogram*> hist;
 | |
|     vector<float> _ranges;
 | |
|     vector<float*> ranges;
 | |
|     bool test_cpp;
 | |
| };
 | |
| 
 | |
| 
 | |
| CV_BaseHistTest::CV_BaseHistTest()
 | |
| {
 | |
|     test_case_count = 100;
 | |
|     max_log_size = 20;
 | |
|     img_max_log_size = 8;
 | |
|     max_cdims = 6;
 | |
|     hist_count = 1;
 | |
|     init_ranges = 0;
 | |
|     gen_random_hist = 0;
 | |
|     gen_hist_max_val = 100;
 | |
| 
 | |
|     test_cpp = false;
 | |
| }
 | |
| 
 | |
| 
 | |
| CV_BaseHistTest::~CV_BaseHistTest()
 | |
| {
 | |
|     clear();
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_BaseHistTest::clear()
 | |
| {
 | |
|     cvtest::BaseTest::clear();
 | |
|     for( size_t i = 0; i < hist.size(); i++ )
 | |
|         cvReleaseHist( &hist[i] );
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_BaseHistTest::read_params( CvFileStorage* fs )
 | |
| {
 | |
|     int code = cvtest::BaseTest::read_params( fs );
 | |
|     if( code < 0 )
 | |
|         return code;
 | |
| 
 | |
|     test_case_count = cvReadInt( find_param( fs, "struct_count" ), test_case_count );
 | |
|     max_log_size = cvReadInt( find_param( fs, "max_log_size" ), max_log_size );
 | |
|     max_log_size = cvtest::clipInt( max_log_size, 1, 20 );
 | |
|     img_max_log_size = cvReadInt( find_param( fs, "max_log_array_size" ), img_max_log_size );
 | |
|     img_max_log_size = cvtest::clipInt( img_max_log_size, 1, 9 );
 | |
| 
 | |
|     max_cdims = cvReadInt( find_param( fs, "max_cdims" ), max_cdims );
 | |
|     max_cdims = cvtest::clipInt( max_cdims, 1, 6 );
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_BaseHistTest::get_hist_params( int /*test_case_idx*/ )
 | |
| {
 | |
|     RNG& rng = ts->get_rng();
 | |
|     int i, max_dim_size, max_ni_dim_size = 31;
 | |
|     double hist_size;
 | |
| 
 | |
|     cdims = cvtest::randInt(rng) % max_cdims + 1;
 | |
|     hist_size = exp(cvtest::randReal(rng)*max_log_size*CV_LOG2);
 | |
|     max_dim_size = cvRound(pow(hist_size,1./cdims));
 | |
|     total_size = 1;
 | |
|     uniform = cvtest::randInt(rng) % 2;
 | |
|     hist_type = cvtest::randInt(rng) % 2 ? CV_HIST_SPARSE : CV_HIST_ARRAY;
 | |
| 
 | |
|     for( i = 0; i < cdims; i++ )
 | |
|     {
 | |
|         dims[i] = cvtest::randInt(rng) % (max_dim_size + 2) + 2;
 | |
|         if( !uniform )
 | |
|             dims[i] = MIN(dims[i], max_ni_dim_size);
 | |
|         total_size *= dims[i];
 | |
|     }
 | |
| 
 | |
|     img_type = cvtest::randInt(rng) % 2 ? CV_32F : CV_8U;
 | |
|     img_size.width = cvRound( exp(cvtest::randReal(rng) * img_max_log_size * CV_LOG2) );
 | |
|     img_size.height = cvRound( exp(cvtest::randReal(rng) * img_max_log_size * CV_LOG2) );
 | |
| 
 | |
|     if( img_type < CV_32F )
 | |
|     {
 | |
|         low = cvtest::getMinVal(img_type);
 | |
|         high = cvtest::getMaxVal(img_type);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         high = 1000;
 | |
|         low = -high;
 | |
|     }
 | |
| 
 | |
|     range_delta = (cvtest::randInt(rng) % 2)*(high-low)*0.05;
 | |
| }
 | |
| 
 | |
| 
 | |
| float** CV_BaseHistTest::get_hist_ranges( int /*test_case_idx*/ )
 | |
| {
 | |
|     double _low = low + range_delta, _high = high - range_delta;
 | |
| 
 | |
|     if( !init_ranges )
 | |
|         return 0;
 | |
| 
 | |
|     ranges.resize(cdims);
 | |
| 
 | |
|     if( uniform )
 | |
|     {
 | |
|         _ranges.resize(cdims*2);
 | |
|         for( int i = 0; i < cdims; i++ )
 | |
|         {
 | |
|             _ranges[i*2] = (float)_low;
 | |
|             _ranges[i*2+1] = (float)_high;
 | |
|             ranges[i] = &_ranges[i*2];
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         int i, dims_sum = 0, ofs = 0;
 | |
|         for( i = 0; i < cdims; i++ )
 | |
|             dims_sum += dims[i] + 1;
 | |
|         _ranges.resize(dims_sum);
 | |
| 
 | |
|         for( i = 0; i < cdims; i++ )
 | |
|         {
 | |
|             int j, n = dims[i];
 | |
|             // generate logarithmic scale
 | |
|             double delta, q, val;
 | |
|             for( j = 0; j < 10; j++ )
 | |
|             {
 | |
|                 q = 1. + (j+1)*0.1;
 | |
|                 if( (pow(q,(double)n)-1)/(q-1.) >= _high-_low )
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             if( j == 0 )
 | |
|             {
 | |
|                 delta = (_high-_low)/n;
 | |
|                 q = 1.;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 q = 1 + j*0.1;
 | |
|                 delta = cvFloor((_high-_low)*(q-1)/(pow(q,(double)n) - 1));
 | |
|                 delta = MAX(delta, 1.);
 | |
|             }
 | |
|             val = _low;
 | |
| 
 | |
|             for( j = 0; j <= n; j++ )
 | |
|             {
 | |
|                 _ranges[j+ofs] = (float)MIN(val,_high);
 | |
|                 val += delta;
 | |
|                 delta *= q;
 | |
|             }
 | |
|             ranges[i] = &_ranges[ofs];
 | |
|             ofs += n + 1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return &ranges[0];
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_BaseHistTest::init_hist( int /*test_case_idx*/, int hist_i )
 | |
| {
 | |
|     if( gen_random_hist )
 | |
|     {
 | |
|         RNG& rng = ts->get_rng();
 | |
| 
 | |
|         if( hist_type == CV_HIST_ARRAY )
 | |
|         {
 | |
|             Mat h = cvarrToMat(hist[hist_i]->bins);
 | |
|             cvtest::randUni(rng, h, Scalar::all(0), Scalar::all(gen_hist_max_val) );
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             CvArr* arr = hist[hist_i]->bins;
 | |
|             int i, j, totalSize = 1, nz_count;
 | |
|             int idx[CV_MAX_DIM];
 | |
|             for( i = 0; i < cdims; i++ )
 | |
|                 totalSize *= dims[i];
 | |
| 
 | |
|             nz_count = cvtest::randInt(rng) % MAX( totalSize/4, 100 );
 | |
|             nz_count = MIN( nz_count, totalSize );
 | |
| 
 | |
|             // a zero number of non-zero elements should be allowed
 | |
|             for( i = 0; i < nz_count; i++ )
 | |
|             {
 | |
|                 for( j = 0; j < cdims; j++ )
 | |
|                     idx[j] = cvtest::randInt(rng) % dims[j];
 | |
|                 cvSetRealND(arr, idx, cvtest::randReal(rng)*gen_hist_max_val);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_BaseHistTest::prepare_test_case( int test_case_idx )
 | |
| {
 | |
|     int i;
 | |
|     float** r;
 | |
| 
 | |
|     clear();
 | |
| 
 | |
|     cvtest::BaseTest::prepare_test_case( test_case_idx );
 | |
|     get_hist_params( test_case_idx );
 | |
|     r = get_hist_ranges( test_case_idx );
 | |
|     hist.resize(hist_count);
 | |
| 
 | |
|     for( i = 0; i < hist_count; i++ )
 | |
|     {
 | |
|         hist[i] = cvCreateHist( cdims, dims, hist_type, r, uniform );
 | |
|         init_hist( test_case_idx, i );
 | |
|     }
 | |
|     test_cpp = (cvtest::randInt(ts->get_rng()) % 2) != 0;
 | |
| 
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_BaseHistTest::run_func(void)
 | |
| {
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_BaseHistTest::validate_test_results( int /*test_case_idx*/ )
 | |
| {
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| ////////////// testing operation for reading/writing individual histogram bins //////////////
 | |
| 
 | |
| class CV_QueryHistTest : public CV_BaseHistTest
 | |
| {
 | |
| public:
 | |
|     CV_QueryHistTest();
 | |
|     ~CV_QueryHistTest();
 | |
|     void clear();
 | |
| 
 | |
| protected:
 | |
|     void run_func(void);
 | |
|     int prepare_test_case( int test_case_idx );
 | |
|     int validate_test_results( int test_case_idx );
 | |
|     void init_hist( int test_case_idx, int i );
 | |
| 
 | |
|     CvMat* indices;
 | |
|     CvMat* values;
 | |
|     CvMat* values0;
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| CV_QueryHistTest::CV_QueryHistTest()
 | |
| {
 | |
|     hist_count = 1;
 | |
|     indices = 0;
 | |
|     values = 0;
 | |
|     values0 = 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| CV_QueryHistTest::~CV_QueryHistTest()
 | |
| {
 | |
|     clear();
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_QueryHistTest::clear()
 | |
| {
 | |
|     cvReleaseMat( &indices );
 | |
|     cvReleaseMat( &values );
 | |
|     cvReleaseMat( &values0 );
 | |
|     CV_BaseHistTest::clear();
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_QueryHistTest::init_hist( int /*test_case_idx*/, int i )
 | |
| {
 | |
|     if( hist_type == CV_HIST_ARRAY )
 | |
|         cvZero( hist[i]->bins );
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_QueryHistTest::prepare_test_case( int test_case_idx )
 | |
| {
 | |
|     int code = CV_BaseHistTest::prepare_test_case( test_case_idx );
 | |
| 
 | |
|     if( code > 0 )
 | |
|     {
 | |
|         int i, j, iters;
 | |
|         float default_value = 0.f;
 | |
|         RNG& rng = ts->get_rng();
 | |
|         CvMat* bit_mask = 0;
 | |
|         int* idx;
 | |
| 
 | |
|         iters = (cvtest::randInt(rng) % MAX(total_size/10,100)) + 1;
 | |
|         iters = MIN( iters, total_size*9/10 + 1 );
 | |
| 
 | |
|         indices = cvCreateMat( 1, iters*cdims, CV_32S );
 | |
|         values = cvCreateMat( 1, iters, CV_32F );
 | |
|         values0 = cvCreateMat( 1, iters, CV_32F );
 | |
|         idx = indices->data.i;
 | |
| 
 | |
|         //printf( "total_size = %d, cdims = %d, iters = %d\n", total_size, cdims, iters );
 | |
| 
 | |
|         bit_mask = cvCreateMat( 1, (total_size + 7)/8, CV_8U );
 | |
|         cvZero( bit_mask );
 | |
| 
 | |
|         #define GET_BIT(n) (bit_mask->data.ptr[(n)/8] & (1 << ((n)&7)))
 | |
|         #define SET_BIT(n) bit_mask->data.ptr[(n)/8] |= (1 << ((n)&7))
 | |
| 
 | |
|         // set random histogram bins' values to the linear indices of the bins
 | |
|         for( i = 0; i < iters; i++ )
 | |
|         {
 | |
|             int lin_idx = 0;
 | |
|             for( j = 0; j < cdims; j++ )
 | |
|             {
 | |
|                 int t = cvtest::randInt(rng) % dims[j];
 | |
|                 idx[i*cdims + j] = t;
 | |
|                 lin_idx = lin_idx*dims[j] + t;
 | |
|             }
 | |
| 
 | |
|             if( cvtest::randInt(rng) % 8 || GET_BIT(lin_idx) )
 | |
|             {
 | |
|                 values0->data.fl[i] = (float)(lin_idx+1);
 | |
|                 SET_BIT(lin_idx);
 | |
|             }
 | |
|             else
 | |
|                 // some histogram bins will not be initialized intentionally,
 | |
|                 // they should be equal to the default value
 | |
|                 values0->data.fl[i] = default_value;
 | |
|         }
 | |
| 
 | |
|         // do the second pass to make values0 consistent with bit_mask
 | |
|         for( i = 0; i < iters; i++ )
 | |
|         {
 | |
|             int lin_idx = 0;
 | |
|             for( j = 0; j < cdims; j++ )
 | |
|                 lin_idx = lin_idx*dims[j] + idx[i*cdims + j];
 | |
| 
 | |
|             if( GET_BIT(lin_idx) )
 | |
|                 values0->data.fl[i] = (float)(lin_idx+1);
 | |
|         }
 | |
| 
 | |
|         cvReleaseMat( &bit_mask );
 | |
|     }
 | |
| 
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_QueryHistTest::run_func(void)
 | |
| {
 | |
|     int i, iters = values->cols;
 | |
|     CvArr* h = hist[0]->bins;
 | |
|     const int* idx = indices->data.i;
 | |
|     float* val = values->data.fl;
 | |
|     float default_value = 0.f;
 | |
| 
 | |
|     // stage 1: write bins
 | |
|     if( cdims == 1 )
 | |
|         for( i = 0; i < iters; i++ )
 | |
|         {
 | |
|             float v0 = values0->data.fl[i];
 | |
|             if( fabs(v0 - default_value) < FLT_EPSILON )
 | |
|                 continue;
 | |
|             if( !(i % 2) )
 | |
|             {
 | |
|                 if( !(i % 4) )
 | |
|                     cvSetReal1D( h, idx[i], v0 );
 | |
|                 else
 | |
|                     *(float*)cvPtr1D( h, idx[i] ) = v0;
 | |
|             }
 | |
|             else
 | |
|                 cvSetRealND( h, idx+i, v0 );
 | |
|         }
 | |
|     else if( cdims == 2 )
 | |
|         for( i = 0; i < iters; i++ )
 | |
|         {
 | |
|             float v0 = values0->data.fl[i];
 | |
|             if( fabs(v0 - default_value) < FLT_EPSILON )
 | |
|                 continue;
 | |
|             if( !(i % 2) )
 | |
|             {
 | |
|                 if( !(i % 4) )
 | |
|                     cvSetReal2D( h, idx[i*2], idx[i*2+1], v0 );
 | |
|                 else
 | |
|                     *(float*)cvPtr2D( h, idx[i*2], idx[i*2+1] ) = v0;
 | |
|             }
 | |
|             else
 | |
|                 cvSetRealND( h, idx+i*2, v0 );
 | |
|         }
 | |
|     else if( cdims == 3 )
 | |
|         for( i = 0; i < iters; i++ )
 | |
|         {
 | |
|             float v0 = values0->data.fl[i];
 | |
|             if( fabs(v0 - default_value) < FLT_EPSILON )
 | |
|                 continue;
 | |
|             if( !(i % 2) )
 | |
|             {
 | |
|                 if( !(i % 4) )
 | |
|                     cvSetReal3D( h, idx[i*3], idx[i*3+1], idx[i*3+2], v0 );
 | |
|                 else
 | |
|                     *(float*)cvPtr3D( h, idx[i*3], idx[i*3+1], idx[i*3+2] ) = v0;
 | |
|             }
 | |
|             else
 | |
|                 cvSetRealND( h, idx+i*3, v0 );
 | |
|         }
 | |
|     else
 | |
|         for( i = 0; i < iters; i++ )
 | |
|         {
 | |
|             float v0 = values0->data.fl[i];
 | |
|             if( fabs(v0 - default_value) < FLT_EPSILON )
 | |
|                 continue;
 | |
|             if( !(i % 2) )
 | |
|                 cvSetRealND( h, idx+i*cdims, v0 );
 | |
|             else
 | |
|                 *(float*)cvPtrND( h, idx+i*cdims ) = v0;
 | |
|         }
 | |
| 
 | |
|     // stage 2: read bins
 | |
|     if( cdims == 1 )
 | |
|         for( i = 0; i < iters; i++ )
 | |
|         {
 | |
|             if( !(i % 2) )
 | |
|                 val[i] = *(float*)cvPtr1D( h, idx[i] );
 | |
|             else
 | |
|                 val[i] = (float)cvGetReal1D( h, idx[i] );
 | |
|         }
 | |
|     else if( cdims == 2 )
 | |
|         for( i = 0; i < iters; i++ )
 | |
|         {
 | |
|             if( !(i % 2) )
 | |
|                 val[i] = *(float*)cvPtr2D( h, idx[i*2], idx[i*2+1] );
 | |
|             else
 | |
|                 val[i] = (float)cvGetReal2D( h, idx[i*2], idx[i*2+1] );
 | |
|         }
 | |
|     else if( cdims == 3 )
 | |
|         for( i = 0; i < iters; i++ )
 | |
|         {
 | |
|             if( !(i % 2) )
 | |
|                 val[i] = *(float*)cvPtr3D( h, idx[i*3], idx[i*3+1], idx[i*3+2] );
 | |
|             else
 | |
|                 val[i] = (float)cvGetReal3D( h, idx[i*3], idx[i*3+1], idx[i*3+2] );
 | |
|         }
 | |
|     else
 | |
|         for( i = 0; i < iters; i++ )
 | |
|         {
 | |
|             if( !(i % 2) )
 | |
|                 val[i] = *(float*)cvPtrND( h, idx+i*cdims );
 | |
|             else
 | |
|                 val[i] = (float)cvGetRealND( h, idx+i*cdims );
 | |
|         }
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_QueryHistTest::validate_test_results( int /*test_case_idx*/ )
 | |
| {
 | |
|     int code = cvtest::TS::OK;
 | |
|     int i, j, iters = values->cols;
 | |
| 
 | |
|     for( i = 0; i < iters; i++ )
 | |
|     {
 | |
|         float v = values->data.fl[i], v0 = values0->data.fl[i];
 | |
| 
 | |
|         if( cvIsNaN(v) || cvIsInf(v) )
 | |
|         {
 | |
|             ts->printf( cvtest::TS::LOG, "The bin #%d has invalid value\n", i );
 | |
|             code = cvtest::TS::FAIL_INVALID_OUTPUT;
 | |
|         }
 | |
|         else if( fabs(v - v0) > FLT_EPSILON )
 | |
|         {
 | |
|             ts->printf( cvtest::TS::LOG, "The bin #%d = %g, while it should be %g\n", i, v, v0 );
 | |
|             code = cvtest::TS::FAIL_BAD_ACCURACY;
 | |
|         }
 | |
| 
 | |
|         if( code < 0 )
 | |
|         {
 | |
|             ts->printf( cvtest::TS::LOG, "The bin index = (" );
 | |
|             for( j = 0; j < cdims; j++ )
 | |
|                 ts->printf( cvtest::TS::LOG, "%d%s", indices->data.i[i*cdims + j],
 | |
|                                         j < cdims-1 ? ", " : ")\n" );
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if( code < 0 )
 | |
|         ts->set_failed_test_info( code );
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| ////////////// cvGetMinMaxHistValue //////////////
 | |
| 
 | |
| class CV_MinMaxHistTest : public CV_BaseHistTest
 | |
| {
 | |
| public:
 | |
|     CV_MinMaxHistTest();
 | |
| 
 | |
| protected:
 | |
|     void run_func(void);
 | |
|     void init_hist(int, int);
 | |
|     int validate_test_results( int test_case_idx );
 | |
|     int min_idx[CV_MAX_DIM], max_idx[CV_MAX_DIM];
 | |
|     float min_val, max_val;
 | |
|     int min_idx0[CV_MAX_DIM], max_idx0[CV_MAX_DIM];
 | |
|     float min_val0, max_val0;
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| CV_MinMaxHistTest::CV_MinMaxHistTest()
 | |
| {
 | |
|     hist_count = 1;
 | |
|     gen_random_hist = 1;
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_MinMaxHistTest::init_hist(int test_case_idx, int hist_i)
 | |
| {
 | |
|     int i, eq = 1;
 | |
|     RNG& rng = ts->get_rng();
 | |
|     CV_BaseHistTest::init_hist( test_case_idx, hist_i );
 | |
| 
 | |
|     for(;;)
 | |
|     {
 | |
|         for( i = 0; i < cdims; i++ )
 | |
|         {
 | |
|             min_idx0[i] = cvtest::randInt(rng) % dims[i];
 | |
|             max_idx0[i] = cvtest::randInt(rng) % dims[i];
 | |
|             eq &= min_idx0[i] == max_idx0[i];
 | |
|         }
 | |
|         if( !eq || total_size == 1 )
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     min_val0 = (float)(-cvtest::randReal(rng)*10 - FLT_EPSILON);
 | |
|     max_val0 = (float)(cvtest::randReal(rng)*10 + FLT_EPSILON + gen_hist_max_val);
 | |
| 
 | |
|     if( total_size == 1 )
 | |
|         min_val0 = max_val0;
 | |
| 
 | |
|     cvSetRealND( hist[0]->bins, min_idx0, min_val0 );
 | |
|     cvSetRealND( hist[0]->bins, max_idx0, max_val0 );
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_MinMaxHistTest::run_func(void)
 | |
| {
 | |
|     if( hist_type != CV_HIST_ARRAY && test_cpp )
 | |
|     {
 | |
|         cv::SparseMat h((CvSparseMat*)hist[0]->bins);
 | |
|         double _min_val = 0, _max_val = 0;
 | |
|         cv::minMaxLoc(h, &_min_val, &_max_val, min_idx, max_idx );
 | |
|         min_val = (float)_min_val;
 | |
|         max_val = (float)_max_val;
 | |
|     }
 | |
|     else
 | |
|         cvGetMinMaxHistValue( hist[0], &min_val, &max_val, min_idx, max_idx );
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_MinMaxHistTest::validate_test_results( int /*test_case_idx*/ )
 | |
| {
 | |
|     int code = cvtest::TS::OK;
 | |
| 
 | |
|     if( cvIsNaN(min_val) || cvIsInf(min_val) ||
 | |
|         cvIsNaN(max_val) || cvIsInf(max_val) )
 | |
|     {
 | |
|         ts->printf( cvtest::TS::LOG,
 | |
|             "The extrema histogram bin values are invalid (min = %g, max = %g)\n", min_val, max_val );
 | |
|         code = cvtest::TS::FAIL_INVALID_OUTPUT;
 | |
|     }
 | |
|     else if( fabs(min_val - min_val0) > FLT_EPSILON ||
 | |
|              fabs(max_val - max_val0) > FLT_EPSILON )
 | |
|     {
 | |
|         ts->printf( cvtest::TS::LOG,
 | |
|             "The extrema histogram bin values are incorrect: (min = %g, should be = %g), (max = %g, should be = %g)\n",
 | |
|             min_val, min_val0, max_val, max_val0 );
 | |
|         code = cvtest::TS::FAIL_BAD_ACCURACY;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         int i;
 | |
|         for( i = 0; i < cdims; i++ )
 | |
|         {
 | |
|             if( min_idx[i] != min_idx0[i] || max_idx[i] != max_idx0[i] )
 | |
|             {
 | |
|                 ts->printf( cvtest::TS::LOG,
 | |
|                     "The %d-th coordinates of extrema histogram bin values are incorrect: "
 | |
|                     "(min = %d, should be = %d), (max = %d, should be = %d)\n",
 | |
|                     i, min_idx[i], min_idx0[i], max_idx[i], max_idx0[i] );
 | |
|                 code = cvtest::TS::FAIL_BAD_ACCURACY;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if( code < 0 )
 | |
|         ts->set_failed_test_info( code );
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| ////////////// cvNormalizeHist //////////////
 | |
| 
 | |
| class CV_NormHistTest : public CV_BaseHistTest
 | |
| {
 | |
| public:
 | |
|     CV_NormHistTest();
 | |
| 
 | |
| protected:
 | |
|     int prepare_test_case( int test_case_idx );
 | |
|     void run_func(void);
 | |
|     int validate_test_results( int test_case_idx );
 | |
|     double factor;
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| CV_NormHistTest::CV_NormHistTest()
 | |
| {
 | |
|     hist_count = 1;
 | |
|     gen_random_hist = 1;
 | |
|     factor = 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_NormHistTest::prepare_test_case( int test_case_idx )
 | |
| {
 | |
|     int code = CV_BaseHistTest::prepare_test_case( test_case_idx );
 | |
| 
 | |
|     if( code > 0 )
 | |
|     {
 | |
|         RNG& rng = ts->get_rng();
 | |
|         factor = cvtest::randReal(rng)*10 + 0.1;
 | |
|         if( hist_type == CV_HIST_SPARSE &&
 | |
|             ((CvSparseMat*)hist[0]->bins)->heap->active_count == 0 )
 | |
|             factor = 0;
 | |
|     }
 | |
| 
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_NormHistTest::run_func(void)
 | |
| {
 | |
|     if( hist_type != CV_HIST_ARRAY && test_cpp )
 | |
|     {
 | |
|         cv::SparseMat h((CvSparseMat*)hist[0]->bins);
 | |
|         cv::normalize(h, h, factor, CV_L1);
 | |
|         cvReleaseSparseMat((CvSparseMat**)&hist[0]->bins);
 | |
|         hist[0]->bins = (CvSparseMat*)h;
 | |
|     }
 | |
|     else
 | |
|         cvNormalizeHist( hist[0], factor );
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_NormHistTest::validate_test_results( int /*test_case_idx*/ )
 | |
| {
 | |
|     int code = cvtest::TS::OK;
 | |
|     double sum = 0;
 | |
| 
 | |
|     if( hist_type == CV_HIST_ARRAY )
 | |
|     {
 | |
|         int i;
 | |
|         const float* ptr = (float*)cvPtr1D( hist[0]->bins, 0 );
 | |
| 
 | |
|         for( i = 0; i < total_size; i++ )
 | |
|             sum += ptr[i];
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         CvSparseMat* sparse = (CvSparseMat*)hist[0]->bins;
 | |
|         CvSparseMatIterator iterator;
 | |
|         CvSparseNode *node;
 | |
| 
 | |
|         for( node = cvInitSparseMatIterator( sparse, &iterator );
 | |
|              node != 0; node = cvGetNextSparseNode( &iterator ))
 | |
|         {
 | |
|             sum += *(float*)CV_NODE_VAL(sparse,node);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if( cvIsNaN(sum) || cvIsInf(sum) )
 | |
|     {
 | |
|         ts->printf( cvtest::TS::LOG,
 | |
|             "The normalized histogram has invalid sum =%g\n", sum );
 | |
|         code = cvtest::TS::FAIL_INVALID_OUTPUT;
 | |
|     }
 | |
|     else if( fabs(sum - factor) > FLT_EPSILON*10*fabs(factor) )
 | |
|     {
 | |
|         ts->printf( cvtest::TS::LOG,
 | |
|             "The normalized histogram has incorrect sum =%g, while it should be =%g\n", sum, factor );
 | |
|         code = cvtest::TS::FAIL_BAD_ACCURACY;
 | |
|     }
 | |
| 
 | |
|     if( code < 0 )
 | |
|         ts->set_failed_test_info( code );
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| ////////////// cvThreshHist //////////////
 | |
| 
 | |
| class CV_ThreshHistTest : public CV_BaseHistTest
 | |
| {
 | |
| public:
 | |
|     CV_ThreshHistTest();
 | |
|     ~CV_ThreshHistTest();
 | |
|     void clear();
 | |
| 
 | |
| protected:
 | |
|     int prepare_test_case( int test_case_idx );
 | |
|     void run_func(void);
 | |
|     int validate_test_results( int test_case_idx );
 | |
|     CvMat* indices;
 | |
|     CvMat* values;
 | |
|     int orig_nz_count;
 | |
| 
 | |
|     double threshold;
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| CV_ThreshHistTest::CV_ThreshHistTest()
 | |
| {
 | |
|     hist_count = 1;
 | |
|     gen_random_hist = 1;
 | |
|     threshold = 0;
 | |
|     indices = values = 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| CV_ThreshHistTest::~CV_ThreshHistTest()
 | |
| {
 | |
|     clear();
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_ThreshHistTest::clear()
 | |
| {
 | |
|     cvReleaseMat( &indices );
 | |
|     cvReleaseMat( &values );
 | |
|     CV_BaseHistTest::clear();
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_ThreshHistTest::prepare_test_case( int test_case_idx )
 | |
| {
 | |
|     int code = CV_BaseHistTest::prepare_test_case( test_case_idx );
 | |
| 
 | |
|     if( code > 0 )
 | |
|     {
 | |
|         RNG& rng = ts->get_rng();
 | |
|         threshold = cvtest::randReal(rng)*gen_hist_max_val;
 | |
| 
 | |
|         if( hist_type == CV_HIST_ARRAY )
 | |
|         {
 | |
|             orig_nz_count = total_size;
 | |
| 
 | |
|             values = cvCreateMat( 1, total_size, CV_32F );
 | |
|             memcpy( values->data.fl, cvPtr1D( hist[0]->bins, 0 ), total_size*sizeof(float) );
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             CvSparseMat* sparse = (CvSparseMat*)hist[0]->bins;
 | |
|             CvSparseMatIterator iterator;
 | |
|             CvSparseNode* node;
 | |
|             int i, k;
 | |
| 
 | |
|             orig_nz_count = sparse->heap->active_count;
 | |
| 
 | |
|             values = cvCreateMat( 1, orig_nz_count+1, CV_32F );
 | |
|             indices = cvCreateMat( 1, (orig_nz_count+1)*cdims, CV_32S );
 | |
| 
 | |
|             for( node = cvInitSparseMatIterator( sparse, &iterator ), i = 0;
 | |
|                  node != 0; node = cvGetNextSparseNode( &iterator ), i++ )
 | |
|             {
 | |
|                  const int* idx = CV_NODE_IDX(sparse,node);
 | |
| 
 | |
|                  OPENCV_ASSERT( i < orig_nz_count, "CV_ThreshHistTest::prepare_test_case", "Buffer overflow" );
 | |
| 
 | |
|                  values->data.fl[i] = *(float*)CV_NODE_VAL(sparse,node);
 | |
|                  for( k = 0; k < cdims; k++ )
 | |
|                      indices->data.i[i*cdims + k] = idx[k];
 | |
|             }
 | |
| 
 | |
|             OPENCV_ASSERT( i == orig_nz_count, "Unmatched buffer size",
 | |
|                 "CV_ThreshHistTest::prepare_test_case" );
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_ThreshHistTest::run_func(void)
 | |
| {
 | |
|     cvThreshHist( hist[0], threshold );
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_ThreshHistTest::validate_test_results( int /*test_case_idx*/ )
 | |
| {
 | |
|     int code = cvtest::TS::OK;
 | |
|     int i;
 | |
|     float* ptr0 = values->data.fl;
 | |
|     float* ptr = 0;
 | |
|     CvSparseMat* sparse = 0;
 | |
| 
 | |
|     if( hist_type == CV_HIST_ARRAY )
 | |
|         ptr = (float*)cvPtr1D( hist[0]->bins, 0 );
 | |
|     else
 | |
|         sparse = (CvSparseMat*)hist[0]->bins;
 | |
| 
 | |
|     if( code > 0 )
 | |
|     {
 | |
|         for( i = 0; i < orig_nz_count; i++ )
 | |
|         {
 | |
|             float v0 = ptr0[i], v;
 | |
| 
 | |
|             if( hist_type == CV_HIST_ARRAY )
 | |
|                 v = ptr[i];
 | |
|             else
 | |
|             {
 | |
|                 v = (float)cvGetRealND( sparse, indices->data.i + i*cdims );
 | |
|                 cvClearND( sparse, indices->data.i + i*cdims );
 | |
|             }
 | |
| 
 | |
|             if( v0 <= threshold ) v0 = 0.f;
 | |
|             if( cvIsNaN(v) || cvIsInf(v) )
 | |
|             {
 | |
|                 ts->printf( cvtest::TS::LOG, "The %d-th bin is invalid (=%g)\n", i, v );
 | |
|                 code = cvtest::TS::FAIL_INVALID_OUTPUT;
 | |
|                 break;
 | |
|             }
 | |
|             else if( fabs(v0 - v) > FLT_EPSILON*10*fabs(v0) )
 | |
|             {
 | |
|                 ts->printf( cvtest::TS::LOG, "The %d-th bin is incorrect (=%g, should be =%g)\n", i, v, v0 );
 | |
|                 code = cvtest::TS::FAIL_BAD_ACCURACY;
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if( code > 0 && hist_type == CV_HIST_SPARSE )
 | |
|     {
 | |
|         if( sparse->heap->active_count > 0 )
 | |
|         {
 | |
|             ts->printf( cvtest::TS::LOG,
 | |
|                 "There some extra histogram bins in the sparse histogram after the thresholding\n" );
 | |
|             code = cvtest::TS::FAIL_INVALID_OUTPUT;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if( code < 0 )
 | |
|         ts->set_failed_test_info( code );
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| ////////////// cvCompareHist //////////////
 | |
| 
 | |
| class CV_CompareHistTest : public CV_BaseHistTest
 | |
| {
 | |
| public:
 | |
|     enum { MAX_METHOD = 4 };
 | |
| 
 | |
|     CV_CompareHistTest();
 | |
| protected:
 | |
|     int prepare_test_case( int test_case_idx );
 | |
|     void run_func(void);
 | |
|     int validate_test_results( int test_case_idx );
 | |
|     double result[MAX_METHOD+1];
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| CV_CompareHistTest::CV_CompareHistTest()
 | |
| {
 | |
|     hist_count = 2;
 | |
|     gen_random_hist = 1;
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_CompareHistTest::prepare_test_case( int test_case_idx )
 | |
| {
 | |
|     int code = CV_BaseHistTest::prepare_test_case( test_case_idx );
 | |
| 
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_CompareHistTest::run_func(void)
 | |
| {
 | |
|     int k;
 | |
|     if( hist_type != CV_HIST_ARRAY && test_cpp )
 | |
|     {
 | |
|         cv::SparseMat h0((CvSparseMat*)hist[0]->bins);
 | |
|         cv::SparseMat h1((CvSparseMat*)hist[1]->bins);
 | |
|         for( k = 0; k < MAX_METHOD; k++ )
 | |
|             result[k] = cv::compareHist(h0, h1, k);
 | |
|     }
 | |
|     else
 | |
|         for( k = 0; k < MAX_METHOD; k++ )
 | |
|             result[k] = cvCompareHist( hist[0], hist[1], k );
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_CompareHistTest::validate_test_results( int /*test_case_idx*/ )
 | |
| {
 | |
|     int code = cvtest::TS::OK;
 | |
|     int i;
 | |
|     double result0[MAX_METHOD+1];
 | |
|     double s0 = 0, s1 = 0, sq0 = 0, sq1 = 0, t;
 | |
| 
 | |
|     for( i = 0; i < MAX_METHOD; i++ )
 | |
|         result0[i] = 0;
 | |
| 
 | |
|     if( hist_type == CV_HIST_ARRAY )
 | |
|     {
 | |
|         float* ptr0 = (float*)cvPtr1D( hist[0]->bins, 0 );
 | |
|         float* ptr1 = (float*)cvPtr1D( hist[1]->bins, 0 );
 | |
| 
 | |
|         for( i = 0; i < total_size; i++ )
 | |
|         {
 | |
|             double v0 = ptr0[i], v1 = ptr1[i];
 | |
|             result0[CV_COMP_CORREL] += v0*v1;
 | |
|             result0[CV_COMP_INTERSECT] += MIN(v0,v1);
 | |
|             if( fabs(v0) > DBL_EPSILON )
 | |
|                 result0[CV_COMP_CHISQR] += (v0 - v1)*(v0 - v1)/v0;
 | |
|             s0 += v0;
 | |
|             s1 += v1;
 | |
|             sq0 += v0*v0;
 | |
|             sq1 += v1*v1;
 | |
|             result0[CV_COMP_BHATTACHARYYA] += sqrt(v0*v1);
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         CvSparseMat* sparse0 = (CvSparseMat*)hist[0]->bins;
 | |
|         CvSparseMat* sparse1 = (CvSparseMat*)hist[1]->bins;
 | |
|         CvSparseMatIterator iterator;
 | |
|         CvSparseNode* node;
 | |
| 
 | |
|         for( node = cvInitSparseMatIterator( sparse0, &iterator );
 | |
|              node != 0; node = cvGetNextSparseNode( &iterator ) )
 | |
|         {
 | |
|             const int* idx = CV_NODE_IDX(sparse0, node);
 | |
|             double v0 = *(float*)CV_NODE_VAL(sparse0, node);
 | |
|             double v1 = (float)cvGetRealND(sparse1, idx);
 | |
| 
 | |
|             result0[CV_COMP_CORREL] += v0*v1;
 | |
|             result0[CV_COMP_INTERSECT] += MIN(v0,v1);
 | |
|             if( fabs(v0) > DBL_EPSILON )
 | |
|                 result0[CV_COMP_CHISQR] += (v0 - v1)*(v0 - v1)/v0;
 | |
|             s0 += v0;
 | |
|             sq0 += v0*v0;
 | |
|             result0[CV_COMP_BHATTACHARYYA] += sqrt(v0*v1);
 | |
|         }
 | |
| 
 | |
|         for( node = cvInitSparseMatIterator( sparse1, &iterator );
 | |
|              node != 0; node = cvGetNextSparseNode( &iterator ) )
 | |
|         {
 | |
|             double v1 = *(float*)CV_NODE_VAL(sparse1, node);
 | |
|             s1 += v1;
 | |
|             sq1 += v1*v1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     t = (sq0 - s0*s0/total_size)*(sq1 - s1*s1/total_size);
 | |
|     result0[CV_COMP_CORREL] = fabs(t) > DBL_EPSILON ?
 | |
|         (result0[CV_COMP_CORREL] - s0*s1/total_size)/sqrt(t) : 1;
 | |
| 
 | |
|     s1 *= s0;
 | |
|     s0 = result0[CV_COMP_BHATTACHARYYA];
 | |
|     s0 = 1. - s0*(s1 > FLT_EPSILON ? 1./sqrt(s1) : 1.);
 | |
|     result0[CV_COMP_BHATTACHARYYA] = sqrt(MAX(s0,0.));
 | |
| 
 | |
|     for( i = 0; i < MAX_METHOD; i++ )
 | |
|     {
 | |
|         double v = result[i], v0 = result0[i];
 | |
|         const char* method_name =
 | |
|             i == CV_COMP_CHISQR ? "Chi-Square" :
 | |
|             i == CV_COMP_CORREL ? "Correlation" :
 | |
|             i == CV_COMP_INTERSECT ? "Intersection" :
 | |
|             i == CV_COMP_BHATTACHARYYA ? "Bhattacharyya" : "Unknown";
 | |
| 
 | |
|         if( cvIsNaN(v) || cvIsInf(v) )
 | |
|         {
 | |
|             ts->printf( cvtest::TS::LOG, "The comparison result using the method #%d (%s) is invalid (=%g)\n",
 | |
|                 i, method_name, v );
 | |
|             code = cvtest::TS::FAIL_INVALID_OUTPUT;
 | |
|             break;
 | |
|         }
 | |
|         else if( fabs(v0 - v) > FLT_EPSILON*10*MAX(fabs(v0),0.1) )
 | |
|         {
 | |
|             ts->printf( cvtest::TS::LOG, "The comparison result using the method #%d (%s)\n\tis inaccurate (=%g, should be =%g)\n",
 | |
|                 i, method_name, v, v0 );
 | |
|             code = cvtest::TS::FAIL_BAD_ACCURACY;
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if( code < 0 )
 | |
|         ts->set_failed_test_info( code );
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| ////////////// cvCalcHist //////////////
 | |
| 
 | |
| class CV_CalcHistTest : public CV_BaseHistTest
 | |
| {
 | |
| public:
 | |
|     CV_CalcHistTest();
 | |
|     ~CV_CalcHistTest();
 | |
|     void clear();
 | |
| 
 | |
| protected:
 | |
|     int prepare_test_case( int test_case_idx );
 | |
|     void run_func(void);
 | |
|     int validate_test_results( int test_case_idx );
 | |
|     IplImage* images[CV_MAX_DIM+1];
 | |
|     int channels[CV_MAX_DIM+1];
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| CV_CalcHistTest::CV_CalcHistTest()
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     hist_count = 2;
 | |
|     gen_random_hist = 0;
 | |
|     init_ranges = 1;
 | |
| 
 | |
|     for( i = 0; i <= CV_MAX_DIM; i++ )
 | |
|     {
 | |
|         images[i] = 0;
 | |
|         channels[i] = 0;
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| CV_CalcHistTest::~CV_CalcHistTest()
 | |
| {
 | |
|     clear();
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_CalcHistTest::clear()
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     for( i = 0; i <= CV_MAX_DIM; i++ )
 | |
|         cvReleaseImage( &images[i] );
 | |
| 
 | |
|     CV_BaseHistTest::clear();
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_CalcHistTest::prepare_test_case( int test_case_idx )
 | |
| {
 | |
|     int code = CV_BaseHistTest::prepare_test_case( test_case_idx );
 | |
| 
 | |
|     if( code > 0 )
 | |
|     {
 | |
|         RNG& rng = ts->get_rng();
 | |
|         int i;
 | |
| 
 | |
|         for( i = 0; i <= CV_MAX_DIM; i++ )
 | |
|         {
 | |
|             if( i < cdims )
 | |
|             {
 | |
|                 int nch = 1; //cvtest::randInt(rng) % 3 + 1;
 | |
|                 images[i] = cvCreateImage( img_size,
 | |
|                     img_type == CV_8U ? IPL_DEPTH_8U : IPL_DEPTH_32F, nch );
 | |
|                 channels[i] = cvtest::randInt(rng) % nch;
 | |
|                 Mat images_i = cvarrToMat(images[i]);
 | |
| 
 | |
|                 cvtest::randUni( rng, images_i, Scalar::all(low), Scalar::all(high) );
 | |
|             }
 | |
|             else if( i == CV_MAX_DIM && cvtest::randInt(rng) % 2 )
 | |
|             {
 | |
|                 // create mask
 | |
|                 images[i] = cvCreateImage( img_size, IPL_DEPTH_8U, 1 );
 | |
|                 Mat images_i = cvarrToMat(images[i]);
 | |
| 
 | |
|                 // make ~25% pixels in the mask non-zero
 | |
|                 cvtest::randUni( rng, images_i, Scalar::all(-2), Scalar::all(2) );
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_CalcHistTest::run_func(void)
 | |
| {
 | |
|     cvCalcHist( images, hist[0], 0, images[CV_MAX_DIM] );
 | |
| }
 | |
| 
 | |
| 
 | |
| static void
 | |
| cvTsCalcHist( IplImage** _images, CvHistogram* hist, IplImage* _mask, int* channels )
 | |
| {
 | |
|     int x, y, k, cdims;
 | |
|     union
 | |
|     {
 | |
|         float* fl;
 | |
|         uchar* ptr;
 | |
|     }
 | |
|     plane[CV_MAX_DIM];
 | |
|     int nch[CV_MAX_DIM];
 | |
|     int dims[CV_MAX_DIM];
 | |
|     int uniform = CV_IS_UNIFORM_HIST(hist);
 | |
|     CvSize img_size = cvGetSize(_images[0]);
 | |
|     CvMat images[CV_MAX_DIM], mask = cvMat(1,1,CV_8U);
 | |
|     int img_depth = _images[0]->depth;
 | |
| 
 | |
|     cdims = cvGetDims( hist->bins, dims );
 | |
| 
 | |
|     cvZero( hist->bins );
 | |
| 
 | |
|     for( k = 0; k < cdims; k++ )
 | |
|     {
 | |
|         cvGetMat( _images[k], &images[k] );
 | |
|         nch[k] = _images[k]->nChannels;
 | |
|     }
 | |
| 
 | |
|     if( _mask )
 | |
|         cvGetMat( _mask, &mask );
 | |
| 
 | |
|     for( y = 0; y < img_size.height; y++ )
 | |
|     {
 | |
|         const uchar* mptr = _mask ? &CV_MAT_ELEM(mask, uchar, y, 0 ) : 0;
 | |
| 
 | |
|         if( img_depth == IPL_DEPTH_8U )
 | |
|             for( k = 0; k < cdims; k++ )
 | |
|                 plane[k].ptr = &CV_MAT_ELEM(images[k], uchar, y, 0 ) + channels[k];
 | |
|         else
 | |
|             for( k = 0; k < cdims; k++ )
 | |
|                 plane[k].fl = &CV_MAT_ELEM(images[k], float, y, 0 ) + channels[k];
 | |
| 
 | |
|         for( x = 0; x < img_size.width; x++ )
 | |
|         {
 | |
|             float val[CV_MAX_DIM];
 | |
|             int idx[CV_MAX_DIM];
 | |
| 
 | |
|             if( mptr && !mptr[x] )
 | |
|                 continue;
 | |
|             if( img_depth == IPL_DEPTH_8U )
 | |
|                 for( k = 0; k < cdims; k++ )
 | |
|                     val[k] = plane[k].ptr[x*nch[k]];
 | |
|             else
 | |
|                 for( k = 0; k < cdims; k++ )
 | |
|                     val[k] = plane[k].fl[x*nch[k]];
 | |
| 
 | |
|             idx[cdims-1] = -1;
 | |
| 
 | |
|             if( uniform )
 | |
|             {
 | |
|                 for( k = 0; k < cdims; k++ )
 | |
|                 {
 | |
|                     double v = val[k], lo = hist->thresh[k][0], hi = hist->thresh[k][1];
 | |
|                     idx[k] = cvFloor((v - lo)*dims[k]/(hi - lo));
 | |
|                     if( idx[k] < 0 || idx[k] >= dims[k] )
 | |
|                         break;
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 for( k = 0; k < cdims; k++ )
 | |
|                 {
 | |
|                     float v = val[k];
 | |
|                     float* t = hist->thresh2[k];
 | |
|                     int j, n = dims[k];
 | |
| 
 | |
|                     for( j = 0; j <= n; j++ )
 | |
|                         if( v < t[j] )
 | |
|                             break;
 | |
|                     if( j <= 0 || j > n )
 | |
|                         break;
 | |
|                     idx[k] = j-1;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if( k < cdims )
 | |
|                 continue;
 | |
| 
 | |
|             (*(float*)cvPtrND( hist->bins, idx ))++;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_CalcHistTest::validate_test_results( int /*test_case_idx*/ )
 | |
| {
 | |
|     int code = cvtest::TS::OK;
 | |
|     double diff;
 | |
|     cvTsCalcHist( images, hist[1], images[CV_MAX_DIM], channels );
 | |
|     diff = cvCompareHist( hist[0], hist[1], CV_COMP_CHISQR );
 | |
|     if( diff > DBL_EPSILON )
 | |
|     {
 | |
|         ts->printf( cvtest::TS::LOG, "The histogram does not match to the reference one\n" );
 | |
|         code = cvtest::TS::FAIL_BAD_ACCURACY;
 | |
| 
 | |
|     }
 | |
| 
 | |
|     if( code < 0 )
 | |
|         ts->set_failed_test_info( code );
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| CV_CalcHistTest hist_calc_test;
 | |
| 
 | |
| 
 | |
| 
 | |
| ////////////// cvCalcBackProject //////////////
 | |
| 
 | |
| class CV_CalcBackProjectTest : public CV_BaseHistTest
 | |
| {
 | |
| public:
 | |
|     CV_CalcBackProjectTest();
 | |
|     ~CV_CalcBackProjectTest();
 | |
|     void clear();
 | |
| 
 | |
| protected:
 | |
|     int prepare_test_case( int test_case_idx );
 | |
|     void run_func(void);
 | |
|     int validate_test_results( int test_case_idx );
 | |
|     IplImage* images[CV_MAX_DIM+3];
 | |
|     int channels[CV_MAX_DIM+3];
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| CV_CalcBackProjectTest::CV_CalcBackProjectTest()
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     hist_count = 1;
 | |
|     gen_random_hist = 0;
 | |
|     init_ranges = 1;
 | |
| 
 | |
|     for( i = 0; i < CV_MAX_DIM+3; i++ )
 | |
|     {
 | |
|         images[i] = 0;
 | |
|         channels[i] = 0;
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| CV_CalcBackProjectTest::~CV_CalcBackProjectTest()
 | |
| {
 | |
|     clear();
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_CalcBackProjectTest::clear()
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     for( i = 0; i < CV_MAX_DIM+3; i++ )
 | |
|         cvReleaseImage( &images[i] );
 | |
| 
 | |
|     CV_BaseHistTest::clear();
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_CalcBackProjectTest::prepare_test_case( int test_case_idx )
 | |
| {
 | |
|     int code = CV_BaseHistTest::prepare_test_case( test_case_idx );
 | |
| 
 | |
|     if( code > 0 )
 | |
|     {
 | |
|         RNG& rng = ts->get_rng();
 | |
|         int i, j, n, img_len = img_size.width*img_size.height;
 | |
| 
 | |
|         for( i = 0; i < CV_MAX_DIM + 3; i++ )
 | |
|         {
 | |
|             if( i < cdims )
 | |
|             {
 | |
|                 int nch = 1; //cvtest::randInt(rng) % 3 + 1;
 | |
|                 images[i] = cvCreateImage( img_size,
 | |
|                     img_type == CV_8U ? IPL_DEPTH_8U : IPL_DEPTH_32F, nch );
 | |
|                 channels[i] = cvtest::randInt(rng) % nch;
 | |
| 
 | |
|                 Mat images_i = cvarrToMat(images[i]);
 | |
|                 cvtest::randUni( rng, images_i, Scalar::all(low), Scalar::all(high) );
 | |
|             }
 | |
|             else if( i == CV_MAX_DIM && cvtest::randInt(rng) % 2 )
 | |
|             {
 | |
|                 // create mask
 | |
|                 images[i] = cvCreateImage( img_size, IPL_DEPTH_8U, 1 );
 | |
|                 Mat images_i = cvarrToMat(images[i]);
 | |
|                 // make ~25% pixels in the mask non-zero
 | |
|                 cvtest::randUni( rng, images_i, Scalar::all(-2), Scalar::all(2) );
 | |
|             }
 | |
|             else if( i > CV_MAX_DIM )
 | |
|             {
 | |
|                 images[i] = cvCreateImage( img_size, images[0]->depth, 1 );
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         cvTsCalcHist( images, hist[0], images[CV_MAX_DIM], channels );
 | |
| 
 | |
|         // now modify the images a bit to add some zeros go to the backprojection
 | |
|         n = cvtest::randInt(rng) % (img_len/20+1);
 | |
|         for( i = 0; i < cdims; i++ )
 | |
|         {
 | |
|             char* data = images[i]->imageData;
 | |
|             for( j = 0; j < n; j++ )
 | |
|             {
 | |
|                 int idx = cvtest::randInt(rng) % img_len;
 | |
|                 double val = cvtest::randReal(rng)*(high - low) + low;
 | |
| 
 | |
|                 if( img_type == CV_8U )
 | |
|                     ((uchar*)data)[idx] = (uchar)cvRound(val);
 | |
|                 else
 | |
|                     ((float*)data)[idx] = (float)val;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_CalcBackProjectTest::run_func(void)
 | |
| {
 | |
|     cvCalcBackProject( images, images[CV_MAX_DIM+1], hist[0] );
 | |
| }
 | |
| 
 | |
| 
 | |
| static void
 | |
| cvTsCalcBackProject( IplImage** images, IplImage* dst, CvHistogram* hist, int* channels )
 | |
| {
 | |
|     int x, y, k, cdims;
 | |
|     union
 | |
|     {
 | |
|         float* fl;
 | |
|         uchar* ptr;
 | |
|     }
 | |
|     plane[CV_MAX_DIM];
 | |
|     int nch[CV_MAX_DIM];
 | |
|     int dims[CV_MAX_DIM];
 | |
|     int uniform = CV_IS_UNIFORM_HIST(hist);
 | |
|     CvSize img_size = cvGetSize(images[0]);
 | |
|     int img_depth = images[0]->depth;
 | |
| 
 | |
|     cdims = cvGetDims( hist->bins, dims );
 | |
| 
 | |
|     for( k = 0; k < cdims; k++ )
 | |
|         nch[k] = images[k]->nChannels;
 | |
| 
 | |
|     for( y = 0; y < img_size.height; y++ )
 | |
|     {
 | |
|         if( img_depth == IPL_DEPTH_8U )
 | |
|             for( k = 0; k < cdims; k++ )
 | |
|                 plane[k].ptr = &CV_IMAGE_ELEM(images[k], uchar, y, 0 ) + channels[k];
 | |
|         else
 | |
|             for( k = 0; k < cdims; k++ )
 | |
|                 plane[k].fl = &CV_IMAGE_ELEM(images[k], float, y, 0 ) + channels[k];
 | |
| 
 | |
|         for( x = 0; x < img_size.width; x++ )
 | |
|         {
 | |
|             float val[CV_MAX_DIM];
 | |
|             float bin_val = 0;
 | |
|             int idx[CV_MAX_DIM];
 | |
| 
 | |
|             if( img_depth == IPL_DEPTH_8U )
 | |
|                 for( k = 0; k < cdims; k++ )
 | |
|                     val[k] = plane[k].ptr[x*nch[k]];
 | |
|             else
 | |
|                 for( k = 0; k < cdims; k++ )
 | |
|                     val[k] = plane[k].fl[x*nch[k]];
 | |
|             idx[cdims-1] = -1;
 | |
| 
 | |
|             if( uniform )
 | |
|             {
 | |
|                 for( k = 0; k < cdims; k++ )
 | |
|                 {
 | |
|                     double v = val[k], lo = hist->thresh[k][0], hi = hist->thresh[k][1];
 | |
|                     idx[k] = cvFloor((v - lo)*dims[k]/(hi - lo));
 | |
|                     if( idx[k] < 0 || idx[k] >= dims[k] )
 | |
|                         break;
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 for( k = 0; k < cdims; k++ )
 | |
|                 {
 | |
|                     float v = val[k];
 | |
|                     float* t = hist->thresh2[k];
 | |
|                     int j, n = dims[k];
 | |
| 
 | |
|                     for( j = 0; j <= n; j++ )
 | |
|                         if( v < t[j] )
 | |
|                             break;
 | |
|                     if( j <= 0 || j > n )
 | |
|                         break;
 | |
|                     idx[k] = j-1;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if( k == cdims )
 | |
|                 bin_val = (float)cvGetRealND( hist->bins, idx );
 | |
| 
 | |
|             if( img_depth == IPL_DEPTH_8U )
 | |
|             {
 | |
|                 int t = cvRound(bin_val);
 | |
|                 CV_IMAGE_ELEM( dst, uchar, y, x ) = saturate_cast<uchar>(t);
 | |
|             }
 | |
|             else
 | |
|                 CV_IMAGE_ELEM( dst, float, y, x ) = bin_val;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_CalcBackProjectTest::validate_test_results( int /*test_case_idx*/ )
 | |
| {
 | |
|     int code = cvtest::TS::OK;
 | |
| 
 | |
|     cvTsCalcBackProject( images, images[CV_MAX_DIM+2], hist[0], channels );
 | |
|     Mat a = cvarrToMat(images[CV_MAX_DIM+1]), b = cvarrToMat(images[CV_MAX_DIM+2]);
 | |
|     double threshold = a.depth() == CV_8U ? 2 : FLT_EPSILON;
 | |
|     code = cvtest::cmpEps2( ts, a, b, threshold, true, "Back project image" );
 | |
| 
 | |
|     if( code < 0 )
 | |
|         ts->set_failed_test_info( code );
 | |
| 
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| ////////////// cvCalcBackProjectPatch //////////////
 | |
| 
 | |
| class CV_CalcBackProjectPatchTest : public CV_BaseHistTest
 | |
| {
 | |
| public:
 | |
|     CV_CalcBackProjectPatchTest();
 | |
|     ~CV_CalcBackProjectPatchTest();
 | |
|     void clear();
 | |
| 
 | |
| protected:
 | |
|     int prepare_test_case( int test_case_idx );
 | |
|     void run_func(void);
 | |
|     int validate_test_results( int test_case_idx );
 | |
|     IplImage* images[CV_MAX_DIM+2];
 | |
|     int channels[CV_MAX_DIM+2];
 | |
| 
 | |
|     CvSize patch_size;
 | |
|     double factor;
 | |
|     int method;
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| CV_CalcBackProjectPatchTest::CV_CalcBackProjectPatchTest()
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     hist_count = 1;
 | |
|     gen_random_hist = 0;
 | |
|     init_ranges = 1;
 | |
|     img_max_log_size = 6;
 | |
| 
 | |
|     for( i = 0; i < CV_MAX_DIM+2; i++ )
 | |
|     {
 | |
|         images[i] = 0;
 | |
|         channels[i] = 0;
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| CV_CalcBackProjectPatchTest::~CV_CalcBackProjectPatchTest()
 | |
| {
 | |
|     clear();
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_CalcBackProjectPatchTest::clear()
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     for( i = 0; i < CV_MAX_DIM+2; i++ )
 | |
|         cvReleaseImage( &images[i] );
 | |
| 
 | |
|     CV_BaseHistTest::clear();
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_CalcBackProjectPatchTest::prepare_test_case( int test_case_idx )
 | |
| {
 | |
|     int code = CV_BaseHistTest::prepare_test_case( test_case_idx );
 | |
| 
 | |
|     if( code > 0 )
 | |
|     {
 | |
|         RNG& rng = ts->get_rng();
 | |
|         int i, j, n, img_len = img_size.width*img_size.height;
 | |
| 
 | |
|         patch_size.width = cvtest::randInt(rng) % img_size.width + 1;
 | |
|         patch_size.height = cvtest::randInt(rng) % img_size.height + 1;
 | |
|         patch_size.width = MIN( patch_size.width, 30 );
 | |
|         patch_size.height = MIN( patch_size.height, 30 );
 | |
| 
 | |
|         factor = 1.;
 | |
|         method = cvtest::randInt(rng) % CV_CompareHistTest::MAX_METHOD;
 | |
| 
 | |
|         for( i = 0; i < CV_MAX_DIM + 2; i++ )
 | |
|         {
 | |
|             if( i < cdims )
 | |
|             {
 | |
|                 int nch = 1; //cvtest::randInt(rng) % 3 + 1;
 | |
|                 images[i] = cvCreateImage( img_size,
 | |
|                     img_type == CV_8U ? IPL_DEPTH_8U : IPL_DEPTH_32F, nch );
 | |
|                 channels[i] = cvtest::randInt(rng) % nch;
 | |
| 
 | |
|                 Mat images_i = cvarrToMat(images[i]);
 | |
|                 cvtest::randUni( rng, images_i, Scalar::all(low), Scalar::all(high) );
 | |
|             }
 | |
|             else if( i >= CV_MAX_DIM )
 | |
|             {
 | |
|                 images[i] = cvCreateImage(
 | |
|                     cvSize(img_size.width - patch_size.width + 1,
 | |
|                            img_size.height - patch_size.height + 1),
 | |
|                     IPL_DEPTH_32F, 1 );
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         cvTsCalcHist( images, hist[0], 0, channels );
 | |
|         cvNormalizeHist( hist[0], factor );
 | |
| 
 | |
|         // now modify the images a bit
 | |
|         n = cvtest::randInt(rng) % (img_len/10+1);
 | |
|         for( i = 0; i < cdims; i++ )
 | |
|         {
 | |
|             char* data = images[i]->imageData;
 | |
|             for( j = 0; j < n; j++ )
 | |
|             {
 | |
|                 int idx = cvtest::randInt(rng) % img_len;
 | |
|                 double val = cvtest::randReal(rng)*(high - low) + low;
 | |
| 
 | |
|                 if( img_type == CV_8U )
 | |
|                     ((uchar*)data)[idx] = (uchar)cvRound(val);
 | |
|                 else
 | |
|                     ((float*)data)[idx] = (float)val;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_CalcBackProjectPatchTest::run_func(void)
 | |
| {
 | |
|     cvCalcBackProjectPatch( images, images[CV_MAX_DIM], patch_size, hist[0], method, factor );
 | |
| }
 | |
| 
 | |
| 
 | |
| static void
 | |
| cvTsCalcBackProjectPatch( IplImage** images, IplImage* dst, CvSize patch_size,
 | |
|                           CvHistogram* hist, int method,
 | |
|                           double factor, int* channels )
 | |
| {
 | |
|     CvHistogram* model = 0;
 | |
| 
 | |
|     IplImage imgstub[CV_MAX_DIM], *img[CV_MAX_DIM];
 | |
|     IplROI roi;
 | |
|     int i, dims;
 | |
|     int x, y;
 | |
|     CvSize size = cvGetSize(dst);
 | |
| 
 | |
|     dims = cvGetDims( hist->bins );
 | |
|     cvCopyHist( hist, &model );
 | |
|     cvNormalizeHist( hist, factor );
 | |
|     cvZero( dst );
 | |
| 
 | |
|     for( i = 0; i < dims; i++ )
 | |
|     {
 | |
|         CvMat stub, *mat;
 | |
|         mat = cvGetMat( images[i], &stub, 0, 0 );
 | |
|         img[i] = cvGetImage( mat, &imgstub[i] );
 | |
|         img[i]->roi = &roi;
 | |
|     }
 | |
| 
 | |
|     roi.coi = 0;
 | |
| 
 | |
|     for( y = 0; y < size.height; y++ )
 | |
|     {
 | |
|         for( x = 0; x < size.width; x++ )
 | |
|         {
 | |
|             double result;
 | |
| 
 | |
|             roi.xOffset = x;
 | |
|             roi.yOffset = y;
 | |
|             roi.width = patch_size.width;
 | |
|             roi.height = patch_size.height;
 | |
| 
 | |
|             cvTsCalcHist( img, model, 0, channels );
 | |
|             cvNormalizeHist( model, factor );
 | |
|             result = cvCompareHist( model, hist, method );
 | |
|             CV_IMAGE_ELEM( dst, float, y, x ) = (float)result;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     cvReleaseHist( &model );
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_CalcBackProjectPatchTest::validate_test_results( int /*test_case_idx*/ )
 | |
| {
 | |
|     int code = cvtest::TS::OK;
 | |
|     double err_level = 5e-3;
 | |
| 
 | |
|     cvTsCalcBackProjectPatch( images, images[CV_MAX_DIM+1],
 | |
|         patch_size, hist[0], method, factor, channels );
 | |
| 
 | |
|     Mat a = cvarrToMat(images[CV_MAX_DIM]), b = cvarrToMat(images[CV_MAX_DIM+1]);
 | |
|     code = cvtest::cmpEps2( ts, a, b, err_level, true, "BackProjectPatch result" );
 | |
| 
 | |
|     if( code < 0 )
 | |
|         ts->set_failed_test_info( code );
 | |
| 
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| ////////////// cvCalcBayesianProb //////////////
 | |
| 
 | |
| class CV_BayesianProbTest : public CV_BaseHistTest
 | |
| {
 | |
| public:
 | |
|     enum { MAX_METHOD = 4 };
 | |
| 
 | |
|     CV_BayesianProbTest();
 | |
| protected:
 | |
|     int prepare_test_case( int test_case_idx );
 | |
|     void run_func(void);
 | |
|     int validate_test_results( int test_case_idx );
 | |
|     void init_hist( int test_case_idx, int i );
 | |
|     void get_hist_params( int test_case_idx );
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| CV_BayesianProbTest::CV_BayesianProbTest()
 | |
| {
 | |
|     hist_count = CV_MAX_DIM;
 | |
|     gen_random_hist = 1;
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_BayesianProbTest::get_hist_params( int test_case_idx )
 | |
| {
 | |
|     CV_BaseHistTest::get_hist_params( test_case_idx );
 | |
|     hist_type = CV_HIST_ARRAY;
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_BayesianProbTest::init_hist( int test_case_idx, int hist_i )
 | |
| {
 | |
|     if( hist_i < hist_count/2 )
 | |
|         CV_BaseHistTest::init_hist( test_case_idx, hist_i );
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_BayesianProbTest::prepare_test_case( int test_case_idx )
 | |
| {
 | |
|     RNG& rng = ts->get_rng();
 | |
| 
 | |
|     hist_count = (cvtest::randInt(rng) % (MAX_HIST/2-1) + 2)*2;
 | |
|     hist_count = MIN( hist_count, MAX_HIST );
 | |
|     int code = CV_BaseHistTest::prepare_test_case( test_case_idx );
 | |
| 
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| 
 | |
| void CV_BayesianProbTest::run_func(void)
 | |
| {
 | |
|     cvCalcBayesianProb( &hist[0], hist_count/2, &hist[hist_count/2] );
 | |
| }
 | |
| 
 | |
| 
 | |
| int CV_BayesianProbTest::validate_test_results( int /*test_case_idx*/ )
 | |
| {
 | |
|     int code = cvtest::TS::OK;
 | |
|     int i, j, n = hist_count/2;
 | |
|     double s[CV_MAX_DIM];
 | |
|     const double err_level = 1e-5;
 | |
| 
 | |
|     for( i = 0; i < total_size; i++ )
 | |
|     {
 | |
|         double sum = 0;
 | |
|         for( j = 0; j < n; j++ )
 | |
|         {
 | |
|             double v = hist[j]->mat.data.fl[i];
 | |
|             sum += v;
 | |
|             s[j] = v;
 | |
|         }
 | |
|         sum = sum > DBL_EPSILON ? 1./sum : 0;
 | |
| 
 | |
|         for( j = 0; j < n; j++ )
 | |
|         {
 | |
|             double v0 = s[j]*sum;
 | |
|             double v = hist[j+n]->mat.data.fl[i];
 | |
| 
 | |
|             if( cvIsNaN(v) || cvIsInf(v) )
 | |
|             {
 | |
|                 ts->printf( cvtest::TS::LOG,
 | |
|                     "The element #%d in the destination histogram #%d is invalid (=%g)\n",
 | |
|                     i, j, v );
 | |
|                 code = cvtest::TS::FAIL_INVALID_OUTPUT;
 | |
|                 break;
 | |
|             }
 | |
|             else if( fabs(v0 - v) > err_level*fabs(v0) )
 | |
|             {
 | |
|                 ts->printf( cvtest::TS::LOG,
 | |
|                     "The element #%d in the destination histogram #%d is inaccurate (=%g, should be =%g)\n",
 | |
|                     i, j, v, v0 );
 | |
|                 code = cvtest::TS::FAIL_BAD_ACCURACY;
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
|         if( j < n )
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     if( code < 0 )
 | |
|         ts->set_failed_test_info( code );
 | |
|     return code;
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| TEST(Imgproc_Hist_Calc, accuracy) { CV_CalcHistTest test; test.safe_run(); }
 | |
| TEST(Imgproc_Hist_Query, accuracy) { CV_QueryHistTest test; test.safe_run(); }
 | |
| 
 | |
| TEST(Imgproc_Hist_Compare, accuracy) { CV_CompareHistTest test; test.safe_run(); }
 | |
| TEST(Imgproc_Hist_Threshold, accuracy) { CV_ThreshHistTest test; test.safe_run(); }
 | |
| TEST(Imgproc_Hist_Normalize, accuracy) { CV_NormHistTest test; test.safe_run(); }
 | |
| TEST(Imgproc_Hist_MinMaxVal, accuracy) { CV_MinMaxHistTest test; test.safe_run(); }
 | |
| 
 | |
| TEST(Imgproc_Hist_CalcBackProject, accuracy) { CV_CalcBackProjectTest test; test.safe_run(); }
 | |
| TEST(Imgproc_Hist_CalcBackProjectPatch, accuracy) { CV_CalcBackProjectPatchTest test; test.safe_run(); }
 | |
| TEST(Imgproc_Hist_BayesianProb, accuracy) { CV_BayesianProbTest test; test.safe_run(); }
 | |
| 
 | |
| /* End Of File */
 | 
