reworked nearly all of the OpenCV tests (except for opencv_gpu tests) - they now use the Google Test engine.
This commit is contained in:
359
modules/imgproc/test/test_approxpoly.cpp
Normal file
359
modules/imgproc/test/test_approxpoly.cpp
Normal file
@@ -0,0 +1,359 @@
|
||||
/*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 <limits.h>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
//
|
||||
// TODO!!!:
|
||||
// check_slice (and/or check) seem(s) to be broken, or this is a bug in function
|
||||
// (or its inability to handle possible self-intersections in the generated contours).
|
||||
//
|
||||
// At least, if // return TotalErrors;
|
||||
// is uncommented in check_slice, the test fails easily.
|
||||
// So, now (and it looks like since 0.9.6)
|
||||
// we only check that the set of vertices of the approximated polygon is
|
||||
// a subset of vertices of the original contour.
|
||||
//
|
||||
|
||||
class CV_ApproxPolyTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
CV_ApproxPolyTest();
|
||||
~CV_ApproxPolyTest();
|
||||
void clear();
|
||||
//int write_default_params(CvFileStorage* fs);
|
||||
|
||||
protected:
|
||||
//int read_params( CvFileStorage* fs );
|
||||
|
||||
int check_slice( CvPoint StartPt, CvPoint EndPt,
|
||||
CvSeqReader* SrcReader, float Eps,
|
||||
int* j, int Count );
|
||||
int check( CvSeq* SrcSeq, CvSeq* DstSeq, float Eps );
|
||||
|
||||
bool get_contour( int /*type*/, CvSeq** Seq, int* d,
|
||||
CvMemStorage* storage );
|
||||
|
||||
void run(int);
|
||||
};
|
||||
|
||||
|
||||
CV_ApproxPolyTest::CV_ApproxPolyTest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CV_ApproxPolyTest::~CV_ApproxPolyTest()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
void CV_ApproxPolyTest::clear()
|
||||
{
|
||||
cvtest::BaseTest::clear();
|
||||
}
|
||||
|
||||
|
||||
/*int CV_ApproxPolyTest::write_default_params( CvFileStorage* fs )
|
||||
{
|
||||
cvtest::BaseTest::write_default_params( fs );
|
||||
if( ts->get_testing_mode() != cvtest::TS::TIMING_MODE )
|
||||
{
|
||||
write_param( fs, "test_case_count", test_case_count );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CV_ApproxPolyTest::read_params( CvFileStorage* fs )
|
||||
{
|
||||
int code = cvtest::BaseTest::read_params( fs );
|
||||
if( code < 0 )
|
||||
return code;
|
||||
|
||||
test_case_count = cvReadInt( find_param( fs, "test_case_count" ), test_case_count );
|
||||
min_log_size = cvtest::clipInt( min_log_size, 1, 10 );
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
|
||||
bool CV_ApproxPolyTest::get_contour( int /*type*/, CvSeq** Seq, int* d,
|
||||
CvMemStorage* storage )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
int max_x = INT_MIN, max_y = INT_MIN, min_x = INT_MAX, min_y = INT_MAX;
|
||||
int i;
|
||||
CvSeq* seq;
|
||||
int total = cvtest::randInt(rng) % 1000 + 1;
|
||||
CvPoint center;
|
||||
int radius, angle;
|
||||
double deg_to_rad = CV_PI/180.;
|
||||
CvPoint pt;
|
||||
|
||||
center.x = cvtest::randInt( rng ) % 1000;
|
||||
center.y = cvtest::randInt( rng ) % 1000;
|
||||
radius = cvtest::randInt( rng ) % 1000;
|
||||
angle = cvtest::randInt( rng ) % 360;
|
||||
|
||||
seq = cvCreateSeq( CV_SEQ_POLYGON, sizeof(CvContour), sizeof(CvPoint), storage );
|
||||
|
||||
for( i = 0; i < total; i++ )
|
||||
{
|
||||
int d_radius = cvtest::randInt( rng ) % 10 - 5;
|
||||
int d_angle = 360/total;//cvtest::randInt( rng ) % 10 - 5;
|
||||
pt.x = cvRound( center.x + radius*cos(angle*deg_to_rad));
|
||||
pt.y = cvRound( center.x - radius*sin(angle*deg_to_rad));
|
||||
radius += d_radius;
|
||||
angle += d_angle;
|
||||
cvSeqPush( seq, &pt );
|
||||
|
||||
max_x = MAX( max_x, pt.x );
|
||||
max_y = MAX( max_y, pt.y );
|
||||
|
||||
min_x = MIN( min_x, pt.x );
|
||||
min_y = MIN( min_y, pt.y );
|
||||
}
|
||||
|
||||
*d = (max_x - min_x)*(max_x - min_x) + (max_y - min_y)*(max_y - min_y);
|
||||
*Seq = seq;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int CV_ApproxPolyTest::check_slice( CvPoint StartPt, CvPoint EndPt,
|
||||
CvSeqReader* SrcReader, float Eps,
|
||||
int* _j, int Count )
|
||||
{
|
||||
///////////
|
||||
CvPoint Pt;
|
||||
///////////
|
||||
bool flag;
|
||||
double dy,dx;
|
||||
double A,B,C;
|
||||
double Sq;
|
||||
double sin_a = 0;
|
||||
double cos_a = 0;
|
||||
double d = 0;
|
||||
double dist;
|
||||
///////////
|
||||
int j, TotalErrors = 0;
|
||||
|
||||
////////////////////////////////
|
||||
if( SrcReader == NULL )
|
||||
{
|
||||
assert( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////// init line ////////////
|
||||
flag = true;
|
||||
|
||||
dx = (double)StartPt.x - (double)EndPt.x;
|
||||
dy = (double)StartPt.y - (double)EndPt.y;
|
||||
|
||||
if( ( dx == 0 ) && ( dy == 0 ) ) flag = false;
|
||||
else
|
||||
{
|
||||
A = -dy;
|
||||
B = dx;
|
||||
C = dy * (double)StartPt.x - dx * (double)StartPt.y;
|
||||
Sq = sqrt( A*A + B*B );
|
||||
|
||||
sin_a = B/Sq;
|
||||
cos_a = A/Sq;
|
||||
d = C/Sq;
|
||||
}
|
||||
|
||||
/////// find start point and check distance ////////
|
||||
for( j = *_j; j < Count; j++ )
|
||||
{
|
||||
CV_READ_SEQ_ELEM( Pt, *SrcReader );
|
||||
if( StartPt.x == Pt.x && StartPt.y == Pt.y ) break;
|
||||
else
|
||||
{
|
||||
if( flag ) dist = sin_a * Pt.y + cos_a * Pt.x - d;
|
||||
else dist = sqrt( (double)(EndPt.y - Pt.y)*(EndPt.y - Pt.y) + (EndPt.x - Pt.x)*(EndPt.x - Pt.x) );
|
||||
if( dist > Eps ) TotalErrors++;
|
||||
}
|
||||
}
|
||||
|
||||
*_j = j;
|
||||
|
||||
//return TotalErrors;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CV_ApproxPolyTest::check( CvSeq* SrcSeq, CvSeq* DstSeq, float Eps )
|
||||
{
|
||||
//////////
|
||||
CvSeqReader DstReader;
|
||||
CvSeqReader SrcReader;
|
||||
CvPoint StartPt, EndPt;
|
||||
///////////
|
||||
int TotalErrors = 0;
|
||||
///////////
|
||||
int Count;
|
||||
int i,j;
|
||||
|
||||
assert( SrcSeq && DstSeq );
|
||||
|
||||
////////// init ////////////////////
|
||||
Count = SrcSeq->total;
|
||||
|
||||
cvStartReadSeq( DstSeq, &DstReader, 0 );
|
||||
cvStartReadSeq( SrcSeq, &SrcReader, 0 );
|
||||
|
||||
CV_READ_SEQ_ELEM( StartPt, DstReader );
|
||||
for( i = 0 ; i < Count ; )
|
||||
{
|
||||
CV_READ_SEQ_ELEM( EndPt, SrcReader );
|
||||
i++;
|
||||
if( StartPt.x == EndPt.x && StartPt.y == EndPt.y ) break;
|
||||
}
|
||||
|
||||
///////// start ////////////////
|
||||
for( i = 1, j = 0 ; i <= DstSeq->total ; )
|
||||
{
|
||||
///////// read slice ////////////
|
||||
EndPt.x = StartPt.x;
|
||||
EndPt.y = StartPt.y;
|
||||
CV_READ_SEQ_ELEM( StartPt, DstReader );
|
||||
i++;
|
||||
|
||||
TotalErrors += check_slice( StartPt, EndPt, &SrcReader, Eps, &j, Count );
|
||||
|
||||
if( j > Count )
|
||||
{
|
||||
TotalErrors++;
|
||||
return TotalErrors;
|
||||
} //if( !flag )
|
||||
|
||||
} // for( int i = 0 ; i < DstSeq->total ; i++ )
|
||||
|
||||
return TotalErrors;
|
||||
}
|
||||
|
||||
|
||||
//extern CvTestContourGenerator cvTsTestContours[];
|
||||
|
||||
void CV_ApproxPolyTest::run( int /*start_from*/ )
|
||||
{
|
||||
int code = cvtest::TS::OK;
|
||||
CvMemStorage* storage = 0;
|
||||
////////////// Variables ////////////////
|
||||
int IntervalsCount = 10;
|
||||
///////////
|
||||
//CvTestContourGenerator Cont;
|
||||
CvSeq* SrcSeq = NULL;
|
||||
CvSeq* DstSeq;
|
||||
int iDiam;
|
||||
float dDiam, Eps, EpsStep;
|
||||
|
||||
for( int i = 0; i < 30; i++ )
|
||||
{
|
||||
CvMemStoragePos pos;
|
||||
|
||||
ts->update_context( this, i, false );
|
||||
|
||||
///////////////////// init contour /////////
|
||||
dDiam = 0;
|
||||
while( sqrt(dDiam) / IntervalsCount == 0 )
|
||||
{
|
||||
if( storage != 0 )
|
||||
cvReleaseMemStorage(&storage);
|
||||
|
||||
storage = cvCreateMemStorage( 0 );
|
||||
if( get_contour( 0, &SrcSeq, &iDiam, storage ) )
|
||||
dDiam = (float)iDiam;
|
||||
}
|
||||
dDiam = (float)sqrt( dDiam );
|
||||
|
||||
storage = SrcSeq->storage;
|
||||
|
||||
////////////////// test /////////////
|
||||
EpsStep = dDiam / IntervalsCount ;
|
||||
for( Eps = EpsStep ; Eps < dDiam ; Eps += EpsStep )
|
||||
{
|
||||
cvSaveMemStoragePos( storage, &pos );
|
||||
|
||||
////////// call function ////////////
|
||||
DstSeq = cvApproxPoly( SrcSeq, SrcSeq->header_size, storage,
|
||||
CV_POLY_APPROX_DP, Eps );
|
||||
|
||||
if( DstSeq == NULL )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG,
|
||||
"cvApproxPoly returned NULL for contour #%d, espilon = %g\n", i, Eps );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
goto _exit_;
|
||||
} // if( DstSeq == NULL )
|
||||
|
||||
code = check( SrcSeq, DstSeq, Eps );
|
||||
if( code != 0 )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG,
|
||||
"Incorrect result for the contour #%d approximated with epsilon=%g\n", i, Eps );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
goto _exit_;
|
||||
}
|
||||
|
||||
cvRestoreMemStoragePos( storage, &pos );
|
||||
} // for( Eps = EpsStep ; Eps <= Diam ; Eps += EpsStep )
|
||||
|
||||
///////////// free memory ///////////////////
|
||||
cvReleaseMemStorage(&storage);
|
||||
} // for( int i = 0; NULL != ( Cont = Contours[i] ) ; i++ )
|
||||
|
||||
_exit_:
|
||||
cvReleaseMemStorage(&storage);
|
||||
|
||||
if( code < 0 )
|
||||
ts->set_failed_test_info( code );
|
||||
}
|
||||
|
||||
TEST(Imgproc_ApproxPoly, accuracy) { CV_ApproxPolyTest test; test.safe_run(); }
|
||||
|
||||
287
modules/imgproc/test/test_canny.cpp
Normal file
287
modules/imgproc/test/test_canny.cpp
Normal file
@@ -0,0 +1,287 @@
|
||||
/*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_CannyTest : public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
CV_CannyTest();
|
||||
|
||||
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 );
|
||||
int prepare_test_case( int test_case_idx );
|
||||
void run_func();
|
||||
void prepare_to_validation( int );
|
||||
int validate_test_results( int /*test_case_idx*/ );
|
||||
|
||||
int aperture_size;
|
||||
bool use_true_gradient;
|
||||
double threshold1, threshold2;
|
||||
bool test_cpp;
|
||||
};
|
||||
|
||||
|
||||
CV_CannyTest::CV_CannyTest()
|
||||
{
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[OUTPUT].push_back(NULL);
|
||||
test_array[REF_OUTPUT].push_back(NULL);
|
||||
element_wise_relative_error = true;
|
||||
aperture_size = 0;
|
||||
use_true_gradient = false;
|
||||
threshold1 = threshold2 = 0;
|
||||
|
||||
test_cpp = false;
|
||||
}
|
||||
|
||||
|
||||
void CV_CannyTest::get_test_array_types_and_sizes( int test_case_idx,
|
||||
vector<vector<Size> >& sizes,
|
||||
vector<vector<int> >& types )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
double thresh_range;
|
||||
|
||||
cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
|
||||
types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_8U;
|
||||
|
||||
aperture_size = cvtest::randInt(rng) % 2 ? 5 : 3;
|
||||
thresh_range = aperture_size == 3 ? 300 : 1000;
|
||||
|
||||
threshold1 = cvtest::randReal(rng)*thresh_range;
|
||||
threshold2 = cvtest::randReal(rng)*thresh_range*0.3;
|
||||
|
||||
if( cvtest::randInt(rng) % 2 )
|
||||
CV_SWAP( threshold1, threshold2, thresh_range );
|
||||
|
||||
use_true_gradient = cvtest::randInt(rng) % 2 != 0;
|
||||
test_cpp = (cvtest::randInt(rng) & 256) == 0;
|
||||
}
|
||||
|
||||
|
||||
int CV_CannyTest::prepare_test_case( int test_case_idx )
|
||||
{
|
||||
int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
|
||||
if( code > 0 )
|
||||
{
|
||||
Mat& src = test_mat[INPUT][0];
|
||||
GaussianBlur(src, src, Size(11, 11), 5, 5);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
double CV_CannyTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void CV_CannyTest::run_func()
|
||||
{
|
||||
if(!test_cpp)
|
||||
cvCanny( test_array[INPUT][0], test_array[OUTPUT][0], threshold1, threshold2,
|
||||
aperture_size + (use_true_gradient ? CV_CANNY_L2_GRADIENT : 0));
|
||||
else
|
||||
{
|
||||
cv::Mat _out = cv::cvarrToMat(test_array[OUTPUT][0]);
|
||||
cv::Canny(cv::cvarrToMat(test_array[INPUT][0]), _out, threshold1, threshold2,
|
||||
aperture_size + (use_true_gradient ? CV_CANNY_L2_GRADIENT : 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cannyFollow( int x, int y, float lowThreshold, const Mat& mag, Mat& dst )
|
||||
{
|
||||
static const int ofs[][2] = {{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}};
|
||||
int i;
|
||||
|
||||
dst.at<uchar>(y, x) = (uchar)255;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
int x1 = x + ofs[i][0];
|
||||
int y1 = y + ofs[i][1];
|
||||
if( (unsigned)x1 < (unsigned)mag.cols &&
|
||||
(unsigned)y1 < (unsigned)mag.rows &&
|
||||
mag.at<float>(y1, x1) > lowThreshold &&
|
||||
!dst.at<uchar>(y1, x1) )
|
||||
cannyFollow( x1, y1, lowThreshold, mag, dst );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_Canny( const Mat& src, Mat& dst,
|
||||
double threshold1, double threshold2,
|
||||
int aperture_size, bool use_true_gradient )
|
||||
{
|
||||
int m = aperture_size;
|
||||
Point anchor(m/2, m/2);
|
||||
const double tan_pi_8 = tan(CV_PI/8.);
|
||||
const double tan_3pi_8 = tan(CV_PI*3/8);
|
||||
float lowThreshold = (float)MIN(threshold1, threshold2);
|
||||
float highThreshold = (float)MAX(threshold1, threshold2);
|
||||
|
||||
int x, y, width = src.cols, height = src.rows;
|
||||
|
||||
Mat dxkernel = cvtest::calcSobelKernel2D( 1, 0, m, 0 );
|
||||
Mat dykernel = cvtest::calcSobelKernel2D( 0, 1, m, 0 );
|
||||
Mat dx, dy, mag(height, width, CV_32F);
|
||||
cvtest::filter2D(src, dx, CV_16S, dxkernel, anchor, 0, BORDER_REPLICATE);
|
||||
cvtest::filter2D(src, dy, CV_16S, dykernel, anchor, 0, BORDER_REPLICATE);
|
||||
|
||||
// calc gradient magnitude
|
||||
for( y = 0; y < height; y++ )
|
||||
{
|
||||
for( x = 0; x < width; x++ )
|
||||
{
|
||||
int dxval = dx.at<short>(y, x), dyval = dy.at<short>(y, x);
|
||||
mag.at<float>(y, x) = use_true_gradient ?
|
||||
(float)sqrt((double)(dxval*dxval + dyval*dyval)) :
|
||||
(float)(fabs(dxval) + fabs(dyval));
|
||||
}
|
||||
}
|
||||
|
||||
// calc gradient direction, do nonmaxima suppression
|
||||
for( y = 0; y < height; y++ )
|
||||
{
|
||||
for( x = 0; x < width; x++ )
|
||||
{
|
||||
|
||||
float a = mag.at<float>(y, x), b = 0, c = 0;
|
||||
int y1 = 0, y2 = 0, x1 = 0, x2 = 0;
|
||||
|
||||
if( a <= lowThreshold )
|
||||
continue;
|
||||
|
||||
int dxval = dx.at<short>(y, x);
|
||||
int dyval = dy.at<short>(y, x);
|
||||
|
||||
double tg = dxval ? (double)dyval/dxval : DBL_MAX*CV_SIGN(dyval);
|
||||
|
||||
if( fabs(tg) < tan_pi_8 )
|
||||
{
|
||||
y1 = y2 = y; x1 = x + 1; x2 = x - 1;
|
||||
}
|
||||
else if( tan_pi_8 <= tg && tg <= tan_3pi_8 )
|
||||
{
|
||||
y1 = y + 1; y2 = y - 1; x1 = x + 1; x2 = x - 1;
|
||||
}
|
||||
else if( -tan_3pi_8 <= tg && tg <= -tan_pi_8 )
|
||||
{
|
||||
y1 = y - 1; y2 = y + 1; x1 = x + 1; x2 = x - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( fabs(tg) > tan_3pi_8 );
|
||||
x1 = x2 = x; y1 = y + 1; y2 = y - 1;
|
||||
}
|
||||
|
||||
if( (unsigned)y1 < (unsigned)height && (unsigned)x1 < (unsigned)width )
|
||||
b = (float)fabs(mag.at<float>(y1, x1));
|
||||
|
||||
if( (unsigned)y2 < (unsigned)height && (unsigned)x2 < (unsigned)width )
|
||||
c = (float)fabs(mag.at<float>(y2, x2));
|
||||
|
||||
if( (a > b || (a == b && ((x1 == x+1 && y1 == y) || (x1 == x && y1 == y+1)))) && a > c )
|
||||
;
|
||||
else
|
||||
mag.at<float>(y, x) = -a;
|
||||
}
|
||||
}
|
||||
|
||||
dst = Scalar::all(0);
|
||||
|
||||
// hysteresis threshold
|
||||
for( y = 0; y < height; y++ )
|
||||
{
|
||||
for( x = 0; x < width; x++ )
|
||||
if( mag.at<float>(y, x) > highThreshold && !dst.at<uchar>(y, x) )
|
||||
cannyFollow( x, y, lowThreshold, mag, dst );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CV_CannyTest::prepare_to_validation( int )
|
||||
{
|
||||
Mat src = test_mat[INPUT][0], dst = test_mat[REF_OUTPUT][0];
|
||||
test_Canny( src, dst, threshold1, threshold2, aperture_size, use_true_gradient );
|
||||
}
|
||||
|
||||
|
||||
int CV_CannyTest::validate_test_results( int test_case_idx )
|
||||
{
|
||||
int code = cvtest::TS::OK, nz0;
|
||||
prepare_to_validation(test_case_idx);
|
||||
|
||||
double err = cvtest::norm(test_mat[OUTPUT][0], test_mat[REF_OUTPUT][0], CV_L1);
|
||||
if( err == 0 )
|
||||
return code;
|
||||
|
||||
if( err != cvRound(err) || cvRound(err)%255 != 0 )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "Some of the pixels, produced by Canny, are not 0's or 255's; the difference is %g\n", err );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return code;
|
||||
}
|
||||
|
||||
nz0 = cvRound(cvtest::norm(test_mat[REF_OUTPUT][0], CV_L1)/255);
|
||||
err = (err/255/MAX(nz0,100))*100;
|
||||
if( err > 1 )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "Too high percentage of non-matching edge pixels = %g%%\n", err);
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
TEST(Imgproc_Canny, accuracy) { CV_CannyTest test; test.safe_run(); }
|
||||
|
||||
/* End of file. */
|
||||
1645
modules/imgproc/test/test_color.cpp
Normal file
1645
modules/imgproc/test/test_color.cpp
Normal file
File diff suppressed because it is too large
Load Diff
393
modules/imgproc/test/test_contours.cpp
Normal file
393
modules/imgproc/test/test_contours.cpp
Normal file
@@ -0,0 +1,393 @@
|
||||
/*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_FindContourTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
enum { NUM_IMG = 4 };
|
||||
|
||||
CV_FindContourTest();
|
||||
~CV_FindContourTest();
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
int read_params( CvFileStorage* fs );
|
||||
int prepare_test_case( int test_case_idx );
|
||||
int validate_test_results( int test_case_idx );
|
||||
void run_func();
|
||||
|
||||
int min_blob_size, max_blob_size;
|
||||
int blob_count, max_log_blob_count;
|
||||
int retr_mode, approx_method;
|
||||
|
||||
int min_log_img_size, max_log_img_size;
|
||||
CvSize img_size;
|
||||
int count, count2;
|
||||
|
||||
IplImage* img[NUM_IMG];
|
||||
CvMemStorage* storage;
|
||||
CvSeq *contours, *contours2, *chain;
|
||||
};
|
||||
|
||||
|
||||
CV_FindContourTest::CV_FindContourTest()
|
||||
{
|
||||
int i;
|
||||
|
||||
test_case_count = 300;
|
||||
min_blob_size = 1;
|
||||
max_blob_size = 50;
|
||||
max_log_blob_count = 10;
|
||||
|
||||
min_log_img_size = 3;
|
||||
max_log_img_size = 10;
|
||||
|
||||
for( i = 0; i < NUM_IMG; i++ )
|
||||
img[i] = 0;
|
||||
|
||||
storage = 0;
|
||||
}
|
||||
|
||||
|
||||
CV_FindContourTest::~CV_FindContourTest()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
void CV_FindContourTest::clear()
|
||||
{
|
||||
int i;
|
||||
|
||||
cvtest::BaseTest::clear();
|
||||
|
||||
for( i = 0; i < NUM_IMG; i++ )
|
||||
cvReleaseImage( &img[i] );
|
||||
|
||||
cvReleaseMemStorage( &storage );
|
||||
}
|
||||
|
||||
|
||||
int CV_FindContourTest::read_params( CvFileStorage* fs )
|
||||
{
|
||||
int t;
|
||||
int code = cvtest::BaseTest::read_params( fs );
|
||||
|
||||
if( code < 0 )
|
||||
return code;
|
||||
|
||||
min_blob_size = cvReadInt( find_param( fs, "min_blob_size" ), min_blob_size );
|
||||
max_blob_size = cvReadInt( find_param( fs, "max_blob_size" ), max_blob_size );
|
||||
max_log_blob_count = cvReadInt( find_param( fs, "max_log_blob_count" ), max_log_blob_count );
|
||||
min_log_img_size = cvReadInt( find_param( fs, "min_log_img_size" ), min_log_img_size );
|
||||
max_log_img_size = cvReadInt( find_param( fs, "max_log_img_size" ), max_log_img_size );
|
||||
|
||||
min_blob_size = cvtest::clipInt( min_blob_size, 1, 100 );
|
||||
max_blob_size = cvtest::clipInt( max_blob_size, 1, 100 );
|
||||
|
||||
if( min_blob_size > max_blob_size )
|
||||
CV_SWAP( min_blob_size, max_blob_size, t );
|
||||
|
||||
max_log_blob_count = cvtest::clipInt( max_log_blob_count, 1, 10 );
|
||||
|
||||
min_log_img_size = cvtest::clipInt( min_log_img_size, 1, 10 );
|
||||
max_log_img_size = cvtest::clipInt( max_log_img_size, 1, 10 );
|
||||
|
||||
if( min_log_img_size > max_log_img_size )
|
||||
CV_SWAP( min_log_img_size, max_log_img_size, t );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cvTsGenerateBlobImage( IplImage* img, int min_blob_size, int max_blob_size,
|
||||
int blob_count, int min_brightness, int max_brightness,
|
||||
RNG& rng )
|
||||
{
|
||||
int i;
|
||||
CvSize size;
|
||||
|
||||
assert( img->depth == IPL_DEPTH_8U && img->nChannels == 1 );
|
||||
|
||||
cvZero( img );
|
||||
|
||||
// keep the border clear
|
||||
cvSetImageROI( img, cvRect(1,1,img->width-2,img->height-2) );
|
||||
size = cvGetSize( img );
|
||||
|
||||
for( i = 0; i < blob_count; i++ )
|
||||
{
|
||||
CvPoint center;
|
||||
CvSize axes;
|
||||
int angle = cvtest::randInt(rng) % 180;
|
||||
int brightness = cvtest::randInt(rng) %
|
||||
(max_brightness - min_brightness) + min_brightness;
|
||||
center.x = cvtest::randInt(rng) % size.width;
|
||||
center.y = cvtest::randInt(rng) % size.height;
|
||||
|
||||
axes.width = (cvtest::randInt(rng) %
|
||||
(max_blob_size - min_blob_size) + min_blob_size + 1)/2;
|
||||
axes.height = (cvtest::randInt(rng) %
|
||||
(max_blob_size - min_blob_size) + min_blob_size + 1)/2;
|
||||
|
||||
cvEllipse( img, center, axes, angle, 0, 360, cvScalar(brightness), CV_FILLED );
|
||||
}
|
||||
|
||||
cvResetImageROI( img );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cvTsMarkContours( IplImage* img, int val )
|
||||
{
|
||||
int i, j;
|
||||
int step = img->widthStep;
|
||||
|
||||
assert( img->depth == IPL_DEPTH_8U && img->nChannels == 1 && (val&1) != 0);
|
||||
|
||||
for( i = 1; i < img->height - 1; i++ )
|
||||
for( j = 1; j < img->width - 1; j++ )
|
||||
{
|
||||
uchar* t = (uchar*)(img->imageData + img->widthStep*i + j);
|
||||
if( *t == 1 && (t[-step] == 0 || t[-1] == 0 || t[1] == 0 || t[step] == 0))
|
||||
*t = (uchar)val;
|
||||
}
|
||||
|
||||
cvThreshold( img, img, val - 2, val, CV_THRESH_BINARY );
|
||||
}
|
||||
|
||||
|
||||
int CV_FindContourTest::prepare_test_case( int test_case_idx )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
const int min_brightness = 0, max_brightness = 2;
|
||||
int i, code = cvtest::BaseTest::prepare_test_case( test_case_idx );
|
||||
|
||||
if( code < 0 )
|
||||
return code;
|
||||
|
||||
clear();
|
||||
|
||||
blob_count = cvRound(exp(cvtest::randReal(rng)*max_log_blob_count*CV_LOG2));
|
||||
|
||||
img_size.width = cvRound(exp((cvtest::randReal(rng)*
|
||||
(max_log_img_size - min_log_img_size) + min_log_img_size)*CV_LOG2));
|
||||
img_size.height = cvRound(exp((cvtest::randReal(rng)*
|
||||
(max_log_img_size - min_log_img_size) + min_log_img_size)*CV_LOG2));
|
||||
|
||||
approx_method = cvtest::randInt( rng ) % 4 + 1;
|
||||
retr_mode = cvtest::randInt( rng ) % 4;
|
||||
|
||||
storage = cvCreateMemStorage( 1 << 10 );
|
||||
|
||||
for( i = 0; i < NUM_IMG; i++ )
|
||||
img[i] = cvCreateImage( img_size, 8, 1 );
|
||||
|
||||
cvTsGenerateBlobImage( img[0], min_blob_size, max_blob_size,
|
||||
blob_count, min_brightness, max_brightness, rng );
|
||||
|
||||
cvCopy( img[0], img[1] );
|
||||
cvCopy( img[0], img[2] );
|
||||
|
||||
cvTsMarkContours( img[1], 255 );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void CV_FindContourTest::run_func()
|
||||
{
|
||||
contours = contours2 = chain = 0;
|
||||
count = cvFindContours( img[2], storage, &contours, sizeof(CvContour), retr_mode, approx_method );
|
||||
|
||||
cvZero( img[3] );
|
||||
|
||||
if( contours && retr_mode != CV_RETR_EXTERNAL && approx_method < CV_CHAIN_APPROX_TC89_L1 )
|
||||
cvDrawContours( img[3], contours, cvScalar(255), cvScalar(255), INT_MAX, -1 );
|
||||
|
||||
cvCopy( img[0], img[2] );
|
||||
|
||||
count2 = cvFindContours( img[2], storage, &chain, sizeof(CvChain), retr_mode, CV_CHAIN_CODE );
|
||||
|
||||
if( chain )
|
||||
contours2 = cvApproxChains( chain, storage, approx_method, 0, 0, 1 );
|
||||
|
||||
cvZero( img[2] );
|
||||
|
||||
if( contours && retr_mode != CV_RETR_EXTERNAL && approx_method < CV_CHAIN_APPROX_TC89_L1 )
|
||||
cvDrawContours( img[2], contours2, cvScalar(255), cvScalar(255), INT_MAX );
|
||||
}
|
||||
|
||||
|
||||
// the whole testing is done here, run_func() is not utilized in this test
|
||||
int CV_FindContourTest::validate_test_results( int /*test_case_idx*/ )
|
||||
{
|
||||
int i, code = cvtest::TS::OK;
|
||||
|
||||
cvCmpS( img[0], 0, img[0], CV_CMP_GT );
|
||||
|
||||
if( count != count2 )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "The number of contours retrieved with different "
|
||||
"approximation methods is not the same\n"
|
||||
"(%d contour(s) for method %d vs %d contour(s) for method %d)\n",
|
||||
count, approx_method, count2, CV_CHAIN_CODE );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
}
|
||||
|
||||
if( retr_mode != CV_RETR_EXTERNAL && approx_method < CV_CHAIN_APPROX_TC89_L1 )
|
||||
{
|
||||
Mat _img[4];
|
||||
for( int i = 0; i < 4; i++ )
|
||||
_img[i] = cvarrToMat(img[i]);
|
||||
|
||||
code = cvtest::cmpEps2(ts, _img[0], _img[3], 0, true, "Comparing original image with the map of filled contours" );
|
||||
|
||||
if( code < 0 )
|
||||
goto _exit_;
|
||||
|
||||
code = cvtest::cmpEps2( ts, _img[1], _img[2], 0, true,
|
||||
"Comparing contour outline vs manually produced edge map" );
|
||||
|
||||
if( code < 0 )
|
||||
goto _exit_;
|
||||
}
|
||||
|
||||
if( contours )
|
||||
{
|
||||
CvTreeNodeIterator iterator1;
|
||||
CvTreeNodeIterator iterator2;
|
||||
int count3;
|
||||
|
||||
for( i = 0; i < 2; i++ )
|
||||
{
|
||||
CvTreeNodeIterator iterator;
|
||||
cvInitTreeNodeIterator( &iterator, i == 0 ? contours : contours2, INT_MAX );
|
||||
|
||||
for( count3 = 0; cvNextTreeNode( &iterator ) != 0; count3++ )
|
||||
;
|
||||
|
||||
if( count3 != count )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG,
|
||||
"The returned number of retrieved contours (using the approx_method = %d) does not match\n"
|
||||
"to the actual number of contours in the tree/list (returned %d, actual %d)\n",
|
||||
i == 0 ? approx_method : 0, count, count3 );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
goto _exit_;
|
||||
}
|
||||
}
|
||||
|
||||
cvInitTreeNodeIterator( &iterator1, contours, INT_MAX );
|
||||
cvInitTreeNodeIterator( &iterator2, contours2, INT_MAX );
|
||||
|
||||
for( count3 = 0; count3 < count; count3++ )
|
||||
{
|
||||
CvSeq* seq1 = (CvSeq*)cvNextTreeNode( &iterator1 );
|
||||
CvSeq* seq2 = (CvSeq*)cvNextTreeNode( &iterator2 );
|
||||
CvSeqReader reader1;
|
||||
CvSeqReader reader2;
|
||||
|
||||
if( !seq1 || !seq2 )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG,
|
||||
"There are NULL pointers in the original contour tree or the "
|
||||
"tree produced by cvApproxChains\n" );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
goto _exit_;
|
||||
}
|
||||
|
||||
cvStartReadSeq( seq1, &reader1 );
|
||||
cvStartReadSeq( seq2, &reader2 );
|
||||
|
||||
if( seq1->total != seq2->total )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG,
|
||||
"The original contour #%d has %d points, while the corresponding contour has %d point\n",
|
||||
count3, seq1->total, seq2->total );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
goto _exit_;
|
||||
}
|
||||
|
||||
for( i = 0; i < seq1->total; i++ )
|
||||
{
|
||||
CvPoint pt1;
|
||||
CvPoint pt2;
|
||||
|
||||
CV_READ_SEQ_ELEM( pt1, reader1 );
|
||||
CV_READ_SEQ_ELEM( pt2, reader2 );
|
||||
|
||||
if( pt1.x != pt2.x || pt1.y != pt2.y )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG,
|
||||
"The point #%d in the contour #%d is different from the corresponding point "
|
||||
"in the approximated chain ((%d,%d) vs (%d,%d)", count3, i, pt1.x, pt1.y, pt2.x, pt2.y );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
goto _exit_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_exit_:
|
||||
if( code < 0 )
|
||||
{
|
||||
#if 0
|
||||
cvNamedWindow( "test", 0 );
|
||||
cvShowImage( "test", img[0] );
|
||||
cvWaitKey();
|
||||
#endif
|
||||
ts->set_failed_test_info( code );
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
TEST(Imgproc_FindContours, accuracy) { CV_FindContourTest test; test.safe_run(); }
|
||||
|
||||
/* End of file. */
|
||||
1583
modules/imgproc/test/test_convhull.cpp
Normal file
1583
modules/imgproc/test/test_convhull.cpp
Normal file
File diff suppressed because it is too large
Load Diff
297
modules/imgproc/test/test_distancetransform.cpp
Normal file
297
modules/imgproc/test/test_distancetransform.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
/*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_DisTransTest : public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
CV_DisTransTest();
|
||||
|
||||
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 );
|
||||
|
||||
void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
|
||||
int prepare_test_case( int test_case_idx );
|
||||
|
||||
int mask_size;
|
||||
int dist_type;
|
||||
int fill_labels;
|
||||
float mask[3];
|
||||
};
|
||||
|
||||
|
||||
CV_DisTransTest::CV_DisTransTest()
|
||||
{
|
||||
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);
|
||||
optional_mask = false;
|
||||
element_wise_relative_error = true;
|
||||
}
|
||||
|
||||
|
||||
void CV_DisTransTest::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[OUTPUT][0] = types[REF_OUTPUT][0] = CV_32FC1;
|
||||
types[OUTPUT][1] = types[REF_OUTPUT][1] = CV_32SC1;
|
||||
|
||||
if( cvtest::randInt(rng) & 1 )
|
||||
{
|
||||
mask_size = 3;
|
||||
dist_type = cvtest::randInt(rng) % 4;
|
||||
dist_type = dist_type == 0 ? CV_DIST_C : dist_type == 1 ? CV_DIST_L1 :
|
||||
dist_type == 2 ? CV_DIST_L2 : CV_DIST_USER;
|
||||
}
|
||||
else
|
||||
{
|
||||
mask_size = 5;
|
||||
dist_type = cvtest::randInt(rng) % 10;
|
||||
dist_type = dist_type == 0 ? CV_DIST_C : dist_type == 1 ? CV_DIST_L1 :
|
||||
dist_type < 6 ? CV_DIST_L2 : CV_DIST_USER;
|
||||
}
|
||||
|
||||
// for now, check only the "labeled" distance transform mode
|
||||
fill_labels = 0;
|
||||
|
||||
if( !fill_labels )
|
||||
sizes[OUTPUT][1] = sizes[REF_OUTPUT][1] = cvSize(0,0);
|
||||
|
||||
if( dist_type == CV_DIST_USER )
|
||||
{
|
||||
mask[0] = (float)(1.1 - cvtest::randReal(rng)*0.2);
|
||||
mask[1] = (float)(1.9 - cvtest::randReal(rng)*0.8);
|
||||
mask[2] = (float)(3. - cvtest::randReal(rng));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double CV_DisTransTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
|
||||
{
|
||||
Size sz = test_mat[INPUT][0].size();
|
||||
return dist_type == CV_DIST_C || dist_type == CV_DIST_L1 ? 0 : 0.01*MAX(sz.width, sz.height);
|
||||
}
|
||||
|
||||
|
||||
void CV_DisTransTest::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(0);
|
||||
high = Scalar::all(10);
|
||||
}
|
||||
}
|
||||
|
||||
int CV_DisTransTest::prepare_test_case( int test_case_idx )
|
||||
{
|
||||
int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
|
||||
if( code > 0 )
|
||||
{
|
||||
// the function's response to an "all-nonzeros" image is not determined,
|
||||
// so put at least one zero point
|
||||
Mat& mat = test_mat[INPUT][0];
|
||||
RNG& rng = ts->get_rng();
|
||||
int i = cvtest::randInt(rng) % mat.rows;
|
||||
int j = cvtest::randInt(rng) % mat.cols;
|
||||
mat.at<uchar>(i,j) = 0;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
void CV_DisTransTest::run_func()
|
||||
{
|
||||
cvDistTransform( test_array[INPUT][0], test_array[OUTPUT][0], dist_type, mask_size,
|
||||
dist_type == CV_DIST_USER ? mask : 0, test_array[OUTPUT][1] );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cvTsDistTransform( const CvMat* _src, CvMat* _dst, int dist_type,
|
||||
int mask_size, float* _mask, CvMat* /*_labels*/ )
|
||||
{
|
||||
int i, j, k;
|
||||
int width = _src->cols, height = _src->rows;
|
||||
const float init_val = 1e6;
|
||||
float mask[3];
|
||||
CvMat* temp;
|
||||
int ofs[16];
|
||||
float delta[16];
|
||||
int tstep, count;
|
||||
|
||||
assert( mask_size == 3 || mask_size == 5 );
|
||||
|
||||
if( dist_type == CV_DIST_USER )
|
||||
memcpy( mask, _mask, sizeof(mask) );
|
||||
else if( dist_type == CV_DIST_C )
|
||||
{
|
||||
mask_size = 3;
|
||||
mask[0] = mask[1] = 1.f;
|
||||
}
|
||||
else if( dist_type == CV_DIST_L1 )
|
||||
{
|
||||
mask_size = 3;
|
||||
mask[0] = 1.f;
|
||||
mask[1] = 2.f;
|
||||
}
|
||||
else if( mask_size == 3 )
|
||||
{
|
||||
mask[0] = 0.955f;
|
||||
mask[1] = 1.3693f;
|
||||
}
|
||||
else
|
||||
{
|
||||
mask[0] = 1.0f;
|
||||
mask[1] = 1.4f;
|
||||
mask[2] = 2.1969f;
|
||||
}
|
||||
|
||||
temp = cvCreateMat( height + mask_size-1, width + mask_size-1, CV_32F );
|
||||
tstep = temp->step / sizeof(float);
|
||||
|
||||
if( mask_size == 3 )
|
||||
{
|
||||
count = 4;
|
||||
ofs[0] = -1; delta[0] = mask[0];
|
||||
ofs[1] = -tstep-1; delta[1] = mask[1];
|
||||
ofs[2] = -tstep; delta[2] = mask[0];
|
||||
ofs[3] = -tstep+1; delta[3] = mask[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 8;
|
||||
ofs[0] = -1; delta[0] = mask[0];
|
||||
ofs[1] = -tstep-2; delta[1] = mask[2];
|
||||
ofs[2] = -tstep-1; delta[2] = mask[1];
|
||||
ofs[3] = -tstep; delta[3] = mask[0];
|
||||
ofs[4] = -tstep+1; delta[4] = mask[1];
|
||||
ofs[5] = -tstep+2; delta[5] = mask[2];
|
||||
ofs[6] = -tstep*2-1; delta[6] = mask[2];
|
||||
ofs[7] = -tstep*2+1; delta[7] = mask[2];
|
||||
}
|
||||
|
||||
for( i = 0; i < mask_size/2; i++ )
|
||||
{
|
||||
float* t0 = (float*)(temp->data.ptr + i*temp->step);
|
||||
float* t1 = (float*)(temp->data.ptr + (temp->rows - i - 1)*temp->step);
|
||||
|
||||
for( j = 0; j < width + mask_size - 1; j++ )
|
||||
t0[j] = t1[j] = init_val;
|
||||
}
|
||||
|
||||
for( i = 0; i < height; i++ )
|
||||
{
|
||||
uchar* s = _src->data.ptr + i*_src->step;
|
||||
float* tmp = (float*)(temp->data.ptr + temp->step*(i + (mask_size/2))) + (mask_size/2);
|
||||
|
||||
for( j = 0; j < mask_size/2; j++ )
|
||||
tmp[-j-1] = tmp[j + width] = init_val;
|
||||
|
||||
for( j = 0; j < width; j++ )
|
||||
{
|
||||
if( s[j] == 0 )
|
||||
tmp[j] = 0;
|
||||
else
|
||||
{
|
||||
float min_dist = init_val;
|
||||
for( k = 0; k < count; k++ )
|
||||
{
|
||||
float t = tmp[j+ofs[k]] + delta[k];
|
||||
if( min_dist > t )
|
||||
min_dist = t;
|
||||
}
|
||||
tmp[j] = min_dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( i = height - 1; i >= 0; i-- )
|
||||
{
|
||||
float* d = (float*)(_dst->data.ptr + i*_dst->step);
|
||||
float* tmp = (float*)(temp->data.ptr + temp->step*(i + (mask_size/2))) + (mask_size/2);
|
||||
|
||||
for( j = width - 1; j >= 0; j-- )
|
||||
{
|
||||
float min_dist = tmp[j];
|
||||
if( min_dist > mask[0] )
|
||||
{
|
||||
for( k = 0; k < count; k++ )
|
||||
{
|
||||
float t = tmp[j-ofs[k]] + delta[k];
|
||||
if( min_dist > t )
|
||||
min_dist = t;
|
||||
}
|
||||
tmp[j] = min_dist;
|
||||
}
|
||||
d[j] = min_dist;
|
||||
}
|
||||
}
|
||||
|
||||
cvReleaseMat( &temp );
|
||||
}
|
||||
|
||||
|
||||
void CV_DisTransTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
CvMat _input = test_mat[INPUT][0], _output = test_mat[REF_OUTPUT][0];
|
||||
|
||||
cvTsDistTransform( &_input, &_output, dist_type, mask_size, mask, 0 );
|
||||
}
|
||||
|
||||
|
||||
TEST(Imgproc_DistanceTransform, accuracy) { CV_DisTransTest test; test.safe_run(); }
|
||||
|
||||
|
||||
95
modules/imgproc/test/test_emd.cpp
Normal file
95
modules/imgproc/test/test_emd.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/*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;
|
||||
|
||||
/*////////////////////// emd_test /////////////////////////*/
|
||||
|
||||
class CV_EMDTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
CV_EMDTest();
|
||||
protected:
|
||||
void run(int);
|
||||
};
|
||||
|
||||
|
||||
CV_EMDTest::CV_EMDTest()
|
||||
{
|
||||
}
|
||||
|
||||
void CV_EMDTest::run( int )
|
||||
{
|
||||
int code = cvtest::TS::OK;
|
||||
const double success_error_level = 1e-6;
|
||||
#define M 10000
|
||||
double emd0 = 2460./210;
|
||||
static float cost[] =
|
||||
{
|
||||
16, 16, 13, 22, 17,
|
||||
14, 14, 13, 19, 15,
|
||||
19, 19, 20, 23, M,
|
||||
M , 0, M, 0, 0
|
||||
};
|
||||
static float w1[] = { 50, 60, 50, 50 },
|
||||
w2[] = { 30, 20, 70, 30, 60 };
|
||||
Mat _w1(4, 1, CV_32F, w1);
|
||||
Mat _w2(5, 1, CV_32F, w2);
|
||||
Mat _cost(_w1.rows, _w2.rows, CV_32F, cost);
|
||||
|
||||
float emd = EMD( _w1, _w2, -1, _cost );
|
||||
if( fabs( emd - emd0 ) > success_error_level*emd0 )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG,
|
||||
"The computed distance is %.2f, while it should be %.2f\n", emd, emd0 );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
}
|
||||
|
||||
if( code < 0 )
|
||||
ts->set_failed_test_info( code );
|
||||
}
|
||||
|
||||
TEST(Imgproc_EMD, regression) { CV_EMDTest test; test.safe_run(); }
|
||||
|
||||
/* End of file. */
|
||||
1776
modules/imgproc/test/test_filter.cpp
Normal file
1776
modules/imgproc/test/test_filter.cpp
Normal file
File diff suppressed because it is too large
Load Diff
533
modules/imgproc/test/test_floodfill.cpp
Normal file
533
modules/imgproc/test/test_floodfill.cpp
Normal file
@@ -0,0 +1,533 @@
|
||||
/*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_FloodFillTest : public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
CV_FloodFillTest();
|
||||
|
||||
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 );
|
||||
|
||||
void fill_array( int test_case_idx, int i, int j, Mat& arr );
|
||||
|
||||
/*int write_default_params(CvFileStorage* fs);
|
||||
void get_timing_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types
|
||||
CvSize** whole_sizes, bool *are_images );
|
||||
void print_timing_params( int test_case_idx, char* ptr, int params_left );*/
|
||||
CvPoint seed_pt;
|
||||
CvScalar new_val;
|
||||
CvScalar l_diff, u_diff;
|
||||
int connectivity;
|
||||
bool use_mask, mask_only;
|
||||
int range_type;
|
||||
int new_mask_val;
|
||||
bool test_cpp;
|
||||
};
|
||||
|
||||
|
||||
CV_FloodFillTest::CV_FloodFillTest()
|
||||
{
|
||||
test_array[INPUT_OUTPUT].push_back(NULL);
|
||||
test_array[INPUT_OUTPUT].push_back(NULL);
|
||||
test_array[REF_INPUT_OUTPUT].push_back(NULL);
|
||||
test_array[REF_INPUT_OUTPUT].push_back(NULL);
|
||||
test_array[OUTPUT].push_back(NULL);
|
||||
test_array[REF_OUTPUT].push_back(NULL);
|
||||
optional_mask = false;
|
||||
element_wise_relative_error = true;
|
||||
|
||||
test_cpp = false;
|
||||
}
|
||||
|
||||
|
||||
void CV_FloodFillTest::get_test_array_types_and_sizes( int test_case_idx,
|
||||
vector<vector<Size> >& sizes,
|
||||
vector<vector<int> >& types )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
int depth, cn;
|
||||
int i;
|
||||
double buf[8];
|
||||
cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
|
||||
|
||||
depth = cvtest::randInt(rng) % 2;
|
||||
depth = depth == 0 ? CV_8U : CV_32F;
|
||||
cn = cvtest::randInt(rng) & 1 ? 3 : 1;
|
||||
|
||||
use_mask = (cvtest::randInt(rng) & 1) != 0;
|
||||
connectivity = (cvtest::randInt(rng) & 1) ? 4 : 8;
|
||||
mask_only = use_mask && (cvtest::randInt(rng) & 1) != 0;
|
||||
new_mask_val = cvtest::randInt(rng) & 255;
|
||||
range_type = cvtest::randInt(rng) % 3;
|
||||
|
||||
types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(depth, cn);
|
||||
types[INPUT_OUTPUT][1] = types[REF_INPUT_OUTPUT][1] = CV_8UC1;
|
||||
types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_64FC1;
|
||||
sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(9,1);
|
||||
|
||||
if( !use_mask )
|
||||
sizes[INPUT_OUTPUT][1] = sizes[REF_INPUT_OUTPUT][1] = cvSize(0,0);
|
||||
else
|
||||
{
|
||||
CvSize sz = sizes[INPUT_OUTPUT][0];
|
||||
sizes[INPUT_OUTPUT][1] = sizes[REF_INPUT_OUTPUT][1] = cvSize(sz.width+2,sz.height+2);
|
||||
}
|
||||
|
||||
seed_pt.x = cvtest::randInt(rng) % sizes[INPUT_OUTPUT][0].width;
|
||||
seed_pt.y = cvtest::randInt(rng) % sizes[INPUT_OUTPUT][0].height;
|
||||
|
||||
if( range_type == 0 )
|
||||
l_diff = u_diff = Scalar::all(0.);
|
||||
else
|
||||
{
|
||||
Mat m( 1, 8, CV_16S, buf );
|
||||
rng.fill( m, RNG::NORMAL, Scalar::all(0), Scalar::all(32) );
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
l_diff.val[i] = fabs(m.at<short>(i)/16.);
|
||||
u_diff.val[i] = fabs(m.at<short>(i+4)/16.);
|
||||
}
|
||||
}
|
||||
|
||||
new_val = Scalar::all(0.);
|
||||
for( i = 0; i < cn; i++ )
|
||||
new_val.val[i] = cvtest::randReal(rng)*255;
|
||||
|
||||
test_cpp = (cvtest::randInt(rng) & 256) == 0;
|
||||
}
|
||||
|
||||
|
||||
double CV_FloodFillTest::get_success_error_level( int /*test_case_idx*/, int i, int j )
|
||||
{
|
||||
return i == OUTPUT ? FLT_EPSILON : j == 0 ? FLT_EPSILON : 0;
|
||||
}
|
||||
|
||||
|
||||
void CV_FloodFillTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
|
||||
if( i != INPUT && i != INPUT_OUTPUT )
|
||||
{
|
||||
cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );
|
||||
return;
|
||||
}
|
||||
|
||||
if( j == 0 )
|
||||
{
|
||||
Mat tmp = arr;
|
||||
Scalar m = Scalar::all(128);
|
||||
Scalar s = Scalar::all(10);
|
||||
|
||||
if( arr.depth() == CV_32FC1 )
|
||||
tmp.create(arr.size(), CV_MAKETYPE(CV_8U, arr.channels()));
|
||||
|
||||
if( range_type == 0 )
|
||||
s = Scalar::all(2);
|
||||
|
||||
rng.fill(tmp, RNG::NORMAL, m, s );
|
||||
if( arr.data != tmp.data )
|
||||
cvtest::convert(tmp, arr, arr.type());
|
||||
}
|
||||
else
|
||||
{
|
||||
Scalar l = Scalar::all(-2);
|
||||
Scalar u = Scalar::all(2);
|
||||
cvtest::randUni(rng, arr, l, u );
|
||||
rectangle( arr, Point(0,0), Point(arr.cols-1,arr.rows-1), Scalar::all(1), 1, 8, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CV_FloodFillTest::run_func()
|
||||
{
|
||||
int flags = connectivity + (mask_only ? CV_FLOODFILL_MASK_ONLY : 0) +
|
||||
(range_type == 1 ? CV_FLOODFILL_FIXED_RANGE : 0) + (new_mask_val << 8);
|
||||
double* odata = test_mat[OUTPUT][0].ptr<double>();
|
||||
|
||||
if(!test_cpp)
|
||||
{
|
||||
CvConnectedComp comp;
|
||||
cvFloodFill( test_array[INPUT_OUTPUT][0], seed_pt, new_val, l_diff, u_diff, &comp,
|
||||
flags, test_array[INPUT_OUTPUT][1] );
|
||||
odata[0] = comp.area;
|
||||
odata[1] = comp.rect.x;
|
||||
odata[2] = comp.rect.y;
|
||||
odata[3] = comp.rect.width;
|
||||
odata[4] = comp.rect.height;
|
||||
odata[5] = comp.value.val[0];
|
||||
odata[6] = comp.value.val[1];
|
||||
odata[7] = comp.value.val[2];
|
||||
odata[8] = comp.value.val[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::Mat img = cv::cvarrToMat(test_array[INPUT_OUTPUT][0]),
|
||||
mask = test_array[INPUT_OUTPUT][1] ? cv::cvarrToMat(test_array[INPUT_OUTPUT][1]) : cv::Mat();
|
||||
cv::Rect rect;
|
||||
int area;
|
||||
if( !mask.data )
|
||||
area = cv::floodFill( img, seed_pt, new_val, &rect, l_diff, u_diff, flags );
|
||||
else
|
||||
area = cv::floodFill( img, mask, seed_pt, new_val, &rect, l_diff, u_diff, flags );
|
||||
odata[0] = area;
|
||||
odata[1] = rect.x;
|
||||
odata[2] = rect.y;
|
||||
odata[3] = rect.width;
|
||||
odata[4] = rect.height;
|
||||
odata[5] = odata[6] = odata[7] = odata[8] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef struct ff_offset_pair_t
|
||||
{
|
||||
int mofs, iofs;
|
||||
}
|
||||
ff_offset_pair_t;
|
||||
|
||||
static void
|
||||
cvTsFloodFill( CvMat* _img, CvPoint seed_pt, CvScalar new_val,
|
||||
CvScalar l_diff, CvScalar u_diff, CvMat* _mask,
|
||||
double* comp, int connectivity, int range_type,
|
||||
int new_mask_val, bool mask_only )
|
||||
{
|
||||
CvMemStorage* st = cvCreateMemStorage();
|
||||
ff_offset_pair_t p0, p;
|
||||
CvSeq* seq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(p0), st );
|
||||
CvMat* tmp = _img;
|
||||
CvMat* mask;
|
||||
CvRect r = cvRect( 0, 0, -1, -1 );
|
||||
int area = 0;
|
||||
int i, j;
|
||||
ushort* m;
|
||||
float* img;
|
||||
int mstep, step;
|
||||
int cn = CV_MAT_CN(_img->type);
|
||||
int mdelta[8], idelta[8], ncount;
|
||||
int cols = _img->cols, rows = _img->rows;
|
||||
int u0 = 0, u1 = 0, u2 = 0;
|
||||
double s0 = 0, s1 = 0, s2 = 0;
|
||||
|
||||
if( CV_MAT_DEPTH(_img->type) == CV_8U )
|
||||
{
|
||||
tmp = cvCreateMat( rows, cols, CV_MAKETYPE(CV_32F,CV_MAT_CN(_img->type)) );
|
||||
cvTsConvert(_img, tmp);
|
||||
}
|
||||
|
||||
mask = cvCreateMat( rows + 2, cols + 2, CV_16UC1 );
|
||||
|
||||
if( _mask )
|
||||
cvTsConvert( _mask, mask );
|
||||
else
|
||||
{
|
||||
cvTsZero( mask );
|
||||
cvRectangle( mask, cvPoint(0,0), cvPoint(mask->cols-1,mask->rows-1), Scalar::all(1.), 1, 8, 0 );
|
||||
}
|
||||
|
||||
new_mask_val = (new_mask_val != 0 ? new_mask_val : 1) << 8;
|
||||
|
||||
m = (ushort*)(mask->data.ptr + mask->step) + 1;
|
||||
mstep = mask->step / sizeof(m[0]);
|
||||
img = tmp->data.fl;
|
||||
step = tmp->step / sizeof(img[0]);
|
||||
|
||||
p0.mofs = seed_pt.y*mstep + seed_pt.x;
|
||||
p0.iofs = seed_pt.y*step + seed_pt.x*cn;
|
||||
|
||||
if( m[p0.mofs] )
|
||||
goto _exit_;
|
||||
|
||||
cvSeqPush( seq, &p0 );
|
||||
m[p0.mofs] = (ushort)new_mask_val;
|
||||
|
||||
if( connectivity == 4 )
|
||||
{
|
||||
ncount = 4;
|
||||
mdelta[0] = -mstep; idelta[0] = -step;
|
||||
mdelta[1] = -1; idelta[1] = -cn;
|
||||
mdelta[2] = 1; idelta[2] = cn;
|
||||
mdelta[3] = mstep; idelta[3] = step;
|
||||
}
|
||||
else
|
||||
{
|
||||
ncount = 8;
|
||||
mdelta[0] = -mstep-1; mdelta[1] = -mstep; mdelta[2] = -mstep+1;
|
||||
idelta[0] = -step-cn; idelta[1] = -step; idelta[2] = -step+cn;
|
||||
|
||||
mdelta[3] = -1; mdelta[4] = 1;
|
||||
idelta[3] = -cn; idelta[4] = cn;
|
||||
|
||||
mdelta[5] = mstep-1; mdelta[6] = mstep; mdelta[7] = mstep+1;
|
||||
idelta[5] = step-cn; idelta[6] = step; idelta[7] = step+cn;
|
||||
}
|
||||
|
||||
if( cn == 1 )
|
||||
{
|
||||
float a0 = (float)-l_diff.val[0];
|
||||
float b0 = (float)u_diff.val[0];
|
||||
|
||||
s0 = img[p0.iofs];
|
||||
|
||||
if( range_type < 2 )
|
||||
{
|
||||
a0 += (float)s0; b0 += (float)s0;
|
||||
}
|
||||
|
||||
while( seq->total )
|
||||
{
|
||||
cvSeqPop( seq, &p0 );
|
||||
float a = a0, b = b0;
|
||||
float* ptr = img + p0.iofs;
|
||||
ushort* mptr = m + p0.mofs;
|
||||
|
||||
if( range_type == 2 )
|
||||
a += ptr[0], b += ptr[0];
|
||||
|
||||
for( i = 0; i < ncount; i++ )
|
||||
{
|
||||
int md = mdelta[i], id = idelta[i];
|
||||
float v;
|
||||
if( !mptr[md] && a <= (v = ptr[id]) && v <= b )
|
||||
{
|
||||
mptr[md] = (ushort)new_mask_val;
|
||||
p.mofs = p0.mofs + md;
|
||||
p.iofs = p0.iofs + id;
|
||||
cvSeqPush( seq, &p );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float a0 = (float)-l_diff.val[0];
|
||||
float a1 = (float)-l_diff.val[1];
|
||||
float a2 = (float)-l_diff.val[2];
|
||||
float b0 = (float)u_diff.val[0];
|
||||
float b1 = (float)u_diff.val[1];
|
||||
float b2 = (float)u_diff.val[2];
|
||||
|
||||
s0 = img[p0.iofs];
|
||||
s1 = img[p0.iofs + 1];
|
||||
s2 = img[p0.iofs + 2];
|
||||
|
||||
if( range_type < 2 )
|
||||
{
|
||||
a0 += (float)s0; b0 += (float)s0;
|
||||
a1 += (float)s1; b1 += (float)s1;
|
||||
a2 += (float)s2; b2 += (float)s2;
|
||||
}
|
||||
|
||||
while( seq->total )
|
||||
{
|
||||
cvSeqPop( seq, &p0 );
|
||||
float _a0 = a0, _a1 = a1, _a2 = a2;
|
||||
float _b0 = b0, _b1 = b1, _b2 = b2;
|
||||
float* ptr = img + p0.iofs;
|
||||
ushort* mptr = m + p0.mofs;
|
||||
|
||||
if( range_type == 2 )
|
||||
{
|
||||
_a0 += ptr[0]; _b0 += ptr[0];
|
||||
_a1 += ptr[1]; _b1 += ptr[1];
|
||||
_a2 += ptr[2]; _b2 += ptr[2];
|
||||
}
|
||||
|
||||
for( i = 0; i < ncount; i++ )
|
||||
{
|
||||
int md = mdelta[i], id = idelta[i];
|
||||
float v;
|
||||
if( !mptr[md] &&
|
||||
_a0 <= (v = ptr[id]) && v <= _b0 &&
|
||||
_a1 <= (v = ptr[id+1]) && v <= _b1 &&
|
||||
_a2 <= (v = ptr[id+2]) && v <= _b2 )
|
||||
{
|
||||
mptr[md] = (ushort)new_mask_val;
|
||||
p.mofs = p0.mofs + md;
|
||||
p.iofs = p0.iofs + id;
|
||||
cvSeqPush( seq, &p );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r.x = r.width = seed_pt.x;
|
||||
r.y = r.height = seed_pt.y;
|
||||
|
||||
if( !mask_only )
|
||||
{
|
||||
s0 = new_val.val[0];
|
||||
s1 = new_val.val[1];
|
||||
s2 = new_val.val[2];
|
||||
|
||||
if( tmp != _img )
|
||||
{
|
||||
u0 = saturate_cast<uchar>(s0);
|
||||
u1 = saturate_cast<uchar>(s1);
|
||||
u2 = saturate_cast<uchar>(s2);
|
||||
|
||||
s0 = u0;
|
||||
s1 = u1;
|
||||
s2 = u2;
|
||||
}
|
||||
}
|
||||
else
|
||||
s0 = s1 = s2 = 0;
|
||||
|
||||
new_mask_val >>= 8;
|
||||
|
||||
for( i = 0; i < rows; i++ )
|
||||
{
|
||||
float* ptr = img + i*step;
|
||||
ushort* mptr = m + i*mstep;
|
||||
uchar* dmptr = _mask ? _mask->data.ptr + (i+1)*_mask->step + 1 : 0;
|
||||
uchar* dptr = tmp != _img ? _img->data.ptr + i*_img->step : 0;
|
||||
double area0 = area;
|
||||
|
||||
for( j = 0; j < cols; j++ )
|
||||
{
|
||||
if( mptr[j] > 255 )
|
||||
{
|
||||
if( dmptr )
|
||||
dmptr[j] = (uchar)new_mask_val;
|
||||
if( !mask_only )
|
||||
{
|
||||
if( cn == 1 )
|
||||
{
|
||||
if( dptr )
|
||||
dptr[j] = (uchar)u0;
|
||||
else
|
||||
ptr[j] = (float)s0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( dptr )
|
||||
{
|
||||
dptr[j*3] = (uchar)u0;
|
||||
dptr[j*3+1] = (uchar)u1;
|
||||
dptr[j*3+2] = (uchar)u2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr[j*3] = (float)s0;
|
||||
ptr[j*3+1] = (float)s1;
|
||||
ptr[j*3+2] = (float)s2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( cn == 1 )
|
||||
s0 += ptr[j];
|
||||
else
|
||||
{
|
||||
s0 += ptr[j*3];
|
||||
s1 += ptr[j*3+1];
|
||||
s2 += ptr[j*3+2];
|
||||
}
|
||||
}
|
||||
|
||||
area++;
|
||||
if( r.x > j )
|
||||
r.x = j;
|
||||
if( r.width < j )
|
||||
r.width = j;
|
||||
}
|
||||
}
|
||||
|
||||
if( area != area0 )
|
||||
{
|
||||
if( r.y > i )
|
||||
r.y = i;
|
||||
if( r.height < i )
|
||||
r.height = i;
|
||||
}
|
||||
}
|
||||
|
||||
_exit_:
|
||||
cvReleaseMat( &mask );
|
||||
if( tmp != _img )
|
||||
cvReleaseMat( &tmp );
|
||||
|
||||
comp[0] = area;
|
||||
comp[1] = r.x;
|
||||
comp[2] = r.y;
|
||||
comp[3] = r.width - r.x + 1;
|
||||
comp[4] = r.height - r.y + 1;
|
||||
if( mask_only )
|
||||
{
|
||||
double t = area ? 1./area : 0;
|
||||
s0 *= t;
|
||||
s1 *= t;
|
||||
s2 *= t;
|
||||
}
|
||||
comp[5] = s0;
|
||||
comp[6] = s1;
|
||||
comp[7] = s2;
|
||||
comp[8] = 0;
|
||||
}
|
||||
|
||||
|
||||
void CV_FloodFillTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
double* comp = test_mat[REF_OUTPUT][0].ptr<double>();
|
||||
CvMat _input = test_mat[REF_INPUT_OUTPUT][0];
|
||||
CvMat _mask = test_mat[REF_INPUT_OUTPUT][1];
|
||||
cvTsFloodFill( &_input, seed_pt, new_val, l_diff, u_diff,
|
||||
_mask.data.ptr ? &_mask : 0,
|
||||
comp, connectivity, range_type,
|
||||
new_mask_val, mask_only );
|
||||
if(test_cpp)
|
||||
comp[5] = comp[6] = comp[7] = comp[8] = 0;
|
||||
}
|
||||
|
||||
TEST(Imgproc_FloodFill, accuracy) { CV_FloodFillTest test; test.safe_run(); }
|
||||
|
||||
/* End of file. */
|
||||
141
modules/imgproc/test/test_grabcut.cpp
Normal file
141
modules/imgproc/test/test_grabcut.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., 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 the copyright holders 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>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
class CV_GrabcutTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
CV_GrabcutTest();
|
||||
~CV_GrabcutTest();
|
||||
protected:
|
||||
bool verify(const Mat& mask, const Mat& exp);
|
||||
void run(int);
|
||||
};
|
||||
|
||||
CV_GrabcutTest::CV_GrabcutTest() {}
|
||||
CV_GrabcutTest::~CV_GrabcutTest() {}
|
||||
|
||||
bool CV_GrabcutTest::verify(const Mat& mask, const Mat& exp)
|
||||
{
|
||||
const float maxDiffRatio = 0.005f;
|
||||
int expArea = countNonZero( exp );
|
||||
int nonIntersectArea = countNonZero( mask != exp );
|
||||
|
||||
float curRatio = (float)nonIntersectArea / (float)expArea;
|
||||
ts->printf( cvtest::TS::LOG, "nonIntersectArea/expArea = %f\n", curRatio );
|
||||
return curRatio < maxDiffRatio;
|
||||
}
|
||||
|
||||
void CV_GrabcutTest::run( int /* start_from */)
|
||||
{
|
||||
cvtest::DefaultRngAuto defRng;
|
||||
|
||||
Mat img = imread(string(ts->get_data_path()) + "shared/airplane.jpg");
|
||||
Mat mask_prob = imread(string(ts->get_data_path()) + "grabcut/mask_prob.png", 0);
|
||||
Mat exp_mask1 = imread(string(ts->get_data_path()) + "grabcut/exp_mask1.png", 0);
|
||||
Mat exp_mask2 = imread(string(ts->get_data_path()) + "grabcut/exp_mask2.png", 0);
|
||||
|
||||
if (img.empty() || (!mask_prob.empty() && img.size() != mask_prob.size()) ||
|
||||
(!exp_mask1.empty() && img.size() != exp_mask1.size()) ||
|
||||
(!exp_mask2.empty() && img.size() != exp_mask2.size()) )
|
||||
{
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
|
||||
return;
|
||||
}
|
||||
|
||||
Rect rect(Point(24, 126), Point(483, 294));
|
||||
Mat exp_bgdModel, exp_fgdModel;
|
||||
|
||||
Mat mask;
|
||||
mask = Scalar(0);
|
||||
Mat bgdModel, fgdModel;
|
||||
grabCut( img, mask, rect, bgdModel, fgdModel, 0, GC_INIT_WITH_RECT );
|
||||
grabCut( img, mask, rect, bgdModel, fgdModel, 2, GC_EVAL );
|
||||
|
||||
// Multiply images by 255 for more visuality of test data.
|
||||
if( mask_prob.empty() )
|
||||
{
|
||||
mask.copyTo( mask_prob );
|
||||
imwrite(string(ts->get_data_path()) + "grabcut/mask_prob.png", mask_prob);
|
||||
}
|
||||
if( exp_mask1.empty() )
|
||||
{
|
||||
exp_mask1 = (mask & 1) * 255;
|
||||
imwrite(string(ts->get_data_path()) + "grabcut/exp_mask1.png", exp_mask1);
|
||||
}
|
||||
|
||||
if (!verify((mask & 1) * 255, exp_mask1))
|
||||
{
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
|
||||
return;
|
||||
}
|
||||
|
||||
mask = mask_prob;
|
||||
bgdModel.release();
|
||||
fgdModel.release();
|
||||
rect = Rect();
|
||||
grabCut( img, mask, rect, bgdModel, fgdModel, 0, GC_INIT_WITH_MASK );
|
||||
grabCut( img, mask, rect, bgdModel, fgdModel, 1, GC_EVAL );
|
||||
|
||||
if( exp_mask2.empty() )
|
||||
{
|
||||
exp_mask2 = (mask & 1) * 255;
|
||||
imwrite(string(ts->get_data_path()) + "grabcut/exp_mask2.png", exp_mask2);
|
||||
}
|
||||
|
||||
if (!verify((mask & 1) * 255, exp_mask2))
|
||||
{
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
|
||||
return;
|
||||
}
|
||||
ts->set_failed_test_info(cvtest::TS::OK);
|
||||
}
|
||||
|
||||
TEST(Imgproc_GrabCut, regression) { CV_GrabcutTest test; test.safe_run(); }
|
||||
|
||||
1842
modules/imgproc/test/test_histograms.cpp
Normal file
1842
modules/imgproc/test/test_histograms.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1387
modules/imgproc/test/test_imgwarp.cpp
Normal file
1387
modules/imgproc/test/test_imgwarp.cpp
Normal file
File diff suppressed because it is too large
Load Diff
121
modules/imgproc/test/test_inpaint.cpp
Normal file
121
modules/imgproc/test/test_inpaint.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., 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 the copyright holders 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 cv;
|
||||
|
||||
class CV_InpaintTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
CV_InpaintTest();
|
||||
~CV_InpaintTest();
|
||||
protected:
|
||||
void run(int);
|
||||
};
|
||||
|
||||
CV_InpaintTest::CV_InpaintTest()
|
||||
{
|
||||
}
|
||||
CV_InpaintTest::~CV_InpaintTest() {}
|
||||
|
||||
void CV_InpaintTest::run( int )
|
||||
{
|
||||
string folder = string(ts->get_data_path()) + "inpaint/";
|
||||
Mat orig = imread(folder + "orig.jpg");
|
||||
Mat exp1 = imread(folder + "exp1.png");
|
||||
Mat exp2 = imread(folder + "exp2.png");
|
||||
Mat mask = imread(folder + "mask.png");
|
||||
|
||||
if (orig.empty() || exp1.empty() || exp2.empty() || mask.empty())
|
||||
{
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
|
||||
return;
|
||||
}
|
||||
|
||||
Mat inv_mask;
|
||||
mask.convertTo(inv_mask, CV_8UC3, -1.0, 255.0);
|
||||
|
||||
Mat mask1ch;
|
||||
cv::cvtColor(mask, mask1ch, CV_BGR2GRAY);
|
||||
|
||||
Mat test = orig.clone();
|
||||
test.setTo(Scalar::all(255), mask1ch);
|
||||
|
||||
Mat res1, res2;
|
||||
inpaint( test, mask1ch, res1, 5, CV_INPAINT_NS );
|
||||
inpaint( test, mask1ch, res2, 5, CV_INPAINT_TELEA );
|
||||
|
||||
imwrite("d:/exp1.png", res1);
|
||||
imwrite("d:/exp2.png", res2);
|
||||
|
||||
Mat diff1, diff2;
|
||||
absdiff( orig, res1, diff1 );
|
||||
absdiff( orig, res2, diff2 );
|
||||
|
||||
double n1 = norm(diff1.reshape(1), NORM_INF, inv_mask.reshape(1));
|
||||
double n2 = norm(diff2.reshape(1), NORM_INF, inv_mask.reshape(1));
|
||||
|
||||
if (n1 != 0 || n2 != 0)
|
||||
{
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
|
||||
return;
|
||||
}
|
||||
|
||||
absdiff( exp1, res1, diff1 );
|
||||
absdiff( exp2, res2, diff2 );
|
||||
|
||||
n1 = norm(diff1.reshape(1), NORM_INF, mask.reshape(1));
|
||||
n2 = norm(diff2.reshape(1), NORM_INF, mask.reshape(1));
|
||||
|
||||
const int jpeg_thres = 3;
|
||||
if (n1 > jpeg_thres || n2 > jpeg_thres)
|
||||
{
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
|
||||
return;
|
||||
}
|
||||
|
||||
ts->set_failed_test_info(cvtest::TS::OK);
|
||||
}
|
||||
|
||||
TEST(Imgproc_Inpaint, regression) { CV_InpaintTest test; test.safe_run(); }
|
||||
4
modules/imgproc/test/test_main.cpp
Normal file
4
modules/imgproc/test/test_main.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
CV_TEST_MAIN("cv")
|
||||
|
||||
393
modules/imgproc/test/test_moments.cpp
Normal file
393
modules/imgproc/test/test_moments.cpp
Normal file
@@ -0,0 +1,393 @@
|
||||
/*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;
|
||||
|
||||
// image moments
|
||||
class CV_MomentsTest : public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
CV_MomentsTest();
|
||||
|
||||
protected:
|
||||
|
||||
enum { MOMENT_COUNT = 25 };
|
||||
int prepare_test_case( int test_case_idx );
|
||||
void prepare_to_validation( int /*test_case_idx*/ );
|
||||
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 );
|
||||
void run_func();
|
||||
int coi;
|
||||
bool is_binary;
|
||||
};
|
||||
|
||||
|
||||
CV_MomentsTest::CV_MomentsTest()
|
||||
{
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[OUTPUT].push_back(NULL);
|
||||
test_array[REF_OUTPUT].push_back(NULL);
|
||||
coi = -1;
|
||||
is_binary = false;
|
||||
//element_wise_relative_error = false;
|
||||
}
|
||||
|
||||
|
||||
void CV_MomentsTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high )
|
||||
{
|
||||
cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high );
|
||||
int depth = CV_MAT_DEPTH(type);
|
||||
|
||||
if( depth == CV_16U )
|
||||
{
|
||||
low = Scalar::all(0);
|
||||
high = Scalar::all(1000);
|
||||
}
|
||||
else if( depth == CV_16S )
|
||||
{
|
||||
low = Scalar::all(-1000);
|
||||
high = Scalar::all(1000);
|
||||
}
|
||||
else if( depth == CV_32F )
|
||||
{
|
||||
low = Scalar::all(-1);
|
||||
high = Scalar::all(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CV_MomentsTest::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 );
|
||||
int cn = cvtest::randInt(rng) % 4 + 1;
|
||||
int depth = cvtest::randInt(rng) % 4;
|
||||
depth = depth == 0 ? CV_8U : depth == 1 ? CV_16U : depth == 2 ? CV_16S : CV_32F;
|
||||
if( cn == 2 )
|
||||
cn = 1;
|
||||
|
||||
types[INPUT][0] = CV_MAKETYPE(depth, cn);
|
||||
types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_64FC1;
|
||||
sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(MOMENT_COUNT,1);
|
||||
|
||||
is_binary = cvtest::randInt(rng) % 2 != 0;
|
||||
coi = 0;
|
||||
cvmat_allowed = true;
|
||||
if( cn > 1 )
|
||||
{
|
||||
coi = cvtest::randInt(rng) % cn;
|
||||
cvmat_allowed = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double CV_MomentsTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
|
||||
{
|
||||
int depth = test_mat[INPUT][0].depth();
|
||||
return depth != CV_32F ? FLT_EPSILON*10 : FLT_EPSILON*100;
|
||||
}
|
||||
|
||||
int CV_MomentsTest::prepare_test_case( int test_case_idx )
|
||||
{
|
||||
int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
|
||||
if( code > 0 )
|
||||
{
|
||||
int cn = test_mat[INPUT][0].channels();
|
||||
if( cn > 1 )
|
||||
cvSetImageCOI( (IplImage*)test_array[INPUT][0], coi + 1 );
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
void CV_MomentsTest::run_func()
|
||||
{
|
||||
CvMoments* m = (CvMoments*)test_mat[OUTPUT][0].ptr<double>();
|
||||
double* others = (double*)(m + 1);
|
||||
cvMoments( test_array[INPUT][0], m, is_binary );
|
||||
others[0] = cvGetNormalizedCentralMoment( m, 2, 0 );
|
||||
others[1] = cvGetNormalizedCentralMoment( m, 1, 1 );
|
||||
others[2] = cvGetNormalizedCentralMoment( m, 0, 2 );
|
||||
others[3] = cvGetNormalizedCentralMoment( m, 3, 0 );
|
||||
others[4] = cvGetNormalizedCentralMoment( m, 2, 1 );
|
||||
others[5] = cvGetNormalizedCentralMoment( m, 1, 2 );
|
||||
others[6] = cvGetNormalizedCentralMoment( m, 0, 3 );
|
||||
}
|
||||
|
||||
|
||||
void CV_MomentsTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
Mat& src = test_mat[INPUT][0];
|
||||
CvMoments m;
|
||||
double* mdata = test_mat[REF_OUTPUT][0].ptr<double>();
|
||||
int depth = src.depth();
|
||||
int cn = src.channels();
|
||||
int i, y, x, cols = src.cols;
|
||||
double xc = 0., yc = 0.;
|
||||
|
||||
memset( &m, 0, sizeof(m));
|
||||
|
||||
for( y = 0; y < src.rows; y++ )
|
||||
{
|
||||
double s0 = 0, s1 = 0, s2 = 0, s3 = 0;
|
||||
uchar* ptr = src.ptr(y);
|
||||
for( x = 0; x < cols; x++ )
|
||||
{
|
||||
double val;
|
||||
if( depth == CV_8U )
|
||||
val = ptr[x*cn + coi];
|
||||
else if( depth == CV_16U )
|
||||
val = ((ushort*)ptr)[x*cn + coi];
|
||||
else if( depth == CV_16S )
|
||||
val = ((short*)ptr)[x*cn + coi];
|
||||
else
|
||||
val = ((float*)ptr)[x*cn + coi];
|
||||
|
||||
if( is_binary )
|
||||
val = val != 0;
|
||||
|
||||
s0 += val;
|
||||
s1 += val*x;
|
||||
s2 += val*x*x;
|
||||
s3 += ((val*x)*x)*x;
|
||||
}
|
||||
|
||||
m.m00 += s0;
|
||||
m.m01 += s0*y;
|
||||
m.m02 += (s0*y)*y;
|
||||
m.m03 += ((s0*y)*y)*y;
|
||||
|
||||
m.m10 += s1;
|
||||
m.m11 += s1*y;
|
||||
m.m12 += (s1*y)*y;
|
||||
|
||||
m.m20 += s2;
|
||||
m.m21 += s2*y;
|
||||
|
||||
m.m30 += s3;
|
||||
}
|
||||
|
||||
if( m.m00 != 0 )
|
||||
{
|
||||
xc = m.m10/m.m00, yc = m.m01/m.m00;
|
||||
m.inv_sqrt_m00 = 1./sqrt(fabs(m.m00));
|
||||
}
|
||||
|
||||
for( y = 0; y < src.rows; y++ )
|
||||
{
|
||||
double s0 = 0, s1 = 0, s2 = 0, s3 = 0, y1 = y - yc;
|
||||
uchar* ptr = src.ptr(y);
|
||||
for( x = 0; x < cols; x++ )
|
||||
{
|
||||
double val, x1 = x - xc;
|
||||
if( depth == CV_8U )
|
||||
val = ptr[x*cn + coi];
|
||||
else if( depth == CV_16U )
|
||||
val = ((ushort*)ptr)[x*cn + coi];
|
||||
else if( depth == CV_16S )
|
||||
val = ((short*)ptr)[x*cn + coi];
|
||||
else
|
||||
val = ((float*)ptr)[x*cn + coi];
|
||||
|
||||
if( is_binary )
|
||||
val = val != 0;
|
||||
|
||||
s0 += val;
|
||||
s1 += val*x1;
|
||||
s2 += val*x1*x1;
|
||||
s3 += ((val*x1)*x1)*x1;
|
||||
}
|
||||
|
||||
m.mu02 += s0*y1*y1;
|
||||
m.mu03 += ((s0*y1)*y1)*y1;
|
||||
|
||||
m.mu11 += s1*y1;
|
||||
m.mu12 += (s1*y1)*y1;
|
||||
|
||||
m.mu20 += s2;
|
||||
m.mu21 += s2*y1;
|
||||
|
||||
m.mu30 += s3;
|
||||
}
|
||||
|
||||
memcpy( mdata, &m, sizeof(m));
|
||||
mdata += sizeof(m)/sizeof(m.m00);
|
||||
|
||||
/* calc normalized moments */
|
||||
{
|
||||
double inv_m00 = m.inv_sqrt_m00*m.inv_sqrt_m00;
|
||||
double s2 = inv_m00*inv_m00; /* 1./(m00 ^ (2/2 + 1)) */
|
||||
double s3 = s2*m.inv_sqrt_m00; /* 1./(m00 ^ (3/2 + 1)) */
|
||||
|
||||
mdata[0] = m.mu20 * s2;
|
||||
mdata[1] = m.mu11 * s2;
|
||||
mdata[2] = m.mu02 * s2;
|
||||
|
||||
mdata[3] = m.mu30 * s3;
|
||||
mdata[4] = m.mu21 * s3;
|
||||
mdata[5] = m.mu12 * s3;
|
||||
mdata[6] = m.mu03 * s3;
|
||||
}
|
||||
|
||||
double* a = test_mat[REF_OUTPUT][0].ptr<double>();
|
||||
double* b = test_mat[OUTPUT][0].ptr<double>();
|
||||
for( i = 0; i < MOMENT_COUNT; i++ )
|
||||
{
|
||||
if( fabs(a[i]) < 1e-3 )
|
||||
a[i] = 0;
|
||||
if( fabs(b[i]) < 1e-3 )
|
||||
b[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Hu invariants
|
||||
class CV_HuMomentsTest : public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
CV_HuMomentsTest();
|
||||
|
||||
protected:
|
||||
|
||||
enum { MOMENT_COUNT = 18, HU_MOMENT_COUNT = 7 };
|
||||
|
||||
int prepare_test_case( int test_case_idx );
|
||||
void prepare_to_validation( int /*test_case_idx*/ );
|
||||
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 );
|
||||
void run_func();
|
||||
};
|
||||
|
||||
|
||||
CV_HuMomentsTest::CV_HuMomentsTest()
|
||||
{
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[OUTPUT].push_back(NULL);
|
||||
test_array[REF_OUTPUT].push_back(NULL);
|
||||
}
|
||||
|
||||
|
||||
void CV_HuMomentsTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high )
|
||||
{
|
||||
cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high );
|
||||
low = Scalar::all(-10000);
|
||||
high = Scalar::all(10000);
|
||||
}
|
||||
|
||||
|
||||
void CV_HuMomentsTest::get_test_array_types_and_sizes( int test_case_idx,
|
||||
vector<vector<Size> >& sizes, vector<vector<int> >& types )
|
||||
{
|
||||
cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
|
||||
types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_64FC1;
|
||||
sizes[INPUT][0] = cvSize(MOMENT_COUNT,1);
|
||||
sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(HU_MOMENT_COUNT,1);
|
||||
}
|
||||
|
||||
|
||||
double CV_HuMomentsTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
|
||||
{
|
||||
return FLT_EPSILON;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int CV_HuMomentsTest::prepare_test_case( int test_case_idx )
|
||||
{
|
||||
int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
|
||||
if( code > 0 )
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
void CV_HuMomentsTest::run_func()
|
||||
{
|
||||
cvGetHuMoments( (CvMoments*)test_mat[INPUT][0].data,
|
||||
(CvHuMoments*)test_mat[OUTPUT][0].data );
|
||||
}
|
||||
|
||||
|
||||
void CV_HuMomentsTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
CvMoments* m = (CvMoments*)test_mat[INPUT][0].data;
|
||||
CvHuMoments* hu = (CvHuMoments*)test_mat[REF_OUTPUT][0].data;
|
||||
|
||||
double inv_m00 = m->inv_sqrt_m00*m->inv_sqrt_m00;
|
||||
double s2 = inv_m00*inv_m00; /* 1./(m00 ^ (2/2 + 1)) */
|
||||
double s3 = s2*m->inv_sqrt_m00; /* 1./(m00 ^ (3/2 + 1)) */
|
||||
|
||||
double nu20 = m->mu20 * s2;
|
||||
double nu11 = m->mu11 * s2;
|
||||
double nu02 = m->mu02 * s2;
|
||||
|
||||
double nu30 = m->mu30 * s3;
|
||||
double nu21 = m->mu21 * s3;
|
||||
double nu12 = m->mu12 * s3;
|
||||
double nu03 = m->mu03 * s3;
|
||||
|
||||
#undef sqr
|
||||
#define sqr(a) ((a)*(a))
|
||||
|
||||
hu->hu1 = nu20 + nu02;
|
||||
hu->hu2 = sqr(nu20 - nu02) + 4*sqr(nu11);
|
||||
hu->hu3 = sqr(nu30 - 3*nu12) + sqr(3*nu21 - nu03);
|
||||
hu->hu4 = sqr(nu30 + nu12) + sqr(nu21 + nu03);
|
||||
hu->hu5 = (nu30 - 3*nu12)*(nu30 + nu12)*(sqr(nu30 + nu12) - 3*sqr(nu21 + nu03)) +
|
||||
(3*nu21 - nu03)*(nu21 + nu03)*(3*sqr(nu30 + nu12) - sqr(nu21 + nu03));
|
||||
hu->hu6 = (nu20 - nu02)*(sqr(nu30 + nu12) - sqr(nu21 + nu03)) +
|
||||
4*nu11*(nu30 + nu12)*(nu21 + nu03);
|
||||
hu->hu7 = (3*nu21 - nu03)*(nu30 + nu12)*(sqr(nu30 + nu12) - 3*sqr(nu21 + nu03)) +
|
||||
(3*nu12 - nu30)*(nu21 + nu03)*(3*sqr(nu30 + nu12) - sqr(nu21 + nu03));
|
||||
}
|
||||
|
||||
|
||||
TEST(Imgproc_Moments, accuracy) { CV_MomentsTest test; test.safe_run(); }
|
||||
TEST(Imgproc_HuMoments, accuracy) { CV_HuMomentsTest test; test.safe_run(); }
|
||||
1
modules/imgproc/test/test_precomp.cpp
Normal file
1
modules/imgproc/test/test_precomp.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "test_precomp.hpp"
|
||||
11
modules/imgproc/test/test_precomp.hpp
Normal file
11
modules/imgproc/test/test_precomp.hpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef __OPENCV_TEST_PRECOMP_HPP__
|
||||
#define __OPENCV_TEST_PRECOMP_HPP__
|
||||
|
||||
#include "opencv2/ts/ts.hpp"
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include "opencv2/highgui/highgui_c.h"
|
||||
#include <iostream>
|
||||
|
||||
#endif
|
||||
204
modules/imgproc/test/test_pyrsegmentation.cpp
Normal file
204
modules/imgproc/test/test_pyrsegmentation.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
/*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_PyrSegmentationTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
CV_PyrSegmentationTest();
|
||||
protected:
|
||||
void run(int);
|
||||
};
|
||||
|
||||
#define SCAN 0
|
||||
|
||||
CV_PyrSegmentationTest::CV_PyrSegmentationTest()
|
||||
{
|
||||
}
|
||||
|
||||
void CV_PyrSegmentationTest::run( int /*start_from*/ )
|
||||
{
|
||||
Mat _image_f, _image, _image_s;
|
||||
const int level = 5;
|
||||
const double range = 15;
|
||||
|
||||
int code = cvtest::TS::OK;
|
||||
|
||||
CvPoint _cp[] ={{33,33}, {43,33}, {43,43}, {33,43}};
|
||||
CvPoint _cp2[] ={{50,50}, {70,50}, {70,70}, {50,70}};
|
||||
CvPoint* cp = _cp;
|
||||
CvPoint* cp2 = _cp2;
|
||||
CvConnectedComp *dst_comp[3];
|
||||
CvRect rect[3] = {{50,50,21,21}, {0,0,128,128}, {33,33,11,11}};
|
||||
double a[3] = {441.0, 15822.0, 121.0};
|
||||
|
||||
/* ippiPoint cp3[] ={130,130, 150,130, 150,150, 130,150}; */
|
||||
/* CvPoint cp[] ={0,0, 5,5, 5,0, 10,5, 10,0, 15,5, 15,0}; */
|
||||
int nPoints = 4;
|
||||
int block_size = 1000;
|
||||
|
||||
CvMemStorage *storage; /* storage for connected component writing */
|
||||
CvSeq *comp;
|
||||
|
||||
RNG& rng = ts->get_rng();
|
||||
int i, j, iter;
|
||||
|
||||
IplImage *image, *image_f, *image_s;
|
||||
CvSize size = {128, 128};
|
||||
const int threshold1 = 50, threshold2 = 50;
|
||||
|
||||
rect[1].width = size.width;
|
||||
rect[1].height = size.height;
|
||||
a[1] = size.width*size.height - a[0] - a[2];
|
||||
|
||||
OPENCV_CALL( storage = cvCreateMemStorage( block_size ) );
|
||||
|
||||
for( iter = 0; iter < 2; iter++ )
|
||||
{
|
||||
int channels = iter == 0 ? 1 : 3;
|
||||
int mask[] = {0,0,0};
|
||||
|
||||
image = cvCreateImage(size, 8, channels );
|
||||
image_s = cvCloneImage( image );
|
||||
image_f = cvCloneImage( image );
|
||||
|
||||
if( channels == 1 )
|
||||
{
|
||||
int color1 = 30, color2 = 110, color3 = 190;
|
||||
|
||||
cvSet( image, cvScalarAll(color1));
|
||||
cvFillPoly( image, &cp, &nPoints, 1, cvScalar(color2));
|
||||
cvFillPoly( image, &cp2, &nPoints, 1, cvScalar(color3));
|
||||
}
|
||||
else
|
||||
{
|
||||
CvScalar color1 = CV_RGB(30,30,30), color2 = CV_RGB(255,0,0), color3 = CV_RGB(0,255,0);
|
||||
|
||||
assert( channels == 3 );
|
||||
cvSet( image, color1 );
|
||||
cvFillPoly( image, &cp, &nPoints, 1, color2);
|
||||
cvFillPoly( image, &cp2, &nPoints, 1, color3);
|
||||
}
|
||||
|
||||
_image_f = cvarrToMat(image_f);
|
||||
cvtest::randUni( rng, _image_f, cvScalarAll(0), cvScalarAll(range*2) );
|
||||
cvAddWeighted( image, 1, image_f, 1, -range, image_f );
|
||||
|
||||
cvPyrSegmentation( image_f, image_s,
|
||||
storage, &comp,
|
||||
level, threshold1, threshold2 );
|
||||
|
||||
if(comp->total != 3)
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG,
|
||||
"The segmentation function returned %d (not 3) components\n", comp->total );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
goto _exit_;
|
||||
}
|
||||
/* read the connected components */
|
||||
dst_comp[0] = (CvConnectedComp*)CV_GET_SEQ_ELEM( CvConnectedComp, comp, 0 );
|
||||
dst_comp[1] = (CvConnectedComp*)CV_GET_SEQ_ELEM( CvConnectedComp, comp, 1 );
|
||||
dst_comp[2] = (CvConnectedComp*)CV_GET_SEQ_ELEM( CvConnectedComp, comp, 2 );
|
||||
|
||||
/*{
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
CvRect r = dst_comp[i]->rect;
|
||||
cvRectangle( image_s, cvPoint(r.x,r.y), cvPoint(r.x+r.width,r.y+r.height),
|
||||
CV_RGB(255,255,255), 3, 8, 0 );
|
||||
}
|
||||
|
||||
cvNamedWindow( "test", 1 );
|
||||
cvShowImage( "test", image_s );
|
||||
cvWaitKey(0);
|
||||
}*/
|
||||
|
||||
_image = cvarrToMat(image);
|
||||
_image_s = cvarrToMat(image_s);
|
||||
code = cvtest::cmpEps2( ts, _image, _image_s, 10, false, "the output image" );
|
||||
if( code < 0 )
|
||||
goto _exit_;
|
||||
|
||||
for( i = 0; i < 3; i++)
|
||||
{
|
||||
for( j = 0; j < 3; j++ )
|
||||
{
|
||||
if( !mask[j] && dst_comp[i]->area == a[j] &&
|
||||
dst_comp[i]->rect.x == rect[j].x &&
|
||||
dst_comp[i]->rect.y == rect[j].y &&
|
||||
dst_comp[i]->rect.width == rect[j].width &&
|
||||
dst_comp[i]->rect.height == rect[j].height )
|
||||
{
|
||||
mask[j] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( j == 3 )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "The component #%d is incorrect\n", i );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
goto _exit_;
|
||||
}
|
||||
}
|
||||
|
||||
cvReleaseImage(&image_f);
|
||||
cvReleaseImage(&image);
|
||||
cvReleaseImage(&image_s);
|
||||
}
|
||||
|
||||
_exit_:
|
||||
|
||||
cvReleaseMemStorage( &storage );
|
||||
cvReleaseImage(&image_f);
|
||||
cvReleaseImage(&image);
|
||||
cvReleaseImage(&image_s);
|
||||
|
||||
if( code < 0 )
|
||||
ts->set_failed_test_info( code );
|
||||
}
|
||||
|
||||
TEST(Imgproc_PyrSegmentation, regression) { CV_PyrSegmentationTest test; test.safe_run(); }
|
||||
|
||||
/* End of file. */
|
||||
341
modules/imgproc/test/test_subdivisions.cpp
Normal file
341
modules/imgproc/test/test_subdivisions.cpp
Normal file
@@ -0,0 +1,341 @@
|
||||
/*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_SubdivTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
CV_SubdivTest();
|
||||
~CV_SubdivTest();
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
int read_params( CvFileStorage* fs );
|
||||
int prepare_test_case( int test_case_idx );
|
||||
int validate_test_results( int test_case_idx );
|
||||
void run_func();
|
||||
|
||||
int min_log_img_size, max_log_img_size;
|
||||
CvSize img_size;
|
||||
int min_log_point_count;
|
||||
int max_log_point_count;
|
||||
int point_count;
|
||||
CvSubdiv2D* subdiv;
|
||||
CvMemStorage* storage;
|
||||
};
|
||||
|
||||
|
||||
CV_SubdivTest::CV_SubdivTest()
|
||||
{
|
||||
test_case_count = 100;
|
||||
min_log_point_count = 1;
|
||||
max_log_point_count = 10;
|
||||
min_log_img_size = 1;
|
||||
max_log_img_size = 10;
|
||||
|
||||
storage = 0;
|
||||
}
|
||||
|
||||
|
||||
CV_SubdivTest::~CV_SubdivTest()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
void CV_SubdivTest::clear()
|
||||
{
|
||||
cvtest::BaseTest::clear();
|
||||
cvReleaseMemStorage( &storage );
|
||||
}
|
||||
|
||||
|
||||
int CV_SubdivTest::read_params( CvFileStorage* fs )
|
||||
{
|
||||
int code = cvtest::BaseTest::read_params( fs );
|
||||
int t;
|
||||
|
||||
if( code < 0 )
|
||||
return code;
|
||||
|
||||
test_case_count = cvReadInt( find_param( fs, "test_case_count" ), test_case_count );
|
||||
min_log_point_count = cvReadInt( find_param( fs, "min_log_point_count" ), min_log_point_count );
|
||||
max_log_point_count = cvReadInt( find_param( fs, "max_log_point_count" ), max_log_point_count );
|
||||
min_log_img_size = cvReadInt( find_param( fs, "min_log_img_size" ), min_log_img_size );
|
||||
max_log_img_size = cvReadInt( find_param( fs, "max_log_img_size" ), max_log_img_size );
|
||||
|
||||
min_log_point_count = cvtest::clipInt( min_log_point_count, 1, 10 );
|
||||
max_log_point_count = cvtest::clipInt( max_log_point_count, 1, 10 );
|
||||
if( min_log_point_count > max_log_point_count )
|
||||
CV_SWAP( min_log_point_count, max_log_point_count, t );
|
||||
|
||||
min_log_img_size = cvtest::clipInt( min_log_img_size, 1, 10 );
|
||||
max_log_img_size = cvtest::clipInt( max_log_img_size, 1, 10 );
|
||||
if( min_log_img_size > max_log_img_size )
|
||||
CV_SWAP( min_log_img_size, max_log_img_size, t );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CV_SubdivTest::prepare_test_case( int test_case_idx )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
int code = cvtest::BaseTest::prepare_test_case( test_case_idx );
|
||||
if( code < 0 )
|
||||
return code;
|
||||
|
||||
clear();
|
||||
|
||||
point_count = cvRound(exp((cvtest::randReal(rng)*
|
||||
(max_log_point_count - min_log_point_count) + min_log_point_count)*CV_LOG2));
|
||||
img_size.width = cvRound(exp((cvtest::randReal(rng)*
|
||||
(max_log_img_size - min_log_img_size) + min_log_img_size)*CV_LOG2));
|
||||
img_size.height = cvRound(exp((cvtest::randReal(rng)*
|
||||
(max_log_img_size - min_log_img_size) + min_log_img_size)*CV_LOG2));
|
||||
|
||||
storage = cvCreateMemStorage( 1 << 10 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void CV_SubdivTest::run_func()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static inline double sqdist( CvPoint2D32f pt1, CvPoint2D32f pt2 )
|
||||
{
|
||||
double dx = pt1.x - pt2.x;
|
||||
double dy = pt1.y - pt2.y;
|
||||
|
||||
return dx*dx + dy*dy;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
subdiv2DCheck( CvSubdiv2D* subdiv )
|
||||
{
|
||||
int i, j, total = subdiv->edges->total;
|
||||
CV_Assert( subdiv != 0 );
|
||||
|
||||
for( i = 0; i < total; i++ )
|
||||
{
|
||||
CvQuadEdge2D* edge = (CvQuadEdge2D*)cvGetSetElem(subdiv->edges,i);
|
||||
|
||||
if( edge && CV_IS_SET_ELEM( edge ))
|
||||
{
|
||||
for( j = 0; j < 4; j++ )
|
||||
{
|
||||
CvSubdiv2DEdge e = (CvSubdiv2DEdge)edge + j;
|
||||
CvSubdiv2DEdge o_next = cvSubdiv2DNextEdge(e);
|
||||
CvSubdiv2DEdge o_prev = cvSubdiv2DGetEdge(e, CV_PREV_AROUND_ORG );
|
||||
CvSubdiv2DEdge d_prev = cvSubdiv2DGetEdge(e, CV_PREV_AROUND_DST );
|
||||
CvSubdiv2DEdge d_next = cvSubdiv2DGetEdge(e, CV_NEXT_AROUND_DST );
|
||||
|
||||
// check points
|
||||
if( cvSubdiv2DEdgeOrg(e) != cvSubdiv2DEdgeOrg(o_next))
|
||||
return 0;
|
||||
if( cvSubdiv2DEdgeOrg(e) != cvSubdiv2DEdgeOrg(o_prev))
|
||||
return 0;
|
||||
if( cvSubdiv2DEdgeDst(e) != cvSubdiv2DEdgeDst(d_next))
|
||||
return 0;
|
||||
if( cvSubdiv2DEdgeDst(e) != cvSubdiv2DEdgeDst(d_prev))
|
||||
return 0;
|
||||
if( j % 2 == 0 )
|
||||
{
|
||||
if( cvSubdiv2DEdgeDst(o_next) != cvSubdiv2DEdgeOrg(d_prev))
|
||||
return 0;
|
||||
if( cvSubdiv2DEdgeDst(o_prev) != cvSubdiv2DEdgeOrg(d_next))
|
||||
return 0;
|
||||
if( cvSubdiv2DGetEdge(cvSubdiv2DGetEdge(cvSubdiv2DGetEdge(
|
||||
e,CV_NEXT_AROUND_LEFT),CV_NEXT_AROUND_LEFT),CV_NEXT_AROUND_LEFT) != e )
|
||||
return 0;
|
||||
if( cvSubdiv2DGetEdge(cvSubdiv2DGetEdge(cvSubdiv2DGetEdge(
|
||||
e,CV_NEXT_AROUND_RIGHT),CV_NEXT_AROUND_RIGHT),CV_NEXT_AROUND_RIGHT) != e)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// the whole testing is done here, run_func() is not utilized in this test
|
||||
int CV_SubdivTest::validate_test_results( int /*test_case_idx*/ )
|
||||
{
|
||||
int code = cvtest::TS::OK;
|
||||
RNG& rng = ts->get_rng();
|
||||
int j, k, real_count = point_count;
|
||||
double xrange = img_size.width*(1 - FLT_EPSILON);
|
||||
double yrange = img_size.height*(1 - FLT_EPSILON);
|
||||
|
||||
subdiv = subdiv = cvCreateSubdivDelaunay2D(
|
||||
cvRect( 0, 0, img_size.width, img_size.height ), storage );
|
||||
|
||||
CvSeq* seq = cvCreateSeq( 0, sizeof(*seq), sizeof(CvPoint2D32f), storage );
|
||||
CvSeqWriter writer;
|
||||
cvStartAppendToSeq( seq, &writer );
|
||||
|
||||
// insert random points
|
||||
for( j = 0; j < point_count; j++ )
|
||||
{
|
||||
CvPoint2D32f pt;
|
||||
CvSubdiv2DPoint* point;
|
||||
|
||||
pt.x = (float)(cvtest::randReal(rng)*xrange);
|
||||
pt.y = (float)(cvtest::randReal(rng)*yrange);
|
||||
|
||||
CvSubdiv2DPointLocation loc =
|
||||
cvSubdiv2DLocate( subdiv, pt, 0, &point );
|
||||
|
||||
if( loc == CV_PTLOC_VERTEX )
|
||||
{
|
||||
int index = cvSeqElemIdx( (CvSeq*)subdiv, point );
|
||||
CvPoint2D32f* pt1;
|
||||
cvFlushSeqWriter( &writer );
|
||||
pt1 = (CvPoint2D32f*)cvGetSeqElem( seq, index - 3 );
|
||||
|
||||
if( !pt1 ||
|
||||
fabs(pt1->x - pt.x) > FLT_EPSILON ||
|
||||
fabs(pt1->y - pt.y) > FLT_EPSILON )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "The point #%d: (%.1f,%.1f) is said to coinside with a subdivision vertex, "
|
||||
"however it could be found in a sequence of inserted points\n", j, pt.x, pt.y );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
goto _exit_;
|
||||
}
|
||||
real_count--;
|
||||
}
|
||||
|
||||
point = cvSubdivDelaunay2DInsert( subdiv, pt );
|
||||
if( point->pt.x != pt.x || point->pt.y != pt.y )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "The point #%d: (%.1f,%.1f) has been incorrectly added\n", j, pt.x, pt.y );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
goto _exit_;
|
||||
}
|
||||
|
||||
if( (j + 1) % 10 == 0 || j == point_count - 1 )
|
||||
{
|
||||
if( !subdiv2DCheck( subdiv ))
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "Subdivision consistency check failed after inserting the point #%d\n", j );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
goto _exit_;
|
||||
}
|
||||
}
|
||||
|
||||
if( loc != CV_PTLOC_VERTEX )
|
||||
{
|
||||
CV_WRITE_SEQ_ELEM( pt, writer );
|
||||
}
|
||||
}
|
||||
|
||||
if( code < 0 )
|
||||
goto _exit_;
|
||||
|
||||
cvCalcSubdivVoronoi2D( subdiv );
|
||||
seq = cvEndWriteSeq( &writer );
|
||||
|
||||
if( !subdiv2DCheck( subdiv ))
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "The subdivision failed consistency check after building the Voronoi tesselation\n" );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
goto _exit_;
|
||||
}
|
||||
|
||||
for( j = 0; j < MAX((point_count - 5)/10 + 5, 10); j++ )
|
||||
{
|
||||
CvPoint2D32f pt;
|
||||
double minDistance;
|
||||
|
||||
pt.x = (float)(cvtest::randReal(rng)*xrange);
|
||||
pt.y = (float)(cvtest::randReal(rng)*yrange);
|
||||
|
||||
CvSubdiv2DPoint* point = cvFindNearestPoint2D( subdiv, pt );
|
||||
CvSeqReader reader;
|
||||
|
||||
if( !point )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "There is no nearest point (?!) for the point (%.1f, %.1f) in the subdivision\n",
|
||||
pt.x, pt.y );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
goto _exit_;
|
||||
}
|
||||
|
||||
cvStartReadSeq( seq, &reader );
|
||||
minDistance = sqdist( pt, point->pt );
|
||||
|
||||
for( k = 0; k < seq->total; k++ )
|
||||
{
|
||||
CvPoint2D32f ptt;
|
||||
CV_READ_SEQ_ELEM( ptt, reader );
|
||||
|
||||
double distance = sqdist( pt, ptt );
|
||||
if( minDistance > distance && sqdist(ptt, point->pt) > FLT_EPSILON*1000 )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "The triangulation vertex (%.3f,%.3f) was said to be nearest to (%.3f,%.3f),\n"
|
||||
"whereas another vertex (%.3f,%.3f) is closer\n",
|
||||
point->pt.x, point->pt.y, pt.x, pt.y, ptt.x, ptt.y );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
goto _exit_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_exit_:
|
||||
if( code < 0 )
|
||||
ts->set_failed_test_info( code );
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
TEST(Imgproc_Subdiv, correctness) { CV_SubdivTest test; test.safe_run(); }
|
||||
|
||||
/* End of file. */
|
||||
|
||||
336
modules/imgproc/test/test_templmatch.cpp
Normal file
336
modules/imgproc/test/test_templmatch.cpp
Normal file
@@ -0,0 +1,336 @@
|
||||
/*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_TemplMatchTest : public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
CV_TemplMatchTest();
|
||||
|
||||
protected:
|
||||
int read_params( CvFileStorage* fs );
|
||||
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 );
|
||||
void run_func();
|
||||
void prepare_to_validation( int );
|
||||
|
||||
int max_template_size;
|
||||
int method;
|
||||
bool test_cpp;
|
||||
};
|
||||
|
||||
|
||||
CV_TemplMatchTest::CV_TemplMatchTest()
|
||||
{
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[OUTPUT].push_back(NULL);
|
||||
test_array[REF_OUTPUT].push_back(NULL);
|
||||
element_wise_relative_error = false;
|
||||
max_template_size = 100;
|
||||
method = 0;
|
||||
test_cpp = false;
|
||||
}
|
||||
|
||||
|
||||
int CV_TemplMatchTest::read_params( CvFileStorage* fs )
|
||||
{
|
||||
int code = cvtest::ArrayTest::read_params( fs );
|
||||
if( code < 0 )
|
||||
return code;
|
||||
|
||||
max_template_size = cvReadInt( find_param( fs, "max_template_size" ), max_template_size );
|
||||
max_template_size = cvtest::clipInt( max_template_size, 1, 100 );
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
void CV_TemplMatchTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high )
|
||||
{
|
||||
cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high );
|
||||
int depth = CV_MAT_DEPTH(type);
|
||||
if( depth == CV_32F )
|
||||
{
|
||||
low = Scalar::all(-10.);
|
||||
high = Scalar::all(10.);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CV_TemplMatchTest::get_test_array_types_and_sizes( int test_case_idx,
|
||||
vector<vector<Size> >& sizes, vector<vector<int> >& types )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
int depth = cvtest::randInt(rng) % 2, cn = cvtest::randInt(rng) & 1 ? 3 : 1;
|
||||
cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
|
||||
depth = depth == 0 ? CV_8U : CV_32F;
|
||||
|
||||
types[INPUT][0] = types[INPUT][1] = CV_MAKETYPE(depth,cn);
|
||||
types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_32FC1;
|
||||
|
||||
sizes[INPUT][1].width = cvtest::randInt(rng)%MIN(sizes[INPUT][1].width,max_template_size) + 1;
|
||||
sizes[INPUT][1].height = cvtest::randInt(rng)%MIN(sizes[INPUT][1].height,max_template_size) + 1;
|
||||
sizes[OUTPUT][0].width = sizes[INPUT][0].width - sizes[INPUT][1].width + 1;
|
||||
sizes[OUTPUT][0].height = sizes[INPUT][0].height - sizes[INPUT][1].height + 1;
|
||||
sizes[REF_OUTPUT][0] = sizes[OUTPUT][0];
|
||||
|
||||
method = cvtest::randInt(rng)%6;
|
||||
test_cpp = (cvtest::randInt(rng) & 256) == 0;
|
||||
}
|
||||
|
||||
|
||||
double CV_TemplMatchTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
|
||||
{
|
||||
if( test_mat[INPUT][1].depth() == CV_8U ||
|
||||
(method >= CV_TM_CCOEFF && test_mat[INPUT][1].cols*test_mat[INPUT][1].rows <= 2) )
|
||||
return 1e-2;
|
||||
else
|
||||
return 1e-3;
|
||||
}
|
||||
|
||||
|
||||
void CV_TemplMatchTest::run_func()
|
||||
{
|
||||
if(!test_cpp)
|
||||
cvMatchTemplate( test_array[INPUT][0], test_array[INPUT][1], test_array[OUTPUT][0], method );
|
||||
else
|
||||
{
|
||||
cv::Mat _out = cv::cvarrToMat(test_array[OUTPUT][0]);
|
||||
cv::matchTemplate(cv::cvarrToMat(test_array[INPUT][0]), cv::cvarrToMat(test_array[INPUT][1]), _out, method);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void cvTsMatchTemplate( const CvMat* img, const CvMat* templ, CvMat* result, int method )
|
||||
{
|
||||
int i, j, k, l;
|
||||
int depth = CV_MAT_DEPTH(img->type), cn = CV_MAT_CN(img->type);
|
||||
int width_n = templ->cols*cn, height = templ->rows;
|
||||
int a_step = img->step / CV_ELEM_SIZE(img->type & CV_MAT_DEPTH_MASK);
|
||||
int b_step = templ->step / CV_ELEM_SIZE(templ->type & CV_MAT_DEPTH_MASK);
|
||||
CvScalar b_mean, b_sdv;
|
||||
double b_denom = 1., b_sum2 = 0;
|
||||
int area = templ->rows*templ->cols;
|
||||
|
||||
cvAvgSdv(templ, &b_mean, &b_sdv);
|
||||
|
||||
for( i = 0; i < cn; i++ )
|
||||
b_sum2 += (b_sdv.val[i]*b_sdv.val[i] + b_mean.val[i]*b_mean.val[i])*area;
|
||||
|
||||
if( b_sdv.val[0]*b_sdv.val[0] + b_sdv.val[1]*b_sdv.val[1] +
|
||||
b_sdv.val[2]*b_sdv.val[2] + b_sdv.val[3]*b_sdv.val[3] < DBL_EPSILON &&
|
||||
method == CV_TM_CCOEFF_NORMED )
|
||||
{
|
||||
cvSet( result, cvScalarAll(1.) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( method & 1 )
|
||||
{
|
||||
b_denom = 0;
|
||||
if( method != CV_TM_CCOEFF_NORMED )
|
||||
{
|
||||
b_denom = b_sum2;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < cn; i++ )
|
||||
b_denom += b_sdv.val[i]*b_sdv.val[i]*area;
|
||||
}
|
||||
b_denom = sqrt(b_denom);
|
||||
if( b_denom == 0 )
|
||||
b_denom = 1.;
|
||||
}
|
||||
|
||||
assert( CV_TM_SQDIFF <= method && method <= CV_TM_CCOEFF_NORMED );
|
||||
|
||||
for( i = 0; i < result->rows; i++ )
|
||||
{
|
||||
for( j = 0; j < result->cols; j++ )
|
||||
{
|
||||
CvScalar a_sum = {{ 0, 0, 0, 0 }}, a_sum2 = {{ 0, 0, 0, 0 }};
|
||||
CvScalar ccorr = {{ 0, 0, 0, 0 }};
|
||||
double value = 0.;
|
||||
|
||||
if( depth == CV_8U )
|
||||
{
|
||||
const uchar* a = img->data.ptr + i*img->step + j*cn;
|
||||
const uchar* b = templ->data.ptr;
|
||||
|
||||
if( cn == 1 || method < CV_TM_CCOEFF )
|
||||
{
|
||||
for( k = 0; k < height; k++, a += a_step, b += b_step )
|
||||
for( l = 0; l < width_n; l++ )
|
||||
{
|
||||
ccorr.val[0] += a[l]*b[l];
|
||||
a_sum.val[0] += a[l];
|
||||
a_sum2.val[0] += a[l]*a[l];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( k = 0; k < height; k++, a += a_step, b += b_step )
|
||||
for( l = 0; l < width_n; l += 3 )
|
||||
{
|
||||
ccorr.val[0] += a[l]*b[l];
|
||||
ccorr.val[1] += a[l+1]*b[l+1];
|
||||
ccorr.val[2] += a[l+2]*b[l+2];
|
||||
a_sum.val[0] += a[l];
|
||||
a_sum.val[1] += a[l+1];
|
||||
a_sum.val[2] += a[l+2];
|
||||
a_sum2.val[0] += a[l]*a[l];
|
||||
a_sum2.val[1] += a[l+1]*a[l+1];
|
||||
a_sum2.val[2] += a[l+2]*a[l+2];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const float* a = (const float*)(img->data.ptr + i*img->step) + j*cn;
|
||||
const float* b = (const float*)templ->data.ptr;
|
||||
|
||||
if( cn == 1 || method < CV_TM_CCOEFF )
|
||||
{
|
||||
for( k = 0; k < height; k++, a += a_step, b += b_step )
|
||||
for( l = 0; l < width_n; l++ )
|
||||
{
|
||||
ccorr.val[0] += a[l]*b[l];
|
||||
a_sum.val[0] += a[l];
|
||||
a_sum2.val[0] += a[l]*a[l];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( k = 0; k < height; k++, a += a_step, b += b_step )
|
||||
for( l = 0; l < width_n; l += 3 )
|
||||
{
|
||||
ccorr.val[0] += a[l]*b[l];
|
||||
ccorr.val[1] += a[l+1]*b[l+1];
|
||||
ccorr.val[2] += a[l+2]*b[l+2];
|
||||
a_sum.val[0] += a[l];
|
||||
a_sum.val[1] += a[l+1];
|
||||
a_sum.val[2] += a[l+2];
|
||||
a_sum2.val[0] += a[l]*a[l];
|
||||
a_sum2.val[1] += a[l+1]*a[l+1];
|
||||
a_sum2.val[2] += a[l+2]*a[l+2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch( method )
|
||||
{
|
||||
case CV_TM_CCORR:
|
||||
case CV_TM_CCORR_NORMED:
|
||||
value = ccorr.val[0];
|
||||
break;
|
||||
case CV_TM_SQDIFF:
|
||||
case CV_TM_SQDIFF_NORMED:
|
||||
value = (a_sum2.val[0] + b_sum2 - 2*ccorr.val[0]);
|
||||
break;
|
||||
default:
|
||||
value = (ccorr.val[0] - a_sum.val[0]*b_mean.val[0]+
|
||||
ccorr.val[1] - a_sum.val[1]*b_mean.val[1]+
|
||||
ccorr.val[2] - a_sum.val[2]*b_mean.val[2]);
|
||||
}
|
||||
|
||||
if( method & 1 )
|
||||
{
|
||||
double denom;
|
||||
|
||||
// calc denominator
|
||||
if( method != CV_TM_CCOEFF_NORMED )
|
||||
{
|
||||
denom = a_sum2.val[0] + a_sum2.val[1] + a_sum2.val[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
denom = a_sum2.val[0] - (a_sum.val[0]*a_sum.val[0])/area;
|
||||
denom += a_sum2.val[1] - (a_sum.val[1]*a_sum.val[1])/area;
|
||||
denom += a_sum2.val[2] - (a_sum.val[2]*a_sum.val[2])/area;
|
||||
}
|
||||
denom = sqrt(MAX(denom,0))*b_denom;
|
||||
if( fabs(value) < denom )
|
||||
value /= denom;
|
||||
else if( fabs(value) < denom*1.125 )
|
||||
value = value > 0 ? 1 : -1;
|
||||
else
|
||||
value = method != CV_TM_SQDIFF_NORMED ? 0 : 1;
|
||||
}
|
||||
|
||||
((float*)(result->data.ptr + result->step*i))[j] = (float)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CV_TemplMatchTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
CvMat _input = test_mat[INPUT][0], _templ = test_mat[INPUT][1];
|
||||
CvMat _output = test_mat[REF_OUTPUT][0];
|
||||
cvTsMatchTemplate( &_input, &_templ, &_output, method );
|
||||
|
||||
//if( ts->get_current_test_info()->test_case_idx == 0 )
|
||||
/*{
|
||||
CvFileStorage* fs = cvOpenFileStorage( "_match_template.yml", 0, CV_STORAGE_WRITE );
|
||||
cvWrite( fs, "image", &test_mat[INPUT][0] );
|
||||
cvWrite( fs, "template", &test_mat[INPUT][1] );
|
||||
cvWrite( fs, "ref", &test_mat[REF_OUTPUT][0] );
|
||||
cvWrite( fs, "opencv", &test_mat[OUTPUT][0] );
|
||||
cvWriteInt( fs, "method", method );
|
||||
cvReleaseFileStorage( &fs );
|
||||
}*/
|
||||
|
||||
if( method >= CV_TM_CCOEFF )
|
||||
{
|
||||
// avoid numerical stability problems in singular cases (when the results are near to 0)
|
||||
const double delta = 10.;
|
||||
test_mat[REF_OUTPUT][0] += Scalar::all(delta);
|
||||
test_mat[OUTPUT][0] += Scalar::all(delta);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Imgproc_MatchTemplate, accuracy) { CV_TemplMatchTest test; test.safe_run(); }
|
||||
217
modules/imgproc/test/test_thresh.cpp
Normal file
217
modules/imgproc/test/test_thresh.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
/*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_ThreshTest : public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
CV_ThreshTest();
|
||||
|
||||
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 );
|
||||
|
||||
int thresh_type;
|
||||
float thresh_val;
|
||||
float max_val;
|
||||
};
|
||||
|
||||
|
||||
CV_ThreshTest::CV_ThreshTest()
|
||||
{
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[OUTPUT].push_back(NULL);
|
||||
test_array[REF_OUTPUT].push_back(NULL);
|
||||
optional_mask = false;
|
||||
element_wise_relative_error = true;
|
||||
}
|
||||
|
||||
|
||||
void CV_ThreshTest::get_test_array_types_and_sizes( int test_case_idx,
|
||||
vector<vector<Size> >& sizes, vector<vector<int> >& types )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
int depth = cvtest::randInt(rng) % 2, cn = cvtest::randInt(rng) % 4 + 1;
|
||||
cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
|
||||
depth = depth == 0 ? CV_8U : CV_32F;
|
||||
|
||||
types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth,cn);
|
||||
thresh_type = cvtest::randInt(rng) % 5;
|
||||
|
||||
if( depth == CV_8U )
|
||||
{
|
||||
thresh_val = (float)(cvtest::randReal(rng)*350. - 50.);
|
||||
max_val = (float)(cvtest::randReal(rng)*350. - 50.);
|
||||
if( cvtest::randInt(rng)%4 == 0 )
|
||||
max_val = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
thresh_val = (float)(cvtest::randReal(rng)*1000. - 500.);
|
||||
max_val = (float)(cvtest::randReal(rng)*1000. - 500.);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double CV_ThreshTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
|
||||
{
|
||||
return FLT_EPSILON*10;
|
||||
}
|
||||
|
||||
|
||||
void CV_ThreshTest::run_func()
|
||||
{
|
||||
cvThreshold( test_array[INPUT][0], test_array[OUTPUT][0],
|
||||
thresh_val, max_val, thresh_type );
|
||||
}
|
||||
|
||||
|
||||
static void test_threshold( const Mat& _src, Mat& _dst,
|
||||
float thresh, float maxval, int thresh_type )
|
||||
{
|
||||
int i, j;
|
||||
int depth = _src.depth(), cn = _src.channels();
|
||||
int width_n = _src.cols*cn, height = _src.rows;
|
||||
int ithresh = cvFloor(thresh), ithresh2, imaxval = cvRound(maxval);
|
||||
const uchar* src = _src.data;
|
||||
uchar* dst = _dst.data;
|
||||
size_t srcstep = _src.step, dststep = _dst.step;
|
||||
|
||||
ithresh2 = saturate_cast<uchar>(ithresh);
|
||||
imaxval = saturate_cast<uchar>(imaxval);
|
||||
|
||||
assert( depth == CV_8U || depth == CV_32F );
|
||||
|
||||
switch( thresh_type )
|
||||
{
|
||||
case CV_THRESH_BINARY:
|
||||
for( i = 0; i < height; i++, src += srcstep, dst += dststep )
|
||||
{
|
||||
if( depth == CV_8U )
|
||||
for( j = 0; j < width_n; j++ )
|
||||
dst[j] = (uchar)(src[j] > ithresh ? imaxval : 0);
|
||||
else
|
||||
for( j = 0; j < width_n; j++ )
|
||||
((float*)dst)[j] = ((const float*)src)[j] > thresh ? maxval : 0.f;
|
||||
}
|
||||
break;
|
||||
case CV_THRESH_BINARY_INV:
|
||||
for( i = 0; i < height; i++, src += srcstep, dst += dststep )
|
||||
{
|
||||
if( depth == CV_8U )
|
||||
for( j = 0; j < width_n; j++ )
|
||||
dst[j] = (uchar)(src[j] > ithresh ? 0 : imaxval);
|
||||
else
|
||||
for( j = 0; j < width_n; j++ )
|
||||
((float*)dst)[j] = ((const float*)src)[j] > thresh ? 0.f : maxval;
|
||||
}
|
||||
break;
|
||||
case CV_THRESH_TRUNC:
|
||||
for( i = 0; i < height; i++, src += srcstep, dst += dststep )
|
||||
{
|
||||
if( depth == CV_8U )
|
||||
for( j = 0; j < width_n; j++ )
|
||||
{
|
||||
int s = src[j];
|
||||
dst[j] = (uchar)(s > ithresh ? ithresh2 : s);
|
||||
}
|
||||
else
|
||||
for( j = 0; j < width_n; j++ )
|
||||
{
|
||||
float s = ((const float*)src)[j];
|
||||
((float*)dst)[j] = s > thresh ? thresh : s;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CV_THRESH_TOZERO:
|
||||
for( i = 0; i < height; i++, src += srcstep, dst += dststep )
|
||||
{
|
||||
if( depth == CV_8U )
|
||||
for( j = 0; j < width_n; j++ )
|
||||
{
|
||||
int s = src[j];
|
||||
dst[j] = (uchar)(s > ithresh ? s : 0);
|
||||
}
|
||||
else
|
||||
for( j = 0; j < width_n; j++ )
|
||||
{
|
||||
float s = ((const float*)src)[j];
|
||||
((float*)dst)[j] = s > thresh ? s : 0.f;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CV_THRESH_TOZERO_INV:
|
||||
for( i = 0; i < height; i++, src += srcstep, dst += dststep )
|
||||
{
|
||||
if( depth == CV_8U )
|
||||
for( j = 0; j < width_n; j++ )
|
||||
{
|
||||
int s = src[j];
|
||||
dst[j] = (uchar)(s > ithresh ? 0 : s);
|
||||
}
|
||||
else
|
||||
for( j = 0; j < width_n; j++ )
|
||||
{
|
||||
float s = ((const float*)src)[j];
|
||||
((float*)dst)[j] = s > thresh ? 0.f : s;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CV_ThreshTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
test_threshold( test_mat[INPUT][0], test_mat[REF_OUTPUT][0],
|
||||
thresh_val, max_val, thresh_type );
|
||||
}
|
||||
|
||||
TEST(Imgproc_Threshold, accuracy) { CV_ThreshTest test; test.safe_run(); }
|
||||
|
||||
133
modules/imgproc/test/test_watershed.cpp
Normal file
133
modules/imgproc/test/test_watershed.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., 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 the copyright holders 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 cv;
|
||||
using namespace std;
|
||||
|
||||
class CV_WatershedTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
CV_WatershedTest();
|
||||
~CV_WatershedTest();
|
||||
protected:
|
||||
void run(int);
|
||||
};
|
||||
|
||||
CV_WatershedTest::CV_WatershedTest() {}
|
||||
CV_WatershedTest::~CV_WatershedTest() {}
|
||||
|
||||
void CV_WatershedTest::run( int /* start_from */)
|
||||
{
|
||||
string exp_path = string(ts->get_data_path()) + "watershed/wshed_exp.png";
|
||||
Mat exp = imread(exp_path, 0);
|
||||
Mat orig = imread(string(ts->get_data_path()) + "inpaint/orig.jpg");
|
||||
FileStorage fs(string(ts->get_data_path()) + "watershed/comp.xml", FileStorage::READ);
|
||||
|
||||
if (orig.empty() || !fs.isOpened())
|
||||
{
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
|
||||
return;
|
||||
}
|
||||
|
||||
CvSeq* cnts = (CvSeq*)fs["contours"].readObj();
|
||||
|
||||
Mat markers(orig.size(), CV_32SC1);
|
||||
markers = Scalar(0);
|
||||
IplImage iplmrks = markers;
|
||||
|
||||
vector<unsigned char> colors(1);
|
||||
for(int i = 0; cnts != 0; cnts = cnts->h_next, ++i )
|
||||
{
|
||||
cvDrawContours( &iplmrks, cnts, Scalar::all(i + 1), Scalar::all(i + 1), -1, CV_FILLED);
|
||||
Point* p = (Point*)cvGetSeqElem(cnts, 0);
|
||||
|
||||
//expected image was added with 1 in order to save to png
|
||||
//so now we substract 1 to get real color
|
||||
if(exp.data)
|
||||
colors.push_back(exp.ptr(p->y)[p->x] - 1);
|
||||
}
|
||||
fs.release();
|
||||
const int compNum = (int)(colors.size() - 1);
|
||||
|
||||
watershed(orig, markers);
|
||||
|
||||
for(int j = 0; j < markers.rows; ++j)
|
||||
{
|
||||
int* line = markers.ptr<int>(j);
|
||||
for(int i = 0; i < markers.cols; ++i)
|
||||
{
|
||||
int& pixel = line[i];
|
||||
|
||||
if (pixel == -1) // border
|
||||
continue;
|
||||
|
||||
if (pixel <= 0 || pixel > compNum)
|
||||
continue; // bad result, doing nothing and going to get error latter;
|
||||
|
||||
// repaint in saved color to compare with expected;
|
||||
if(exp.data)
|
||||
pixel = colors[pixel];
|
||||
}
|
||||
}
|
||||
|
||||
Mat markers8U;
|
||||
markers.convertTo(markers8U, CV_8U, 1, 1);
|
||||
|
||||
if( exp.empty() || orig.size() != exp.size() )
|
||||
{
|
||||
imwrite(exp_path, markers8U);
|
||||
exp = markers8U;
|
||||
}
|
||||
|
||||
if (0 != norm(markers8U, exp, NORM_INF))
|
||||
{
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
|
||||
return;
|
||||
}
|
||||
ts->set_failed_test_info(cvtest::TS::OK);
|
||||
}
|
||||
|
||||
TEST(Imgproc_Watershed, regression) { CV_WatershedTest test; test.safe_run(); }
|
||||
|
||||
Reference in New Issue
Block a user