From 8cbdd0c833dcdbd0c92a1c16cce14045167ef9e8 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Tue, 5 Mar 2024 12:18:31 +0300 Subject: [PATCH] Merge pull request #25075 from mshabunin:cleanup-imgproc-1 C-API cleanup: apps, imgproc_c and some constants #25075 Merge with https://github.com/opencv/opencv_contrib/pull/3642 * Removed obsolete apps - traincascade and createsamples (please use older OpenCV versions if you need them). These apps relied heavily on C-API * removed all mentions of imgproc C-API headers (imgproc_c.h, types_c.h) - they were empty, included core C-API headers * replaced usage of several C constants with C++ ones (error codes, norm modes, RNG modes, PCA modes, ...) - most part of this PR (split into two parts - all modules and calib+3d - for easier backporting) * removed imgproc C-API headers (as separate commit, so that other changes could be backported to 4.x) Most of these changes can be backported to 4.x. --- apps/CMakeLists.txt | 2 - apps/createsamples/CMakeLists.txt | 4 - apps/createsamples/createsamples.cpp | 258 - apps/createsamples/utility.cpp | 1464 ------ apps/createsamples/utility.hpp | 124 - apps/traincascade/CMakeLists.txt | 5 - apps/traincascade/HOGfeatures.cpp | 250 - apps/traincascade/HOGfeatures.h | 78 - apps/traincascade/boost.cpp | 1718 ------- apps/traincascade/boost.h | 86 - apps/traincascade/cascadeclassifier.cpp | 570 --- apps/traincascade/cascadeclassifier.h | 125 - apps/traincascade/features.cpp | 93 - apps/traincascade/haarfeatures.cpp | 312 -- apps/traincascade/haarfeatures.h | 89 - apps/traincascade/imagestorage.cpp | 186 - apps/traincascade/imagestorage.h | 50 - apps/traincascade/lbpfeatures.cpp | 67 - apps/traincascade/lbpfeatures.h | 57 - apps/traincascade/old_ml.hpp | 2041 -------- apps/traincascade/old_ml_boost.cpp | 2160 --------- apps/traincascade/old_ml_data.cpp | 792 ---- apps/traincascade/old_ml_inner_functions.cpp | 1684 ------- apps/traincascade/old_ml_precomp.hpp | 376 -- apps/traincascade/old_ml_tree.cpp | 4153 ----------------- apps/traincascade/traincascade.cpp | 129 - apps/traincascade/traincascade_features.h | 101 - .../others/barcode_detect_and_decode.markdown | 2 +- .../others/cascade_classifier.markdown | 6 +- .../others/table_of_content_other.markdown | 1 - doc/tutorials/others/traincascade.markdown | 224 - modules/3d/src/calibration_base.cpp | 13 +- modules/3d/src/levmarq.cpp | 20 +- modules/3d/src/rgbd/pose_graph.cpp | 2 +- modules/3d/src/solvepnp.cpp | 2 +- modules/3d/src/triangulate.cpp | 4 +- modules/3d/test/test_fundam.cpp | 8 +- modules/3d/test/test_undistort.cpp | 2 +- modules/3d/test/test_undistort_badarg.cpp | 16 +- modules/calib/src/calibinit.cpp | 1 - modules/calib/src/calibration.cpp | 48 +- modules/calib/test/test_cameracalibration.cpp | 4 +- .../test/test_cameracalibration_badarg.cpp | 48 +- modules/calib/test/test_cornerssubpix.cpp | 1 - modules/core/include/opencv2/core/private.hpp | 7 - modules/core/perf/opencl/perf_arithm.cpp | 11 +- modules/core/src/alloc.cpp | 2 +- modules/core/src/arithm.cpp | 16 +- modules/core/src/array.cpp | 258 +- modules/core/src/batch_distance.cpp | 2 +- modules/core/src/command_line_parser.cpp | 6 +- modules/core/src/copy.cpp | 4 +- modules/core/src/datastructs.cpp | 214 +- modules/core/src/dxt.cpp | 4 +- modules/core/src/glob.cpp | 2 +- modules/core/src/lapack.cpp | 4 +- modules/core/src/mathfuncs.cpp | 2 +- modules/core/src/matmul.dispatch.cpp | 4 +- modules/core/src/matrix.cpp | 20 +- modules/core/src/matrix_c.cpp | 12 +- modules/core/src/matrix_expressions.cpp | 8 +- modules/core/src/matrix_operations.cpp | 2 +- modules/core/src/matrix_sparse.cpp | 8 +- modules/core/src/matrix_wrap.cpp | 8 +- modules/core/src/norm.cpp | 6 +- modules/core/src/pca.cpp | 16 +- modules/core/src/rand.cpp | 4 +- modules/core/src/system.cpp | 110 +- modules/core/src/types.cpp | 2 +- modules/core/src/umatrix.cpp | 16 +- modules/core/test/ocl/test_arithm.cpp | 2 +- modules/core/test/test_arithm.cpp | 8 +- modules/core/test/test_ds.cpp | 5 +- modules/core/test/test_dxt.cpp | 5 +- modules/core/test/test_io.cpp | 14 +- modules/core/test/test_mat.cpp | 55 +- modules/core/test/test_math.cpp | 7 +- modules/core/test/test_operations.cpp | 23 +- modules/core/test/test_rand.cpp | 22 +- modules/core/test/test_umat.cpp | 1 + modules/dnn/src/dnn_utils.cpp | 2 +- .../dnn/src/int8layers/convolution_layer.cpp | 2 +- .../src/layers/cpu_kernels/convolution.cpp | 2 +- modules/dnn/src/vkcom/src/context.cpp | 10 +- modules/dnn/src/vkcom/src/op_conv.cpp | 2 +- modules/dnn/src/vkcom/src/op_naryEltwise.cpp | 2 +- modules/dnn/src/vkcom/src/pipeline.cpp | 4 +- .../test/FlannBasedDescriptorMatcherTest.java | 2 +- modules/features2d/src/mser.cpp | 2 +- .../gapi/src/backends/fluid/gfluidimgproc.cpp | 1 - modules/highgui/src/precomp.hpp | 2 +- modules/highgui/src/window.cpp | 26 +- modules/highgui/src/window_QT.cpp | 66 +- modules/highgui/src/window_cocoa.mm | 102 +- modules/highgui/src/window_gtk.cpp | 26 +- modules/highgui/src/window_winrt.cpp | 28 +- modules/imgcodecs/test/test_precomp.hpp | 1 - .../include/opencv2/imgproc/imgproc_c.h | 48 - .../imgproc/include/opencv2/imgproc/types_c.h | 48 - modules/imgproc/perf/perf_houghcircles.cpp | 1 - modules/imgproc/src/_geom.h | 2 + modules/imgproc/src/approx.cpp | 8 +- .../imgproc/src/bilateral_filter.dispatch.cpp | 2 +- modules/imgproc/src/box_filter.simd.hpp | 6 +- modules/imgproc/src/canny.cpp | 2 +- modules/imgproc/src/clahe.cpp | 2 +- modules/imgproc/src/color.cpp | 4 +- modules/imgproc/src/color_yuv.simd.hpp | 8 +- modules/imgproc/src/connectedcomponents.cpp | 6 +- modules/imgproc/src/contours.cpp | 41 +- modules/imgproc/src/demosaicing.cpp | 8 +- modules/imgproc/src/deriv.cpp | 2 +- modules/imgproc/src/distransform.cpp | 4 +- modules/imgproc/src/emd.cpp | 36 +- modules/imgproc/src/filter.simd.hpp | 6 +- modules/imgproc/src/floodfill.cpp | 14 +- modules/imgproc/src/grabcut.cpp | 14 +- modules/imgproc/src/histogram.cpp | 22 +- modules/imgproc/src/imgwarp.cpp | 16 +- modules/imgproc/src/linefit.cpp | 4 +- modules/imgproc/src/matchcontours.cpp | 2 +- modules/imgproc/src/median_blur.simd.hpp | 2 +- modules/imgproc/src/moments.cpp | 4 +- modules/imgproc/src/morph.dispatch.cpp | 4 +- modules/imgproc/src/morph.simd.hpp | 6 +- modules/imgproc/src/precomp.hpp | 3 +- modules/imgproc/src/pyramids.cpp | 4 +- modules/imgproc/src/resize.cpp | 2 +- modules/imgproc/src/rotcalipers.cpp | 2 +- modules/imgproc/src/samplers.cpp | 2 +- modules/imgproc/src/segmentation.cpp | 8 +- modules/imgproc/src/shapedescr.cpp | 6 +- modules/imgproc/src/subdivision2d.cpp | 10 +- modules/imgproc/src/templmatch.cpp | 4 +- modules/imgproc/src/thresh.cpp | 14 +- modules/imgproc/test/test_canny.cpp | 5 +- modules/imgproc/test/test_color.cpp | 3 +- modules/imgproc/test/test_convhull.cpp | 1 + modules/imgproc/test/test_filter.cpp | 1 + modules/imgproc/test/test_imgwarp.cpp | 1 + modules/imgproc/test/test_pc.cpp | 1 + modules/imgproc/test/test_precomp.hpp | 1 - modules/imgproc/test/test_templmatch.cpp | 1 + modules/photo/src/inpaint.cpp | 8 +- modules/stitching/src/motion_estimators.cpp | 2 +- modules/ts/include/opencv2/ts/ocl_test.hpp | 1 - modules/ts/src/ts.cpp | 2 +- modules/ts/src/ts_func.cpp | 3 +- modules/videoio/src/cap_mjpeg_encoder.cpp | 4 +- modules/videoio/src/cap_msmf.cpp | 6 +- modules/videoio/src/cap_openni2.cpp | 16 +- modules/videoio/src/precomp.hpp | 1 - 152 files changed, 820 insertions(+), 18160 deletions(-) delete mode 100644 apps/createsamples/CMakeLists.txt delete mode 100644 apps/createsamples/createsamples.cpp delete mode 100644 apps/createsamples/utility.cpp delete mode 100644 apps/createsamples/utility.hpp delete mode 100644 apps/traincascade/CMakeLists.txt delete mode 100644 apps/traincascade/HOGfeatures.cpp delete mode 100644 apps/traincascade/HOGfeatures.h delete mode 100644 apps/traincascade/boost.cpp delete mode 100644 apps/traincascade/boost.h delete mode 100644 apps/traincascade/cascadeclassifier.cpp delete mode 100644 apps/traincascade/cascadeclassifier.h delete mode 100644 apps/traincascade/features.cpp delete mode 100644 apps/traincascade/haarfeatures.cpp delete mode 100644 apps/traincascade/haarfeatures.h delete mode 100644 apps/traincascade/imagestorage.cpp delete mode 100644 apps/traincascade/imagestorage.h delete mode 100644 apps/traincascade/lbpfeatures.cpp delete mode 100644 apps/traincascade/lbpfeatures.h delete mode 100644 apps/traincascade/old_ml.hpp delete mode 100644 apps/traincascade/old_ml_boost.cpp delete mode 100644 apps/traincascade/old_ml_data.cpp delete mode 100644 apps/traincascade/old_ml_inner_functions.cpp delete mode 100644 apps/traincascade/old_ml_precomp.hpp delete mode 100644 apps/traincascade/old_ml_tree.cpp delete mode 100644 apps/traincascade/traincascade.cpp delete mode 100644 apps/traincascade/traincascade_features.h delete mode 100644 doc/tutorials/others/traincascade.markdown delete mode 100644 modules/imgproc/include/opencv2/imgproc/imgproc_c.h delete mode 100644 modules/imgproc/include/opencv2/imgproc/types_c.h diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index e9a7be7c66..84a0a1dcc5 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -53,8 +53,6 @@ macro(ocv_add_app directory) endif() endmacro() -#ocv_add_app(traincascade) -#ocv_add_app(createsamples) ocv_add_app(annotation) ocv_add_app(visualisation) ocv_add_app(interactive-calibration) diff --git a/apps/createsamples/CMakeLists.txt b/apps/createsamples/CMakeLists.txt deleted file mode 100644 index 108119908a..0000000000 --- a/apps/createsamples/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -file(GLOB SRCS *.cpp) -ocv_add_application(opencv_createsamples - MODULES opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_3d opencv_features2d opencv_videoio - SRCS ${SRCS}) diff --git a/apps/createsamples/createsamples.cpp b/apps/createsamples/createsamples.cpp deleted file mode 100644 index 83a55f0a93..0000000000 --- a/apps/createsamples/createsamples.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// Intel License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2000, Intel Corporation, all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * The name of Intel Corporation may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// This software is provided by the copyright holders and contributors "as is" and -// any express or implied warranties, including, but not limited to, the implied -// warranties of merchantability and fitness for a particular purpose are disclaimed. -// In no event shall the Intel Corporation or contributors be liable for any direct, -// indirect, incidental, special, exemplary, or consequential damages -// (including, but not limited to, procurement of substitute goods or services; -// loss of use, data, or profits; or business interruption) however caused -// and on any theory of liability, whether in contract, strict liability, -// or tort (including negligence or otherwise) arising in any way out of -// the use of this software, even if advised of the possibility of such damage. -// -//M*/ - -/* - * createsamples.cpp - * - * Create test/training samples - */ - -#include "opencv2/core.hpp" -#include "utility.hpp" -#include -#include -#include -#include - -using namespace std; - -int main( int argc, char* argv[] ) -{ - int i = 0; - char* nullname = (char*)"(NULL)"; - char* vecname = NULL; /* .vec file name */ - char* infoname = NULL; /* file name with marked up image descriptions */ - char* imagename = NULL; /* single sample image */ - char* bgfilename = NULL; /* background */ - int num = 1000; - int bgcolor = 0; - int bgthreshold = 80; - int invert = 0; - int maxintensitydev = 40; - double maxxangle = 1.1; - double maxyangle = 1.1; - double maxzangle = 0.5; - int showsamples = 0; - /* the samples are adjusted to this scale in the sample preview window */ - double scale = 4.0; - int width = 24; - int height = 24; - double maxscale = -1.0; - int rngseed = 12345; - - if( argc == 1 ) - { - printf( "Usage: %s\n [-info ]\n" - " [-img ]\n" - " [-vec ]\n" - " [-bg ]\n [-num ]\n" - " [-bgcolor ]\n" - " [-inv] [-randinv] [-bgthresh ]\n" - " [-maxidev ]\n" - " [-maxxangle ]\n" - " [-maxyangle ]\n" - " [-maxzangle ]\n" - " [-show []]\n" - " [-w ]\n [-h ]\n" - " [-maxscale ]\n" - " [-rngseed ]\n", - argv[0], num, bgcolor, bgthreshold, maxintensitydev, - maxxangle, maxyangle, maxzangle, scale, width, height, maxscale, rngseed ); - - return 0; - } - - for( i = 1; i < argc; ++i ) - { - if( !strcmp( argv[i], "-info" ) ) - { - infoname = argv[++i]; - } - else if( !strcmp( argv[i], "-img" ) ) - { - imagename = argv[++i]; - } - else if( !strcmp( argv[i], "-vec" ) ) - { - vecname = argv[++i]; - } - else if( !strcmp( argv[i], "-bg" ) ) - { - bgfilename = argv[++i]; - } - else if( !strcmp( argv[i], "-num" ) ) - { - num = atoi( argv[++i] ); - } - else if( !strcmp( argv[i], "-bgcolor" ) ) - { - bgcolor = atoi( argv[++i] ); - } - else if( !strcmp( argv[i], "-bgthresh" ) ) - { - bgthreshold = atoi( argv[++i] ); - } - else if( !strcmp( argv[i], "-inv" ) ) - { - invert = 1; - } - else if( !strcmp( argv[i], "-randinv" ) ) - { - invert = CV_RANDOM_INVERT; - } - else if( !strcmp( argv[i], "-maxidev" ) ) - { - maxintensitydev = atoi( argv[++i] ); - } - else if( !strcmp( argv[i], "-maxxangle" ) ) - { - maxxangle = atof( argv[++i] ); - } - else if( !strcmp( argv[i], "-maxyangle" ) ) - { - maxyangle = atof( argv[++i] ); - } - else if( !strcmp( argv[i], "-maxzangle" ) ) - { - maxzangle = atof( argv[++i] ); - } - else if( !strcmp( argv[i], "-show" ) ) - { - showsamples = 1; - if( i+1 < argc && strlen( argv[i+1] ) > 0 && argv[i+1][0] != '-' ) - { - double d; - d = strtod( argv[i+1], 0 ); - if( d != -HUGE_VAL && d != HUGE_VAL && d > 0 ) scale = d; - ++i; - } - } - else if( !strcmp( argv[i], "-w" ) ) - { - width = atoi( argv[++i] ); - } - else if( !strcmp( argv[i], "-h" ) ) - { - height = atoi( argv[++i] ); - } - else if( !strcmp( argv[i], "-maxscale" ) ) - { - maxscale = atof( argv[++i] ); - } - else if (!strcmp(argv[i], "-rngseed")) - { - rngseed = atoi(argv[++i]); - } - } - - cv::setRNGSeed( rngseed ); - - printf( "Info file name: %s\n", ((infoname == NULL) ? nullname : infoname ) ); - printf( "Img file name: %s\n", ((imagename == NULL) ? nullname : imagename ) ); - printf( "Vec file name: %s\n", ((vecname == NULL) ? nullname : vecname ) ); - printf( "BG file name: %s\n", ((bgfilename == NULL) ? nullname : bgfilename ) ); - printf( "Num: %d\n", num ); - printf( "BG color: %d\n", bgcolor ); - printf( "BG threshold: %d\n", bgthreshold ); - printf( "Invert: %s\n", (invert == CV_RANDOM_INVERT) ? "RANDOM" - : ( (invert) ? "TRUE" : "FALSE" ) ); - printf( "Max intensity deviation: %d\n", maxintensitydev ); - printf( "Max x angle: %g\n", maxxangle ); - printf( "Max y angle: %g\n", maxyangle ); - printf( "Max z angle: %g\n", maxzangle ); - printf( "Show samples: %s\n", (showsamples) ? "TRUE" : "FALSE" ); - if( showsamples ) - { - printf( "Scale: %g\n", scale ); - } - printf( "Width: %d\n", width ); - printf( "Height: %d\n", height ); - printf( "Max Scale: %g\n", maxscale ); - printf( "RNG Seed: %d\n", rngseed ); - - /* determine action */ - if( imagename && vecname ) - { - printf( "Create training samples from single image applying distortions...\n" ); - - cvCreateTrainingSamples( vecname, imagename, bgcolor, bgthreshold, bgfilename, - num, invert, maxintensitydev, - maxxangle, maxyangle, maxzangle, - showsamples, width, height ); - - printf( "Done\n" ); - } - else if( imagename && bgfilename && infoname ) - { - printf( "Create test samples from single image applying distortions...\n" ); - - cvCreateTestSamples( infoname, imagename, bgcolor, bgthreshold, bgfilename, num, - invert, maxintensitydev, - maxxangle, maxyangle, maxzangle, showsamples, width, height, maxscale); - - printf( "Done\n" ); - } - else if( infoname && vecname ) - { - int total; - - printf( "Create training samples from images collection...\n" ); - - total = cvCreateTrainingSamplesFromInfo( infoname, vecname, num, showsamples, - width, height ); - - printf( "Done. Created %d samples\n", total ); - } - else if( vecname ) - { - printf( "View samples from vec file (press ESC to exit)...\n" ); - - cvShowVecSamples( vecname, width, height, scale ); - - printf( "Done\n" ); - } - else - { - printf( "Nothing to do\n" ); - } - - return 0; -} diff --git a/apps/createsamples/utility.cpp b/apps/createsamples/utility.cpp deleted file mode 100644 index 5bc1a89443..0000000000 --- a/apps/createsamples/utility.cpp +++ /dev/null @@ -1,1464 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// Intel License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2000, Intel Corporation, all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * The name of Intel Corporation may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// This software is provided by the copyright holders and contributors "as is" and -// any express or implied warranties, including, but not limited to, the implied -// warranties of merchantability and fitness for a particular purpose are disclaimed. -// In no event shall the Intel Corporation or contributors be liable for any direct, -// indirect, incidental, special, exemplary, or consequential damages -// (including, but not limited to, procurement of substitute goods or services; -// loss of use, data, or profits; or business interruption) however caused -// and on any theory of liability, whether in contract, strict liability, -// or tort (including negligence or otherwise) arising in any way out of -// the use of this software, even if advised of the possibility of such damage. -// -//M*/ -#include -#include - -#include -#include -#ifdef _WIN32 -#include -#endif /* _WIN32 */ - -#include "utility.hpp" -#include "opencv2/core.hpp" -#include "opencv2/imgcodecs.hpp" -#include "opencv2/imgproc.hpp" -#include "opencv2/highgui.hpp" -#include "opencv2/3d.hpp" - -#if defined __GNUC__ && __GNUC__ >= 8 -#pragma GCC diagnostic ignored "-Wclass-memaccess" -#endif - -using namespace cv; - -#ifndef PATH_MAX -#define PATH_MAX 512 -#endif /* PATH_MAX */ - -#define __BEGIN__ __CV_BEGIN__ -#define __END__ __CV_END__ -#define EXIT __CV_EXIT__ - -static int icvMkDir( const char* filename ) -{ - char path[PATH_MAX+1]; - char* p; - int pos; - -#ifdef _WIN32 - struct _stat st; -#else /* _WIN32 */ - struct stat st; - mode_t mode; - - mode = 0755; -#endif /* _WIN32 */ - - path[0] = '\0'; - strncat( path, filename, PATH_MAX ); - - p = path; - for( ; ; ) - { - pos = (int)strcspn( p, "/\\" ); - - if( pos == (int) strlen( p ) ) break; - if( pos != 0 ) - { - p[pos] = '\0'; - -#ifdef _WIN32 - if( p[pos-1] != ':' ) - { - if( _stat( path, &st ) != 0 ) - { - if( _mkdir( path ) != 0 ) return 0; - } - } -#else /* _WIN32 */ - if( stat( path, &st ) != 0 ) - { - if( mkdir( path, mode ) != 0 ) return 0; - } -#endif /* _WIN32 */ - } - - p[pos] = '/'; - - p += pos + 1; - } - - return 1; -} - -static void icvWriteVecHeader( FILE* file, int count, int width, int height ) -{ - int vecsize; - short tmp; - - /* number of samples */ - fwrite( &count, sizeof( count ), 1, file ); - /* vector size */ - vecsize = width * height; - fwrite( &vecsize, sizeof( vecsize ), 1, file ); - /* min/max values */ - tmp = 0; - fwrite( &tmp, sizeof( tmp ), 1, file ); - fwrite( &tmp, sizeof( tmp ), 1, file ); -} - -static void icvWriteVecSample( FILE* file, Mat sample ) -{ - uchar chartmp = 0; - fwrite( &chartmp, sizeof( chartmp ), 1, file ); - for(int r = 0; r < sample.rows; r++ ) - { - for(int c = 0; c < sample.cols; c++ ) - { - short tmp = sample.at(r,c); - fwrite( &tmp, sizeof( tmp ), 1, file ); - } - } -} - -/* Calculates coefficients of perspective transformation - * which maps into rectangle ((0,0), (w,0), (w,h), (h,0)): - * - * c00*xi + c01*yi + c02 - * ui = --------------------- - * c20*xi + c21*yi + c22 - * - * c10*xi + c11*yi + c12 - * vi = --------------------- - * c20*xi + c21*yi + c22 - * - * Coefficients are calculated by solving linear system: - * / x0 y0 1 0 0 0 -x0*u0 -y0*u0 \ /c00\ /u0\ - * | x1 y1 1 0 0 0 -x1*u1 -y1*u1 | |c01| |u1| - * | x2 y2 1 0 0 0 -x2*u2 -y2*u2 | |c02| |u2| - * | x3 y3 1 0 0 0 -x3*u3 -y3*u3 |.|c10|=|u3|, - * | 0 0 0 x0 y0 1 -x0*v0 -y0*v0 | |c11| |v0| - * | 0 0 0 x1 y1 1 -x1*v1 -y1*v1 | |c12| |v1| - * | 0 0 0 x2 y2 1 -x2*v2 -y2*v2 | |c20| |v2| - * \ 0 0 0 x3 y3 1 -x3*v3 -y3*v3 / \c21/ \v3/ - * - * where: - * (xi, yi) = (quad[i][0], quad[i][1]) - * cij - coeffs[i][j], coeffs[2][2] = 1 - * (ui, vi) - rectangle vertices - */ -static void cvGetPerspectiveTransform( Size src_size, double quad[4][2], double coeffs[3][3] ) -{ - double a[8][8]; - double b[8]; - - Mat A( 8, 8, CV_64FC1, a ); - Mat B( 8, 1, CV_64FC1, b ); - Mat X( 8, 1, CV_64FC1, coeffs ); - - int i; - for( i = 0; i < 4; ++i ) - { - a[i][0] = quad[i][0]; a[i][1] = quad[i][1]; a[i][2] = 1; - a[i][3] = a[i][4] = a[i][5] = a[i][6] = a[i][7] = 0; - b[i] = 0; - } - for( i = 4; i < 8; ++i ) - { - a[i][3] = quad[i-4][0]; a[i][4] = quad[i-4][1]; a[i][5] = 1; - a[i][0] = a[i][1] = a[i][2] = a[i][6] = a[i][7] = 0; - b[i] = 0; - } - - int u = src_size.width - 1; - int v = src_size.height - 1; - - a[1][6] = -quad[1][0] * u; a[1][7] = -quad[1][1] * u; - a[2][6] = -quad[2][0] * u; a[2][7] = -quad[2][1] * u; - b[1] = b[2] = u; - - a[6][6] = -quad[2][0] * v; a[6][7] = -quad[2][1] * v; - a[7][6] = -quad[3][0] * v; a[7][7] = -quad[3][1] * v; - b[6] = b[7] = v; - - solve( A, B, X ); - - coeffs[2][2] = 1; -} - -/* Warps source into destination by a perspective transform */ -static void cvWarpPerspective( Mat src, Mat dst, double quad[4][2] ) -{ - int fill_value = 0; - - double c[3][3]; /* transformation coefficients */ - double q[4][2]; /* rearranged quad */ - - int left = 0; - int right = 0; - int next_right = 0; - int next_left = 0; - double y_min = 0; - double y_max = 0; - double k_left, b_left, k_right, b_right; - - double d = 0; - int direction = 0; - int i; - - if( src.type() != CV_8UC1 || src.dims != 2 ) - { - CV_Error( Error::StsBadArg, - "Source must be two-dimensional array of CV_8UC1 type." ); - } - if( dst.type() != CV_8UC1 || dst.dims != 2 ) - { - CV_Error( Error::StsBadArg, - "Destination must be two-dimensional array of CV_8UC1 type." ); - } - - cvGetPerspectiveTransform( src.size(), quad, c ); - - /* if direction > 0 then vertices in quad follow in a CW direction, - otherwise they follow in a CCW direction */ - direction = 0; - for( i = 0; i < 4; ++i ) - { - int ni = i + 1; if( ni == 4 ) ni = 0; - int pi = i - 1; if( pi == -1 ) pi = 3; - - d = (quad[i][0] - quad[pi][0])*(quad[ni][1] - quad[i][1]) - - (quad[i][1] - quad[pi][1])*(quad[ni][0] - quad[i][0]); - int cur_direction = d > 0 ? 1 : d < 0 ? -1 : 0; - if( direction == 0 ) - { - direction = cur_direction; - } - else if( direction * cur_direction < 0 ) - { - direction = 0; - break; - } - } - if( direction == 0 ) - { - CV_Error(Error::StsBadArg, "Quadrangle is nonconvex or degenerated." ); - } - - /* is the index of the topmost quad vertice - if there are two such vertices is the leftmost one */ - left = 0; - for( i = 1; i < 4; ++i ) - { - if( (quad[i][1] < quad[left][1]) || - ((quad[i][1] == quad[left][1]) && (quad[i][0] < quad[left][0])) ) - { - left = i; - } - } - /* rearrange vertices in such way that they follow in a CW - direction and the first vertice is the topmost one and put them - into */ - if( direction > 0 ) - { - for( i = left; i < 4; ++i ) - { - q[i-left][0] = quad[i][0]; - q[i-left][1] = quad[i][1]; - } - for( i = 0; i < left; ++i ) - { - q[4-left+i][0] = quad[i][0]; - q[4-left+i][1] = quad[i][1]; - } - } - else - { - for( i = left; i >= 0; --i ) - { - q[left-i][0] = quad[i][0]; - q[left-i][1] = quad[i][1]; - } - for( i = 3; i > left; --i ) - { - q[4+left-i][0] = quad[i][0]; - q[4+left-i][1] = quad[i][1]; - } - } - - left = right = 0; - /* if there are two topmost points, is the index of the rightmost one - otherwise */ - if( q[left][1] == q[left+1][1] ) - { - right = 1; - } - - /* follows in a CCW direction */ - next_left = 3; - /* follows in a CW direction */ - next_right = right + 1; - - /* subtraction of 1 prevents skipping of the first row */ - y_min = q[left][1] - 1; - - /* left edge equation: y = k_left * x + b_left */ - k_left = (q[left][0] - q[next_left][0]) / - (q[left][1] - q[next_left][1]); - b_left = (q[left][1] * q[next_left][0] - - q[left][0] * q[next_left][1]) / - (q[left][1] - q[next_left][1]); - - /* right edge equation: y = k_right * x + b_right */ - k_right = (q[right][0] - q[next_right][0]) / - (q[right][1] - q[next_right][1]); - b_right = (q[right][1] * q[next_right][0] - - q[right][0] * q[next_right][1]) / - (q[right][1] - q[next_right][1]); - - for(;;) - { - int x, y; - - y_max = MIN( q[next_left][1], q[next_right][1] ); - - int iy_min = MAX( cvRound(y_min), 0 ) + 1; - int iy_max = MIN( cvRound(y_max), dst.rows - 1 ); - - double x_min = k_left * iy_min + b_left; - double x_max = k_right * iy_min + b_right; - - /* walk through the destination quadrangle row by row */ - for( y = iy_min; y <= iy_max; ++y ) - { - int ix_min = MAX( cvRound( x_min ), 0 ); - int ix_max = MIN( cvRound( x_max ), dst.cols - 1 ); - - for( x = ix_min; x <= ix_max; ++x ) - { - /* calculate coordinates of the corresponding source array point */ - double div = (c[2][0] * x + c[2][1] * y + c[2][2]); - double src_x = (c[0][0] * x + c[0][1] * y + c[0][2]) / div; - double src_y = (c[1][0] * x + c[1][1] * y + c[1][2]) / div; - - int isrc_x = cvFloor( src_x ); - int isrc_y = cvFloor( src_y ); - double delta_x = src_x - isrc_x; - double delta_y = src_y - isrc_y; - - int i00, i10, i01, i11; - i00 = i10 = i01 = i11 = (int) fill_value; - - /* linear interpolation using 2x2 neighborhood */ - if( isrc_x >= 0 && isrc_x < src.cols && - isrc_y >= 0 && isrc_y < src.rows ) - { - i00 = src.at(isrc_y, isrc_x); - } - if( isrc_x >= -1 && isrc_x + 1 < src.cols && - isrc_y >= 0 && isrc_y < src.rows ) - { - i10 = src.at(isrc_y, isrc_x + 1); - } - if( isrc_x >= 0 && isrc_x < src.cols && - isrc_y >= -1 && isrc_y + 1 < src.rows ) - { - i01 = src.at(isrc_y + 1, isrc_x); - } - if( isrc_x >= -1 && isrc_x + 1 < src.cols && - isrc_y >= -1 && isrc_y + 1 < src.rows ) - { - i11 = src.at(isrc_y + 1, isrc_x + 1); - } - - double i0 = i00 + (i10 - i00)*delta_x; - double i1 = i01 + (i11 - i01)*delta_x; - - dst.at(y, x) = (uchar) (i0 + (i1 - i0)*delta_y); - } - x_min += k_left; - x_max += k_right; - } - - if( (next_left == next_right) || - (next_left+1 == next_right && q[next_left][1] == q[next_right][1]) ) - { - break; - } - - if( y_max == q[next_left][1] ) - { - left = next_left; - next_left = left - 1; - - k_left = (q[left][0] - q[next_left][0]) / - (q[left][1] - q[next_left][1]); - b_left = (q[left][1] * q[next_left][0] - - q[left][0] * q[next_left][1]) / - (q[left][1] - q[next_left][1]); - } - if( y_max == q[next_right][1] ) - { - right = next_right; - next_right = right + 1; - - k_right = (q[right][0] - q[next_right][0]) / - (q[right][1] - q[next_right][1]); - b_right = (q[right][1] * q[next_right][0] - - q[right][0] * q[next_right][1]) / - (q[right][1] - q[next_right][1]); - } - y_min = y_max; - } -} - -static -void icvRandomQuad( int width, int height, double quad[4][2], - double maxxangle, - double maxyangle, - double maxzangle ) -{ - double distfactor = 3.0; - double distfactor2 = 1.0; - - double halfw, halfh; - int i; - - double rotVectData[3]; - double vectData[3]; - double rotMatData[9]; - - double d; - - Mat rotVect( 3, 1, CV_64FC1, &rotVectData[0] ); - Mat rotMat( 3, 3, CV_64FC1, &rotMatData[0] ); - Mat vect( 3, 1, CV_64FC1, &vectData[0] ); - - rotVectData[0] = theRNG().uniform( -maxxangle, maxxangle ); - rotVectData[1] = ( maxyangle - fabs( rotVectData[0] ) ) * theRNG().uniform( -1.0, 1.0 ); - rotVectData[2] = theRNG().uniform( -maxzangle, maxzangle ); - d = ( distfactor + distfactor2 * theRNG().uniform( -1.0, 1.0 ) ) * width; - - Rodrigues( rotVect, rotMat ); - - halfw = 0.5 * width; - halfh = 0.5 * height; - - quad[0][0] = -halfw; - quad[0][1] = -halfh; - quad[1][0] = halfw; - quad[1][1] = -halfh; - quad[2][0] = halfw; - quad[2][1] = halfh; - quad[3][0] = -halfw; - quad[3][1] = halfh; - - for( i = 0; i < 4; i++ ) - { - rotVectData[0] = quad[i][0]; - rotVectData[1] = quad[i][1]; - rotVectData[2] = 0.0; - gemm(rotMat, rotVect, 1., Mat(), 1., vect); - quad[i][0] = vectData[0] * d / (d + vectData[2]) + halfw; - quad[i][1] = vectData[1] * d / (d + vectData[2]) + halfh; - } -} - - -typedef struct CvSampleDistortionData -{ - Mat src; - Mat erode; - Mat dilate; - Mat mask; - Mat img; - Mat maskimg; - int dx; - int dy; - int bgcolor; -} CvSampleDistortionData; - -#if defined CV_OPENMP && (defined _MSC_VER || defined CV_ICC) -#define CV_OPENMP 1 -#else -#undef CV_OPENMP -#endif - -typedef struct CvBackgroundData -{ - int count; - char** filename; - int last; - int round; - Size winsize; -} CvBackgroundData; - -typedef struct CvBackgroundReader -{ - Mat src; - Mat img; - Point offset; - float scale; - float scalefactor; - float stepfactor; - Point point; -} CvBackgroundReader; - -/* - * Background reader - * Created in each thread - */ -CvBackgroundReader* cvbgreader = NULL; - -#if defined CV_OPENMP -#pragma omp threadprivate(cvbgreader) -#endif - -CvBackgroundData* cvbgdata = NULL; - -static int icvStartSampleDistortion( const char* imgfilename, int bgcolor, int bgthreshold, - CvSampleDistortionData* data ) -{ - memset( data, 0, sizeof( *data ) ); - data->src = imread( imgfilename, IMREAD_GRAYSCALE ); - if( !(data->src.empty()) && data->src.type() == CV_8UC1 ) - { - int r, c; - - data->dx = data->src.cols / 2; - data->dy = data->src.rows / 2; - data->bgcolor = bgcolor; - - data->mask = data->src.clone(); - data->erode = data->src.clone(); - data->dilate = data->src.clone(); - - /* make mask image */ - for( r = 0; r < data->mask.rows; r++ ) - { - for( c = 0; c < data->mask.cols; c++ ) - { - uchar& pmask = data->mask.at(r, c); - if( bgcolor - bgthreshold <= (int)pmask && - (int)pmask <= bgcolor + bgthreshold ) - { - pmask = (uchar) 0; - } - else - { - pmask = (uchar) 255; - } - } - } - - /* extend borders of source image */ - erode( data->src, data->erode, Mat() ); - dilate( data->src, data->dilate, Mat() ); - for( r = 0; r < data->mask.rows; r++ ) - { - for( c = 0; c < data->mask.cols; c++ ) - { - uchar& pmask = data->mask.at(r, c); - if( pmask == 0 ) - { - uchar& psrc = data->src.at(r, c); - uchar& perode = data->erode.at(r, c); - uchar& pdilate = data->dilate.at(r, c); - uchar de = (uchar)(bgcolor - perode); - uchar dd = (uchar)(pdilate - bgcolor); - if( de >= dd && de > bgthreshold ) - { - psrc = perode; - } - if( dd > de && dd > bgthreshold ) - { - psrc = pdilate; - } - } - } - } - - data->img = Mat(Size( data->src.cols + 2 * data->dx, data->src.rows + 2 * data->dy ), CV_8UC1); - data->maskimg = Mat(Size(data->src.cols + 2 * data->dx, data->src.rows + 2 * data->dy), CV_8UC1); - - return 1; - } - - return 0; -} - -static -void icvPlaceDistortedSample( Mat background, - int inverse, int maxintensitydev, - double maxxangle, double maxyangle, double maxzangle, - int inscribe, double maxshiftf, double maxscalef, - CvSampleDistortionData* data ) -{ - double quad[4][2]; - int r, c; - int forecolordev; - float scale; - - Rect cr; - Rect roi; - - double xshift, yshift, randscale; - - icvRandomQuad( data->src.cols, data->src.rows, quad, - maxxangle, maxyangle, maxzangle ); - quad[0][0] += (double) data->dx; - quad[0][1] += (double) data->dy; - quad[1][0] += (double) data->dx; - quad[1][1] += (double) data->dy; - quad[2][0] += (double) data->dx; - quad[2][1] += (double) data->dy; - quad[3][0] += (double) data->dx; - quad[3][1] += (double) data->dy; - - data->img = data->bgcolor; - data->maskimg = 0; - - cvWarpPerspective( data->src, data->img, quad ); - cvWarpPerspective( data->mask, data->maskimg, quad ); - - GaussianBlur( data->maskimg, data->maskimg, Size(3, 3), 0, 0 ); - - cr.x = data->dx; - cr.y = data->dy; - cr.width = data->src.cols; - cr.height = data->src.rows; - - if( inscribe ) - { - /* quad's circumscribing rectangle */ - cr.x = (int) MIN( quad[0][0], quad[3][0] ); - cr.y = (int) MIN( quad[0][1], quad[1][1] ); - cr.width = (int) (MAX( quad[1][0], quad[2][0] ) + 0.5F ) - cr.x; - cr.height = (int) (MAX( quad[2][1], quad[3][1] ) + 0.5F ) - cr.y; - } - - xshift = theRNG().uniform( 0., maxshiftf ); - yshift = theRNG().uniform( 0., maxshiftf ); - - cr.x -= (int) ( xshift * cr.width ); - cr.y -= (int) ( yshift * cr.height ); - cr.width = (int) ((1.0 + maxshiftf) * cr.width ); - cr.height = (int) ((1.0 + maxshiftf) * cr.height); - - randscale = theRNG().uniform( 0., maxscalef ); - cr.x -= (int) ( 0.5 * randscale * cr.width ); - cr.y -= (int) ( 0.5 * randscale * cr.height ); - cr.width = (int) ((1.0 + randscale) * cr.width ); - cr.height = (int) ((1.0 + randscale) * cr.height); - - scale = MAX( ((float) cr.width) / background.cols, ((float) cr.height) / background.rows ); - - roi.x = (int) (-0.5F * (scale * background.cols - cr.width) + cr.x); - roi.y = (int) (-0.5F * (scale * background.rows - cr.height) + cr.y); - roi.width = (int) (scale * background.cols); - roi.height = (int) (scale * background.rows); - - Mat img( background.size(), CV_8UC1 ); - Mat maskimg( background.size(), CV_8UC1 ); - - resize( data->img(roi & Rect(Point(0,0), data->img.size())), img, img.size(), 0, 0, INTER_LINEAR_EXACT); - resize( data->maskimg(roi & Rect(Point(0, 0), data->maskimg.size())), maskimg, maskimg.size(), 0, 0, INTER_LINEAR_EXACT); - - forecolordev = theRNG().uniform( -maxintensitydev, maxintensitydev ); - - for( r = 0; r < img.rows; r++ ) - { - for( c = 0; c < img.cols; c++ ) - { - uchar& pbg = background.at(r, c); - uchar& palpha = maskimg.at(r, c); - uchar chartmp = (uchar) MAX( 0, MIN( 255, forecolordev + img.at(r, c)) ); - if( inverse ) - { - chartmp ^= 0xFF; - } - pbg = (uchar) ((chartmp*palpha + (255 - palpha)*pbg) / 255); - } - } -} - -static -CvBackgroundData* icvCreateBackgroundData( const char* filename, Size winsize ) -{ - CvBackgroundData* data = NULL; - - const char* dir = NULL; - char full[PATH_MAX]; - char* imgfilename = NULL; - size_t datasize = 0; - int count = 0; - FILE* input = NULL; - char* tmp = NULL; - int len = 0; - - CV_Assert( filename != NULL ); - - dir = strrchr( filename, '\\' ); - if( dir == NULL ) - { - dir = strrchr( filename, '/' ); - } - if( dir == NULL ) - { - imgfilename = &(full[0]); - } - else - { - strncpy( &(full[0]), filename, (dir - filename + 1) ); - imgfilename = &(full[(dir - filename + 1)]); - } - - input = fopen( filename, "r" ); - if( input != NULL ) - { - count = 0; - datasize = 0; - - /* count */ - while( !feof( input ) ) - { - *imgfilename = '\0'; - if( !fgets( imgfilename, PATH_MAX - (int)(imgfilename - full) - 1, input )) - break; - len = (int)strlen( imgfilename ); - for( ; len > 0 && isspace(imgfilename[len-1]); len-- ) - imgfilename[len-1] = '\0'; - if( len > 0 ) - { - if( (*imgfilename) == '#' ) continue; /* comment */ - count++; - datasize += sizeof( char ) * (strlen( &(full[0]) ) + 1); - } - } - if( count > 0 ) - { - //rewind( input ); - fseek( input, 0, SEEK_SET ); - datasize += sizeof( *data ) + sizeof( char* ) * count; - data = (CvBackgroundData*) fastMalloc( datasize ); - memset( (void*) data, 0, datasize ); - data->count = count; - data->filename = (char**) (data + 1); - data->last = 0; - data->round = 0; - data->winsize = winsize; - tmp = (char*) (data->filename + data->count); - count = 0; - while( !feof( input ) ) - { - *imgfilename = '\0'; - if( !fgets( imgfilename, PATH_MAX - (int)(imgfilename - full) - 1, input )) - break; - len = (int)strlen( imgfilename ); - if( len > 0 && imgfilename[len-1] == '\n' ) - imgfilename[len-1] = 0, len--; - if( len > 0 ) - { - if( (*imgfilename) == '#' ) continue; /* comment */ - data->filename[count++] = tmp; - strcpy( tmp, &(full[0]) ); - tmp += strlen( &(full[0]) ) + 1; - } - } - } - fclose( input ); - } - - return data; -} - -static -CvBackgroundReader* icvCreateBackgroundReader() -{ - CvBackgroundReader* reader = NULL; - - reader = new CvBackgroundReader; - reader->scale = 1.0F; - reader->scalefactor = 1.4142135623730950488016887242097F; - reader->stepfactor = 0.5F; - - return reader; -} - -static -void icvGetNextFromBackgroundData( CvBackgroundData* data, - CvBackgroundReader* reader ) -{ - Mat img; - int round = 0; - int i = 0; - Point offset; - - CV_Assert( data != NULL && reader != NULL ); - - #ifdef CV_OPENMP - #pragma omp critical(c_background_data) - #endif /* CV_OPENMP */ - { - for( i = 0; i < data->count; i++ ) - { - round = data->round; - - data->last = theRNG().uniform( 0, RAND_MAX ) % data->count; - -#ifdef CV_VERBOSE - printf( "Open background image: %s\n", data->filename[data->last] ); -#endif /* CV_VERBOSE */ - - img = imread( data->filename[data->last], IMREAD_GRAYSCALE ); - if( img.empty() ) - continue; - data->round += data->last / data->count; - data->round = data->round % (data->winsize.width * data->winsize.height); - - offset.x = round % data->winsize.width; - offset.y = round / data->winsize.width; - - offset.x = MIN( offset.x, img.cols - data->winsize.width ); - offset.y = MIN( offset.y, img.rows - data->winsize.height ); - - if( !img.empty() && img.type() == CV_8UC1 && offset.x >= 0 && offset.y >= 0 ) - { - break; - } - img = Mat(); - } - } - if( img.empty() ) - { - /* no appropriate image */ - -#ifdef CV_VERBOSE - printf( "Invalid background description file.\n" ); -#endif /* CV_VERBOSE */ - - CV_Assert( 0 ); - exit( 1 ); - } - - reader->src = img; - - //reader->offset.x = round % data->winsize.width; - //reader->offset.y = round / data->winsize.width; - reader->offset = offset; - reader->point = reader->offset; - reader->scale = MAX( - ((float) data->winsize.width + reader->point.x) / ((float) reader->src.cols), - ((float) data->winsize.height + reader->point.y) / ((float) reader->src.rows) ); - - resize( reader->src, reader->img, - Size((int)(reader->scale * reader->src.cols + 0.5F), (int)(reader->scale * reader->src.rows + 0.5F)), 0, 0, INTER_LINEAR_EXACT); -} - -/* - * icvGetBackgroundImage - * - * Get an image from background - * must be allocated and have size, previously passed to icvInitBackgroundReaders - * - * Usage example: - * icvInitBackgroundReaders( "bg.txt", cvSize( 24, 24 ) ); - * ... - * #pragma omp parallel - * { - * ... - * icvGetBackgroundImage( cvbgdata, cvbgreader, img ); - * ... - * } - * ... - * icvDestroyBackgroundReaders(); - */ -static -void icvGetBackgroundImage( CvBackgroundData* data, - CvBackgroundReader* reader, - Mat& img ) -{ - CV_Assert( data != NULL && reader != NULL ); - - if( reader->img.empty() ) - { - icvGetNextFromBackgroundData( data, reader ); - } - - img = reader->img(Rect(reader->point.x, reader->point.y, data->winsize.width, data->winsize.height)).clone(); - - if( (int) ( reader->point.x + (1.0F + reader->stepfactor ) * data->winsize.width ) - < reader->img.cols ) - { - reader->point.x += (int) (reader->stepfactor * data->winsize.width); - } - else - { - reader->point.x = reader->offset.x; - if( (int) ( reader->point.y + (1.0F + reader->stepfactor ) * data->winsize.height ) - < reader->img.rows ) - { - reader->point.y += (int) (reader->stepfactor * data->winsize.height); - } - else - { - reader->point.y = reader->offset.y; - reader->scale *= reader->scalefactor; - if( reader->scale <= 1.0F ) - { - resize(reader->src, reader->img, - Size((int)(reader->scale * reader->src.cols), (int)(reader->scale * reader->src.rows)), 0, 0, INTER_LINEAR_EXACT); - } - else - { - icvGetNextFromBackgroundData( data, reader ); - } - } - } -} - -/* - * icvInitBackgroundReaders - * - * Initialize background reading process. - * and are initialized. - * Must be called before any usage of background - * - * filename - name of background description file - * winsize - size of images will be obtained from background - * - * return 1 on success, 0 otherwise. - */ -static int icvInitBackgroundReaders( const char* filename, Size winsize ) -{ - if( cvbgdata == NULL && filename != NULL ) - { - cvbgdata = icvCreateBackgroundData( filename, winsize ); - } - - if( cvbgdata ) - { - - #ifdef CV_OPENMP - #pragma omp parallel - #endif /* CV_OPENMP */ - { - #ifdef CV_OPENMP - #pragma omp critical(c_create_bg_data) - #endif /* CV_OPENMP */ - { - if( cvbgreader == NULL ) - { - cvbgreader = icvCreateBackgroundReader(); - } - } - } - - } - - return (cvbgdata != NULL); -} - -/* - * icvDestroyBackgroundReaders - * - * Finish background reading process - */ -static -void icvDestroyBackgroundReaders() -{ - /* release background reader in each thread */ - #ifdef CV_OPENMP - #pragma omp parallel - #endif /* CV_OPENMP */ - { - #ifdef CV_OPENMP - #pragma omp critical(c_release_bg_data) - #endif /* CV_OPENMP */ - { - if( cvbgreader != NULL ) - { - delete cvbgreader; - cvbgreader = NULL; - } - } - } - - if( cvbgdata != NULL ) - { - fastFree(cvbgdata); - cvbgdata = NULL; - } -} - -void cvCreateTrainingSamples( const char* filename, - const char* imgfilename, int bgcolor, int bgthreshold, - const char* bgfilename, int count, - int invert, int maxintensitydev, - double maxxangle, double maxyangle, double maxzangle, - int showsamples, - int winwidth, int winheight ) -{ - CvSampleDistortionData data; - - CV_Assert( filename != NULL ); - CV_Assert( imgfilename != NULL ); - - if( !icvMkDir( filename ) ) - { - fprintf( stderr, "Unable to create output file: %s\n", filename ); - return; - } - if( icvStartSampleDistortion( imgfilename, bgcolor, bgthreshold, &data ) ) - { - FILE* output = NULL; - - output = fopen( filename, "wb" ); - if( output != NULL ) - { - int i; - int inverse; - - const int hasbg = (bgfilename != NULL && icvInitBackgroundReaders( bgfilename, - Size( winwidth,winheight ) ) ); - - Mat sample( winheight, winwidth, CV_8UC1 ); - - icvWriteVecHeader( output, count, sample.cols, sample.rows ); - - if( showsamples ) - { - namedWindow( "Sample", WINDOW_AUTOSIZE ); - } - - inverse = invert; - for( i = 0; i < count; i++ ) - { - if( hasbg ) - { - icvGetBackgroundImage( cvbgdata, cvbgreader, sample ); - } - else - { - sample = bgcolor; - } - - if( invert == CV_RANDOM_INVERT ) - { - inverse = theRNG().uniform( 0, 2 ); - } - icvPlaceDistortedSample( sample, inverse, maxintensitydev, - maxxangle, maxyangle, maxzangle, - 0 /* nonzero means placing image without cut offs */, - 0.0 /* nonzero adds random shifting */, - 0.0 /* nonzero adds random scaling */, - &data ); - - if( showsamples ) - { - imshow( "Sample", sample ); - if( (waitKey( 0 ) & 0xFF) == 27 ) - { - showsamples = 0; - } - } - - icvWriteVecSample( output, sample ); - -#ifdef CV_VERBOSE - if( i % 500 == 0 ) - { - printf( "\r%3d%%", 100 * i / count ); - } -#endif /* CV_VERBOSE */ - } - icvDestroyBackgroundReaders(); - fclose( output ); - } /* if( output != NULL ) */ - } - -#ifdef CV_VERBOSE - printf( "\r \r" ); -#endif /* CV_VERBOSE */ - -} - -#define CV_INFO_FILENAME "info.dat" - -void cvCreateTestSamples( const char* infoname, - const char* imgfilename, int bgcolor, int bgthreshold, - const char* bgfilename, int count, - int invert, int maxintensitydev, - double maxxangle, double maxyangle, double maxzangle, - int showsamples, - int winwidth, int winheight, double maxscale ) -{ - CvSampleDistortionData data; - - CV_Assert( infoname != NULL ); - CV_Assert( imgfilename != NULL ); - CV_Assert( bgfilename != NULL ); - - if( !icvMkDir( infoname ) ) - { - -#if CV_VERBOSE - fprintf( stderr, "Unable to create directory hierarchy: %s\n", infoname ); -#endif /* CV_VERBOSE */ - - return; - } - if( icvStartSampleDistortion( imgfilename, bgcolor, bgthreshold, &data ) ) - { - char fullname[PATH_MAX]; - char* filename; - FILE* info; - - if( icvInitBackgroundReaders( bgfilename, Size( 10, 10 ) ) ) - { - int i; - int x, y, width, height; - float scale; - int inverse; - - if( showsamples ) - { - namedWindow( "Image", WINDOW_AUTOSIZE ); - } - - info = fopen( infoname, "w" ); - strcpy( fullname, infoname ); - filename = strrchr( fullname, '\\' ); - if( filename == NULL ) - { - filename = strrchr( fullname, '/' ); - } - if( filename == NULL ) - { - filename = fullname; - } - else - { - filename++; // character after last / or \ - } - - count = MIN( count, cvbgdata->count ); - inverse = invert; - for( i = 0; i < count; i++ ) - { - icvGetNextFromBackgroundData( cvbgdata, cvbgreader ); - if( maxscale < 0.0 ) - { - maxscale = MIN( 0.7F * cvbgreader->src.cols / winwidth, - 0.7F * cvbgreader->src.rows / winheight ); - } - - if( maxscale < 1.0F ) continue; - - scale = theRNG().uniform( 1.0F, (float)maxscale ); - - width = (int) (scale * winwidth); - height = (int) (scale * winheight); - x = (int) ( theRNG().uniform( 0.1, 0.8 ) * (cvbgreader->src.cols - width)); - y = (int) ( theRNG().uniform( 0.1, 0.8 ) * (cvbgreader->src.rows - height)); - - if( invert == CV_RANDOM_INVERT ) - { - inverse = theRNG().uniform( 0, 2 ); - } - icvPlaceDistortedSample( cvbgreader->src(Rect(x, y, width, height)), inverse, maxintensitydev, - maxxangle, maxyangle, maxzangle, - 1, 0.0, 0.0, &data ); - - - snprintf( filename, sizeof(fullname) - (filename - fullname), "%04d_%04d_%04d_%04d_%04d.jpg", - (i + 1), x, y, width, height ); - - if( info ) - { - fprintf( info, "%s %d %d %d %d %d\n", - filename, 1, x, y, width, height ); - } - - imwrite( fullname, cvbgreader->src ); - if( showsamples ) - { - imshow( "Image", cvbgreader->src ); - if( (waitKey( 0 ) & 0xFF) == 27 ) - { - showsamples = 0; - } - } - } - if( info ) fclose( info ); - icvDestroyBackgroundReaders(); - } - } -} - - -int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilename, - int num, - int showsamples, - int winwidth, int winheight ) -{ - char fullname[PATH_MAX]; - char* filename; - - FILE* info; - FILE* vec; - int line; - int error; - int i; - int x, y, width, height; - int total; - - CV_Assert( infoname != NULL ); - CV_Assert( vecfilename != NULL ); - - total = 0; - if( !icvMkDir( vecfilename ) ) - { - -#if CV_VERBOSE - fprintf( stderr, "Unable to create directory hierarchy: %s\n", vecfilename ); -#endif /* CV_VERBOSE */ - - return total; - } - - info = fopen( infoname, "r" ); - if( info == NULL ) - { - -#if CV_VERBOSE - fprintf( stderr, "Unable to open file: %s\n", infoname ); -#endif /* CV_VERBOSE */ - - return total; - } - - vec = fopen( vecfilename, "wb" ); - if( vec == NULL ) - { - -#if CV_VERBOSE - fprintf( stderr, "Unable to open file: %s\n", vecfilename ); -#endif /* CV_VERBOSE */ - - fclose( info ); - - return total; - } - - icvWriteVecHeader( vec, num, winwidth, winheight ); - - if( showsamples ) - { - namedWindow( "Sample", WINDOW_AUTOSIZE ); - } - - strcpy( fullname, infoname ); - filename = strrchr( fullname, '\\' ); - if( filename == NULL ) - { - filename = strrchr( fullname, '/' ); - } - if( filename == NULL ) - { - filename = fullname; - } - else - { - filename++; - } - - for( line = 1, error = 0, total = 0; total < num ;line++ ) - { - Mat src; - int count; - - if(fscanf(info, "%s %d", filename, &count) == 2) - { - src = imread( fullname, IMREAD_GRAYSCALE ); - if(src.empty()) - { - -#if CV_VERBOSE - fprintf( stderr, "Unable to open image: %s\n", fullname ); -#endif /* CV_VERBOSE */ - - } - } - for( i = 0; (i < count) && (total < num); i++, total++ ) - { - error = ( fscanf( info, "%d %d %d %d", &x, &y, &width, &height ) != 4 ); - if( error ) break; - Mat sample; - resize( src(Rect(x, y, width, height)), sample, Size(winwidth, winheight), 0, 0, - width >= winwidth && height >= winheight ? INTER_AREA : INTER_LINEAR_EXACT ); - - if( showsamples ) - { - imshow( "Sample", sample ); - if( (waitKey( 0 ) & 0xFF) == 27 ) - { - showsamples = 0; - } - } - icvWriteVecSample( vec, sample ); - } - - if( error ) - { - -#if CV_VERBOSE - fprintf( stderr, "%s(%d) : parse error", infoname, line ); -#endif /* CV_VERBOSE */ - - break; - } - } - - fclose( vec ); - fclose( info ); - - return total; -} - -typedef struct CvVecFile -{ - FILE* input; - int count; - int vecsize; - int last; -} CvVecFile; - -static -int icvGetTraininDataFromVec( Mat& img, CvVecFile& userdata ) -{ - AutoBuffer vector(userdata.vecsize); - uchar tmp = 0; - int r = 0; - int c = 0; - - CV_Assert( img.rows * img.cols == userdata.vecsize ); - - size_t elements_read = fread( &tmp, sizeof( tmp ), 1, userdata.input ); - CV_Assert(elements_read == 1); - elements_read = fread(vector.data(), sizeof(short), userdata.vecsize, userdata.input); - CV_Assert(elements_read == (size_t)userdata.vecsize); - - if( feof( userdata.input ) || userdata.last++ >= userdata.count ) - { - return 0; - } - - for( r = 0; r < img.rows; r++ ) - { - for( c = 0; c < img.cols; c++ ) - { - img.at(r, c) = (uchar) ( vector[r * img.cols + c] ); - } - } - - return 1; -} -void cvShowVecSamples( const char* filename, int winwidth, int winheight, - double scale ) -{ - CvVecFile file; - short tmp; - int i; - - tmp = 0; - file.input = fopen( filename, "rb" ); - - if( file.input != NULL ) - { - size_t elements_read1 = fread( &file.count, sizeof( file.count ), 1, file.input ); - size_t elements_read2 = fread( &file.vecsize, sizeof( file.vecsize ), 1, file.input ); - size_t elements_read3 = fread( &tmp, sizeof( tmp ), 1, file.input ); - size_t elements_read4 = fread( &tmp, sizeof( tmp ), 1, file.input ); - CV_Assert(elements_read1 == 1 && elements_read2 == 1 && elements_read3 == 1 && elements_read4 == 1); - - if( file.vecsize != winwidth * winheight ) - { - int guessed_w = 0; - int guessed_h = 0; - - fprintf( stderr, "Warning: specified sample width=%d and height=%d " - "does not correspond to .vec file vector size=%d.\n", - winwidth, winheight, file.vecsize ); - if( file.vecsize > 0 ) - { - guessed_w = cvFloor( sqrt( (float) file.vecsize ) ); - if( guessed_w > 0 ) - { - guessed_h = file.vecsize / guessed_w; - } - } - - if( guessed_w <= 0 || guessed_h <= 0 || guessed_w * guessed_h != file.vecsize) - { - fprintf( stderr, "Error: failed to guess sample width and height\n" ); - fclose( file.input ); - - return; - } - else - { - winwidth = guessed_w; - winheight = guessed_h; - fprintf( stderr, "Guessed width=%d, guessed height=%d\n", - winwidth, winheight ); - } - } - - if( !feof( file.input ) && scale > 0 ) - { - file.last = 0; - namedWindow( "Sample", WINDOW_AUTOSIZE ); - for( i = 0; i < file.count; i++ ) - { - Mat sample(winheight, winwidth, CV_8UC1); - icvGetTraininDataFromVec( sample, file ); - if( scale != 1.0 ) - resize( sample, sample, - Size(MAX(1, cvCeil(scale * winwidth)), MAX(1, cvCeil(scale * winheight))), 0, 0, INTER_LINEAR_EXACT); - imshow( "Sample", sample ); - if( waitKey( 0 ) == 27 ) break; - } - } - fclose( file.input ); - } -} diff --git a/apps/createsamples/utility.hpp b/apps/createsamples/utility.hpp deleted file mode 100644 index d04947c9be..0000000000 --- a/apps/createsamples/utility.hpp +++ /dev/null @@ -1,124 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// Intel License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2000, Intel Corporation, all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * The name of Intel Corporation may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// This software is provided by the copyright holders and contributors "as is" and -// any express or implied warranties, including, but not limited to, the implied -// warranties of merchantability and fitness for a particular purpose are disclaimed. -// In no event shall the Intel Corporation or contributors be liable for any direct, -// indirect, incidental, special, exemplary, or consequential damages -// (including, but not limited to, procurement of substitute goods or services; -// loss of use, data, or profits; or business interruption) however caused -// and on any theory of liability, whether in contract, strict liability, -// or tort (including negligence or otherwise) arising in any way out of -// the use of this software, even if advised of the possibility of such damage. -// -//M*/ - -#ifndef __CREATESAMPLES_UTILITY_HPP__ -#define __CREATESAMPLES_UTILITY_HPP__ - -#define CV_VERBOSE 1 - -/* - * cvCreateTrainingSamples - * - * Create training samples applying random distortions to sample image and - * store them in .vec file - * - * filename - .vec file name - * imgfilename - sample image file name - * bgcolor - background color for sample image - * bgthreshold - background color threshold. Pixels those colors are in range - * [bgcolor-bgthreshold, bgcolor+bgthreshold] are considered as transparent - * bgfilename - background description file name. If not NULL samples - * will be put on arbitrary background - * count - desired number of samples - * invert - if not 0 sample foreground pixels will be inverted - * if invert == CV_RANDOM_INVERT then samples will be inverted randomly - * maxintensitydev - desired max intensity deviation of foreground samples pixels - * maxxangle - max rotation angles - * maxyangle - * maxzangle - * showsamples - if not 0 samples will be shown - * winwidth - desired samples width - * winheight - desired samples height - */ -#define CV_RANDOM_INVERT 0x7FFFFFFF - -void cvCreateTrainingSamples( const char* filename, - const char* imgfilename, int bgcolor, int bgthreshold, - const char* bgfilename, int count, - int invert = 0, int maxintensitydev = 40, - double maxxangle = 1.1, - double maxyangle = 1.1, - double maxzangle = 0.5, - int showsamples = 0, - int winwidth = 24, int winheight = 24 ); - -void cvCreateTestSamples( const char* infoname, - const char* imgfilename, int bgcolor, int bgthreshold, - const char* bgfilename, int count, - int invert, int maxintensitydev, - double maxxangle, double maxyangle, double maxzangle, - int showsamples, - int winwidth, int winheight, double maxscale ); - -/* - * cvCreateTrainingSamplesFromInfo - * - * Create training samples from a set of marked up images and store them into .vec file - * infoname - file in which marked up image descriptions are stored - * num - desired number of samples - * showsamples - if not 0 samples will be shown - * winwidth - sample width - * winheight - sample height - * - * Return number of successfully created samples - */ -int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilename, - int num, - int showsamples, - int winwidth, int winheight ); - -/* - * cvShowVecSamples - * - * Shows samples stored in .vec file - * - * filename - * .vec file name - * winwidth - * sample width - * winheight - * sample height - * scale - * the scale each sample is adjusted to - */ -void cvShowVecSamples( const char* filename, int winwidth, int winheight, double scale ); - -#endif //__CREATESAMPLES_UTILITY_HPP__ diff --git a/apps/traincascade/CMakeLists.txt b/apps/traincascade/CMakeLists.txt deleted file mode 100644 index ec90ebbff3..0000000000 --- a/apps/traincascade/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -ocv_warnings_disable(CMAKE_CXX_FLAGS -Woverloaded-virtual -Winconsistent-missing-override -Wsuggest-override) -file(GLOB SRCS *.cpp) -ocv_add_application(opencv_traincascade - MODULES opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_3d opencv_features2d - SRCS ${SRCS}) diff --git a/apps/traincascade/HOGfeatures.cpp b/apps/traincascade/HOGfeatures.cpp deleted file mode 100644 index 0707f936d5..0000000000 --- a/apps/traincascade/HOGfeatures.cpp +++ /dev/null @@ -1,250 +0,0 @@ -#include "opencv2/core.hpp" -#include "opencv2/imgproc.hpp" - -#include "HOGfeatures.h" -#include "cascadeclassifier.h" - -using namespace std; -using namespace cv; - -CvHOGFeatureParams::CvHOGFeatureParams() -{ - maxCatCount = 0; - name = HOGF_NAME; - featSize = N_BINS * N_CELLS; -} - -void CvHOGEvaluator::init(const CvFeatureParams *_featureParams, int _maxSampleCount, Size _winSize) -{ - CV_Assert( _maxSampleCount > 0); - int cols = (_winSize.width + 1) * (_winSize.height + 1); - for (int bin = 0; bin < N_BINS; bin++) - { - hist.push_back(Mat(_maxSampleCount, cols, CV_32FC1)); - } - normSum.create( (int)_maxSampleCount, cols, CV_32FC1 ); - CvFeatureEvaluator::init( _featureParams, _maxSampleCount, _winSize ); -} - -void CvHOGEvaluator::setImage(const Mat &img, uchar clsLabel, int idx) -{ - CV_DbgAssert( !hist.empty()); - CvFeatureEvaluator::setImage( img, clsLabel, idx ); - vector integralHist; - for (int bin = 0; bin < N_BINS; bin++) - { - integralHist.push_back( Mat(winSize.height + 1, winSize.width + 1, hist[bin].type(), hist[bin].ptr((int)idx)) ); - } - Mat integralNorm(winSize.height + 1, winSize.width + 1, normSum.type(), normSum.ptr((int)idx)); - integralHistogram(img, integralHist, integralNorm, (int)N_BINS); -} - -//void CvHOGEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const -//{ -// _writeFeatures( features, fs, featureMap ); -//} - -void CvHOGEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const -{ - int featIdx; - int componentIdx; - const Mat_& featureMap_ = (const Mat_&)featureMap; - fs << FEATURES << "["; - for ( int fi = 0; fi < featureMap.cols; fi++ ) - if ( featureMap_(0, fi) >= 0 ) - { - fs << "{"; - featIdx = fi / getFeatureSize(); - componentIdx = fi % getFeatureSize(); - features[featIdx].write( fs, componentIdx ); - fs << "}"; - } - fs << "]"; -} - -void CvHOGEvaluator::generateFeatures() -{ - int offset = winSize.width + 1; - Size blockStep; - int x, y, t, w, h; - - for (t = 8; t <= winSize.width/2; t+=8) //t = size of a cell. blocksize = 4*cellSize - { - blockStep = Size(4,4); - w = 2*t; //width of a block - h = 2*t; //height of a block - for (x = 0; x <= winSize.width - w; x += blockStep.width) - { - for (y = 0; y <= winSize.height - h; y += blockStep.height) - { - features.push_back(Feature(offset, x, y, t, t)); - } - } - w = 2*t; - h = 4*t; - for (x = 0; x <= winSize.width - w; x += blockStep.width) - { - for (y = 0; y <= winSize.height - h; y += blockStep.height) - { - features.push_back(Feature(offset, x, y, t, 2*t)); - } - } - w = 4*t; - h = 2*t; - for (x = 0; x <= winSize.width - w; x += blockStep.width) - { - for (y = 0; y <= winSize.height - h; y += blockStep.height) - { - features.push_back(Feature(offset, x, y, 2*t, t)); - } - } - } - - numFeatures = (int)features.size(); -} - -CvHOGEvaluator::Feature::Feature() -{ - for (int i = 0; i < N_CELLS; i++) - { - rect[i] = Rect(0, 0, 0, 0); - } -} - -CvHOGEvaluator::Feature::Feature( int offset, int x, int y, int cellW, int cellH ) -{ - rect[0] = Rect(x, y, cellW, cellH); //cell0 - rect[1] = Rect(x+cellW, y, cellW, cellH); //cell1 - rect[2] = Rect(x, y+cellH, cellW, cellH); //cell2 - rect[3] = Rect(x+cellW, y+cellH, cellW, cellH); //cell3 - - for (int i = 0; i < N_CELLS; i++) - { - CV_SUM_OFFSETS(fastRect[i].p0, fastRect[i].p1, fastRect[i].p2, fastRect[i].p3, rect[i], offset); - } -} - -void CvHOGEvaluator::Feature::write(FileStorage &fs) const -{ - fs << CC_RECTS << "["; - for( int i = 0; i < N_CELLS; i++ ) - { - fs << "[:" << rect[i].x << rect[i].y << rect[i].width << rect[i].height << "]"; - } - fs << "]"; -} - -//cell and bin idx writing -//void CvHOGEvaluator::Feature::write(FileStorage &fs, int varIdx) const -//{ -// int featComponent = varIdx % (N_CELLS * N_BINS); -// int cellIdx = featComponent / N_BINS; -// int binIdx = featComponent % N_BINS; -// -// fs << CC_RECTS << "[:" << rect[cellIdx].x << rect[cellIdx].y << -// rect[cellIdx].width << rect[cellIdx].height << binIdx << "]"; -//} - -//cell[0] and featComponent idx writing. By cell[0] it's possible to recover all block -//All block is necessary for block normalization -void CvHOGEvaluator::Feature::write(FileStorage &fs, int featComponentIdx) const -{ - fs << CC_RECT << "[:" << rect[0].x << rect[0].y << - rect[0].width << rect[0].height << featComponentIdx << "]"; -} - - -void CvHOGEvaluator::integralHistogram(const Mat &img, vector &histogram, Mat &norm, int nbins) const -{ - CV_Assert( img.type() == CV_8U || img.type() == CV_8UC3 ); - int x, y, binIdx; - - Size gradSize(img.size()); - Size histSize(histogram[0].size()); - Mat grad(gradSize, CV_32F); - Mat qangle(gradSize, CV_8U); - - AutoBuffer mapbuf(gradSize.width + gradSize.height + 4); - int* xmap = mapbuf.data() + 1; - int* ymap = xmap + gradSize.width + 2; - - const int borderType = (int)BORDER_REPLICATE; - - for( x = -1; x < gradSize.width + 1; x++ ) - xmap[x] = borderInterpolate(x, gradSize.width, borderType); - for( y = -1; y < gradSize.height + 1; y++ ) - ymap[y] = borderInterpolate(y, gradSize.height, borderType); - - int width = gradSize.width; - AutoBuffer _dbuf(width*4); - float* dbuf = _dbuf.data(); - Mat Dx(1, width, CV_32F, dbuf); - Mat Dy(1, width, CV_32F, dbuf + width); - Mat Mag(1, width, CV_32F, dbuf + width*2); - Mat Angle(1, width, CV_32F, dbuf + width*3); - - float angleScale = (float)(nbins/CV_PI); - - for( y = 0; y < gradSize.height; y++ ) - { - const uchar* currPtr = img.ptr(ymap[y]); - const uchar* prevPtr = img.ptr(ymap[y-1]); - const uchar* nextPtr = img.ptr(ymap[y+1]); - float* gradPtr = grad.ptr(y); - uchar* qanglePtr = qangle.ptr(y); - - for( x = 0; x < width; x++ ) - { - dbuf[x] = (float)(currPtr[xmap[x+1]] - currPtr[xmap[x-1]]); - dbuf[width + x] = (float)(nextPtr[xmap[x]] - prevPtr[xmap[x]]); - } - cartToPolar( Dx, Dy, Mag, Angle, false ); - for( x = 0; x < width; x++ ) - { - float mag = dbuf[x+width*2]; - float angle = dbuf[x+width*3]; - angle = angle*angleScale - 0.5f; - int bidx = cvFloor(angle); - angle -= bidx; - if( bidx < 0 ) - bidx += nbins; - else if( bidx >= nbins ) - bidx -= nbins; - - qanglePtr[x] = (uchar)bidx; - gradPtr[x] = mag; - } - } - integral(grad, norm, grad.depth()); - - float* histBuf; - const float* magBuf; - const uchar* binsBuf; - - int binsStep = (int)( qangle.step / sizeof(uchar) ); - int histStep = (int)( histogram[0].step / sizeof(float) ); - int magStep = (int)( grad.step / sizeof(float) ); - for( binIdx = 0; binIdx < nbins; binIdx++ ) - { - histBuf = histogram[binIdx].ptr(); - magBuf = grad.ptr(); - binsBuf = qangle.ptr(); - - memset( histBuf, 0, histSize.width * sizeof(histBuf[0]) ); - histBuf += histStep + 1; - for( y = 0; y < qangle.rows; y++ ) - { - histBuf[-1] = 0.f; - float strSum = 0.f; - for( x = 0; x < qangle.cols; x++ ) - { - if( binsBuf[x] == binIdx ) - strSum += magBuf[x]; - histBuf[x] = histBuf[-histStep + x] + strSum; - } - histBuf += histStep; - binsBuf += binsStep; - magBuf += magStep; - } - } -} diff --git a/apps/traincascade/HOGfeatures.h b/apps/traincascade/HOGfeatures.h deleted file mode 100644 index 3d4092eab9..0000000000 --- a/apps/traincascade/HOGfeatures.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef _OPENCV_HOGFEATURES_H_ -#define _OPENCV_HOGFEATURES_H_ - -#include "traincascade_features.h" - -//#define TEST_INTHIST_BUILD -//#define TEST_FEAT_CALC - -#define N_BINS 9 -#define N_CELLS 4 - -#define HOGF_NAME "HOGFeatureParams" -struct CvHOGFeatureParams : public CvFeatureParams -{ - CvHOGFeatureParams(); -}; - -class CvHOGEvaluator : public CvFeatureEvaluator -{ -public: - virtual ~CvHOGEvaluator() {} - virtual void init(const CvFeatureParams *_featureParams, - int _maxSampleCount, cv::Size _winSize ); - virtual void setImage(const cv::Mat& img, uchar clsLabel, int idx); - virtual float operator()(int varIdx, int sampleIdx) const; - virtual void writeFeatures( cv::FileStorage &fs, const cv::Mat& featureMap ) const; -protected: - virtual void generateFeatures(); - virtual void integralHistogram(const cv::Mat &img, std::vector &histogram, cv::Mat &norm, int nbins) const; - class Feature - { - public: - Feature(); - Feature( int offset, int x, int y, int cellW, int cellH ); - float calc( const std::vector &_hists, const cv::Mat &_normSum, size_t y, int featComponent ) const; - void write( cv::FileStorage &fs ) const; - void write( cv::FileStorage &fs, int varIdx ) const; - - cv::Rect rect[N_CELLS]; //cells - - struct - { - int p0, p1, p2, p3; - } fastRect[N_CELLS]; - }; - std::vector features; - - cv::Mat normSum; //for normalization calculation (L1 or L2) - std::vector hist; -}; - -inline float CvHOGEvaluator::operator()(int varIdx, int sampleIdx) const -{ - int featureIdx = varIdx / (N_BINS * N_CELLS); - int componentIdx = varIdx % (N_BINS * N_CELLS); - //return features[featureIdx].calc( hist, sampleIdx, componentIdx); - return features[featureIdx].calc( hist, normSum, sampleIdx, componentIdx); -} - -inline float CvHOGEvaluator::Feature::calc( const std::vector& _hists, const cv::Mat& _normSum, size_t y, int featComponent ) const -{ - float normFactor; - float res; - - int binIdx = featComponent % N_BINS; - int cellIdx = featComponent / N_BINS; - - const float *phist = _hists[binIdx].ptr((int)y); - res = phist[fastRect[cellIdx].p0] - phist[fastRect[cellIdx].p1] - phist[fastRect[cellIdx].p2] + phist[fastRect[cellIdx].p3]; - - const float *pnormSum = _normSum.ptr((int)y); - normFactor = (float)(pnormSum[fastRect[0].p0] - pnormSum[fastRect[1].p1] - pnormSum[fastRect[2].p2] + pnormSum[fastRect[3].p3]); - res = (res > 0.001f) ? ( res / (normFactor + 0.001f) ) : 0.f; //for cutting negative values, which appear due to floating precision - - return res; -} - -#endif // _OPENCV_HOGFEATURES_H_ diff --git a/apps/traincascade/boost.cpp b/apps/traincascade/boost.cpp deleted file mode 100644 index d409216b8a..0000000000 --- a/apps/traincascade/boost.cpp +++ /dev/null @@ -1,1718 +0,0 @@ -#include "opencv2/core.hpp" -#include "opencv2/core/utility.hpp" - -using cv::Size; -using cv::Mat; -using cv::Point; -using cv::FileStorage; -using cv::Rect; -using cv::Ptr; -using cv::FileNode; -using cv::Mat_; -using cv::Range; -using cv::FileNodeIterator; -using cv::ParallelLoopBody; - - -using cv::Size; -using cv::Mat; -using cv::Point; -using cv::FileStorage; -using cv::Rect; -using cv::Ptr; -using cv::FileNode; -using cv::Mat_; -using cv::Range; -using cv::FileNodeIterator; -using cv::ParallelLoopBody; - - -#include "boost.h" -#include "cascadeclassifier.h" -#include - -#include "cvconfig.h" - -using namespace std; - -static inline double -logRatio( double val ) -{ - const double eps = 1e-5; - - val = max( val, eps ); - val = min( val, 1. - eps ); - return log( val/(1. - val) ); -} - -template -class LessThanIdx -{ -public: - LessThanIdx( const T* _arr ) : arr(_arr) {} - bool operator()(Idx a, Idx b) const { return arr[a] < arr[b]; } - const T* arr; -}; - -static inline int cvAlign( int size, int align ) -{ - CV_DbgAssert( (align & (align-1)) == 0 && size < INT_MAX ); - return (size + align - 1) & -align; -} - -#define CV_THRESHOLD_EPS (0.00001F) - -static const int MinBlockSize = 1 << 16; -static const int BlockSizeDelta = 1 << 10; - -// TODO remove this code duplication with ml/precomp.hpp - -static int CV_CDECL icvCmpIntegers( const void* a, const void* b ) -{ - return *(const int*)a - *(const int*)b; -} - -static CvMat* cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, bool check_for_duplicates=false ) -{ - CvMat* idx = 0; - - CV_FUNCNAME( "cvPreprocessIndexArray" ); - - __CV_BEGIN__; - - int i, idx_total, idx_selected = 0, step, type, prev = INT_MIN, is_sorted = 1; - uchar* srcb = 0; - int* srci = 0; - int* dsti; - - if( !CV_IS_MAT(idx_arr) ) - CV_ERROR( CV_StsBadArg, "Invalid index array" ); - - if( idx_arr->rows != 1 && idx_arr->cols != 1 ) - CV_ERROR( CV_StsBadSize, "the index array must be 1-dimensional" ); - - idx_total = idx_arr->rows + idx_arr->cols - 1; - srcb = idx_arr->data.ptr; - srci = idx_arr->data.i; - - type = CV_MAT_TYPE(idx_arr->type); - step = CV_IS_MAT_CONT(idx_arr->type) ? 1 : idx_arr->step/CV_ELEM_SIZE(type); - - switch( type ) - { - case CV_8UC1: - case CV_8SC1: - // idx_arr is array of 1's and 0's - - // i.e. it is a mask of the selected components - if( idx_total != data_arr_size ) - CV_ERROR( CV_StsUnmatchedSizes, - "Component mask should contain as many elements as the total number of input variables" ); - - for( i = 0; i < idx_total; i++ ) - idx_selected += srcb[i*step] != 0; - - if( idx_selected == 0 ) - CV_ERROR( CV_StsOutOfRange, "No components/input_variables is selected!" ); - - break; - case CV_32SC1: - // idx_arr is array of integer indices of selected components - if( idx_total > data_arr_size ) - CV_ERROR( CV_StsOutOfRange, - "index array may not contain more elements than the total number of input variables" ); - idx_selected = idx_total; - // check if sorted already - for( i = 0; i < idx_total; i++ ) - { - int val = srci[i*step]; - if( val >= prev ) - { - is_sorted = 0; - break; - } - prev = val; - } - break; - default: - CV_ERROR( CV_StsUnsupportedFormat, "Unsupported index array data type " - "(it should be 8uC1, 8sC1 or 32sC1)" ); - } - - CV_CALL( idx = cvCreateMat( 1, idx_selected, CV_32SC1 )); - dsti = idx->data.i; - - if( type < CV_32SC1 ) - { - for( i = 0; i < idx_total; i++ ) - if( srcb[i*step] ) - *dsti++ = i; - } - else - { - for( i = 0; i < idx_total; i++ ) - dsti[i] = srci[i*step]; - - if( !is_sorted ) - qsort( dsti, idx_total, sizeof(dsti[0]), icvCmpIntegers ); - - if( dsti[0] < 0 || dsti[idx_total-1] >= data_arr_size ) - CV_ERROR( CV_StsOutOfRange, "the index array elements are out of range" ); - - if( check_for_duplicates ) - { - for( i = 1; i < idx_total; i++ ) - if( dsti[i] <= dsti[i-1] ) - CV_ERROR( CV_StsBadArg, "There are duplicated index array elements" ); - } - } - - __CV_END__; - - if( cvGetErrStatus() < 0 ) - cvReleaseMat( &idx ); - - return idx; -} - -//----------------------------- CascadeBoostParams ------------------------------------------------- - -CvCascadeBoostParams::CvCascadeBoostParams() : minHitRate( 0.995F), maxFalseAlarm( 0.5F ) -{ - boost_type = CvBoost::GENTLE; - use_surrogates = use_1se_rule = truncate_pruned_tree = false; -} - -CvCascadeBoostParams::CvCascadeBoostParams( int _boostType, - float _minHitRate, float _maxFalseAlarm, - double _weightTrimRate, int _maxDepth, int _maxWeakCount ) : - CvBoostParams( _boostType, _maxWeakCount, _weightTrimRate, _maxDepth, false, 0 ) -{ - boost_type = CvBoost::GENTLE; - minHitRate = _minHitRate; - maxFalseAlarm = _maxFalseAlarm; - use_surrogates = use_1se_rule = truncate_pruned_tree = false; -} - -void CvCascadeBoostParams::write( FileStorage &fs ) const -{ - string boostTypeStr = boost_type == CvBoost::DISCRETE ? CC_DISCRETE_BOOST : - boost_type == CvBoost::REAL ? CC_REAL_BOOST : - boost_type == CvBoost::LOGIT ? CC_LOGIT_BOOST : - boost_type == CvBoost::GENTLE ? CC_GENTLE_BOOST : string(); - CV_Assert( !boostTypeStr.empty() ); - fs << CC_BOOST_TYPE << boostTypeStr; - fs << CC_MINHITRATE << minHitRate; - fs << CC_MAXFALSEALARM << maxFalseAlarm; - fs << CC_TRIM_RATE << weight_trim_rate; - fs << CC_MAX_DEPTH << max_depth; - fs << CC_WEAK_COUNT << weak_count; -} - -bool CvCascadeBoostParams::read( const FileNode &node ) -{ - string boostTypeStr; - FileNode rnode = node[CC_BOOST_TYPE]; - rnode >> boostTypeStr; - boost_type = !boostTypeStr.compare( CC_DISCRETE_BOOST ) ? CvBoost::DISCRETE : - !boostTypeStr.compare( CC_REAL_BOOST ) ? CvBoost::REAL : - !boostTypeStr.compare( CC_LOGIT_BOOST ) ? CvBoost::LOGIT : - !boostTypeStr.compare( CC_GENTLE_BOOST ) ? CvBoost::GENTLE : -1; - if (boost_type == -1) - CV_Error( CV_StsBadArg, "unsupported Boost type" ); - node[CC_MINHITRATE] >> minHitRate; - node[CC_MAXFALSEALARM] >> maxFalseAlarm; - node[CC_TRIM_RATE] >> weight_trim_rate ; - node[CC_MAX_DEPTH] >> max_depth ; - node[CC_WEAK_COUNT] >> weak_count ; - if ( minHitRate <= 0 || minHitRate > 1 || - maxFalseAlarm <= 0 || maxFalseAlarm > 1 || - weight_trim_rate <= 0 || weight_trim_rate > 1 || - max_depth <= 0 || weak_count <= 0 ) - CV_Error( CV_StsBadArg, "bad parameters range"); - return true; -} - -void CvCascadeBoostParams::printDefaults() const -{ - cout << "--boostParams--" << endl; - cout << " [-bt <{" << CC_DISCRETE_BOOST << ", " - << CC_REAL_BOOST << ", " - << CC_LOGIT_BOOST ", " - << CC_GENTLE_BOOST << "(default)}>]" << endl; - cout << " [-minHitRate = " << minHitRate << ">]" << endl; - cout << " [-maxFalseAlarmRate ]" << endl; - cout << " [-weightTrimRate ]" << endl; - cout << " [-maxDepth ]" << endl; - cout << " [-maxWeakCount ]" << endl; -} - -void CvCascadeBoostParams::printAttrs() const -{ - string boostTypeStr = boost_type == CvBoost::DISCRETE ? CC_DISCRETE_BOOST : - boost_type == CvBoost::REAL ? CC_REAL_BOOST : - boost_type == CvBoost::LOGIT ? CC_LOGIT_BOOST : - boost_type == CvBoost::GENTLE ? CC_GENTLE_BOOST : string(); - CV_Assert( !boostTypeStr.empty() ); - cout << "boostType: " << boostTypeStr << endl; - cout << "minHitRate: " << minHitRate << endl; - cout << "maxFalseAlarmRate: " << maxFalseAlarm << endl; - cout << "weightTrimRate: " << weight_trim_rate << endl; - cout << "maxDepth: " << max_depth << endl; - cout << "maxWeakCount: " << weak_count << endl; -} - -bool CvCascadeBoostParams::scanAttr( const string prmName, const string val) -{ - bool res = true; - - if( !prmName.compare( "-bt" ) ) - { - boost_type = !val.compare( CC_DISCRETE_BOOST ) ? CvBoost::DISCRETE : - !val.compare( CC_REAL_BOOST ) ? CvBoost::REAL : - !val.compare( CC_LOGIT_BOOST ) ? CvBoost::LOGIT : - !val.compare( CC_GENTLE_BOOST ) ? CvBoost::GENTLE : -1; - if (boost_type == -1) - res = false; - } - else if( !prmName.compare( "-minHitRate" ) ) - { - minHitRate = (float) atof( val.c_str() ); - } - else if( !prmName.compare( "-maxFalseAlarmRate" ) ) - { - maxFalseAlarm = (float) atof( val.c_str() ); - } - else if( !prmName.compare( "-weightTrimRate" ) ) - { - weight_trim_rate = (float) atof( val.c_str() ); - } - else if( !prmName.compare( "-maxDepth" ) ) - { - max_depth = atoi( val.c_str() ); - } - else if( !prmName.compare( "-maxWeakCount" ) ) - { - weak_count = atoi( val.c_str() ); - } - else - res = false; - - return res; -} - -CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_idx ) -{ - CvDTreeNode* root = 0; - CvMat* isubsample_idx = 0; - CvMat* subsample_co = 0; - - bool isMakeRootCopy = true; - - if( !data_root ) - CV_Error( CV_StsError, "No training data has been set" ); - - if( _subsample_idx ) - { - CV_Assert( (isubsample_idx = cvPreprocessIndexArray( _subsample_idx, sample_count )) != 0 ); - - if( isubsample_idx->cols + isubsample_idx->rows - 1 == sample_count ) - { - const int* sidx = isubsample_idx->data.i; - for( int i = 0; i < sample_count; i++ ) - { - if( sidx[i] != i ) - { - isMakeRootCopy = false; - break; - } - } - } - else - isMakeRootCopy = false; - } - - if( isMakeRootCopy ) - { - // make a copy of the root node - CvDTreeNode temp; - int i; - root = new_node( 0, 1, 0, 0 ); - temp = *root; - *root = *data_root; - root->num_valid = temp.num_valid; - if( root->num_valid ) - { - for( i = 0; i < var_count; i++ ) - root->num_valid[i] = data_root->num_valid[i]; - } - root->cv_Tn = temp.cv_Tn; - root->cv_node_risk = temp.cv_node_risk; - root->cv_node_error = temp.cv_node_error; - } - else - { - int* sidx = isubsample_idx->data.i; - // co - array of count/offset pairs (to handle duplicated values in _subsample_idx) - int* co, cur_ofs = 0; - int workVarCount = get_work_var_count(); - int count = isubsample_idx->rows + isubsample_idx->cols - 1; - - root = new_node( 0, count, 1, 0 ); - - CV_Assert( (subsample_co = cvCreateMat( 1, sample_count*2, CV_32SC1 )) != 0); - cvZero( subsample_co ); - co = subsample_co->data.i; - for( int i = 0; i < count; i++ ) - co[sidx[i]*2]++; - for( int i = 0; i < sample_count; i++ ) - { - if( co[i*2] ) - { - co[i*2+1] = cur_ofs; - cur_ofs += co[i*2]; - } - else - co[i*2+1] = -1; - } - - cv::AutoBuffer inn_buf(sample_count*(2*sizeof(int) + sizeof(float))); - // subsample ordered variables - for( int vi = 0; vi < numPrecalcIdx; vi++ ) - { - int ci = get_var_type(vi); - CV_Assert( ci < 0 ); - - int *src_idx_buf = (int*)inn_buf.data(); - float *src_val_buf = (float*)(src_idx_buf + sample_count); - int* sample_indices_buf = (int*)(src_val_buf + sample_count); - const int* src_idx = 0; - const float* src_val = 0; - get_ord_var_data( data_root, vi, src_val_buf, src_idx_buf, &src_val, &src_idx, sample_indices_buf ); - - int j = 0, idx, count_i; - int num_valid = data_root->get_num_valid(vi); - CV_Assert( num_valid == sample_count ); - - if (is_buf_16u) - { - unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - (size_t)vi*sample_count + data_root->offset); - for( int i = 0; i < num_valid; i++ ) - { - idx = src_idx[i]; - count_i = co[idx*2]; - if( count_i ) - for( cur_ofs = co[idx*2+1]; count_i > 0; count_i--, j++, cur_ofs++ ) - udst_idx[j] = (unsigned short)cur_ofs; - } - } - else - { - int* idst_idx = buf->data.i + root->buf_idx*get_length_subbuf() + - (size_t)vi*sample_count + root->offset; - for( int i = 0; i < num_valid; i++ ) - { - idx = src_idx[i]; - count_i = co[idx*2]; - if( count_i ) - for( cur_ofs = co[idx*2+1]; count_i > 0; count_i--, j++, cur_ofs++ ) - idst_idx[j] = cur_ofs; - } - } - } - - // subsample cv_lables - const int* src_lbls = get_cv_labels(data_root, (int*)inn_buf.data()); - if (is_buf_16u) - { - unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - (size_t)(workVarCount-1)*sample_count + root->offset); - for( int i = 0; i < count; i++ ) - udst[i] = (unsigned short)src_lbls[sidx[i]]; - } - else - { - int* idst = buf->data.i + root->buf_idx*get_length_subbuf() + - (size_t)(workVarCount-1)*sample_count + root->offset; - for( int i = 0; i < count; i++ ) - idst[i] = src_lbls[sidx[i]]; - } - - // subsample sample_indices - const int* sample_idx_src = get_sample_indices(data_root, (int*)inn_buf.data()); - if (is_buf_16u) - { - unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - (size_t)workVarCount*sample_count + root->offset); - for( int i = 0; i < count; i++ ) - sample_idx_dst[i] = (unsigned short)sample_idx_src[sidx[i]]; - } - else - { - int* sample_idx_dst = buf->data.i + root->buf_idx*get_length_subbuf() + - (size_t)workVarCount*sample_count + root->offset; - for( int i = 0; i < count; i++ ) - sample_idx_dst[i] = sample_idx_src[sidx[i]]; - } - - for( int vi = 0; vi < var_count; vi++ ) - root->set_num_valid(vi, count); - } - - cvReleaseMat( &isubsample_idx ); - cvReleaseMat( &subsample_co ); - - return root; -} - -//---------------------------- CascadeBoostTrainData ----------------------------- - -CvCascadeBoostTrainData::CvCascadeBoostTrainData( const CvFeatureEvaluator* _featureEvaluator, - const CvDTreeParams& _params ) -{ - is_classifier = true; - var_all = var_count = (int)_featureEvaluator->getNumFeatures(); - - featureEvaluator = _featureEvaluator; - shared = true; - set_params( _params ); - max_c_count = MAX( 2, featureEvaluator->getMaxCatCount() ); - var_type = cvCreateMat( 1, var_count + 2, CV_32SC1 ); - if ( featureEvaluator->getMaxCatCount() > 0 ) - { - numPrecalcIdx = 0; - cat_var_count = var_count; - ord_var_count = 0; - for( int vi = 0; vi < var_count; vi++ ) - { - var_type->data.i[vi] = vi; - } - } - else - { - cat_var_count = 0; - ord_var_count = var_count; - for( int vi = 1; vi <= var_count; vi++ ) - { - var_type->data.i[vi-1] = -vi; - } - } - var_type->data.i[var_count] = cat_var_count; - var_type->data.i[var_count+1] = cat_var_count+1; - - int maxSplitSize = cvAlign(sizeof(CvDTreeSplit) + (MAX(0,max_c_count - 33)/32)*sizeof(int),sizeof(void*)); - int treeBlockSize = MAX((int)sizeof(CvDTreeNode)*8, maxSplitSize); - treeBlockSize = MAX(treeBlockSize + BlockSizeDelta, MinBlockSize); - tree_storage = cvCreateMemStorage( treeBlockSize ); - node_heap = cvCreateSet( 0, sizeof(node_heap[0]), sizeof(CvDTreeNode), tree_storage ); - split_heap = cvCreateSet( 0, sizeof(split_heap[0]), maxSplitSize, tree_storage ); -} - -CvCascadeBoostTrainData::CvCascadeBoostTrainData( const CvFeatureEvaluator* _featureEvaluator, - int _numSamples, - int _precalcValBufSize, int _precalcIdxBufSize, - const CvDTreeParams& _params ) -{ - setData( _featureEvaluator, _numSamples, _precalcValBufSize, _precalcIdxBufSize, _params ); -} - -void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluator, - int _numSamples, - int _precalcValBufSize, int _precalcIdxBufSize, - const CvDTreeParams& _params ) -{ - int* idst = 0; - unsigned short* udst = 0; - - uint64 effective_buf_size = 0; - int effective_buf_height = 0, effective_buf_width = 0; - - - clear(); - shared = true; - have_labels = true; - have_priors = false; - is_classifier = true; - - rng = &cv::theRNG(); - - set_params( _params ); - - CV_Assert( _featureEvaluator ); - featureEvaluator = _featureEvaluator; - - max_c_count = MAX( 2, featureEvaluator->getMaxCatCount() ); - _resp = cvMat(featureEvaluator->getCls()); - responses = &_resp; - // TODO: check responses: elements must be 0 or 1 - - if( _precalcValBufSize < 0 || _precalcIdxBufSize < 0) - CV_Error( CV_StsOutOfRange, "_numPrecalcVal and _numPrecalcIdx must be positive or 0" ); - - var_count = var_all = featureEvaluator->getNumFeatures() * featureEvaluator->getFeatureSize(); - sample_count = _numSamples; - - is_buf_16u = false; - if (sample_count < 65536) - is_buf_16u = true; - - numPrecalcVal = min( cvRound((double)_precalcValBufSize*1048576. / (sizeof(float)*sample_count)), var_count ); - numPrecalcIdx = min( cvRound((double)_precalcIdxBufSize*1048576. / - ((is_buf_16u ? sizeof(unsigned short) : sizeof (int))*sample_count)), var_count ); - - assert( numPrecalcIdx >= 0 && numPrecalcVal >= 0 ); - - valCache.create( numPrecalcVal, sample_count, CV_32FC1 ); - var_type = cvCreateMat( 1, var_count + 2, CV_32SC1 ); - - if ( featureEvaluator->getMaxCatCount() > 0 ) - { - numPrecalcIdx = 0; - cat_var_count = var_count; - ord_var_count = 0; - for( int vi = 0; vi < var_count; vi++ ) - { - var_type->data.i[vi] = vi; - } - } - else - { - cat_var_count = 0; - ord_var_count = var_count; - for( int vi = 1; vi <= var_count; vi++ ) - { - var_type->data.i[vi-1] = -vi; - } - } - var_type->data.i[var_count] = cat_var_count; - var_type->data.i[var_count+1] = cat_var_count+1; - work_var_count = ( cat_var_count ? 0 : numPrecalcIdx ) + 1/*cv_lables*/; - buf_count = 2; - - buf_size = -1; // the member buf_size is obsolete - - effective_buf_size = (uint64)(work_var_count + 1)*(uint64)sample_count * buf_count; // this is the total size of "CvMat buf" to be allocated - effective_buf_width = sample_count; - effective_buf_height = work_var_count+1; - - if (effective_buf_width >= effective_buf_height) - effective_buf_height *= buf_count; - else - effective_buf_width *= buf_count; - - if ((uint64)effective_buf_width * (uint64)effective_buf_height != effective_buf_size) - { - CV_Error(CV_StsBadArg, "The memory buffer cannot be allocated since its size exceeds integer fields limit"); - } - - if ( is_buf_16u ) - buf = cvCreateMat( effective_buf_height, effective_buf_width, CV_16UC1 ); - else - buf = cvCreateMat( effective_buf_height, effective_buf_width, CV_32SC1 ); - - cat_count = cvCreateMat( 1, cat_var_count + 1, CV_32SC1 ); - - // precalculate valCache and set indices in buf - precalculate(); - - // now calculate the maximum size of split, - // create memory storage that will keep nodes and splits of the decision tree - // allocate root node and the buffer for the whole training data - int maxSplitSize = cvAlign(sizeof(CvDTreeSplit) + - (MAX(0,sample_count - 33)/32)*sizeof(int),sizeof(void*)); - int treeBlockSize = MAX((int)sizeof(CvDTreeNode)*8, maxSplitSize); - treeBlockSize = MAX(treeBlockSize + BlockSizeDelta, MinBlockSize); - tree_storage = cvCreateMemStorage( treeBlockSize ); - node_heap = cvCreateSet( 0, sizeof(*node_heap), sizeof(CvDTreeNode), tree_storage ); - - int nvSize = var_count*sizeof(int); - nvSize = cvAlign(MAX( nvSize, (int)sizeof(CvSetElem) ), sizeof(void*)); - int tempBlockSize = nvSize; - tempBlockSize = MAX( tempBlockSize + BlockSizeDelta, MinBlockSize ); - temp_storage = cvCreateMemStorage( tempBlockSize ); - nv_heap = cvCreateSet( 0, sizeof(*nv_heap), nvSize, temp_storage ); - - data_root = new_node( 0, sample_count, 0, 0 ); - - // set sample labels - if (is_buf_16u) - udst = (unsigned short*)(buf->data.s + (size_t)work_var_count*sample_count); - else - idst = buf->data.i + (size_t)work_var_count*sample_count; - - for (int si = 0; si < sample_count; si++) - { - if (udst) - udst[si] = (unsigned short)si; - else - idst[si] = si; - } - for( int vi = 0; vi < var_count; vi++ ) - data_root->set_num_valid(vi, sample_count); - for( int vi = 0; vi < cat_var_count; vi++ ) - cat_count->data.i[vi] = max_c_count; - - cat_count->data.i[cat_var_count] = 2; - - maxSplitSize = cvAlign(sizeof(CvDTreeSplit) + - (MAX(0,max_c_count - 33)/32)*sizeof(int),sizeof(void*)); - split_heap = cvCreateSet( 0, sizeof(*split_heap), maxSplitSize, tree_storage ); - - priors = cvCreateMat( 1, get_num_classes(), CV_64F ); - cvSet(priors, cvScalar(1)); - priors_mult = cvCloneMat( priors ); - counts = cvCreateMat( 1, get_num_classes(), CV_32SC1 ); - direction = cvCreateMat( 1, sample_count, CV_8UC1 ); - split_buf = cvCreateMat( 1, sample_count, CV_32SC1 );//TODO: make a pointer -} - -void CvCascadeBoostTrainData::free_train_data() -{ - CvDTreeTrainData::free_train_data(); - valCache.release(); -} - -const int* CvCascadeBoostTrainData::get_class_labels( CvDTreeNode* n, int* labelsBuf) -{ - int nodeSampleCount = n->sample_count; - int rStep = CV_IS_MAT_CONT( responses->type ) ? 1 : responses->step / CV_ELEM_SIZE( responses->type ); - - int* sampleIndicesBuf = labelsBuf; // - const int* sampleIndices = get_sample_indices(n, sampleIndicesBuf); - for( int si = 0; si < nodeSampleCount; si++ ) - { - int sidx = sampleIndices[si]; - labelsBuf[si] = (int)responses->data.fl[sidx*rStep]; - } - return labelsBuf; -} - -const int* CvCascadeBoostTrainData::get_sample_indices( CvDTreeNode* n, int* indicesBuf ) -{ - return CvDTreeTrainData::get_cat_var_data( n, get_work_var_count(), indicesBuf ); -} - -const int* CvCascadeBoostTrainData::get_cv_labels( CvDTreeNode* n, int* labels_buf ) -{ - return CvDTreeTrainData::get_cat_var_data( n, get_work_var_count() - 1, labels_buf ); -} - -void CvCascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ordValuesBuf, int* sortedIndicesBuf, - const float** ordValues, const int** sortedIndices, int* sampleIndicesBuf ) -{ - int nodeSampleCount = n->sample_count; - const int* sampleIndices = get_sample_indices(n, sampleIndicesBuf); - - if ( vi < numPrecalcIdx ) - { - if( !is_buf_16u ) - *sortedIndices = buf->data.i + n->buf_idx*get_length_subbuf() + (size_t)vi*sample_count + n->offset; - else - { - const unsigned short* shortIndices = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + - (size_t)vi*sample_count + n->offset ); - for( int i = 0; i < nodeSampleCount; i++ ) - sortedIndicesBuf[i] = shortIndices[i]; - - *sortedIndices = sortedIndicesBuf; - } - - if( vi < numPrecalcVal ) - { - for( int i = 0; i < nodeSampleCount; i++ ) - { - int idx = (*sortedIndices)[i]; - idx = sampleIndices[idx]; - ordValuesBuf[i] = valCache.at( vi, idx); - } - } - else - { - for( int i = 0; i < nodeSampleCount; i++ ) - { - int idx = (*sortedIndices)[i]; - idx = sampleIndices[idx]; - ordValuesBuf[i] = (*featureEvaluator)( vi, idx); - } - } - } - else // vi >= numPrecalcIdx - { - cv::AutoBuffer abuf(nodeSampleCount); - float* sampleValues = &abuf[0]; - - if ( vi < numPrecalcVal ) - { - for( int i = 0; i < nodeSampleCount; i++ ) - { - sortedIndicesBuf[i] = i; - sampleValues[i] = valCache.at( vi, sampleIndices[i] ); - } - } - else - { - for( int i = 0; i < nodeSampleCount; i++ ) - { - sortedIndicesBuf[i] = i; - sampleValues[i] = (*featureEvaluator)( vi, sampleIndices[i]); - } - } - std::sort(sortedIndicesBuf, sortedIndicesBuf + nodeSampleCount, LessThanIdx(&sampleValues[0]) ); - for( int i = 0; i < nodeSampleCount; i++ ) - ordValuesBuf[i] = (&sampleValues[0])[sortedIndicesBuf[i]]; - *sortedIndices = sortedIndicesBuf; - } - - *ordValues = ordValuesBuf; -} - -const int* CvCascadeBoostTrainData::get_cat_var_data( CvDTreeNode* n, int vi, int* catValuesBuf ) -{ - int nodeSampleCount = n->sample_count; - int* sampleIndicesBuf = catValuesBuf; // - const int* sampleIndices = get_sample_indices(n, sampleIndicesBuf); - - if ( vi < numPrecalcVal ) - { - for( int i = 0; i < nodeSampleCount; i++ ) - catValuesBuf[i] = (int) valCache.at( vi, sampleIndices[i]); - } - else - { - if( vi >= numPrecalcVal && vi < var_count ) - { - for( int i = 0; i < nodeSampleCount; i++ ) - catValuesBuf[i] = (int)(*featureEvaluator)( vi, sampleIndices[i] ); - } - else - { - get_cv_labels( n, catValuesBuf ); - } - } - - return catValuesBuf; -} - -float CvCascadeBoostTrainData::getVarValue( int vi, int si ) -{ - if ( vi < numPrecalcVal && !valCache.empty() ) - return valCache.at( vi, si ); - return (*featureEvaluator)( vi, si ); -} - - -struct FeatureIdxOnlyPrecalc : ParallelLoopBody -{ - FeatureIdxOnlyPrecalc( const CvFeatureEvaluator* _featureEvaluator, CvMat* _buf, int _sample_count, bool _is_buf_16u ) - { - featureEvaluator = _featureEvaluator; - sample_count = _sample_count; - udst = (unsigned short*)_buf->data.s; - idst = _buf->data.i; - is_buf_16u = _is_buf_16u; - } - void operator()( const Range& range ) const - { - cv::AutoBuffer valCache(sample_count); - float* valCachePtr = valCache.data(); - for ( int fi = range.start; fi < range.end; fi++) - { - for( int si = 0; si < sample_count; si++ ) - { - valCachePtr[si] = (*featureEvaluator)( fi, si ); - if ( is_buf_16u ) - *(udst + (size_t)fi*sample_count + si) = (unsigned short)si; - else - *(idst + (size_t)fi*sample_count + si) = si; - } - if ( is_buf_16u ) - std::sort(udst + (size_t)fi*sample_count, udst + (size_t)(fi + 1)*sample_count, LessThanIdx(valCachePtr) ); - else - std::sort(idst + (size_t)fi*sample_count, idst + (size_t)(fi + 1)*sample_count, LessThanIdx(valCachePtr) ); - } - } - const CvFeatureEvaluator* featureEvaluator; - int sample_count; - int* idst; - unsigned short* udst; - bool is_buf_16u; -}; - -struct FeatureValAndIdxPrecalc : ParallelLoopBody -{ - FeatureValAndIdxPrecalc( const CvFeatureEvaluator* _featureEvaluator, CvMat* _buf, Mat* _valCache, int _sample_count, bool _is_buf_16u ) - { - featureEvaluator = _featureEvaluator; - valCache = _valCache; - sample_count = _sample_count; - udst = (unsigned short*)_buf->data.s; - idst = _buf->data.i; - is_buf_16u = _is_buf_16u; - } - void operator()( const Range& range ) const - { - for ( int fi = range.start; fi < range.end; fi++) - { - for( int si = 0; si < sample_count; si++ ) - { - valCache->at(fi,si) = (*featureEvaluator)( fi, si ); - if ( is_buf_16u ) - *(udst + (size_t)fi*sample_count + si) = (unsigned short)si; - else - *(idst + (size_t)fi*sample_count + si) = si; - } - if ( is_buf_16u ) - std::sort(udst + (size_t)fi*sample_count, udst + (size_t)(fi + 1)*sample_count, LessThanIdx(valCache->ptr(fi)) ); - else - std::sort(idst + (size_t)fi*sample_count, idst + (size_t)(fi + 1)*sample_count, LessThanIdx(valCache->ptr(fi)) ); - } - } - const CvFeatureEvaluator* featureEvaluator; - Mat* valCache; - int sample_count; - int* idst; - unsigned short* udst; - bool is_buf_16u; -}; - -struct FeatureValOnlyPrecalc : ParallelLoopBody -{ - FeatureValOnlyPrecalc( const CvFeatureEvaluator* _featureEvaluator, Mat* _valCache, int _sample_count ) - { - featureEvaluator = _featureEvaluator; - valCache = _valCache; - sample_count = _sample_count; - } - void operator()( const Range& range ) const - { - for ( int fi = range.start; fi < range.end; fi++) - for( int si = 0; si < sample_count; si++ ) - valCache->at(fi,si) = (*featureEvaluator)( fi, si ); - } - const CvFeatureEvaluator* featureEvaluator; - Mat* valCache; - int sample_count; -}; - -void CvCascadeBoostTrainData::precalculate() -{ - int minNum = MIN( numPrecalcVal, numPrecalcIdx); - - double proctime = -TIME( 0 ); - parallel_for_( Range(numPrecalcVal, numPrecalcIdx), - FeatureIdxOnlyPrecalc(featureEvaluator, buf, sample_count, is_buf_16u!=0) ); - parallel_for_( Range(0, minNum), - FeatureValAndIdxPrecalc(featureEvaluator, buf, &valCache, sample_count, is_buf_16u!=0) ); - parallel_for_( Range(minNum, numPrecalcVal), - FeatureValOnlyPrecalc(featureEvaluator, &valCache, sample_count) ); - cout << "Precalculation time: " << (proctime + TIME( 0 )) << endl; -} - -//-------------------------------- CascadeBoostTree ---------------------------------------- - -CvDTreeNode* CvCascadeBoostTree::predict( int sampleIdx ) const -{ - CvDTreeNode* node = root; - if( !node ) - CV_Error( CV_StsError, "The tree has not been trained yet" ); - - if ( ((CvCascadeBoostTrainData*)data)->featureEvaluator->getMaxCatCount() == 0 ) // ordered - { - while( node->left ) - { - CvDTreeSplit* split = node->split; - float val = ((CvCascadeBoostTrainData*)data)->getVarValue( split->var_idx, sampleIdx ); - node = val <= split->ord.c ? node->left : node->right; - } - } - else // categorical - { - while( node->left ) - { - CvDTreeSplit* split = node->split; - int c = (int)((CvCascadeBoostTrainData*)data)->getVarValue( split->var_idx, sampleIdx ); - node = CV_DTREE_CAT_DIR(c, split->subset) < 0 ? node->left : node->right; - } - } - return node; -} - -void CvCascadeBoostTree::write( FileStorage &fs, const Mat& featureMap ) -{ - int maxCatCount = ((CvCascadeBoostTrainData*)data)->featureEvaluator->getMaxCatCount(); - int subsetN = (maxCatCount + 31)/32; - queue internalNodesQueue; - int size = (int)pow( 2.f, (float)ensemble->get_params().max_depth); - std::vector leafVals(size); - int leafValIdx = 0; - int internalNodeIdx = 1; - CvDTreeNode* tempNode; - - CV_DbgAssert( root ); - internalNodesQueue.push( root ); - - fs << "{"; - fs << CC_INTERNAL_NODES << "[:"; - while (!internalNodesQueue.empty()) - { - tempNode = internalNodesQueue.front(); - CV_Assert( tempNode->left ); - if ( !tempNode->left->left && !tempNode->left->right) // left node is leaf - { - leafVals[-leafValIdx] = (float)tempNode->left->value; - fs << leafValIdx-- ; - } - else - { - internalNodesQueue.push( tempNode->left ); - fs << internalNodeIdx++; - } - CV_Assert( tempNode->right ); - if ( !tempNode->right->left && !tempNode->right->right) // right node is leaf - { - leafVals[-leafValIdx] = (float)tempNode->right->value; - fs << leafValIdx--; - } - else - { - internalNodesQueue.push( tempNode->right ); - fs << internalNodeIdx++; - } - int fidx = tempNode->split->var_idx; - fidx = featureMap.empty() ? fidx : featureMap.at(0, fidx); - fs << fidx; - if ( !maxCatCount ) - fs << tempNode->split->ord.c; - else - for( int i = 0; i < subsetN; i++ ) - fs << tempNode->split->subset[i]; - internalNodesQueue.pop(); - } - fs << "]"; // CC_INTERNAL_NODES - - fs << CC_LEAF_VALUES << "[:"; - for (int ni = 0; ni < -leafValIdx; ni++) - fs << leafVals[ni]; - fs << "]"; // CC_LEAF_VALUES - fs << "}"; -} - -void CvCascadeBoostTree::read( const FileNode &node, CvBoost* _ensemble, - CvDTreeTrainData* _data ) -{ - int maxCatCount = ((CvCascadeBoostTrainData*)_data)->featureEvaluator->getMaxCatCount(); - int subsetN = (maxCatCount + 31)/32; - int step = 3 + ( maxCatCount>0 ? subsetN : 1 ); - - queue internalNodesQueue; - int internalNodesIdx, leafValsuesIdx; - CvDTreeNode* prntNode, *cldNode; - - clear(); - data = _data; - ensemble = _ensemble; - pruned_tree_idx = 0; - - // read tree nodes - FileNode rnode = node[CC_INTERNAL_NODES]; - internalNodesIdx = (int) rnode.size() - 1; - FileNode lnode = node[CC_LEAF_VALUES]; - leafValsuesIdx = (int) lnode.size() - 1; - for( size_t i = 0; i < rnode.size()/step; i++ ) - { - prntNode = data->new_node( 0, 0, 0, 0 ); - if ( maxCatCount > 0 ) - { - prntNode->split = data->new_split_cat( 0, 0 ); - for( int j = subsetN-1; j>=0; j--) - { - rnode[internalNodesIdx] >> prntNode->split->subset[j]; --internalNodesIdx; - } - } - else - { - float split_value; - rnode[internalNodesIdx] >> split_value; --internalNodesIdx; - prntNode->split = data->new_split_ord( 0, split_value, 0, 0, 0); - } - rnode[internalNodesIdx] >> prntNode->split->var_idx; --internalNodesIdx; - int ridx, lidx; - rnode[internalNodesIdx] >> ridx; --internalNodesIdx; - rnode[internalNodesIdx] >> lidx; --internalNodesIdx; - if ( ridx <= 0) - { - prntNode->right = cldNode = data->new_node( 0, 0, 0, 0 ); - lnode[leafValsuesIdx] >> cldNode->value; --leafValsuesIdx; - cldNode->parent = prntNode; - } - else - { - prntNode->right = internalNodesQueue.front(); - prntNode->right->parent = prntNode; - internalNodesQueue.pop(); - } - - if ( lidx <= 0) - { - prntNode->left = cldNode = data->new_node( 0, 0, 0, 0 ); - lnode[leafValsuesIdx] >> cldNode->value; --leafValsuesIdx; - cldNode->parent = prntNode; - } - else - { - prntNode->left = internalNodesQueue.front(); - prntNode->left->parent = prntNode; - internalNodesQueue.pop(); - } - - internalNodesQueue.push( prntNode ); - } - - root = internalNodesQueue.front(); - internalNodesQueue.pop(); -} - -void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) -{ - int n = node->sample_count, nl, nr, scount = data->sample_count; - char* dir = (char*)data->direction->data.ptr; - CvDTreeNode *left = 0, *right = 0; - int* newIdx = data->split_buf->data.i; - int newBufIdx = data->get_child_buf_idx( node ); - int workVarCount = data->get_work_var_count(); - CvMat* buf = data->buf; - size_t length_buf_row = data->get_length_subbuf(); - cv::AutoBuffer inn_buf(n*(3*sizeof(int)+sizeof(float))); - int* tempBuf = (int*)inn_buf.data(); - bool splitInputData; - - complete_node_dir(node); - - for( int i = nl = nr = 0; i < n; i++ ) - { - int d = dir[i]; - // initialize new indices for splitting ordered variables - newIdx[i] = (nl & (d-1)) | (nr & -d); // d ? ri : li - nr += d; - nl += d^1; - } - - node->left = left = data->new_node( node, nl, newBufIdx, node->offset ); - node->right = right = data->new_node( node, nr, newBufIdx, node->offset + nl ); - - splitInputData = node->depth + 1 < data->params.max_depth && - (node->left->sample_count > data->params.min_sample_count || - node->right->sample_count > data->params.min_sample_count); - - // split ordered variables, keep both halves sorted. - for( int vi = 0; vi < ((CvCascadeBoostTrainData*)data)->numPrecalcIdx; vi++ ) - { - int ci = data->get_var_type(vi); - if( ci >= 0 || !splitInputData ) - continue; - - int n1 = node->get_num_valid(vi); - float *src_val_buf = (float*)(tempBuf + n); - int *src_sorted_idx_buf = (int*)(src_val_buf + n); - int *src_sample_idx_buf = src_sorted_idx_buf + n; - const int* src_sorted_idx = 0; - const float* src_val = 0; - data->get_ord_var_data(node, vi, src_val_buf, src_sorted_idx_buf, &src_val, &src_sorted_idx, src_sample_idx_buf); - - for(int i = 0; i < n; i++) - tempBuf[i] = src_sorted_idx[i]; - - if (data->is_buf_16u) - { - ushort *ldst, *rdst; - ldst = (ushort*)(buf->data.s + left->buf_idx*length_buf_row + - vi*scount + left->offset); - rdst = (ushort*)(ldst + nl); - - // split sorted - for( int i = 0; i < n1; i++ ) - { - int idx = tempBuf[i]; - int d = dir[idx]; - idx = newIdx[idx]; - if (d) - { - *rdst = (ushort)idx; - rdst++; - } - else - { - *ldst = (ushort)idx; - ldst++; - } - } - CV_Assert( n1 == n ); - } - else - { - int *ldst, *rdst; - ldst = buf->data.i + left->buf_idx*length_buf_row + - vi*scount + left->offset; - rdst = buf->data.i + right->buf_idx*length_buf_row + - vi*scount + right->offset; - - // split sorted - for( int i = 0; i < n1; i++ ) - { - int idx = tempBuf[i]; - int d = dir[idx]; - idx = newIdx[idx]; - if (d) - { - *rdst = idx; - rdst++; - } - else - { - *ldst = idx; - ldst++; - } - } - CV_Assert( n1 == n ); - } - } - - // split cv_labels using newIdx relocation table - int *src_lbls_buf = tempBuf + n; - const int* src_lbls = data->get_cv_labels(node, src_lbls_buf); - - for(int i = 0; i < n; i++) - tempBuf[i] = src_lbls[i]; - - if (data->is_buf_16u) - { - unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*length_buf_row + - (size_t)(workVarCount-1)*scount + left->offset); - unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*length_buf_row + - (size_t)(workVarCount-1)*scount + right->offset); - - for( int i = 0; i < n; i++ ) - { - int idx = tempBuf[i]; - if (dir[i]) - { - *rdst = (unsigned short)idx; - rdst++; - } - else - { - *ldst = (unsigned short)idx; - ldst++; - } - } - - } - else - { - int *ldst = buf->data.i + left->buf_idx*length_buf_row + - (size_t)(workVarCount-1)*scount + left->offset; - int *rdst = buf->data.i + right->buf_idx*length_buf_row + - (size_t)(workVarCount-1)*scount + right->offset; - - for( int i = 0; i < n; i++ ) - { - int idx = tempBuf[i]; - if (dir[i]) - { - *rdst = idx; - rdst++; - } - else - { - *ldst = idx; - ldst++; - } - } - } - - // split sample indices - int *sampleIdx_src_buf = tempBuf + n; - const int* sampleIdx_src = data->get_sample_indices(node, sampleIdx_src_buf); - - for(int i = 0; i < n; i++) - tempBuf[i] = sampleIdx_src[i]; - - if (data->is_buf_16u) - { - unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*length_buf_row + - (size_t)workVarCount*scount + left->offset); - unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*length_buf_row + - (size_t)workVarCount*scount + right->offset); - for (int i = 0; i < n; i++) - { - unsigned short idx = (unsigned short)tempBuf[i]; - if (dir[i]) - { - *rdst = idx; - rdst++; - } - else - { - *ldst = idx; - ldst++; - } - } - } - else - { - int* ldst = buf->data.i + left->buf_idx*length_buf_row + - (size_t)workVarCount*scount + left->offset; - int* rdst = buf->data.i + right->buf_idx*length_buf_row + - (size_t)workVarCount*scount + right->offset; - for (int i = 0; i < n; i++) - { - int idx = tempBuf[i]; - if (dir[i]) - { - *rdst = idx; - rdst++; - } - else - { - *ldst = idx; - ldst++; - } - } - } - - for( int vi = 0; vi < data->var_count; vi++ ) - { - left->set_num_valid(vi, (int)(nl)); - right->set_num_valid(vi, (int)(nr)); - } - - // deallocate the parent node data that is not needed anymore - data->free_node_data(node); -} - -static void auxMarkFeaturesInMap( const CvDTreeNode* node, Mat& featureMap) -{ - if ( node && node->split ) - { - featureMap.ptr(0)[node->split->var_idx] = 1; - auxMarkFeaturesInMap( node->left, featureMap ); - auxMarkFeaturesInMap( node->right, featureMap ); - } -} - -void CvCascadeBoostTree::markFeaturesInMap( Mat& featureMap ) -{ - auxMarkFeaturesInMap( root, featureMap ); -} - -//----------------------------------- CascadeBoost -------------------------------------- - -bool CvCascadeBoost::train( const CvFeatureEvaluator* _featureEvaluator, - int _numSamples, - int _precalcValBufSize, int _precalcIdxBufSize, - const CvCascadeBoostParams& _params ) -{ - bool isTrained = false; - CV_Assert( !data ); - clear(); - data = new CvCascadeBoostTrainData( _featureEvaluator, _numSamples, - _precalcValBufSize, _precalcIdxBufSize, _params ); - CvMemStorage *storage = cvCreateMemStorage(); - weak = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvBoostTree*), storage ); - storage = 0; - - set_params( _params ); - if ( (_params.boost_type == LOGIT) || (_params.boost_type == GENTLE) ) - data->do_responses_copy(); - - update_weights( 0 ); - - cout << "+----+---------+---------+" << endl; - cout << "| N | HR | FA |" << endl; - cout << "+----+---------+---------+" << endl; - - do - { - CvCascadeBoostTree* tree = new CvCascadeBoostTree; - if( !tree->train( data, subsample_mask, this ) ) - { - delete tree; - break; - } - cvSeqPush( weak, &tree ); - update_weights( tree ); - trim_weights(); - if( cvCountNonZero(subsample_mask) == 0 ) - break; - } - while( !isErrDesired() && (weak->total < params.weak_count) ); - - if(weak->total > 0) - { - data->is_classifier = true; - data->free_train_data(); - isTrained = true; - } - else - clear(); - - return isTrained; -} - -float CvCascadeBoost::predict( int sampleIdx, bool returnSum ) const -{ - CV_Assert( weak ); - double sum = 0; - CvSeqReader reader; - cvStartReadSeq( weak, &reader ); - cvSetSeqReaderPos( &reader, 0 ); - for( int i = 0; i < weak->total; i++ ) - { - CvBoostTree* wtree; - CV_READ_SEQ_ELEM( wtree, reader ); - sum += ((CvCascadeBoostTree*)wtree)->predict(sampleIdx)->value; - } - if( !returnSum ) - sum = sum < threshold - CV_THRESHOLD_EPS ? 0.0 : 1.0; - return (float)sum; -} - -bool CvCascadeBoost::set_params( const CvBoostParams& _params ) -{ - minHitRate = ((CvCascadeBoostParams&)_params).minHitRate; - maxFalseAlarm = ((CvCascadeBoostParams&)_params).maxFalseAlarm; - return ( ( minHitRate > 0 ) && ( minHitRate < 1) && - ( maxFalseAlarm > 0 ) && ( maxFalseAlarm < 1) && - CvBoost::set_params( _params )); -} - -void CvCascadeBoost::update_weights( CvBoostTree* tree ) -{ - int n = data->sample_count; - double sumW = 0.; - int step = 0; - float* fdata = 0; - int *sampleIdxBuf; - const int* sampleIdx = 0; - int inn_buf_size = ((params.boost_type == LOGIT) || (params.boost_type == GENTLE) ? n*sizeof(int) : 0) + - ( !tree ? n*sizeof(int) : 0 ); - cv::AutoBuffer inn_buf(inn_buf_size); - uchar* cur_inn_buf_pos = inn_buf.data(); - if ( (params.boost_type == LOGIT) || (params.boost_type == GENTLE) ) - { - step = CV_IS_MAT_CONT(data->responses_copy->type) ? - 1 : data->responses_copy->step / CV_ELEM_SIZE(data->responses_copy->type); - fdata = data->responses_copy->data.fl; - sampleIdxBuf = (int*)cur_inn_buf_pos; cur_inn_buf_pos = (uchar*)(sampleIdxBuf + n); - sampleIdx = data->get_sample_indices( data->data_root, sampleIdxBuf ); - } - CvMat* buf = data->buf; - size_t length_buf_row = data->get_length_subbuf(); - if( !tree ) // before training the first tree, initialize weights and other parameters - { - int* classLabelsBuf = (int*)cur_inn_buf_pos; cur_inn_buf_pos = (uchar*)(classLabelsBuf + n); - const int* classLabels = data->get_class_labels(data->data_root, classLabelsBuf); - // in case of logitboost and gentle adaboost each weak tree is a regression tree, - // so we need to convert class labels to floating-point values - double w0 = 1./n; - double p[2] = { 1, 1 }; - - cvReleaseMat( &orig_response ); - cvReleaseMat( &sum_response ); - cvReleaseMat( &weak_eval ); - cvReleaseMat( &subsample_mask ); - cvReleaseMat( &weights ); - - orig_response = cvCreateMat( 1, n, CV_32S ); - weak_eval = cvCreateMat( 1, n, CV_64F ); - subsample_mask = cvCreateMat( 1, n, CV_8U ); - weights = cvCreateMat( 1, n, CV_64F ); - subtree_weights = cvCreateMat( 1, n + 2, CV_64F ); - - if (data->is_buf_16u) - { - unsigned short* labels = (unsigned short*)(buf->data.s + data->data_root->buf_idx*length_buf_row + - data->data_root->offset + (size_t)(data->work_var_count-1)*data->sample_count); - for( int i = 0; i < n; i++ ) - { - // save original categorical responses {0,1}, convert them to {-1,1} - orig_response->data.i[i] = classLabels[i]*2 - 1; - // make all the samples active at start. - // later, in trim_weights() deactivate/reactive again some, if need - subsample_mask->data.ptr[i] = (uchar)1; - // make all the initial weights the same. - weights->data.db[i] = w0*p[classLabels[i]]; - // set the labels to find (from within weak tree learning proc) - // the particular sample weight, and where to store the response. - labels[i] = (unsigned short)i; - } - } - else - { - int* labels = buf->data.i + data->data_root->buf_idx*length_buf_row + - data->data_root->offset + (size_t)(data->work_var_count-1)*data->sample_count; - - for( int i = 0; i < n; i++ ) - { - // save original categorical responses {0,1}, convert them to {-1,1} - orig_response->data.i[i] = classLabels[i]*2 - 1; - subsample_mask->data.ptr[i] = (uchar)1; - weights->data.db[i] = w0*p[classLabels[i]]; - labels[i] = i; - } - } - - if( params.boost_type == LOGIT ) - { - sum_response = cvCreateMat( 1, n, CV_64F ); - - for( int i = 0; i < n; i++ ) - { - sum_response->data.db[i] = 0; - fdata[sampleIdx[i]*step] = orig_response->data.i[i] > 0 ? 2.f : -2.f; - } - - // in case of logitboost each weak tree is a regression tree. - // the target function values are recalculated for each of the trees - data->is_classifier = false; - } - else if( params.boost_type == GENTLE ) - { - for( int i = 0; i < n; i++ ) - fdata[sampleIdx[i]*step] = (float)orig_response->data.i[i]; - - data->is_classifier = false; - } - } - else - { - // at this moment, for all the samples that participated in the training of the most - // recent weak classifier we know the responses. For other samples we need to compute them - if( have_subsample ) - { - // invert the subsample mask - cvXorS( subsample_mask, cvScalar(1.), subsample_mask ); - - // run tree through all the non-processed samples - for( int i = 0; i < n; i++ ) - if( subsample_mask->data.ptr[i] ) - { - weak_eval->data.db[i] = ((CvCascadeBoostTree*)tree)->predict( i )->value; - } - } - - // now update weights and other parameters for each type of boosting - if( params.boost_type == DISCRETE ) - { - // Discrete AdaBoost: - // weak_eval[i] (=f(x_i)) is in {-1,1} - // err = sum(w_i*(f(x_i) != y_i))/sum(w_i) - // C = log((1-err)/err) - // w_i *= exp(C*(f(x_i) != y_i)) - - double C, err = 0.; - double scale[] = { 1., 0. }; - - for( int i = 0; i < n; i++ ) - { - double w = weights->data.db[i]; - sumW += w; - err += w*(weak_eval->data.db[i] != orig_response->data.i[i]); - } - - if( sumW != 0 ) - err /= sumW; - C = err = -logRatio( err ); - scale[1] = exp(err); - - sumW = 0; - for( int i = 0; i < n; i++ ) - { - double w = weights->data.db[i]* - scale[weak_eval->data.db[i] != orig_response->data.i[i]]; - sumW += w; - weights->data.db[i] = w; - } - - tree->scale( C ); - } - else if( params.boost_type == REAL ) - { - // Real AdaBoost: - // weak_eval[i] = f(x_i) = 0.5*log(p(x_i)/(1-p(x_i))), p(x_i)=P(y=1|x_i) - // w_i *= exp(-y_i*f(x_i)) - - for( int i = 0; i < n; i++ ) - weak_eval->data.db[i] *= -orig_response->data.i[i]; - - cvExp( weak_eval, weak_eval ); - - for( int i = 0; i < n; i++ ) - { - double w = weights->data.db[i]*weak_eval->data.db[i]; - sumW += w; - weights->data.db[i] = w; - } - } - else if( params.boost_type == LOGIT ) - { - // LogitBoost: - // weak_eval[i] = f(x_i) in [-z_max,z_max] - // sum_response = F(x_i). - // F(x_i) += 0.5*f(x_i) - // p(x_i) = exp(F(x_i))/(exp(F(x_i)) + exp(-F(x_i))=1/(1+exp(-2*F(x_i))) - // reuse weak_eval: weak_eval[i] <- p(x_i) - // w_i = p(x_i)*1(1 - p(x_i)) - // z_i = ((y_i+1)/2 - p(x_i))/(p(x_i)*(1 - p(x_i))) - // store z_i to the data->data_root as the new target responses - - const double lbWeightThresh = FLT_EPSILON; - const double lbZMax = 10.; - - for( int i = 0; i < n; i++ ) - { - double s = sum_response->data.db[i] + 0.5*weak_eval->data.db[i]; - sum_response->data.db[i] = s; - weak_eval->data.db[i] = -2*s; - } - - cvExp( weak_eval, weak_eval ); - - for( int i = 0; i < n; i++ ) - { - double p = 1./(1. + weak_eval->data.db[i]); - double w = p*(1 - p), z; - w = MAX( w, lbWeightThresh ); - weights->data.db[i] = w; - sumW += w; - if( orig_response->data.i[i] > 0 ) - { - z = 1./p; - fdata[sampleIdx[i]*step] = (float)min(z, lbZMax); - } - else - { - z = 1./(1-p); - fdata[sampleIdx[i]*step] = (float)-min(z, lbZMax); - } - } - } - else - { - // Gentle AdaBoost: - // weak_eval[i] = f(x_i) in [-1,1] - // w_i *= exp(-y_i*f(x_i)) - assert( params.boost_type == GENTLE ); - - for( int i = 0; i < n; i++ ) - weak_eval->data.db[i] *= -orig_response->data.i[i]; - - cvExp( weak_eval, weak_eval ); - - for( int i = 0; i < n; i++ ) - { - double w = weights->data.db[i] * weak_eval->data.db[i]; - weights->data.db[i] = w; - sumW += w; - } - } - } - - // renormalize weights - if( sumW > FLT_EPSILON ) - { - sumW = 1./sumW; - for( int i = 0; i < n; ++i ) - weights->data.db[i] *= sumW; - } -} - -bool CvCascadeBoost::isErrDesired() -{ - int sCount = data->sample_count, - numPos = 0, numNeg = 0, numFalse = 0, numPosTrue = 0; - vector eval(sCount); - - for( int i = 0; i < sCount; i++ ) - if( ((CvCascadeBoostTrainData*)data)->featureEvaluator->getCls( i ) == 1.0F ) - eval[numPos++] = predict( i, true ); - - std::sort(&eval[0], &eval[0] + numPos); - - int thresholdIdx = (int)((1.0F - minHitRate) * numPos); - - threshold = eval[ thresholdIdx ]; - numPosTrue = numPos - thresholdIdx; - for( int i = thresholdIdx - 1; i >= 0; i--) - if ( abs( eval[i] - threshold) < FLT_EPSILON ) - numPosTrue++; - float hitRate = ((float) numPosTrue) / ((float) numPos); - - for( int i = 0; i < sCount; i++ ) - { - if( ((CvCascadeBoostTrainData*)data)->featureEvaluator->getCls( i ) == 0.0F ) - { - numNeg++; - if( predict( i ) ) - numFalse++; - } - } - float falseAlarm = ((float) numFalse) / ((float) numNeg); - - cout << "|"; cout.width(4); cout << right << weak->total; - cout << "|"; cout.width(9); cout << right << hitRate; - cout << "|"; cout.width(9); cout << right << falseAlarm; - cout << "|" << endl; - cout << "+----+---------+---------+" << endl; - - return falseAlarm <= maxFalseAlarm; -} - -void CvCascadeBoost::write( FileStorage &fs, const Mat& featureMap ) const -{ -// char cmnt[30]; - CvCascadeBoostTree* weakTree; - fs << CC_WEAK_COUNT << weak->total; - fs << CC_STAGE_THRESHOLD << threshold; - fs << CC_WEAK_CLASSIFIERS << "["; - for( int wi = 0; wi < weak->total; wi++) - { - /*snprintf( cmnt, sizeof(cmnt), "tree %i", wi ); - cvWriteComment( fs, cmnt, 0 );*/ - weakTree = *((CvCascadeBoostTree**) cvGetSeqElem( weak, wi )); - weakTree->write( fs, featureMap ); - } - fs << "]"; -} - -bool CvCascadeBoost::read( const FileNode &node, - const CvFeatureEvaluator* _featureEvaluator, - const CvCascadeBoostParams& _params ) -{ - CvMemStorage* storage; - clear(); - data = new CvCascadeBoostTrainData( _featureEvaluator, _params ); - set_params( _params ); - - node[CC_STAGE_THRESHOLD] >> threshold; - FileNode rnode = node[CC_WEAK_CLASSIFIERS]; - - storage = cvCreateMemStorage(); - weak = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvBoostTree*), storage ); - for( FileNodeIterator it = rnode.begin(); it != rnode.end(); it++ ) - { - CvCascadeBoostTree* tree = new CvCascadeBoostTree(); - tree->read( *it, this, data ); - cvSeqPush( weak, &tree ); - } - return true; -} - -void CvCascadeBoost::markUsedFeaturesInMap( Mat& featureMap ) -{ - for( int wi = 0; wi < weak->total; wi++ ) - { - CvCascadeBoostTree* weakTree = *((CvCascadeBoostTree**) cvGetSeqElem( weak, wi )); - weakTree->markFeaturesInMap( featureMap ); - } -} diff --git a/apps/traincascade/boost.h b/apps/traincascade/boost.h deleted file mode 100644 index 48d4789b9c..0000000000 --- a/apps/traincascade/boost.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef _OPENCV_BOOST_H_ -#define _OPENCV_BOOST_H_ - -#include "traincascade_features.h" -#include "old_ml.hpp" - -struct CvCascadeBoostParams : CvBoostParams -{ - float minHitRate; - float maxFalseAlarm; - - CvCascadeBoostParams(); - CvCascadeBoostParams( int _boostType, float _minHitRate, float _maxFalseAlarm, - double _weightTrimRate, int _maxDepth, int _maxWeakCount ); - virtual ~CvCascadeBoostParams() {} - void write( cv::FileStorage &fs ) const; - bool read( const cv::FileNode &node ); - virtual void printDefaults() const; - virtual void printAttrs() const; - virtual bool scanAttr( const std::string prmName, const std::string val); -}; - -struct CvCascadeBoostTrainData : CvDTreeTrainData -{ - CvCascadeBoostTrainData( const CvFeatureEvaluator* _featureEvaluator, - const CvDTreeParams& _params ); - CvCascadeBoostTrainData( const CvFeatureEvaluator* _featureEvaluator, - int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize, - const CvDTreeParams& _params = CvDTreeParams() ); - virtual void setData( const CvFeatureEvaluator* _featureEvaluator, - int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize, - const CvDTreeParams& _params=CvDTreeParams() ); - void precalculate(); - - virtual CvDTreeNode* subsample_data( const CvMat* _subsample_idx ); - - virtual const int* get_class_labels( CvDTreeNode* n, int* labelsBuf ); - virtual const int* get_cv_labels( CvDTreeNode* n, int* labelsBuf); - virtual const int* get_sample_indices( CvDTreeNode* n, int* indicesBuf ); - - virtual void get_ord_var_data( CvDTreeNode* n, int vi, float* ordValuesBuf, int* sortedIndicesBuf, - const float** ordValues, const int** sortedIndices, int* sampleIndicesBuf ); - virtual const int* get_cat_var_data( CvDTreeNode* n, int vi, int* catValuesBuf ); - virtual float getVarValue( int vi, int si ); - virtual void free_train_data(); - - const CvFeatureEvaluator* featureEvaluator; - cv::Mat valCache; // precalculated feature values (CV_32FC1) - CvMat _resp; // for casting - int numPrecalcVal, numPrecalcIdx; -}; - -class CvCascadeBoostTree : public CvBoostTree -{ -public: - virtual CvDTreeNode* predict( int sampleIdx ) const; - void write( cv::FileStorage &fs, const cv::Mat& featureMap ); - void read( const cv::FileNode &node, CvBoost* _ensemble, CvDTreeTrainData* _data ); - void markFeaturesInMap( cv::Mat& featureMap ); -protected: - virtual void split_node_data( CvDTreeNode* n ); -}; - -class CvCascadeBoost : public CvBoost -{ -public: - virtual bool train( const CvFeatureEvaluator* _featureEvaluator, - int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize, - const CvCascadeBoostParams& _params=CvCascadeBoostParams() ); - virtual float predict( int sampleIdx, bool returnSum = false ) const; - - float getThreshold() const { return threshold; } - void write( cv::FileStorage &fs, const cv::Mat& featureMap ) const; - bool read( const cv::FileNode &node, const CvFeatureEvaluator* _featureEvaluator, - const CvCascadeBoostParams& _params ); - void markUsedFeaturesInMap( cv::Mat& featureMap ); -protected: - virtual bool set_params( const CvBoostParams& _params ); - virtual void update_weights( CvBoostTree* tree ); - virtual bool isErrDesired(); - - float threshold; - float minHitRate, maxFalseAlarm; -}; - -#endif diff --git a/apps/traincascade/cascadeclassifier.cpp b/apps/traincascade/cascadeclassifier.cpp deleted file mode 100644 index e364f2e3ed..0000000000 --- a/apps/traincascade/cascadeclassifier.cpp +++ /dev/null @@ -1,570 +0,0 @@ -#include "opencv2/core.hpp" - -#include "cascadeclassifier.h" -#include - -using namespace std; -using namespace cv; - -static const char* stageTypes[] = { CC_BOOST }; -static const char* featureTypes[] = { CC_HAAR, CC_LBP, CC_HOG }; - -CvCascadeParams::CvCascadeParams() : stageType( defaultStageType ), - featureType( defaultFeatureType ), winSize( cvSize(24, 24) ) -{ - name = CC_CASCADE_PARAMS; -} -CvCascadeParams::CvCascadeParams( int _stageType, int _featureType ) : stageType( _stageType ), - featureType( _featureType ), winSize( cvSize(24, 24) ) -{ - name = CC_CASCADE_PARAMS; -} - -//---------------------------- CascadeParams -------------------------------------- - -void CvCascadeParams::write( FileStorage &fs ) const -{ - string stageTypeStr = stageType == BOOST ? CC_BOOST : string(); - CV_Assert( !stageTypeStr.empty() ); - fs << CC_STAGE_TYPE << stageTypeStr; - string featureTypeStr = featureType == CvFeatureParams::HAAR ? CC_HAAR : - featureType == CvFeatureParams::LBP ? CC_LBP : - featureType == CvFeatureParams::HOG ? CC_HOG : - 0; - CV_Assert( !stageTypeStr.empty() ); - fs << CC_FEATURE_TYPE << featureTypeStr; - fs << CC_HEIGHT << winSize.height; - fs << CC_WIDTH << winSize.width; -} - -bool CvCascadeParams::read( const FileNode &node ) -{ - if ( node.empty() ) - return false; - string stageTypeStr, featureTypeStr; - FileNode rnode = node[CC_STAGE_TYPE]; - if ( !rnode.isString() ) - return false; - rnode >> stageTypeStr; - stageType = !stageTypeStr.compare( CC_BOOST ) ? BOOST : -1; - if (stageType == -1) - return false; - rnode = node[CC_FEATURE_TYPE]; - if ( !rnode.isString() ) - return false; - rnode >> featureTypeStr; - featureType = !featureTypeStr.compare( CC_HAAR ) ? CvFeatureParams::HAAR : - !featureTypeStr.compare( CC_LBP ) ? CvFeatureParams::LBP : - !featureTypeStr.compare( CC_HOG ) ? CvFeatureParams::HOG : - -1; - if (featureType == -1) - return false; - node[CC_HEIGHT] >> winSize.height; - node[CC_WIDTH] >> winSize.width; - return winSize.height > 0 && winSize.width > 0; -} - -void CvCascadeParams::printDefaults() const -{ - CvParams::printDefaults(); - cout << " [-stageType <"; - for( int i = 0; i < (int)(sizeof(stageTypes)/sizeof(stageTypes[0])); i++ ) - { - cout << (i ? " | " : "") << stageTypes[i]; - if ( i == defaultStageType ) - cout << "(default)"; - } - cout << ">]" << endl; - - cout << " [-featureType <{"; - for( int i = 0; i < (int)(sizeof(featureTypes)/sizeof(featureTypes[0])); i++ ) - { - cout << (i ? ", " : "") << featureTypes[i]; - if ( i == defaultStageType ) - cout << "(default)"; - } - cout << "}>]" << endl; - cout << " [-w ]" << endl; - cout << " [-h ]" << endl; -} - -void CvCascadeParams::printAttrs() const -{ - cout << "stageType: " << stageTypes[stageType] << endl; - cout << "featureType: " << featureTypes[featureType] << endl; - cout << "sampleWidth: " << winSize.width << endl; - cout << "sampleHeight: " << winSize.height << endl; -} - -bool CvCascadeParams::scanAttr( const string prmName, const string val ) -{ - bool res = true; - if( !prmName.compare( "-stageType" ) ) - { - for( int i = 0; i < (int)(sizeof(stageTypes)/sizeof(stageTypes[0])); i++ ) - if( !val.compare( stageTypes[i] ) ) - stageType = i; - } - else if( !prmName.compare( "-featureType" ) ) - { - for( int i = 0; i < (int)(sizeof(featureTypes)/sizeof(featureTypes[0])); i++ ) - if( !val.compare( featureTypes[i] ) ) - featureType = i; - } - else if( !prmName.compare( "-w" ) ) - { - winSize.width = atoi( val.c_str() ); - } - else if( !prmName.compare( "-h" ) ) - { - winSize.height = atoi( val.c_str() ); - } - else - res = false; - return res; -} - -//---------------------------- CascadeClassifier -------------------------------------- - -bool CvCascadeClassifier::train( const string _cascadeDirName, - const string _posFilename, - const string _negFilename, - int _numPos, int _numNeg, - int _precalcValBufSize, int _precalcIdxBufSize, - int _numStages, - const CvCascadeParams& _cascadeParams, - const CvFeatureParams& _featureParams, - const CvCascadeBoostParams& _stageParams, - bool baseFormatSave, - double acceptanceRatioBreakValue ) -{ - // Start recording clock ticks for training time output - double time = (double)getTickCount(); - - if( _cascadeDirName.empty() || _posFilename.empty() || _negFilename.empty() ) - CV_Error( CV_StsBadArg, "_cascadeDirName or _bgfileName or _vecFileName is NULL" ); - - string dirName; - if (_cascadeDirName.find_last_of("/\\") == (_cascadeDirName.length() - 1) ) - dirName = _cascadeDirName; - else - dirName = _cascadeDirName + '/'; - - numPos = _numPos; - numNeg = _numNeg; - numStages = _numStages; - if ( !imgReader.create( _posFilename, _negFilename, _cascadeParams.winSize ) ) - { - cout << "Image reader can not be created from -vec " << _posFilename - << " and -bg " << _negFilename << "." << endl; - return false; - } - if ( !load( dirName ) ) - { - cascadeParams = _cascadeParams; - featureParams = CvFeatureParams::create(cascadeParams.featureType); - featureParams->init(_featureParams); - stageParams = makePtr(); - *stageParams = _stageParams; - featureEvaluator = CvFeatureEvaluator::create(cascadeParams.featureType); - featureEvaluator->init( featureParams, numPos + numNeg, cascadeParams.winSize ); - stageClassifiers.reserve( numStages ); - }else{ - // Make sure that if model parameters are preloaded, that people are aware of this, - // even when passing other parameters to the training command - cout << "---------------------------------------------------------------------------------" << endl; - cout << "Training parameters are pre-loaded from the parameter file in data folder!" << endl; - cout << "Please empty this folder if you want to use a NEW set of training parameters." << endl; - cout << "---------------------------------------------------------------------------------" << endl; - } - cout << "PARAMETERS:" << endl; - cout << "cascadeDirName: " << _cascadeDirName << endl; - cout << "vecFileName: " << _posFilename << endl; - cout << "bgFileName: " << _negFilename << endl; - cout << "numPos: " << _numPos << endl; - cout << "numNeg: " << _numNeg << endl; - cout << "numStages: " << numStages << endl; - cout << "precalcValBufSize[Mb] : " << _precalcValBufSize << endl; - cout << "precalcIdxBufSize[Mb] : " << _precalcIdxBufSize << endl; - cout << "acceptanceRatioBreakValue : " << acceptanceRatioBreakValue << endl; - cascadeParams.printAttrs(); - stageParams->printAttrs(); - featureParams->printAttrs(); - cout << "Number of unique features given windowSize [" << _cascadeParams.winSize.width << "," << _cascadeParams.winSize.height << "] : " << featureEvaluator->getNumFeatures() << "" << endl; - - int startNumStages = (int)stageClassifiers.size(); - if ( startNumStages > 1 ) - cout << endl << "Stages 0-" << startNumStages-1 << " are loaded" << endl; - else if ( startNumStages == 1) - cout << endl << "Stage 0 is loaded" << endl; - - double requiredLeafFARate = pow( (double) stageParams->maxFalseAlarm, (double) numStages ) / - (double)stageParams->max_depth; - double tempLeafFARate; - - for( int i = startNumStages; i < numStages; i++ ) - { - cout << endl << "===== TRAINING " << i << "-stage =====" << endl; - cout << "= 0) ){ - cout << "The required acceptanceRatio for the model has been reached to avoid overfitting of trainingdata. " - "Branch training terminated." << endl; - break; - } - - Ptr tempStage = makePtr(); - bool isStageTrained = tempStage->train( featureEvaluator, - curNumSamples, _precalcValBufSize, _precalcIdxBufSize, - *stageParams ); - cout << "END>" << endl; - - if(!isStageTrained) - break; - - stageClassifiers.push_back( tempStage ); - - // save params - if( i == 0) - { - std::string paramsFilename = dirName + CC_PARAMS_FILENAME; - FileStorage fs( paramsFilename, FileStorage::WRITE); - if ( !fs.isOpened() ) - { - cout << "Parameters can not be written, because file " << paramsFilename - << " can not be opened." << endl; - return false; - } - fs << FileStorage::getDefaultObjectName(paramsFilename) << "{"; - writeParams( fs ); - fs << "}"; - } - // save current stage - char buf[32]; - snprintf(buf, sizeof(buf), "%s%d", "stage", i ); - string stageFilename = dirName + buf + ".xml"; - FileStorage fs( stageFilename, FileStorage::WRITE ); - if ( !fs.isOpened() ) - { - cout << "Current stage can not be written, because file " << stageFilename - << " can not be opened." << endl; - return false; - } - fs << FileStorage::getDefaultObjectName(stageFilename) << "{"; - tempStage->write( fs, Mat() ); - fs << "}"; - - // Output training time up till now - double seconds = ( (double)getTickCount() - time)/ getTickFrequency(); - int days = int(seconds) / 60 / 60 / 24; - int hours = (int(seconds) / 60 / 60) % 24; - int minutes = (int(seconds) / 60) % 60; - int seconds_left = int(seconds) % 60; - cout << "Training until now has taken " << days << " days " << hours << " hours " << minutes << " minutes " << seconds_left <<" seconds." << endl; - } - - if(stageClassifiers.size() == 0) - { - cout << "Cascade classifier can't be trained. Check the used training parameters." << endl; - return false; - } - - save( dirName + CC_CASCADE_FILENAME, baseFormatSave ); - - return true; -} - -int CvCascadeClassifier::predict( int sampleIdx ) -{ - CV_DbgAssert( sampleIdx < numPos + numNeg ); - for (vector< Ptr >::iterator it = stageClassifiers.begin(); - it != stageClassifiers.end();++it ) - { - if ( (*it)->predict( sampleIdx ) == 0.f ) - return 0; - } - return 1; -} - -bool CvCascadeClassifier::updateTrainingSet( double minimumAcceptanceRatio, double& acceptanceRatio) -{ - int64 posConsumed = 0, negConsumed = 0; - imgReader.restart(); - int posCount = fillPassedSamples( 0, numPos, true, 0, posConsumed ); - if( !posCount ) - return false; - cout << "POS count : consumed " << posCount << " : " << (int)posConsumed << endl; - - int proNumNeg = cvRound( ( ((double)numNeg) * ((double)posCount) ) / numPos ); // apply only a fraction of negative samples. double is required since overflow is possible - int negCount = fillPassedSamples( posCount, proNumNeg, false, minimumAcceptanceRatio, negConsumed ); - if ( !negCount ) - if ( !(negConsumed > 0 && ((double)negCount+1)/(double)negConsumed <= minimumAcceptanceRatio) ) - return false; - - curNumSamples = posCount + negCount; - acceptanceRatio = negConsumed == 0 ? 0 : ( (double)negCount/(double)(int64)negConsumed ); - cout << "NEG count : acceptanceRatio " << negCount << " : " << acceptanceRatio << endl; - return true; -} - -int CvCascadeClassifier::fillPassedSamples( int first, int count, bool isPositive, double minimumAcceptanceRatio, int64& consumed ) -{ - int getcount = 0; - Mat img(cascadeParams.winSize, CV_8UC1); - for( int i = first; i < first + count; i++ ) - { - for( ; ; ) - { - if( consumed != 0 && ((double)getcount+1)/(double)(int64)consumed <= minimumAcceptanceRatio ) - return getcount; - - bool isGetImg = isPositive ? imgReader.getPos( img ) : - imgReader.getNeg( img ); - if( !isGetImg ) - return getcount; - consumed++; - - featureEvaluator->setImage( img, isPositive ? 1 : 0, i ); - if( predict( i ) == 1 ) - { - getcount++; - printf("%s current samples: %d\r", isPositive ? "POS":"NEG", getcount); - fflush(stdout); - break; - } - } - } - return getcount; -} - -void CvCascadeClassifier::writeParams( FileStorage &fs ) const -{ - cascadeParams.write( fs ); - fs << CC_STAGE_PARAMS << "{"; stageParams->write( fs ); fs << "}"; - fs << CC_FEATURE_PARAMS << "{"; featureParams->write( fs ); fs << "}"; -} - -void CvCascadeClassifier::writeFeatures( FileStorage &fs, const Mat& featureMap ) const -{ - featureEvaluator->writeFeatures( fs, featureMap ); -} - -void CvCascadeClassifier::writeStages( FileStorage &fs, const Mat& featureMap ) const -{ - char cmnt[30]; - int i = 0; - fs << CC_STAGES << "["; - for( vector< Ptr >::const_iterator it = stageClassifiers.begin(); - it != stageClassifiers.end();++it, ++i ) - { - snprintf( cmnt, sizeof(cmnt), "stage %d", i ); - fs.writeComment(cmnt); - fs << "{"; - (*it)->write( fs, featureMap ); - fs << "}"; - } - fs << "]"; -} - -bool CvCascadeClassifier::readParams( const FileNode &node ) -{ - if ( !node.isMap() || !cascadeParams.read( node ) ) - return false; - - stageParams = makePtr(); - FileNode rnode = node[CC_STAGE_PARAMS]; - if ( !stageParams->read( rnode ) ) - return false; - - featureParams = CvFeatureParams::create(cascadeParams.featureType); - rnode = node[CC_FEATURE_PARAMS]; - if ( !featureParams->read( rnode ) ) - return false; - return true; -} - -bool CvCascadeClassifier::readStages( const FileNode &node) -{ - FileNode rnode = node[CC_STAGES]; - if (!rnode.empty() || !rnode.isSeq()) - return false; - stageClassifiers.reserve(numStages); - FileNodeIterator it = rnode.begin(); - for( int i = 0; i < min( (int)rnode.size(), numStages ); i++, it++ ) - { - Ptr tempStage = makePtr(); - if ( !tempStage->read( *it, featureEvaluator, *stageParams) ) - return false; - stageClassifiers.push_back(tempStage); - } - return true; -} - -// For old Haar Classifier file saving -#define ICV_HAAR_TYPE_ID "opencv-haar-classifier" -#define ICV_HAAR_SIZE_NAME "size" -#define ICV_HAAR_STAGES_NAME "stages" -#define ICV_HAAR_TREES_NAME "trees" -#define ICV_HAAR_FEATURE_NAME "feature" -#define ICV_HAAR_RECTS_NAME "rects" -#define ICV_HAAR_TILTED_NAME "tilted" -#define ICV_HAAR_THRESHOLD_NAME "threshold" -#define ICV_HAAR_LEFT_NODE_NAME "left_node" -#define ICV_HAAR_LEFT_VAL_NAME "left_val" -#define ICV_HAAR_RIGHT_NODE_NAME "right_node" -#define ICV_HAAR_RIGHT_VAL_NAME "right_val" -#define ICV_HAAR_STAGE_THRESHOLD_NAME "stage_threshold" -#define ICV_HAAR_PARENT_NAME "parent" -#define ICV_HAAR_NEXT_NAME "next" - -void CvCascadeClassifier::save( const string filename, bool baseFormat ) -{ - FileStorage fs( filename, FileStorage::WRITE ); - - if ( !fs.isOpened() ) - return; - - fs << FileStorage::getDefaultObjectName(filename); - if ( !baseFormat ) - { - Mat featureMap; - getUsedFeaturesIdxMap( featureMap ); - fs << "{"; - writeParams( fs ); - fs << CC_STAGE_NUM << (int)stageClassifiers.size(); - writeStages( fs, featureMap ); - writeFeatures( fs, featureMap ); - } - else - { - //char buf[256]; - CvSeq* weak; - if ( cascadeParams.featureType != CvFeatureParams::HAAR ) - CV_Error( CV_StsBadFunc, "old file format is used for Haar-like features only"); - fs << "{:" ICV_HAAR_TYPE_ID; - fs << ICV_HAAR_SIZE_NAME << "[:" << cascadeParams.winSize.width << - cascadeParams.winSize.height << "]"; - fs << ICV_HAAR_STAGES_NAME << "["; - for( size_t si = 0; si < stageClassifiers.size(); si++ ) - { - fs << "{"; //stage - /*snprintf( buf, sizeof(buf), "stage %d", si ); - CV_CALL( cvWriteComment( fs, buf, 1 ) );*/ - weak = stageClassifiers[si]->get_weak_predictors(); - fs << ICV_HAAR_TREES_NAME << "["; - for( int wi = 0; wi < weak->total; wi++ ) - { - int total_inner_node_idx = -1; - queue inner_nodes_queue; - CvCascadeBoostTree* tree = *((CvCascadeBoostTree**) cvGetSeqElem( weak, wi )); - - fs << "["; - /*snprintf( buf, sizeof(buf), "tree %d", wi ); - CV_CALL( cvWriteComment( fs, buf, 1 ) );*/ - - const CvDTreeNode* tempNode; - - inner_nodes_queue.push( tree->get_root() ); - total_inner_node_idx++; - - while (!inner_nodes_queue.empty()) - { - tempNode = inner_nodes_queue.front(); - - fs << "{"; - fs << ICV_HAAR_FEATURE_NAME << "{"; - ((CvHaarEvaluator*)featureEvaluator.get())->writeFeature( fs, tempNode->split->var_idx ); - fs << "}"; - - fs << ICV_HAAR_THRESHOLD_NAME << tempNode->split->ord.c; - - if( tempNode->left->left || tempNode->left->right ) - { - inner_nodes_queue.push( tempNode->left ); - total_inner_node_idx++; - fs << ICV_HAAR_LEFT_NODE_NAME << total_inner_node_idx; - } - else - fs << ICV_HAAR_LEFT_VAL_NAME << tempNode->left->value; - - if( tempNode->right->left || tempNode->right->right ) - { - inner_nodes_queue.push( tempNode->right ); - total_inner_node_idx++; - fs << ICV_HAAR_RIGHT_NODE_NAME << total_inner_node_idx; - } - else - fs << ICV_HAAR_RIGHT_VAL_NAME << tempNode->right->value; - fs << "}"; // ICV_HAAR_FEATURE_NAME - inner_nodes_queue.pop(); - } - fs << "]"; - } - fs << "]"; //ICV_HAAR_TREES_NAME - fs << ICV_HAAR_STAGE_THRESHOLD_NAME << stageClassifiers[si]->getThreshold(); - fs << ICV_HAAR_PARENT_NAME << (int)si-1 << ICV_HAAR_NEXT_NAME << -1; - fs << "}"; //stage - } /* for each stage */ - fs << "]"; //ICV_HAAR_STAGES_NAME - } - fs << "}"; -} - -bool CvCascadeClassifier::load( const string cascadeDirName ) -{ - FileStorage fs( cascadeDirName + CC_PARAMS_FILENAME, FileStorage::READ ); - if ( !fs.isOpened() ) - return false; - FileNode node = fs.getFirstTopLevelNode(); - if ( !readParams( node ) ) - return false; - featureEvaluator = CvFeatureEvaluator::create(cascadeParams.featureType); - featureEvaluator->init( featureParams, numPos + numNeg, cascadeParams.winSize ); - fs.release(); - - char buf[5+10+1] = {0}; - for ( int si = 0; si < numStages; si++ ) - { - snprintf( buf, sizeof(buf), "%s%d", "stage", si); - fs.open( cascadeDirName + buf + ".xml", FileStorage::READ ); - node = fs.getFirstTopLevelNode(); - if ( !fs.isOpened() ) - break; - Ptr tempStage = makePtr(); - - if ( !tempStage->read( node, featureEvaluator, *stageParams )) - { - fs.release(); - break; - } - stageClassifiers.push_back(tempStage); - } - return true; -} - -void CvCascadeClassifier::getUsedFeaturesIdxMap( Mat& featureMap ) -{ - int varCount = featureEvaluator->getNumFeatures() * featureEvaluator->getFeatureSize(); - featureMap.create( 1, varCount, CV_32SC1 ); - featureMap.setTo(Scalar(-1)); - - for( vector< Ptr >::const_iterator it = stageClassifiers.begin(); - it != stageClassifiers.end();++it ) - (*it)->markUsedFeaturesInMap( featureMap ); - - for( int fi = 0, idx = 0; fi < varCount; fi++ ) - if ( featureMap.at(0, fi) >= 0 ) - featureMap.ptr(0)[fi] = idx++; -} diff --git a/apps/traincascade/cascadeclassifier.h b/apps/traincascade/cascadeclassifier.h deleted file mode 100644 index 8f37ee0e6d..0000000000 --- a/apps/traincascade/cascadeclassifier.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef _OPENCV_CASCADECLASSIFIER_H_ -#define _OPENCV_CASCADECLASSIFIER_H_ - -#include -#include "traincascade_features.h" -#include "haarfeatures.h" -#include "lbpfeatures.h" -#include "HOGfeatures.h" //new -#include "boost.h" - -#define CC_CASCADE_FILENAME "cascade.xml" -#define CC_PARAMS_FILENAME "params.xml" - -#define CC_CASCADE_PARAMS "cascadeParams" -#define CC_STAGE_TYPE "stageType" -#define CC_FEATURE_TYPE "featureType" -#define CC_HEIGHT "height" -#define CC_WIDTH "width" - -#define CC_STAGE_NUM "stageNum" -#define CC_STAGES "stages" -#define CC_STAGE_PARAMS "stageParams" - -#define CC_BOOST "BOOST" -#define CC_BOOST_TYPE "boostType" -#define CC_DISCRETE_BOOST "DAB" -#define CC_REAL_BOOST "RAB" -#define CC_LOGIT_BOOST "LB" -#define CC_GENTLE_BOOST "GAB" -#define CC_MINHITRATE "minHitRate" -#define CC_MAXFALSEALARM "maxFalseAlarm" -#define CC_TRIM_RATE "weightTrimRate" -#define CC_MAX_DEPTH "maxDepth" -#define CC_WEAK_COUNT "maxWeakCount" -#define CC_STAGE_THRESHOLD "stageThreshold" -#define CC_WEAK_CLASSIFIERS "weakClassifiers" -#define CC_INTERNAL_NODES "internalNodes" -#define CC_LEAF_VALUES "leafValues" - -#define CC_FEATURES FEATURES -#define CC_FEATURE_PARAMS "featureParams" -#define CC_MAX_CAT_COUNT "maxCatCount" -#define CC_FEATURE_SIZE "featSize" - -#define CC_HAAR "HAAR" -#define CC_MODE "mode" -#define CC_MODE_BASIC "BASIC" -#define CC_MODE_CORE "CORE" -#define CC_MODE_ALL "ALL" -#define CC_RECTS "rects" -#define CC_TILTED "tilted" - -#define CC_LBP "LBP" -#define CC_RECT "rect" - -#define CC_HOG "HOG" - -#ifdef _WIN32 -#define TIME( arg ) (((double) clock()) / CLOCKS_PER_SEC) -#else -#define TIME( arg ) (time( arg )) -#endif - -class CvCascadeParams : public CvParams -{ -public: - enum { BOOST = 0 }; - static const int defaultStageType = BOOST; - static const int defaultFeatureType = CvFeatureParams::HAAR; - - CvCascadeParams(); - CvCascadeParams( int _stageType, int _featureType ); - void write( cv::FileStorage &fs ) const; - bool read( const cv::FileNode &node ); - - void printDefaults() const; - void printAttrs() const; - bool scanAttr( const std::string prmName, const std::string val ); - - int stageType; - int featureType; - cv::Size winSize; -}; - -class CvCascadeClassifier -{ -public: - bool train( const std::string _cascadeDirName, - const std::string _posFilename, - const std::string _negFilename, - int _numPos, int _numNeg, - int _precalcValBufSize, int _precalcIdxBufSize, - int _numStages, - const CvCascadeParams& _cascadeParams, - const CvFeatureParams& _featureParams, - const CvCascadeBoostParams& _stageParams, - bool baseFormatSave = false, - double acceptanceRatioBreakValue = -1.0 ); -private: - int predict( int sampleIdx ); - void save( const std::string cascadeDirName, bool baseFormat = false ); - bool load( const std::string cascadeDirName ); - bool updateTrainingSet( double minimumAcceptanceRatio, double& acceptanceRatio ); - int fillPassedSamples( int first, int count, bool isPositive, double requiredAcceptanceRatio, int64& consumed ); - - void writeParams( cv::FileStorage &fs ) const; - void writeStages( cv::FileStorage &fs, const cv::Mat& featureMap ) const; - void writeFeatures( cv::FileStorage &fs, const cv::Mat& featureMap ) const; - bool readParams( const cv::FileNode &node ); - bool readStages( const cv::FileNode &node ); - - void getUsedFeaturesIdxMap( cv::Mat& featureMap ); - - CvCascadeParams cascadeParams; - cv::Ptr featureParams; - cv::Ptr stageParams; - - cv::Ptr featureEvaluator; - std::vector< cv::Ptr > stageClassifiers; - CvCascadeImageReader imgReader; - int numStages, curNumSamples; - int numPos, numNeg; -}; - -#endif diff --git a/apps/traincascade/features.cpp b/apps/traincascade/features.cpp deleted file mode 100644 index 09e08ac24f..0000000000 --- a/apps/traincascade/features.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "opencv2/core.hpp" - -#include "traincascade_features.h" -#include "cascadeclassifier.h" - -using namespace std; -using namespace cv; - -float calcNormFactor( const Mat& sum, const Mat& sqSum ) -{ - CV_DbgAssert( sum.cols > 3 && sqSum.rows > 3 ); - Rect normrect( 1, 1, sum.cols - 3, sum.rows - 3 ); - size_t p0, p1, p2, p3; - CV_SUM_OFFSETS( p0, p1, p2, p3, normrect, sum.step1() ) - double area = normrect.width * normrect.height; - const int *sp = sum.ptr(); - int valSum = sp[p0] - sp[p1] - sp[p2] + sp[p3]; - const double *sqp = sqSum.ptr(); - double valSqSum = sqp[p0] - sqp[p1] - sqp[p2] + sqp[p3]; - return (float) sqrt( (double) (area * valSqSum - (double)valSum * valSum) ); -} - -CvParams::CvParams() : name( "params" ) {} -void CvParams::printDefaults() const -{ cout << "--" << name << "--" << endl; } -void CvParams::printAttrs() const {} -bool CvParams::scanAttr( const string, const string ) { return false; } - - -//---------------------------- FeatureParams -------------------------------------- - -CvFeatureParams::CvFeatureParams() : maxCatCount( 0 ), featSize( 1 ) -{ - name = CC_FEATURE_PARAMS; -} - -void CvFeatureParams::init( const CvFeatureParams& fp ) -{ - maxCatCount = fp.maxCatCount; - featSize = fp.featSize; -} - -void CvFeatureParams::write( FileStorage &fs ) const -{ - fs << CC_MAX_CAT_COUNT << maxCatCount; - fs << CC_FEATURE_SIZE << featSize; -} - -bool CvFeatureParams::read( const FileNode &node ) -{ - if ( node.empty() ) - return false; - maxCatCount = node[CC_MAX_CAT_COUNT]; - featSize = node[CC_FEATURE_SIZE]; - return ( maxCatCount >= 0 && featSize >= 1 ); -} - -Ptr CvFeatureParams::create( int featureType ) -{ - return featureType == HAAR ? Ptr(new CvHaarFeatureParams) : - featureType == LBP ? Ptr(new CvLBPFeatureParams) : - featureType == HOG ? Ptr(new CvHOGFeatureParams) : - Ptr(); -} - -//------------------------------------- FeatureEvaluator --------------------------------------- - -void CvFeatureEvaluator::init(const CvFeatureParams *_featureParams, - int _maxSampleCount, Size _winSize ) -{ - CV_Assert(_maxSampleCount > 0); - featureParams = (CvFeatureParams *)_featureParams; - winSize = _winSize; - numFeatures = 0; - cls.create( (int)_maxSampleCount, 1, CV_32FC1 ); - generateFeatures(); -} - -void CvFeatureEvaluator::setImage(const Mat &img, uchar clsLabel, int idx) -{ - CV_Assert(img.cols == winSize.width); - CV_Assert(img.rows == winSize.height); - CV_Assert(idx < cls.rows); - cls.ptr(idx)[0] = clsLabel; -} - -Ptr CvFeatureEvaluator::create(int type) -{ - return type == CvFeatureParams::HAAR ? Ptr(new CvHaarEvaluator) : - type == CvFeatureParams::LBP ? Ptr(new CvLBPEvaluator) : - type == CvFeatureParams::HOG ? Ptr(new CvHOGEvaluator) : - Ptr(); -} diff --git a/apps/traincascade/haarfeatures.cpp b/apps/traincascade/haarfeatures.cpp deleted file mode 100644 index c151ee7963..0000000000 --- a/apps/traincascade/haarfeatures.cpp +++ /dev/null @@ -1,312 +0,0 @@ -#include "opencv2/core.hpp" -#include "opencv2/imgproc.hpp" - -#include "haarfeatures.h" -#include "cascadeclassifier.h" - -using namespace std; -using namespace cv; - -CvHaarFeatureParams::CvHaarFeatureParams() : mode(BASIC) -{ - name = HFP_NAME; -} - -CvHaarFeatureParams::CvHaarFeatureParams( int _mode ) : mode( _mode ) -{ - name = HFP_NAME; -} - -void CvHaarFeatureParams::init( const CvFeatureParams& fp ) -{ - CvFeatureParams::init( fp ); - mode = ((const CvHaarFeatureParams&)fp).mode; -} - -void CvHaarFeatureParams::write( FileStorage &fs ) const -{ - CvFeatureParams::write( fs ); - string modeStr = mode == BASIC ? CC_MODE_BASIC : - mode == CORE ? CC_MODE_CORE : - mode == ALL ? CC_MODE_ALL : string(); - CV_Assert( !modeStr.empty() ); - fs << CC_MODE << modeStr; -} - -bool CvHaarFeatureParams::read( const FileNode &node ) -{ - if( !CvFeatureParams::read( node ) ) - return false; - - FileNode rnode = node[CC_MODE]; - if( !rnode.isString() ) - return false; - string modeStr; - rnode >> modeStr; - mode = !modeStr.compare( CC_MODE_BASIC ) ? BASIC : - !modeStr.compare( CC_MODE_CORE ) ? CORE : - !modeStr.compare( CC_MODE_ALL ) ? ALL : -1; - return (mode >= 0); -} - -void CvHaarFeatureParams::printDefaults() const -{ - CvFeatureParams::printDefaults(); - cout << " [-mode <" CC_MODE_BASIC << "(default) | " - << CC_MODE_CORE <<" | " << CC_MODE_ALL << endl; -} - -void CvHaarFeatureParams::printAttrs() const -{ - CvFeatureParams::printAttrs(); - string mode_str = mode == BASIC ? CC_MODE_BASIC : - mode == CORE ? CC_MODE_CORE : - mode == ALL ? CC_MODE_ALL : 0; - cout << "mode: " << mode_str << endl; -} - -bool CvHaarFeatureParams::scanAttr( const string prmName, const string val) -{ - if ( !CvFeatureParams::scanAttr( prmName, val ) ) - { - if( !prmName.compare("-mode") ) - { - mode = !val.compare( CC_MODE_CORE ) ? CORE : - !val.compare( CC_MODE_ALL ) ? ALL : - !val.compare( CC_MODE_BASIC ) ? BASIC : -1; - if (mode == -1) - return false; - } - return false; - } - return true; -} - -//--------------------- HaarFeatureEvaluator ---------------- - -void CvHaarEvaluator::init(const CvFeatureParams *_featureParams, - int _maxSampleCount, Size _winSize ) -{ - CV_Assert(_maxSampleCount > 0); - int cols = (_winSize.width + 1) * (_winSize.height + 1); - sum.create((int)_maxSampleCount, cols, CV_32SC1); - tilted.create((int)_maxSampleCount, cols, CV_32SC1); - normfactor.create(1, (int)_maxSampleCount, CV_32FC1); - CvFeatureEvaluator::init( _featureParams, _maxSampleCount, _winSize ); -} - -void CvHaarEvaluator::setImage(const Mat& img, uchar clsLabel, int idx) -{ - CV_DbgAssert( !sum.empty() && !tilted.empty() && !normfactor.empty() ); - CvFeatureEvaluator::setImage( img, clsLabel, idx); - Mat innSum(winSize.height + 1, winSize.width + 1, sum.type(), sum.ptr((int)idx)); - Mat innSqSum; - if (((const CvHaarFeatureParams*)featureParams)->mode == CvHaarFeatureParams::ALL) - { - Mat innTilted(winSize.height + 1, winSize.width + 1, tilted.type(), tilted.ptr((int)idx)); - integral(img, innSum, innSqSum, innTilted); - } - else - integral(img, innSum, innSqSum); - normfactor.ptr(0)[idx] = calcNormFactor( innSum, innSqSum ); -} - -void CvHaarEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const -{ - _writeFeatures( features, fs, featureMap ); -} - -void CvHaarEvaluator::writeFeature(FileStorage &fs, int fi) const -{ - CV_DbgAssert( fi < (int)features.size() ); - features[fi].write(fs); -} - -void CvHaarEvaluator::generateFeatures() -{ - int mode = ((const CvHaarFeatureParams*)((CvFeatureParams*)featureParams))->mode; - int offset = winSize.width + 1; - for( int x = 0; x < winSize.width; x++ ) - { - for( int y = 0; y < winSize.height; y++ ) - { - for( int dx = 1; dx <= winSize.width; dx++ ) - { - for( int dy = 1; dy <= winSize.height; dy++ ) - { - // haar_x2 - if ( (x+dx*2 <= winSize.width) && (y+dy <= winSize.height) ) - { - features.push_back( Feature( offset, false, - x, y, dx*2, dy, -1, - x+dx, y, dx , dy, +2 ) ); - } - // haar_y2 - if ( (x+dx <= winSize.width) && (y+dy*2 <= winSize.height) ) - { - features.push_back( Feature( offset, false, - x, y, dx, dy*2, -1, - x, y+dy, dx, dy, +2 ) ); - } - // haar_x3 - if ( (x+dx*3 <= winSize.width) && (y+dy <= winSize.height) ) - { - features.push_back( Feature( offset, false, - x, y, dx*3, dy, -1, - x+dx, y, dx , dy, +2 ) ); - } - // haar_y3 - if ( (x+dx <= winSize.width) && (y+dy*3 <= winSize.height) ) - { - features.push_back( Feature( offset, false, - x, y, dx, dy*3, -1, - x, y+dy, dx, dy, +2 ) ); - } - if( mode != CvHaarFeatureParams::BASIC ) - { - // haar_x4 - if ( (x+dx*4 <= winSize.width) && (y+dy <= winSize.height) ) - { - features.push_back( Feature( offset, false, - x, y, dx*4, dy, -1, - x+dx, y, dx*2, dy, +2 ) ); - } - // haar_y4 - if ( (x+dx <= winSize.width ) && (y+dy*4 <= winSize.height) ) - { - features.push_back( Feature( offset, false, - x, y, dx, dy*4, -1, - x, y+dy, dx, dy*2, +2 ) ); - } - } - // x2_y2 - if ( (x+dx*2 <= winSize.width) && (y+dy*2 <= winSize.height) ) - { - features.push_back( Feature( offset, false, - x, y, dx*2, dy*2, -1, - x, y, dx, dy, +2, - x+dx, y+dy, dx, dy, +2 ) ); - } - if (mode != CvHaarFeatureParams::BASIC) - { - if ( (x+dx*3 <= winSize.width) && (y+dy*3 <= winSize.height) ) - { - features.push_back( Feature( offset, false, - x , y , dx*3, dy*3, -1, - x+dx, y+dy, dx , dy , +9) ); - } - } - if (mode == CvHaarFeatureParams::ALL) - { - // tilted haar_x2 - if ( (x+2*dx <= winSize.width) && (y+2*dx+dy <= winSize.height) && (x-dy>= 0) ) - { - features.push_back( Feature( offset, true, - x, y, dx*2, dy, -1, - x, y, dx, dy, +2 ) ); - } - // tilted haar_y2 - if ( (x+dx <= winSize.width) && (y+dx+2*dy <= winSize.height) && (x-2*dy>= 0) ) - { - features.push_back( Feature( offset, true, - x, y, dx, 2*dy, -1, - x, y, dx, dy, +2 ) ); - } - // tilted haar_x3 - if ( (x+3*dx <= winSize.width) && (y+3*dx+dy <= winSize.height) && (x-dy>= 0) ) - { - features.push_back( Feature( offset, true, - x, y, dx*3, dy, -1, - x+dx, y+dx, dx, dy, +3 ) ); - } - // tilted haar_y3 - if ( (x+dx <= winSize.width) && (y+dx+3*dy <= winSize.height) && (x-3*dy>= 0) ) - { - features.push_back( Feature( offset, true, - x, y, dx, 3*dy, -1, - x-dy, y+dy, dx, dy, +3 ) ); - } - // tilted haar_x4 - if ( (x+4*dx <= winSize.width) && (y+4*dx+dy <= winSize.height) && (x-dy>= 0) ) - { - features.push_back( Feature( offset, true, - x, y, dx*4, dy, -1, - x+dx, y+dx, dx*2, dy, +2 ) ); - } - // tilted haar_y4 - if ( (x+dx <= winSize.width) && (y+dx+4*dy <= winSize.height) && (x-4*dy>= 0) ) - { - features.push_back( Feature( offset, true, - x, y, dx, 4*dy, -1, - x-dy, y+dy, dx, 2*dy, +2 ) ); - } - } - } - } - } - } - numFeatures = (int)features.size(); -} - -CvHaarEvaluator::Feature::Feature() -{ - tilted = false; - rect[0].r = rect[1].r = rect[2].r = Rect(0,0,0,0); - rect[0].weight = rect[1].weight = rect[2].weight = 0; -} - -CvHaarEvaluator::Feature::Feature( int offset, bool _tilted, - int x0, int y0, int w0, int h0, float wt0, - int x1, int y1, int w1, int h1, float wt1, - int x2, int y2, int w2, int h2, float wt2 ) -{ - tilted = _tilted; - - rect[0].r.x = x0; - rect[0].r.y = y0; - rect[0].r.width = w0; - rect[0].r.height = h0; - rect[0].weight = wt0; - - rect[1].r.x = x1; - rect[1].r.y = y1; - rect[1].r.width = w1; - rect[1].r.height = h1; - rect[1].weight = wt1; - - rect[2].r.x = x2; - rect[2].r.y = y2; - rect[2].r.width = w2; - rect[2].r.height = h2; - rect[2].weight = wt2; - - if( !tilted ) - { - for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ ) - { - if( rect[j].weight == 0.0F ) - break; - CV_SUM_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset ) - } - } - else - { - for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ ) - { - if( rect[j].weight == 0.0F ) - break; - CV_TILTED_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset ) - } - } -} - -void CvHaarEvaluator::Feature::write( FileStorage &fs ) const -{ - fs << CC_RECTS << "["; - for( int ri = 0; ri < CV_HAAR_FEATURE_MAX && rect[ri].r.width != 0; ++ri ) - { - fs << "[:" << rect[ri].r.x << rect[ri].r.y << - rect[ri].r.width << rect[ri].r.height << rect[ri].weight << "]"; - } - fs << "]" << CC_TILTED << tilted; -} diff --git a/apps/traincascade/haarfeatures.h b/apps/traincascade/haarfeatures.h deleted file mode 100644 index 0894d098c3..0000000000 --- a/apps/traincascade/haarfeatures.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef _OPENCV_HAARFEATURES_H_ -#define _OPENCV_HAARFEATURES_H_ - -#include "traincascade_features.h" - -#define CV_HAAR_FEATURE_MAX 3 - -#define HFP_NAME "haarFeatureParams" -class CvHaarFeatureParams : public CvFeatureParams -{ -public: - enum { BASIC = 0, CORE = 1, ALL = 2 }; - /* 0 - BASIC = Viola - * 1 - CORE = All upright - * 2 - ALL = All features */ - - CvHaarFeatureParams(); - CvHaarFeatureParams( int _mode ); - - virtual void init( const CvFeatureParams& fp ); - virtual void write( cv::FileStorage &fs ) const; - virtual bool read( const cv::FileNode &node ); - - virtual void printDefaults() const; - virtual void printAttrs() const; - virtual bool scanAttr( const std::string prm, const std::string val); - - int mode; -}; - -class CvHaarEvaluator : public CvFeatureEvaluator -{ -public: - virtual void init(const CvFeatureParams *_featureParams, - int _maxSampleCount, cv::Size _winSize ); - virtual void setImage(const cv::Mat& img, uchar clsLabel, int idx); - virtual float operator()(int featureIdx, int sampleIdx) const; - virtual void writeFeatures( cv::FileStorage &fs, const cv::Mat& featureMap ) const; - void writeFeature( cv::FileStorage &fs, int fi ) const; // for old file fornat -protected: - virtual void generateFeatures(); - - class Feature - { - public: - Feature(); - Feature( int offset, bool _tilted, - int x0, int y0, int w0, int h0, float wt0, - int x1, int y1, int w1, int h1, float wt1, - int x2 = 0, int y2 = 0, int w2 = 0, int h2 = 0, float wt2 = 0.0F ); - float calc( const cv::Mat &sum, const cv::Mat &tilted, size_t y) const; - void write( cv::FileStorage &fs ) const; - - bool tilted; - struct - { - cv::Rect r; - float weight; - } rect[CV_HAAR_FEATURE_MAX]; - - struct - { - int p0, p1, p2, p3; - } fastRect[CV_HAAR_FEATURE_MAX]; - }; - - std::vector features; - cv::Mat sum; /* sum images (each row represents image) */ - cv::Mat tilted; /* tilted sum images (each row represents image) */ - cv::Mat normfactor; /* normalization factor */ -}; - -inline float CvHaarEvaluator::operator()(int featureIdx, int sampleIdx) const -{ - float nf = normfactor.at(0, sampleIdx); - return !nf ? 0.0f : (features[featureIdx].calc( sum, tilted, sampleIdx)/nf); -} - -inline float CvHaarEvaluator::Feature::calc( const cv::Mat &_sum, const cv::Mat &_tilted, size_t y) const -{ - const int* img = tilted ? _tilted.ptr((int)y) : _sum.ptr((int)y); - float ret = rect[0].weight * (img[fastRect[0].p0] - img[fastRect[0].p1] - img[fastRect[0].p2] + img[fastRect[0].p3] ) + - rect[1].weight * (img[fastRect[1].p0] - img[fastRect[1].p1] - img[fastRect[1].p2] + img[fastRect[1].p3] ); - if( rect[2].weight != 0.0f ) - ret += rect[2].weight * (img[fastRect[2].p0] - img[fastRect[2].p1] - img[fastRect[2].p2] + img[fastRect[2].p3] ); - return ret; -} - -#endif diff --git a/apps/traincascade/imagestorage.cpp b/apps/traincascade/imagestorage.cpp deleted file mode 100644 index f220e5c2b3..0000000000 --- a/apps/traincascade/imagestorage.cpp +++ /dev/null @@ -1,186 +0,0 @@ -#include "opencv2/core.hpp" -#include "opencv2/core/core_c.h" -#include "opencv2/imgproc.hpp" -#include "opencv2/imgcodecs.hpp" - -#include "imagestorage.h" -#include -#include -#include - -using namespace std; -using namespace cv; - -bool CvCascadeImageReader::create( const string _posFilename, const string _negFilename, Size _winSize ) -{ - return posReader.create(_posFilename) && negReader.create(_negFilename, _winSize); -} - -CvCascadeImageReader::NegReader::NegReader() -{ - src.create( 0, 0 , CV_8UC1 ); - img.create( 0, 0, CV_8UC1 ); - point = offset = Point( 0, 0 ); - scale = 1.0F; - scaleFactor = 1.4142135623730950488016887242097F; - stepFactor = 0.5F; -} - -bool CvCascadeImageReader::NegReader::create( const string _filename, Size _winSize ) -{ - string str; - std::ifstream file(_filename.c_str()); - if ( !file.is_open() ) - return false; - - while( !file.eof() ) - { - std::getline(file, str); - str.erase(str.find_last_not_of(" \n\r\t")+1); - if (str.empty()) break; - if (str.at(0) == '#' ) continue; /* comment */ - imgFilenames.push_back(str); - } - file.close(); - - winSize = _winSize; - last = round = 0; - return true; -} - -bool CvCascadeImageReader::NegReader::nextImg() -{ - Point _offset = Point(0,0); - size_t count = imgFilenames.size(); - for( size_t i = 0; i < count; i++ ) - { - src = imread( imgFilenames[last++], IMREAD_GRAYSCALE ); - if( src.empty() ){ - last %= count; - continue; - } - round += last / count; - round = round % (winSize.width * winSize.height); - last %= count; - - _offset.x = std::min( (int)round % winSize.width, src.cols - winSize.width ); - _offset.y = std::min( (int)round / winSize.width, src.rows - winSize.height ); - if( !src.empty() && src.type() == CV_8UC1 - && _offset.x >= 0 && _offset.y >= 0 ) - break; - } - - if( src.empty() ) - return false; // no appropriate image - point = offset = _offset; - scale = max( ((float)winSize.width + point.x) / ((float)src.cols), - ((float)winSize.height + point.y) / ((float)src.rows) ); - - Size sz( (int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F) ); - resize( src, img, sz, 0, 0, INTER_LINEAR_EXACT ); - return true; -} - -bool CvCascadeImageReader::NegReader::get( Mat& _img ) -{ - CV_Assert( !_img.empty() ); - CV_Assert( _img.type() == CV_8UC1 ); - CV_Assert( _img.cols == winSize.width ); - CV_Assert( _img.rows == winSize.height ); - - if( img.empty() ) - if ( !nextImg() ) - return false; - - Mat mat( winSize.height, winSize.width, CV_8UC1, - (void*)(img.ptr(point.y) + point.x * img.elemSize()), img.step ); - mat.copyTo(_img); - - if( (int)( point.x + (1.0F + stepFactor ) * winSize.width ) < img.cols ) - point.x += (int)(stepFactor * winSize.width); - else - { - point.x = offset.x; - if( (int)( point.y + (1.0F + stepFactor ) * winSize.height ) < img.rows ) - point.y += (int)(stepFactor * winSize.height); - else - { - point.y = offset.y; - scale *= scaleFactor; - if( scale <= 1.0F ) - resize( src, img, Size( (int)(scale*src.cols), (int)(scale*src.rows) ), 0, 0, INTER_LINEAR_EXACT ); - else - { - if ( !nextImg() ) - return false; - } - } - } - return true; -} - -CvCascadeImageReader::PosReader::PosReader() -{ - file = 0; - vec = 0; -} - -bool CvCascadeImageReader::PosReader::create( const string _filename ) -{ - if ( file ) - fclose( file ); - file = fopen( _filename.c_str(), "rb" ); - - if( !file ) - return false; - short tmp = 0; - if( fread( &count, sizeof( count ), 1, file ) != 1 || - fread( &vecSize, sizeof( vecSize ), 1, file ) != 1 || - fread( &tmp, sizeof( tmp ), 1, file ) != 1 || - fread( &tmp, sizeof( tmp ), 1, file ) != 1 ) - CV_Error_( CV_StsParseError, ("wrong file format for %s\n", _filename.c_str()) ); - base = sizeof( count ) + sizeof( vecSize ) + 2*sizeof( tmp ); - if( feof( file ) ) - return false; - last = 0; - vec = (short*) cvAlloc( sizeof( *vec ) * vecSize ); - CV_Assert( vec ); - return true; -} - -bool CvCascadeImageReader::PosReader::get( Mat &_img ) -{ - CV_Assert( _img.rows * _img.cols == vecSize ); - uchar tmp = 0; - size_t elements_read = fread( &tmp, sizeof( tmp ), 1, file ); - if( elements_read != 1 ) - CV_Error( CV_StsBadArg, "Can not get new positive sample. The most possible reason is " - "insufficient count of samples in given vec-file.\n"); - elements_read = fread( vec, sizeof( vec[0] ), vecSize, file ); - if( elements_read != (size_t)(vecSize) ) - CV_Error( CV_StsBadArg, "Can not get new positive sample. Seems that vec-file has incorrect structure.\n"); - - if( feof( file ) || last++ >= count ) - CV_Error( CV_StsBadArg, "Can not get new positive sample. vec-file is over.\n"); - - for( int r = 0; r < _img.rows; r++ ) - { - for( int c = 0; c < _img.cols; c++ ) - _img.ptr(r)[c] = (uchar)vec[r * _img.cols + c]; - } - return true; -} - -void CvCascadeImageReader::PosReader::restart() -{ - CV_Assert( file ); - last = 0; - fseek( file, base, SEEK_SET ); -} - -CvCascadeImageReader::PosReader::~PosReader() -{ - if (file) - fclose( file ); - cvFree( &vec ); -} diff --git a/apps/traincascade/imagestorage.h b/apps/traincascade/imagestorage.h deleted file mode 100644 index 38ca52a8b5..0000000000 --- a/apps/traincascade/imagestorage.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _OPENCV_IMAGESTORAGE_H_ -#define _OPENCV_IMAGESTORAGE_H_ - - -class CvCascadeImageReader -{ -public: - bool create( const std::string _posFilename, const std::string _negFilename, cv::Size _winSize ); - void restart() { posReader.restart(); } - bool getNeg(cv::Mat &_img) { return negReader.get( _img ); } - bool getPos(cv::Mat &_img) { return posReader.get( _img ); } - -private: - class PosReader - { - public: - PosReader(); - virtual ~PosReader(); - bool create( const std::string _filename ); - bool get( cv::Mat &_img ); - void restart(); - - short* vec; - FILE* file; - int count; - int vecSize; - int last; - int base; - } posReader; - - class NegReader - { - public: - NegReader(); - bool create( const std::string _filename, cv::Size _winSize ); - bool get( cv::Mat& _img ); - bool nextImg(); - - cv::Mat src, img; - std::vector imgFilenames; - cv::Point offset, point; - float scale; - float scaleFactor; - float stepFactor; - size_t last, round; - cv::Size winSize; - } negReader; -}; - -#endif diff --git a/apps/traincascade/lbpfeatures.cpp b/apps/traincascade/lbpfeatures.cpp deleted file mode 100644 index e99c6b2b7e..0000000000 --- a/apps/traincascade/lbpfeatures.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "opencv2/core.hpp" -#include "opencv2/imgproc.hpp" - -#include "lbpfeatures.h" -#include "cascadeclassifier.h" - -using namespace cv; - -CvLBPFeatureParams::CvLBPFeatureParams() -{ - maxCatCount = 256; - name = LBPF_NAME; -} - -void CvLBPEvaluator::init(const CvFeatureParams *_featureParams, int _maxSampleCount, Size _winSize) -{ - CV_Assert( _maxSampleCount > 0); - sum.create((int)_maxSampleCount, (_winSize.width + 1) * (_winSize.height + 1), CV_32SC1); - CvFeatureEvaluator::init( _featureParams, _maxSampleCount, _winSize ); -} - -void CvLBPEvaluator::setImage(const Mat &img, uchar clsLabel, int idx) -{ - CV_DbgAssert( !sum.empty() ); - CvFeatureEvaluator::setImage( img, clsLabel, idx ); - Mat innSum(winSize.height + 1, winSize.width + 1, sum.type(), sum.ptr((int)idx)); - integral( img, innSum ); -} - -void CvLBPEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const -{ - _writeFeatures( features, fs, featureMap ); -} - -void CvLBPEvaluator::generateFeatures() -{ - int offset = winSize.width + 1; - for( int x = 0; x < winSize.width; x++ ) - for( int y = 0; y < winSize.height; y++ ) - for( int w = 1; w <= winSize.width / 3; w++ ) - for( int h = 1; h <= winSize.height / 3; h++ ) - if ( (x+3*w <= winSize.width) && (y+3*h <= winSize.height) ) - features.push_back( Feature(offset, x, y, w, h ) ); - numFeatures = (int)features.size(); -} - -CvLBPEvaluator::Feature::Feature() -{ - rect = cvRect(0, 0, 0, 0); -} - -CvLBPEvaluator::Feature::Feature( int offset, int x, int y, int _blockWidth, int _blockHeight ) -{ - Rect tr = rect = cvRect(x, y, _blockWidth, _blockHeight); - CV_SUM_OFFSETS( p[0], p[1], p[4], p[5], tr, offset ) - tr.x += 2*rect.width; - CV_SUM_OFFSETS( p[2], p[3], p[6], p[7], tr, offset ) - tr.y +=2*rect.height; - CV_SUM_OFFSETS( p[10], p[11], p[14], p[15], tr, offset ) - tr.x -= 2*rect.width; - CV_SUM_OFFSETS( p[8], p[9], p[12], p[13], tr, offset ) -} - -void CvLBPEvaluator::Feature::write(FileStorage &fs) const -{ - fs << CC_RECT << "[:" << rect.x << rect.y << rect.width << rect.height << "]"; -} diff --git a/apps/traincascade/lbpfeatures.h b/apps/traincascade/lbpfeatures.h deleted file mode 100644 index 3e36a5887a..0000000000 --- a/apps/traincascade/lbpfeatures.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _OPENCV_LBPFEATURES_H_ -#define _OPENCV_LBPFEATURES_H_ - -#include "traincascade_features.h" - -#define LBPF_NAME "lbpFeatureParams" -struct CvLBPFeatureParams : CvFeatureParams -{ - CvLBPFeatureParams(); - -}; - -class CvLBPEvaluator : public CvFeatureEvaluator -{ -public: - virtual ~CvLBPEvaluator() {} - virtual void init(const CvFeatureParams *_featureParams, - int _maxSampleCount, cv::Size _winSize ); - virtual void setImage(const cv::Mat& img, uchar clsLabel, int idx); - virtual float operator()(int featureIdx, int sampleIdx) const - { return (float)features[featureIdx].calc( sum, sampleIdx); } - virtual void writeFeatures( cv::FileStorage &fs, const cv::Mat& featureMap ) const; -protected: - virtual void generateFeatures(); - - class Feature - { - public: - Feature(); - Feature( int offset, int x, int y, int _block_w, int _block_h ); - uchar calc( const cv::Mat& _sum, size_t y ) const; - void write( cv::FileStorage &fs ) const; - - cv::Rect rect; - int p[16]; - }; - std::vector features; - - cv::Mat sum; -}; - -inline uchar CvLBPEvaluator::Feature::calc(const cv::Mat &_sum, size_t y) const -{ - const int* psum = _sum.ptr((int)y); - int cval = psum[p[5]] - psum[p[6]] - psum[p[9]] + psum[p[10]]; - - return (uchar)((psum[p[0]] - psum[p[1]] - psum[p[4]] + psum[p[5]] >= cval ? 128 : 0) | // 0 - (psum[p[1]] - psum[p[2]] - psum[p[5]] + psum[p[6]] >= cval ? 64 : 0) | // 1 - (psum[p[2]] - psum[p[3]] - psum[p[6]] + psum[p[7]] >= cval ? 32 : 0) | // 2 - (psum[p[6]] - psum[p[7]] - psum[p[10]] + psum[p[11]] >= cval ? 16 : 0) | // 5 - (psum[p[10]] - psum[p[11]] - psum[p[14]] + psum[p[15]] >= cval ? 8 : 0) | // 8 - (psum[p[9]] - psum[p[10]] - psum[p[13]] + psum[p[14]] >= cval ? 4 : 0) | // 7 - (psum[p[8]] - psum[p[9]] - psum[p[12]] + psum[p[13]] >= cval ? 2 : 0) | // 6 - (psum[p[4]] - psum[p[5]] - psum[p[8]] + psum[p[9]] >= cval ? 1 : 0)); // 3 -} - -#endif diff --git a/apps/traincascade/old_ml.hpp b/apps/traincascade/old_ml.hpp deleted file mode 100644 index c457dea6df..0000000000 --- a/apps/traincascade/old_ml.hpp +++ /dev/null @@ -1,2041 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// Intel License Agreement -// -// 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*/ - -#ifndef OPENCV_OLD_ML_HPP -#define OPENCV_OLD_ML_HPP - -#ifdef __cplusplus -# include "opencv2/core.hpp" -#endif - -#include "opencv2/core/core_c.h" -#include - -#ifdef __cplusplus - -#include -#include - -// Apple defines a check() macro somewhere in the debug headers -// that interferes with a method definition in this header -#undef check - -/****************************************************************************************\ -* Main struct definitions * -\****************************************************************************************/ - -/* log(2*PI) */ -#define CV_LOG2PI (1.8378770664093454835606594728112) - -/* columns of matrix are training samples */ -#define CV_COL_SAMPLE 0 - -/* rows of matrix are training samples */ -#define CV_ROW_SAMPLE 1 - -#define CV_IS_ROW_SAMPLE(flags) ((flags) & CV_ROW_SAMPLE) - -struct CvVectors -{ - int type; - int dims, count; - CvVectors* next; - union - { - uchar** ptr; - float** fl; - double** db; - } data; -}; - -#if 0 -/* A structure, representing the lattice range of statmodel parameters. - It is used for optimizing statmodel parameters by cross-validation method. - The lattice is logarithmic, so must be greater than 1. */ -typedef struct CvParamLattice -{ - double min_val; - double max_val; - double step; -} -CvParamLattice; - -CV_INLINE CvParamLattice cvParamLattice( double min_val, double max_val, - double log_step ) -{ - CvParamLattice pl; - pl.min_val = MIN( min_val, max_val ); - pl.max_val = MAX( min_val, max_val ); - pl.step = MAX( log_step, 1. ); - return pl; -} - -CV_INLINE CvParamLattice cvDefaultParamLattice( void ) -{ - CvParamLattice pl = {0,0,0}; - return pl; -} -#endif - -/* Variable type */ -#define CV_VAR_NUMERICAL 0 -#define CV_VAR_ORDERED 0 -#define CV_VAR_CATEGORICAL 1 - -#define CV_TYPE_NAME_ML_SVM "opencv-ml-svm" -#define CV_TYPE_NAME_ML_KNN "opencv-ml-knn" -#define CV_TYPE_NAME_ML_NBAYES "opencv-ml-bayesian" -#define CV_TYPE_NAME_ML_BOOSTING "opencv-ml-boost-tree" -#define CV_TYPE_NAME_ML_TREE "opencv-ml-tree" -#define CV_TYPE_NAME_ML_ANN_MLP "opencv-ml-ann-mlp" -#define CV_TYPE_NAME_ML_CNN "opencv-ml-cnn" -#define CV_TYPE_NAME_ML_RTREES "opencv-ml-random-trees" -#define CV_TYPE_NAME_ML_ERTREES "opencv-ml-extremely-randomized-trees" -#define CV_TYPE_NAME_ML_GBT "opencv-ml-gradient-boosting-trees" - -#define CV_TRAIN_ERROR 0 -#define CV_TEST_ERROR 1 - -class CvStatModel -{ -public: - CvStatModel(); - virtual ~CvStatModel(); - - virtual void clear(); - - CV_WRAP virtual void save( const char* filename, const char* name=0 ) const; - CV_WRAP virtual void load( const char* filename, const char* name=0 ); - - virtual void write( cv::FileStorage& storage, const char* name ) const; - virtual void read( const cv::FileNode& node ); - -protected: - const char* default_model_name; -}; - -/****************************************************************************************\ -* Normal Bayes Classifier * -\****************************************************************************************/ - -/* The structure, representing the grid range of statmodel parameters. - It is used for optimizing statmodel accuracy by varying model parameters, - the accuracy estimate being computed by cross-validation. - The grid is logarithmic, so must be greater than 1. */ - -class CvMLData; - -struct CvParamGrid -{ - // SVM params type - enum { SVM_C=0, SVM_GAMMA=1, SVM_P=2, SVM_NU=3, SVM_COEF=4, SVM_DEGREE=5 }; - - CvParamGrid() - { - min_val = max_val = step = 0; - } - - CvParamGrid( double min_val, double max_val, double log_step ); - //CvParamGrid( int param_id ); - bool check() const; - - CV_PROP_RW double min_val; - CV_PROP_RW double max_val; - CV_PROP_RW double step; -}; - -inline CvParamGrid::CvParamGrid( double _min_val, double _max_val, double _log_step ) -{ - min_val = _min_val; - max_val = _max_val; - step = _log_step; -} - -class CvNormalBayesClassifier : public CvStatModel -{ -public: - CV_WRAP CvNormalBayesClassifier(); - virtual ~CvNormalBayesClassifier(); - - CvNormalBayesClassifier( const CvMat* trainData, const CvMat* responses, - const CvMat* varIdx=0, const CvMat* sampleIdx=0 ); - - virtual bool train( const CvMat* trainData, const CvMat* responses, - const CvMat* varIdx = 0, const CvMat* sampleIdx=0, bool update=false ); - - virtual float predict( const CvMat* samples, CV_OUT CvMat* results=0, CV_OUT CvMat* results_prob=0 ) const; - CV_WRAP virtual void clear(); - - CV_WRAP CvNormalBayesClassifier( const cv::Mat& trainData, const cv::Mat& responses, - const cv::Mat& varIdx=cv::Mat(), const cv::Mat& sampleIdx=cv::Mat() ); - CV_WRAP virtual bool train( const cv::Mat& trainData, const cv::Mat& responses, - const cv::Mat& varIdx = cv::Mat(), const cv::Mat& sampleIdx=cv::Mat(), - bool update=false ); - CV_WRAP virtual float predict( const cv::Mat& samples, CV_OUT cv::Mat* results=0, CV_OUT cv::Mat* results_prob=0 ) const; - - virtual void write( cv::FileStorage& storage, const char* name ) const; - virtual void read( const cv::FileNode& node ); - -protected: - int var_count, var_all; - CvMat* var_idx; - CvMat* cls_labels; - CvMat** count; - CvMat** sum; - CvMat** productsum; - CvMat** avg; - CvMat** inv_eigen_values; - CvMat** cov_rotate_mats; - CvMat* c; -}; - - -/****************************************************************************************\ -* K-Nearest Neighbour Classifier * -\****************************************************************************************/ - -// k Nearest Neighbors -class CvKNearest : public CvStatModel -{ -public: - - CV_WRAP CvKNearest(); - virtual ~CvKNearest(); - - CvKNearest( const CvMat* trainData, const CvMat* responses, - const CvMat* sampleIdx=0, bool isRegression=false, int max_k=32 ); - - virtual bool train( const CvMat* trainData, const CvMat* responses, - const CvMat* sampleIdx=0, bool is_regression=false, - int maxK=32, bool updateBase=false ); - - virtual float find_nearest( const CvMat* samples, int k, CV_OUT CvMat* results=0, - const float** neighbors=0, CV_OUT CvMat* neighborResponses=0, CV_OUT CvMat* dist=0 ) const; - - CV_WRAP CvKNearest( const cv::Mat& trainData, const cv::Mat& responses, - const cv::Mat& sampleIdx=cv::Mat(), bool isRegression=false, int max_k=32 ); - - CV_WRAP virtual bool train( const cv::Mat& trainData, const cv::Mat& responses, - const cv::Mat& sampleIdx=cv::Mat(), bool isRegression=false, - int maxK=32, bool updateBase=false ); - - virtual float find_nearest( const cv::Mat& samples, int k, cv::Mat* results=0, - const float** neighbors=0, cv::Mat* neighborResponses=0, - cv::Mat* dist=0 ) const; - CV_WRAP virtual float find_nearest( const cv::Mat& samples, int k, CV_OUT cv::Mat& results, - CV_OUT cv::Mat& neighborResponses, CV_OUT cv::Mat& dists) const; - - virtual void clear(); - int get_max_k() const; - int get_var_count() const; - int get_sample_count() const; - bool is_regression() const; - - virtual float write_results( int k, int k1, int start, int end, - const float* neighbor_responses, const float* dist, CvMat* _results, - CvMat* _neighbor_responses, CvMat* _dist, Cv32suf* sort_buf ) const; - - virtual void find_neighbors_direct( const CvMat* _samples, int k, int start, int end, - float* neighbor_responses, const float** neighbors, float* dist ) const; - -protected: - - int max_k, var_count; - int total; - bool regression; - CvVectors* samples; -}; - -/****************************************************************************************\ -* Support Vector Machines * -\****************************************************************************************/ - -// SVM training parameters -struct CvSVMParams -{ - CvSVMParams(); - CvSVMParams( int svm_type, int kernel_type, - double degree, double gamma, double coef0, - double Cvalue, double nu, double p, - CvMat* class_weights, CvTermCriteria term_crit ); - - CV_PROP_RW int svm_type; - CV_PROP_RW int kernel_type; - CV_PROP_RW double degree; // for poly - CV_PROP_RW double gamma; // for poly/rbf/sigmoid/chi2 - CV_PROP_RW double coef0; // for poly/sigmoid - - CV_PROP_RW double C; // for CV_SVM_C_SVC, CV_SVM_EPS_SVR and CV_SVM_NU_SVR - CV_PROP_RW double nu; // for CV_SVM_NU_SVC, CV_SVM_ONE_CLASS, and CV_SVM_NU_SVR - CV_PROP_RW double p; // for CV_SVM_EPS_SVR - CvMat* class_weights; // for CV_SVM_C_SVC - CV_PROP_RW CvTermCriteria term_crit; // termination criteria -}; - - -struct CvSVMKernel -{ - typedef void (CvSVMKernel::*Calc)( int vec_count, int vec_size, const float** vecs, - const float* another, float* results ); - CvSVMKernel(); - CvSVMKernel( const CvSVMParams* params, Calc _calc_func ); - virtual bool create( const CvSVMParams* params, Calc _calc_func ); - virtual ~CvSVMKernel(); - - virtual void clear(); - virtual void calc( int vcount, int n, const float** vecs, const float* another, float* results ); - - const CvSVMParams* params; - Calc calc_func; - - virtual void calc_non_rbf_base( int vec_count, int vec_size, const float** vecs, - const float* another, float* results, - double alpha, double beta ); - virtual void calc_intersec( int vcount, int var_count, const float** vecs, - const float* another, float* results ); - virtual void calc_chi2( int vec_count, int vec_size, const float** vecs, - const float* another, float* results ); - virtual void calc_linear( int vec_count, int vec_size, const float** vecs, - const float* another, float* results ); - virtual void calc_rbf( int vec_count, int vec_size, const float** vecs, - const float* another, float* results ); - virtual void calc_poly( int vec_count, int vec_size, const float** vecs, - const float* another, float* results ); - virtual void calc_sigmoid( int vec_count, int vec_size, const float** vecs, - const float* another, float* results ); -}; - - -struct CvSVMKernelRow -{ - CvSVMKernelRow* prev; - CvSVMKernelRow* next; - float* data; -}; - - -struct CvSVMSolutionInfo -{ - double obj; - double rho; - double upper_bound_p; - double upper_bound_n; - double r; // for Solver_NU -}; - -class CvSVMSolver -{ -public: - typedef bool (CvSVMSolver::*SelectWorkingSet)( int& i, int& j ); - typedef float* (CvSVMSolver::*GetRow)( int i, float* row, float* dst, bool existed ); - typedef void (CvSVMSolver::*CalcRho)( double& rho, double& r ); - - CvSVMSolver(); - - CvSVMSolver( int count, int var_count, const float** samples, schar* y, - int alpha_count, double* alpha, double Cp, double Cn, - CvMemStorage* storage, CvSVMKernel* kernel, GetRow get_row, - SelectWorkingSet select_working_set, CalcRho calc_rho ); - virtual bool create( int count, int var_count, const float** samples, schar* y, - int alpha_count, double* alpha, double Cp, double Cn, - CvMemStorage* storage, CvSVMKernel* kernel, GetRow get_row, - SelectWorkingSet select_working_set, CalcRho calc_rho ); - virtual ~CvSVMSolver(); - - virtual void clear(); - virtual bool solve_generic( CvSVMSolutionInfo& si ); - - virtual bool solve_c_svc( int count, int var_count, const float** samples, schar* y, - double Cp, double Cn, CvMemStorage* storage, - CvSVMKernel* kernel, double* alpha, CvSVMSolutionInfo& si ); - virtual bool solve_nu_svc( int count, int var_count, const float** samples, schar* y, - CvMemStorage* storage, CvSVMKernel* kernel, - double* alpha, CvSVMSolutionInfo& si ); - virtual bool solve_one_class( int count, int var_count, const float** samples, - CvMemStorage* storage, CvSVMKernel* kernel, - double* alpha, CvSVMSolutionInfo& si ); - - virtual bool solve_eps_svr( int count, int var_count, const float** samples, const float* y, - CvMemStorage* storage, CvSVMKernel* kernel, - double* alpha, CvSVMSolutionInfo& si ); - - virtual bool solve_nu_svr( int count, int var_count, const float** samples, const float* y, - CvMemStorage* storage, CvSVMKernel* kernel, - double* alpha, CvSVMSolutionInfo& si ); - - virtual float* get_row_base( int i, bool* _existed ); - virtual float* get_row( int i, float* dst ); - - int sample_count; - int var_count; - int cache_size; - int cache_line_size; - const float** samples; - const CvSVMParams* params; - CvMemStorage* storage; - CvSVMKernelRow lru_list; - CvSVMKernelRow* rows; - - int alpha_count; - - double* G; - double* alpha; - - // -1 - lower bound, 0 - free, 1 - upper bound - schar* alpha_status; - - schar* y; - double* b; - float* buf[2]; - double eps; - int max_iter; - double C[2]; // C[0] == Cn, C[1] == Cp - CvSVMKernel* kernel; - - SelectWorkingSet select_working_set_func; - CalcRho calc_rho_func; - GetRow get_row_func; - - virtual bool select_working_set( int& i, int& j ); - virtual bool select_working_set_nu_svm( int& i, int& j ); - virtual void calc_rho( double& rho, double& r ); - virtual void calc_rho_nu_svm( double& rho, double& r ); - - virtual float* get_row_svc( int i, float* row, float* dst, bool existed ); - virtual float* get_row_one_class( int i, float* row, float* dst, bool existed ); - virtual float* get_row_svr( int i, float* row, float* dst, bool existed ); -}; - - -struct CvSVMDecisionFunc -{ - double rho; - int sv_count; - double* alpha; - int* sv_index; -}; - - -// SVM model -class CvSVM : public CvStatModel -{ -public: - // SVM type - enum { C_SVC=100, NU_SVC=101, ONE_CLASS=102, EPS_SVR=103, NU_SVR=104 }; - - // SVM kernel type - enum { LINEAR=0, POLY=1, RBF=2, SIGMOID=3, CHI2=4, INTER=5 }; - - // SVM params type - enum { C=0, GAMMA=1, P=2, NU=3, COEF=4, DEGREE=5 }; - - CV_WRAP CvSVM(); - virtual ~CvSVM(); - - CvSVM( const CvMat* trainData, const CvMat* responses, - const CvMat* varIdx=0, const CvMat* sampleIdx=0, - CvSVMParams params=CvSVMParams() ); - - virtual bool train( const CvMat* trainData, const CvMat* responses, - const CvMat* varIdx=0, const CvMat* sampleIdx=0, - CvSVMParams params=CvSVMParams() ); - - virtual bool train_auto( const CvMat* trainData, const CvMat* responses, - const CvMat* varIdx, const CvMat* sampleIdx, CvSVMParams params, - int kfold = 10, - CvParamGrid Cgrid = get_default_grid(CvSVM::C), - CvParamGrid gammaGrid = get_default_grid(CvSVM::GAMMA), - CvParamGrid pGrid = get_default_grid(CvSVM::P), - CvParamGrid nuGrid = get_default_grid(CvSVM::NU), - CvParamGrid coeffGrid = get_default_grid(CvSVM::COEF), - CvParamGrid degreeGrid = get_default_grid(CvSVM::DEGREE), - bool balanced=false ); - - virtual float predict( const CvMat* sample, bool returnDFVal=false ) const; - virtual float predict( const CvMat* samples, CV_OUT CvMat* results, bool returnDFVal=false ) const; - - CV_WRAP CvSVM( const cv::Mat& trainData, const cv::Mat& responses, - const cv::Mat& varIdx=cv::Mat(), const cv::Mat& sampleIdx=cv::Mat(), - CvSVMParams params=CvSVMParams() ); - - CV_WRAP virtual bool train( const cv::Mat& trainData, const cv::Mat& responses, - const cv::Mat& varIdx=cv::Mat(), const cv::Mat& sampleIdx=cv::Mat(), - CvSVMParams params=CvSVMParams() ); - - CV_WRAP virtual bool train_auto( const cv::Mat& trainData, const cv::Mat& responses, - const cv::Mat& varIdx, const cv::Mat& sampleIdx, CvSVMParams params, - int k_fold = 10, - CvParamGrid Cgrid = CvSVM::get_default_grid(CvSVM::C), - CvParamGrid gammaGrid = CvSVM::get_default_grid(CvSVM::GAMMA), - CvParamGrid pGrid = CvSVM::get_default_grid(CvSVM::P), - CvParamGrid nuGrid = CvSVM::get_default_grid(CvSVM::NU), - CvParamGrid coeffGrid = CvSVM::get_default_grid(CvSVM::COEF), - CvParamGrid degreeGrid = CvSVM::get_default_grid(CvSVM::DEGREE), - bool balanced=false); - CV_WRAP virtual float predict( const cv::Mat& sample, bool returnDFVal=false ) const; - CV_WRAP_AS(predict_all) virtual void predict( cv::InputArray samples, cv::OutputArray results ) const; - - CV_WRAP virtual int get_support_vector_count() const; - virtual const float* get_support_vector(int i) const; - virtual CvSVMParams get_params() const { return params; } - CV_WRAP virtual void clear(); - - virtual const CvSVMDecisionFunc* get_decision_function() const { return decision_func; } - - static CvParamGrid get_default_grid( int param_id ); - - virtual void write( cv::FileStorage& storage, const char* name ) const; - virtual void read( const cv::FileNode& node ); - CV_WRAP int get_var_count() const { return var_idx ? var_idx->cols : var_all; } - -protected: - - virtual bool set_params( const CvSVMParams& params ); - virtual bool train1( int sample_count, int var_count, const float** samples, - const void* responses, double Cp, double Cn, - CvMemStorage* _storage, double* alpha, double& rho ); - virtual bool do_train( int svm_type, int sample_count, int var_count, const float** samples, - const CvMat* responses, CvMemStorage* _storage, double* alpha ); - virtual void create_kernel(); - virtual void create_solver(); - - virtual float predict( const float* row_sample, int row_len, bool returnDFVal=false ) const; - - virtual void write_params( cv::FileStorage& fs ) const; - virtual void read_params( const cv::FileNode& node ); - - void optimize_linear_svm(); - - CvSVMParams params; - CvMat* class_labels; - int var_all; - float** sv; - int sv_total; - CvMat* var_idx; - CvMat* class_weights; - CvSVMDecisionFunc* decision_func; - CvMemStorage* storage; - - CvSVMSolver* solver; - CvSVMKernel* kernel; - -private: - CvSVM(const CvSVM&); - CvSVM& operator = (const CvSVM&); -}; - -/****************************************************************************************\ -* Decision Tree * -\****************************************************************************************/\ -struct CvPair16u32s -{ - unsigned short* u; - int* i; -}; - - -#define CV_DTREE_CAT_DIR(idx,subset) \ - (2*((subset[(idx)>>5]&(1 << ((idx) & 31)))==0)-1) - -struct CvDTreeSplit -{ - int var_idx; - int condensed_idx; - int inversed; - float quality; - CvDTreeSplit* next; - union - { - int subset[2]; - struct - { - float c; - int split_point; - } - ord; - }; -}; - -struct CvDTreeNode -{ - int class_idx; - int Tn; - double value; - - CvDTreeNode* parent; - CvDTreeNode* left; - CvDTreeNode* right; - - CvDTreeSplit* split; - - int sample_count; - int depth; - int* num_valid; - int offset; - int buf_idx; - double maxlr; - - // global pruning data - int complexity; - double alpha; - double node_risk, tree_risk, tree_error; - - // cross-validation pruning data - int* cv_Tn; - double* cv_node_risk; - double* cv_node_error; - - int get_num_valid(int vi) { return num_valid ? num_valid[vi] : sample_count; } - void set_num_valid(int vi, int n) { if( num_valid ) num_valid[vi] = n; } -}; - - -struct CvDTreeParams -{ - CV_PROP_RW int max_categories; - CV_PROP_RW int max_depth; - CV_PROP_RW int min_sample_count; - CV_PROP_RW int cv_folds; - CV_PROP_RW bool use_surrogates; - CV_PROP_RW bool use_1se_rule; - CV_PROP_RW bool truncate_pruned_tree; - CV_PROP_RW float regression_accuracy; - const float* priors; - - CvDTreeParams(); - CvDTreeParams( int max_depth, int min_sample_count, - float regression_accuracy, bool use_surrogates, - int max_categories, int cv_folds, - bool use_1se_rule, bool truncate_pruned_tree, - const float* priors ); -}; - - -struct CvDTreeTrainData -{ - CvDTreeTrainData(); - CvDTreeTrainData( const CvMat* trainData, int tflag, - const CvMat* responses, const CvMat* varIdx=0, - const CvMat* sampleIdx=0, const CvMat* varType=0, - const CvMat* missingDataMask=0, - const CvDTreeParams& params=CvDTreeParams(), - bool _shared=false, bool _add_labels=false ); - virtual ~CvDTreeTrainData(); - - virtual void set_data( const CvMat* trainData, int tflag, - const CvMat* responses, const CvMat* varIdx=0, - const CvMat* sampleIdx=0, const CvMat* varType=0, - const CvMat* missingDataMask=0, - const CvDTreeParams& params=CvDTreeParams(), - bool _shared=false, bool _add_labels=false, - bool _update_data=false ); - virtual void do_responses_copy(); - - virtual void get_vectors( const CvMat* _subsample_idx, - float* values, uchar* missing, float* responses, bool get_class_idx=false ); - - virtual CvDTreeNode* subsample_data( const CvMat* _subsample_idx ); - - virtual void write_params( cv::FileStorage& fs ) const; - virtual void read_params( const cv::FileNode& node ); - - // release all the data - virtual void clear(); - - int get_num_classes() const; - int get_var_type(int vi) const; - int get_work_var_count() const {return work_var_count;} - - virtual const float* get_ord_responses( CvDTreeNode* n, float* values_buf, int* sample_indices_buf ); - virtual const int* get_class_labels( CvDTreeNode* n, int* labels_buf ); - virtual const int* get_cv_labels( CvDTreeNode* n, int* labels_buf ); - virtual const int* get_sample_indices( CvDTreeNode* n, int* indices_buf ); - virtual const int* get_cat_var_data( CvDTreeNode* n, int vi, int* cat_values_buf ); - virtual void get_ord_var_data( CvDTreeNode* n, int vi, float* ord_values_buf, int* sorted_indices_buf, - const float** ord_values, const int** sorted_indices, int* sample_indices_buf ); - virtual int get_child_buf_idx( CvDTreeNode* n ); - - //////////////////////////////////// - - virtual bool set_params( const CvDTreeParams& params ); - virtual CvDTreeNode* new_node( CvDTreeNode* parent, int count, - int storage_idx, int offset ); - - virtual CvDTreeSplit* new_split_ord( int vi, float cmp_val, - int split_point, int inversed, float quality ); - virtual CvDTreeSplit* new_split_cat( int vi, float quality ); - virtual void free_node_data( CvDTreeNode* node ); - virtual void free_train_data(); - virtual void free_node( CvDTreeNode* node ); - - int sample_count, var_all, var_count, max_c_count; - int ord_var_count, cat_var_count, work_var_count; - bool have_labels, have_priors; - bool is_classifier; - int tflag; - - const CvMat* train_data; - const CvMat* responses; - CvMat* responses_copy; // used in Boosting - - int buf_count, buf_size; // buf_size is obsolete, please do not use it, use expression ((int64)buf->rows * (int64)buf->cols / buf_count) instead - bool shared; - int is_buf_16u; - - CvMat* cat_count; - CvMat* cat_ofs; - CvMat* cat_map; - - CvMat* counts; - CvMat* buf; - inline size_t get_length_subbuf() const - { - size_t res = (size_t)(work_var_count + 1) * (size_t)sample_count; - return res; - } - - CvMat* direction; - CvMat* split_buf; - - CvMat* var_idx; - CvMat* var_type; // i-th element = - // k<0 - ordered - // k>=0 - categorical, see k-th element of cat_* arrays - CvMat* priors; - CvMat* priors_mult; - - CvDTreeParams params; - - CvMemStorage* tree_storage; - CvMemStorage* temp_storage; - - CvDTreeNode* data_root; - - CvSet* node_heap; - CvSet* split_heap; - CvSet* cv_heap; - CvSet* nv_heap; - - cv::RNG* rng; -}; - -class CvDTree; -class CvForestTree; - -namespace cv -{ - struct DTreeBestSplitFinder; - struct ForestTreeBestSplitFinder; -} - -class CvDTree : public CvStatModel -{ -public: - CV_WRAP CvDTree(); - virtual ~CvDTree(); - - virtual bool train( const CvMat* trainData, int tflag, - const CvMat* responses, const CvMat* varIdx=0, - const CvMat* sampleIdx=0, const CvMat* varType=0, - const CvMat* missingDataMask=0, - CvDTreeParams params=CvDTreeParams() ); - - virtual bool train( CvMLData* trainData, CvDTreeParams params=CvDTreeParams() ); - - // type in {CV_TRAIN_ERROR, CV_TEST_ERROR} - virtual float calc_error( CvMLData* trainData, int type, std::vector *resp = 0 ); - - virtual bool train( CvDTreeTrainData* trainData, const CvMat* subsampleIdx ); - - virtual CvDTreeNode* predict( const CvMat* sample, const CvMat* missingDataMask=0, - bool preprocessedInput=false ) const; - - CV_WRAP virtual bool train( const cv::Mat& trainData, int tflag, - const cv::Mat& responses, const cv::Mat& varIdx=cv::Mat(), - const cv::Mat& sampleIdx=cv::Mat(), const cv::Mat& varType=cv::Mat(), - const cv::Mat& missingDataMask=cv::Mat(), - CvDTreeParams params=CvDTreeParams() ); - - CV_WRAP virtual CvDTreeNode* predict( const cv::Mat& sample, const cv::Mat& missingDataMask=cv::Mat(), - bool preprocessedInput=false ) const; - CV_WRAP virtual cv::Mat getVarImportance(); - - virtual const CvMat* get_var_importance(); - CV_WRAP virtual void clear(); - - virtual void read( const cv::FileNode& node ); - virtual void write( cv::FileStorage& fs, const char* name ) const; - - // special read & write methods for trees in the tree ensembles - virtual void read( const cv::FileNode& node, CvDTreeTrainData* data ); - virtual void write( cv::FileStorage& fs ) const; - - const CvDTreeNode* get_root() const; - int get_pruned_tree_idx() const; - CvDTreeTrainData* get_data(); - -protected: - friend struct cv::DTreeBestSplitFinder; - - virtual bool do_train( const CvMat* _subsample_idx ); - - virtual void try_split_node( CvDTreeNode* n ); - virtual void split_node_data( CvDTreeNode* n ); - virtual CvDTreeSplit* find_best_split( CvDTreeNode* n ); - virtual CvDTreeSplit* find_split_ord_class( CvDTreeNode* n, int vi, - float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 ); - virtual CvDTreeSplit* find_split_cat_class( CvDTreeNode* n, int vi, - float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 ); - virtual CvDTreeSplit* find_split_ord_reg( CvDTreeNode* n, int vi, - float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 ); - virtual CvDTreeSplit* find_split_cat_reg( CvDTreeNode* n, int vi, - float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 ); - virtual CvDTreeSplit* find_surrogate_split_ord( CvDTreeNode* n, int vi, uchar* ext_buf = 0 ); - virtual CvDTreeSplit* find_surrogate_split_cat( CvDTreeNode* n, int vi, uchar* ext_buf = 0 ); - virtual double calc_node_dir( CvDTreeNode* node ); - virtual void complete_node_dir( CvDTreeNode* node ); - virtual void cluster_categories( const int* vectors, int vector_count, - int var_count, int* sums, int k, int* cluster_labels ); - - virtual void calc_node_value( CvDTreeNode* node ); - - virtual void prune_cv(); - virtual double update_tree_rnc( int T, int fold ); - virtual int cut_tree( int T, int fold, double min_alpha ); - virtual void free_prune_data(bool cut_tree); - virtual void free_tree(); - - virtual void write_node( cv::FileStorage& fs, CvDTreeNode* node ) const; - virtual void write_split( cv::FileStorage& fs, CvDTreeSplit* split ) const; - virtual CvDTreeNode* read_node( const cv::FileNode& node, CvDTreeNode* parent ); - virtual CvDTreeSplit* read_split( const cv::FileNode& node ); - virtual void write_tree_nodes( cv::FileStorage& fs ) const; - virtual void read_tree_nodes( const cv::FileNode& node ); - - CvDTreeNode* root; - CvMat* var_importance; - CvDTreeTrainData* data; - CvMat train_data_hdr, responses_hdr; - cv::Mat train_data_mat, responses_mat; - -public: - int pruned_tree_idx; -}; - - -/****************************************************************************************\ -* Random Trees Classifier * -\****************************************************************************************/ - -class CvRTrees; - -class CvForestTree: public CvDTree -{ -public: - CvForestTree(); - virtual ~CvForestTree(); - - virtual bool train( CvDTreeTrainData* trainData, const CvMat* _subsample_idx, CvRTrees* forest ); - - virtual int get_var_count() const {return data ? data->var_count : 0;} - virtual void read( cv::FileStorage& fs, cv::FileNode& node, CvRTrees* forest, CvDTreeTrainData* _data ); - - /* dummy methods to avoid warnings: BEGIN */ - virtual bool train( const CvMat* trainData, int tflag, - const CvMat* responses, const CvMat* varIdx=0, - const CvMat* sampleIdx=0, const CvMat* varType=0, - const CvMat* missingDataMask=0, - CvDTreeParams params=CvDTreeParams() ); - - virtual bool train( CvDTreeTrainData* trainData, const CvMat* _subsample_idx ); - virtual void read( cv::FileStorage& fs, cv::FileNode& node ); - virtual void read( cv::FileStorage& fs, cv::FileNode& node, - CvDTreeTrainData* data ); - /* dummy methods to avoid warnings: END */ - -protected: - friend struct cv::ForestTreeBestSplitFinder; - - virtual CvDTreeSplit* find_best_split( CvDTreeNode* n ); - CvRTrees* forest; -}; - - -struct CvRTParams : public CvDTreeParams -{ - //Parameters for the forest - CV_PROP_RW bool calc_var_importance; // true <=> RF processes variable importance - CV_PROP_RW int nactive_vars; - CV_PROP_RW CvTermCriteria term_crit; - - CvRTParams(); - CvRTParams( int max_depth, int min_sample_count, - float regression_accuracy, bool use_surrogates, - int max_categories, const float* priors, bool calc_var_importance, - int nactive_vars, int max_num_of_trees_in_the_forest, - float forest_accuracy, int termcrit_type ); -}; - - -class CvRTrees : public CvStatModel -{ -public: - CV_WRAP CvRTrees(); - virtual ~CvRTrees(); - virtual bool train( const CvMat* trainData, int tflag, - const CvMat* responses, const CvMat* varIdx=0, - const CvMat* sampleIdx=0, const CvMat* varType=0, - const CvMat* missingDataMask=0, - CvRTParams params=CvRTParams() ); - - virtual bool train( CvMLData* data, CvRTParams params=CvRTParams() ); - virtual float predict( const CvMat* sample, const CvMat* missing = 0 ) const; - virtual float predict_prob( const CvMat* sample, const CvMat* missing = 0 ) const; - - CV_WRAP virtual bool train( const cv::Mat& trainData, int tflag, - const cv::Mat& responses, const cv::Mat& varIdx=cv::Mat(), - const cv::Mat& sampleIdx=cv::Mat(), const cv::Mat& varType=cv::Mat(), - const cv::Mat& missingDataMask=cv::Mat(), - CvRTParams params=CvRTParams() ); - CV_WRAP virtual float predict( const cv::Mat& sample, const cv::Mat& missing = cv::Mat() ) const; - CV_WRAP virtual float predict_prob( const cv::Mat& sample, const cv::Mat& missing = cv::Mat() ) const; - CV_WRAP virtual cv::Mat getVarImportance(); - - CV_WRAP virtual void clear(); - - virtual const CvMat* get_var_importance(); - virtual float get_proximity( const CvMat* sample1, const CvMat* sample2, - const CvMat* missing1 = 0, const CvMat* missing2 = 0 ) const; - - virtual float calc_error( CvMLData* data, int type , std::vector* resp = 0 ); // type in {CV_TRAIN_ERROR, CV_TEST_ERROR} - - virtual float get_train_error(); - - virtual void read( cv::FileStorage& fs, cv::FileNode& node ); - virtual void write( cv::FileStorage& fs, const char* name ) const; - - CvMat* get_active_var_mask(); - CvRNG* get_rng(); - - int get_tree_count() const; - CvForestTree* get_tree(int i) const; - -protected: - virtual cv::String getName() const; - - virtual bool grow_forest( const CvTermCriteria term_crit ); - - // array of the trees of the forest - CvForestTree** trees; - CvDTreeTrainData* data; - CvMat train_data_hdr, responses_hdr; - cv::Mat train_data_mat, responses_mat; - int ntrees; - int nclasses; - double oob_error; - CvMat* var_importance; - int nsamples; - - cv::RNG* rng; - CvMat* active_var_mask; -}; - -/****************************************************************************************\ -* Extremely randomized trees Classifier * -\****************************************************************************************/ -struct CvERTreeTrainData : public CvDTreeTrainData -{ - virtual void set_data( const CvMat* trainData, int tflag, - const CvMat* responses, const CvMat* varIdx=0, - const CvMat* sampleIdx=0, const CvMat* varType=0, - const CvMat* missingDataMask=0, - const CvDTreeParams& params=CvDTreeParams(), - bool _shared=false, bool _add_labels=false, - bool _update_data=false ); - virtual void get_ord_var_data( CvDTreeNode* n, int vi, float* ord_values_buf, int* missing_buf, - const float** ord_values, const int** missing, int* sample_buf = 0 ); - virtual const int* get_sample_indices( CvDTreeNode* n, int* indices_buf ); - virtual const int* get_cv_labels( CvDTreeNode* n, int* labels_buf ); - virtual const int* get_cat_var_data( CvDTreeNode* n, int vi, int* cat_values_buf ); - virtual void get_vectors( const CvMat* _subsample_idx, float* values, uchar* missing, - float* responses, bool get_class_idx=false ); - virtual CvDTreeNode* subsample_data( const CvMat* _subsample_idx ); - const CvMat* missing_mask; -}; - -class CvForestERTree : public CvForestTree -{ -protected: - virtual double calc_node_dir( CvDTreeNode* node ); - virtual CvDTreeSplit* find_split_ord_class( CvDTreeNode* n, int vi, - float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 ); - virtual CvDTreeSplit* find_split_cat_class( CvDTreeNode* n, int vi, - float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 ); - virtual CvDTreeSplit* find_split_ord_reg( CvDTreeNode* n, int vi, - float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 ); - virtual CvDTreeSplit* find_split_cat_reg( CvDTreeNode* n, int vi, - float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 ); - virtual void split_node_data( CvDTreeNode* n ); -}; - -class CvERTrees : public CvRTrees -{ -public: - CV_WRAP CvERTrees(); - virtual ~CvERTrees(); - virtual bool train( const CvMat* trainData, int tflag, - const CvMat* responses, const CvMat* varIdx=0, - const CvMat* sampleIdx=0, const CvMat* varType=0, - const CvMat* missingDataMask=0, - CvRTParams params=CvRTParams()); - CV_WRAP virtual bool train( const cv::Mat& trainData, int tflag, - const cv::Mat& responses, const cv::Mat& varIdx=cv::Mat(), - const cv::Mat& sampleIdx=cv::Mat(), const cv::Mat& varType=cv::Mat(), - const cv::Mat& missingDataMask=cv::Mat(), - CvRTParams params=CvRTParams()); - virtual bool train( CvMLData* data, CvRTParams params=CvRTParams() ); -protected: - virtual cv::String getName() const; - virtual bool grow_forest( const CvTermCriteria term_crit ); -}; - - -/****************************************************************************************\ -* Boosted tree classifier * -\****************************************************************************************/ - -struct CvBoostParams : public CvDTreeParams -{ - CV_PROP_RW int boost_type; - CV_PROP_RW int weak_count; - CV_PROP_RW int split_criteria; - CV_PROP_RW double weight_trim_rate; - - CvBoostParams(); - CvBoostParams( int boost_type, int weak_count, double weight_trim_rate, - int max_depth, bool use_surrogates, const float* priors ); -}; - - -class CvBoost; - -class CvBoostTree: public CvDTree -{ -public: - CvBoostTree(); - virtual ~CvBoostTree(); - - virtual bool train( CvDTreeTrainData* trainData, - const CvMat* subsample_idx, CvBoost* ensemble ); - - virtual void scale( double s ); - virtual void read( const cv::FileNode& node, - CvBoost* ensemble, CvDTreeTrainData* _data ); - virtual void clear(); - - /* dummy methods to avoid warnings: BEGIN */ - virtual bool train( const CvMat* trainData, int tflag, - const CvMat* responses, const CvMat* varIdx=0, - const CvMat* sampleIdx=0, const CvMat* varType=0, - const CvMat* missingDataMask=0, - CvDTreeParams params=CvDTreeParams() ); - virtual bool train( CvDTreeTrainData* trainData, const CvMat* _subsample_idx ); - - virtual void read( cv::FileNode& node ); - virtual void read( cv::FileNode& node, CvDTreeTrainData* data ); - /* dummy methods to avoid warnings: END */ - -protected: - - virtual void try_split_node( CvDTreeNode* n ); - virtual CvDTreeSplit* find_surrogate_split_ord( CvDTreeNode* n, int vi, uchar* ext_buf = 0 ); - virtual CvDTreeSplit* find_surrogate_split_cat( CvDTreeNode* n, int vi, uchar* ext_buf = 0 ); - virtual CvDTreeSplit* find_split_ord_class( CvDTreeNode* n, int vi, - float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 ); - virtual CvDTreeSplit* find_split_cat_class( CvDTreeNode* n, int vi, - float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 ); - virtual CvDTreeSplit* find_split_ord_reg( CvDTreeNode* n, int vi, - float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 ); - virtual CvDTreeSplit* find_split_cat_reg( CvDTreeNode* n, int vi, - float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 ); - virtual void calc_node_value( CvDTreeNode* n ); - virtual double calc_node_dir( CvDTreeNode* n ); - - CvBoost* ensemble; -}; - - -class CvBoost : public CvStatModel -{ -public: - // Boosting type - enum { DISCRETE=0, REAL=1, LOGIT=2, GENTLE=3 }; - - // Splitting criteria - enum { DEFAULT=0, GINI=1, MISCLASS=3, SQERR=4 }; - - CV_WRAP CvBoost(); - virtual ~CvBoost(); - - CvBoost( const CvMat* trainData, int tflag, - const CvMat* responses, const CvMat* varIdx=0, - const CvMat* sampleIdx=0, const CvMat* varType=0, - const CvMat* missingDataMask=0, - CvBoostParams params=CvBoostParams() ); - - virtual bool train( const CvMat* trainData, int tflag, - const CvMat* responses, const CvMat* varIdx=0, - const CvMat* sampleIdx=0, const CvMat* varType=0, - const CvMat* missingDataMask=0, - CvBoostParams params=CvBoostParams(), - bool update=false ); - - virtual bool train( CvMLData* data, - CvBoostParams params=CvBoostParams(), - bool update=false ); - - virtual float predict( const CvMat* sample, const CvMat* missing=0, - CvMat* weak_responses=0, CvSlice slice=CV_WHOLE_SEQ, - bool raw_mode=false, bool return_sum=false ) const; - - CV_WRAP CvBoost( const cv::Mat& trainData, int tflag, - const cv::Mat& responses, const cv::Mat& varIdx=cv::Mat(), - const cv::Mat& sampleIdx=cv::Mat(), const cv::Mat& varType=cv::Mat(), - const cv::Mat& missingDataMask=cv::Mat(), - CvBoostParams params=CvBoostParams() ); - - CV_WRAP virtual bool train( const cv::Mat& trainData, int tflag, - const cv::Mat& responses, const cv::Mat& varIdx=cv::Mat(), - const cv::Mat& sampleIdx=cv::Mat(), const cv::Mat& varType=cv::Mat(), - const cv::Mat& missingDataMask=cv::Mat(), - CvBoostParams params=CvBoostParams(), - bool update=false ); - - CV_WRAP virtual float predict( const cv::Mat& sample, const cv::Mat& missing=cv::Mat(), - const cv::Range& slice=cv::Range::all(), bool rawMode=false, - bool returnSum=false ) const; - - virtual float calc_error( CvMLData* _data, int type , std::vector *resp = 0 ); // type in {CV_TRAIN_ERROR, CV_TEST_ERROR} - - CV_WRAP virtual void prune( CvSlice slice ); - - CV_WRAP virtual void clear(); - - virtual void write( cv::FileStorage& storage, const char* name ) const; - virtual void read( cv::FileNode& node ); - virtual const CvMat* get_active_vars(bool absolute_idx=true); - - CvSeq* get_weak_predictors(); - - CvMat* get_weights(); - CvMat* get_subtree_weights(); - CvMat* get_weak_response(); - const CvBoostParams& get_params() const; - const CvDTreeTrainData* get_data() const; - -protected: - - virtual bool set_params( const CvBoostParams& params ); - virtual void update_weights( CvBoostTree* tree ); - virtual void trim_weights(); - virtual void write_params( cv::FileStorage & fs ) const; - virtual void read_params( cv::FileNode& node ); - - virtual void initialize_weights(double (&p)[2]); - - CvDTreeTrainData* data; - CvMat train_data_hdr, responses_hdr; - cv::Mat train_data_mat, responses_mat; - CvBoostParams params; - CvSeq* weak; - - CvMat* active_vars; - CvMat* active_vars_abs; - bool have_active_cat_vars; - - CvMat* orig_response; - CvMat* sum_response; - CvMat* weak_eval; - CvMat* subsample_mask; - CvMat* weights; - CvMat* subtree_weights; - bool have_subsample; -}; - - -/****************************************************************************************\ -* Gradient Boosted Trees * -\****************************************************************************************/ - -// DataType: STRUCT CvGBTreesParams -// Parameters of GBT (Gradient Boosted trees model), including single -// tree settings and ensemble parameters. -// -// weak_count - count of trees in the ensemble -// loss_function_type - loss function used for ensemble training -// subsample_portion - portion of whole training set used for -// every single tree training. -// subsample_portion value is in (0.0, 1.0]. -// subsample_portion == 1.0 when whole dataset is -// used on each step. Count of sample used on each -// step is computed as -// int(total_samples_count * subsample_portion). -// shrinkage - regularization parameter. -// Each tree prediction is multiplied on shrinkage value. - - -struct CvGBTreesParams : public CvDTreeParams -{ - CV_PROP_RW int weak_count; - CV_PROP_RW int loss_function_type; - CV_PROP_RW float subsample_portion; - CV_PROP_RW float shrinkage; - - CvGBTreesParams(); - CvGBTreesParams( int loss_function_type, int weak_count, float shrinkage, - float subsample_portion, int max_depth, bool use_surrogates ); -}; - -// DataType: CLASS CvGBTrees -// Gradient Boosting Trees (GBT) algorithm implementation. -// -// data - training dataset -// params - parameters of the CvGBTrees -// weak - array[0..(class_count-1)] of CvSeq -// for storing tree ensembles -// orig_response - original responses of the training set samples -// sum_response - predictions of the current model on the training dataset. -// this matrix is updated on every iteration. -// sum_response_tmp - predictions of the model on the training set on the next -// step. On every iteration values of sum_responses_tmp are -// computed via sum_responses values. When the current -// step is complete sum_response values become equal to -// sum_responses_tmp. -// sampleIdx - indices of samples used for training the ensemble. -// CvGBTrees training procedure takes a set of samples -// (train_data) and a set of responses (responses). -// Only pairs (train_data[i], responses[i]), where i is -// in sample_idx are used for training the ensemble. -// subsample_train - indices of samples used for training a single decision -// tree on the current step. This indices are countered -// relatively to the sample_idx, so that pairs -// (train_data[sample_idx[i]], responses[sample_idx[i]]) -// are used for training a decision tree. -// Training set is randomly splited -// in two parts (subsample_train and subsample_test) -// on every iteration accordingly to the portion parameter. -// subsample_test - relative indices of samples from the training set, -// which are not used for training a tree on the current -// step. -// missing - mask of the missing values in the training set. This -// matrix has the same size as train_data. 1 - missing -// value, 0 - not a missing value. -// class_labels - output class labels map. -// rng - random number generator. Used for splitting the -// training set. -// class_count - count of output classes. -// class_count == 1 in the case of regression, -// and > 1 in the case of classification. -// delta - Huber loss function parameter. -// base_value - start point of the gradient descent procedure. -// model prediction is -// f(x) = f_0 + sum_{i=1..weak_count-1}(f_i(x)), where -// f_0 is the base value. - - - -class CvGBTrees : public CvStatModel -{ -public: - - /* - // DataType: ENUM - // Loss functions implemented in CvGBTrees. - // - // SQUARED_LOSS - // problem: regression - // loss = (x - x')^2 - // - // ABSOLUTE_LOSS - // problem: regression - // loss = abs(x - x') - // - // HUBER_LOSS - // problem: regression - // loss = delta*( abs(x - x') - delta/2), if abs(x - x') > delta - // 1/2*(x - x')^2, if abs(x - x') <= delta, - // where delta is the alpha-quantile of pseudo responses from - // the training set. - // - // DEVIANCE_LOSS - // problem: classification - // - */ - enum {SQUARED_LOSS=0, ABSOLUTE_LOSS, HUBER_LOSS=3, DEVIANCE_LOSS}; - - - /* - // Default constructor. Creates a model only (without training). - // Should be followed by one form of the train(...) function. - // - // API - // CvGBTrees(); - - // INPUT - // OUTPUT - // RESULT - */ - CV_WRAP CvGBTrees(); - - - /* - // Full form constructor. Creates a gradient boosting model and does the - // train. - // - // API - // CvGBTrees( const CvMat* trainData, int tflag, - const CvMat* responses, const CvMat* varIdx=0, - const CvMat* sampleIdx=0, const CvMat* varType=0, - const CvMat* missingDataMask=0, - CvGBTreesParams params=CvGBTreesParams() ); - - // INPUT - // trainData - a set of input feature vectors. - // size of matrix is - // x - // or x - // depending on the tflag parameter. - // matrix values are float. - // tflag - a flag showing how do samples stored in the - // trainData matrix row by row (tflag=CV_ROW_SAMPLE) - // or column by column (tflag=CV_COL_SAMPLE). - // responses - a vector of responses corresponding to the samples - // in trainData. - // varIdx - indices of used variables. zero value means that all - // variables are active. - // sampleIdx - indices of used samples. zero value means that all - // samples from trainData are in the training set. - // varType - vector of length. gives every - // variable type CV_VAR_CATEGORICAL or CV_VAR_ORDERED. - // varType = 0 means all variables are numerical. - // missingDataMask - a mask of misiing values in trainData. - // missingDataMask = 0 means that there are no missing - // values. - // params - parameters of GTB algorithm. - // OUTPUT - // RESULT - */ - CvGBTrees( const CvMat* trainData, int tflag, - const CvMat* responses, const CvMat* varIdx=0, - const CvMat* sampleIdx=0, const CvMat* varType=0, - const CvMat* missingDataMask=0, - CvGBTreesParams params=CvGBTreesParams() ); - - - /* - // Destructor. - */ - virtual ~CvGBTrees(); - - - /* - // Gradient tree boosting model training - // - // API - // virtual bool train( const CvMat* trainData, int tflag, - const CvMat* responses, const CvMat* varIdx=0, - const CvMat* sampleIdx=0, const CvMat* varType=0, - const CvMat* missingDataMask=0, - CvGBTreesParams params=CvGBTreesParams(), - bool update=false ); - - // INPUT - // trainData - a set of input feature vectors. - // size of matrix is - // x - // or x - // depending on the tflag parameter. - // matrix values are float. - // tflag - a flag showing how do samples stored in the - // trainData matrix row by row (tflag=CV_ROW_SAMPLE) - // or column by column (tflag=CV_COL_SAMPLE). - // responses - a vector of responses corresponding to the samples - // in trainData. - // varIdx - indices of used variables. zero value means that all - // variables are active. - // sampleIdx - indices of used samples. zero value means that all - // samples from trainData are in the training set. - // varType - vector of length. gives every - // variable type CV_VAR_CATEGORICAL or CV_VAR_ORDERED. - // varType = 0 means all variables are numerical. - // missingDataMask - a mask of misiing values in trainData. - // missingDataMask = 0 means that there are no missing - // values. - // params - parameters of GTB algorithm. - // update - is not supported now. (!) - // OUTPUT - // RESULT - // Error state. - */ - virtual bool train( const CvMat* trainData, int tflag, - const CvMat* responses, const CvMat* varIdx=0, - const CvMat* sampleIdx=0, const CvMat* varType=0, - const CvMat* missingDataMask=0, - CvGBTreesParams params=CvGBTreesParams(), - bool update=false ); - - - /* - // Gradient tree boosting model training - // - // API - // virtual bool train( CvMLData* data, - CvGBTreesParams params=CvGBTreesParams(), - bool update=false ) {return false;} - - // INPUT - // data - training set. - // params - parameters of GTB algorithm. - // update - is not supported now. (!) - // OUTPUT - // RESULT - // Error state. - */ - virtual bool train( CvMLData* data, - CvGBTreesParams params=CvGBTreesParams(), - bool update=false ); - - - /* - // Response value prediction - // - // API - // virtual float predict_serial( const CvMat* sample, const CvMat* missing=0, - CvMat* weak_responses=0, CvSlice slice = CV_WHOLE_SEQ, - int k=-1 ) const; - - // INPUT - // sample - input sample of the same type as in the training set. - // missing - missing values mask. missing=0 if there are no - // missing values in sample vector. - // weak_responses - predictions of all of the trees. - // not implemented (!) - // slice - part of the ensemble used for prediction. - // slice = CV_WHOLE_SEQ when all trees are used. - // k - number of ensemble used. - // k is in {-1,0,1,..,}. - // in the case of classification problem - // ensembles are built. - // If k = -1 ordinary prediction is the result, - // otherwise function gives the prediction of the - // k-th ensemble only. - // OUTPUT - // RESULT - // Predicted value. - */ - virtual float predict_serial( const CvMat* sample, const CvMat* missing=0, - CvMat* weakResponses=0, CvSlice slice = CV_WHOLE_SEQ, - int k=-1 ) const; - - /* - // Response value prediction. - // Parallel version (in the case of TBB existence) - // - // API - // virtual float predict( const CvMat* sample, const CvMat* missing=0, - CvMat* weak_responses=0, CvSlice slice = CV_WHOLE_SEQ, - int k=-1 ) const; - - // INPUT - // sample - input sample of the same type as in the training set. - // missing - missing values mask. missing=0 if there are no - // missing values in sample vector. - // weak_responses - predictions of all of the trees. - // not implemented (!) - // slice - part of the ensemble used for prediction. - // slice = CV_WHOLE_SEQ when all trees are used. - // k - number of ensemble used. - // k is in {-1,0,1,..,}. - // in the case of classification problem - // ensembles are built. - // If k = -1 ordinary prediction is the result, - // otherwise function gives the prediction of the - // k-th ensemble only. - // OUTPUT - // RESULT - // Predicted value. - */ - virtual float predict( const CvMat* sample, const CvMat* missing=0, - CvMat* weakResponses=0, CvSlice slice = CV_WHOLE_SEQ, - int k=-1 ) const; - - /* - // Deletes all the data. - // - // API - // virtual void clear(); - - // INPUT - // OUTPUT - // delete data, weak, orig_response, sum_response, - // weak_eval, subsample_train, subsample_test, - // sample_idx, missing, lass_labels - // delta = 0.0 - // RESULT - */ - CV_WRAP virtual void clear(); - - /* - // Compute error on the train/test set. - // - // API - // virtual float calc_error( CvMLData* _data, int type, - // std::vector *resp = 0 ); - // - // INPUT - // data - dataset - // type - defines which error is to compute: train (CV_TRAIN_ERROR) or - // test (CV_TEST_ERROR). - // OUTPUT - // resp - vector of predictions - // RESULT - // Error value. - */ - virtual float calc_error( CvMLData* _data, int type, - std::vector *resp = 0 ); - - /* - // - // Write parameters of the gtb model and data. Write learned model. - // - // API - // virtual void write( cv::FileStorage& fs, const char* name ) const; - // - // INPUT - // fs - file storage to read parameters from. - // name - model name. - // OUTPUT - // RESULT - */ - virtual void write( cv::FileStorage& fs, const char* name ) const; - - - /* - // - // Read parameters of the gtb model and data. Read learned model. - // - // API - // virtual void read( cv::FileStorage& fs, cv::FileNode& node ); - // - // INPUT - // fs - file storage to read parameters from. - // node - file node. - // OUTPUT - // RESULT - */ - virtual void read( cv::FileStorage& fs, cv::FileNode& node ); - - - // new-style C++ interface - CV_WRAP CvGBTrees( const cv::Mat& trainData, int tflag, - const cv::Mat& responses, const cv::Mat& varIdx=cv::Mat(), - const cv::Mat& sampleIdx=cv::Mat(), const cv::Mat& varType=cv::Mat(), - const cv::Mat& missingDataMask=cv::Mat(), - CvGBTreesParams params=CvGBTreesParams() ); - - CV_WRAP virtual bool train( const cv::Mat& trainData, int tflag, - const cv::Mat& responses, const cv::Mat& varIdx=cv::Mat(), - const cv::Mat& sampleIdx=cv::Mat(), const cv::Mat& varType=cv::Mat(), - const cv::Mat& missingDataMask=cv::Mat(), - CvGBTreesParams params=CvGBTreesParams(), - bool update=false ); - - CV_WRAP virtual float predict( const cv::Mat& sample, const cv::Mat& missing=cv::Mat(), - const cv::Range& slice = cv::Range::all(), - int k=-1 ) const; - -protected: - - /* - // Compute the gradient vector components. - // - // API - // virtual void find_gradient( const int k = 0); - - // INPUT - // k - used for classification problem, determining current - // tree ensemble. - // OUTPUT - // changes components of data->responses - // which correspond to samples used for training - // on the current step. - // RESULT - */ - virtual void find_gradient( const int k = 0); - - - /* - // - // Change values in tree leaves according to the used loss function. - // - // API - // virtual void change_values(CvDTree* tree, const int k = 0); - // - // INPUT - // tree - decision tree to change. - // k - used for classification problem, determining current - // tree ensemble. - // OUTPUT - // changes 'value' fields of the trees' leaves. - // changes sum_response_tmp. - // RESULT - */ - virtual void change_values(CvDTree* tree, const int k = 0); - - - /* - // - // Find optimal constant prediction value according to the used loss - // function. - // The goal is to find a constant which gives the minimal summary loss - // on the _Idx samples. - // - // API - // virtual float find_optimal_value( const CvMat* _Idx ); - // - // INPUT - // _Idx - indices of the samples from the training set. - // OUTPUT - // RESULT - // optimal constant value. - */ - virtual float find_optimal_value( const CvMat* _Idx ); - - - /* - // - // Randomly split the whole training set in two parts according - // to params.portion. - // - // API - // virtual void do_subsample(); - // - // INPUT - // OUTPUT - // subsample_train - indices of samples used for training - // subsample_test - indices of samples used for test - // RESULT - */ - virtual void do_subsample(); - - - /* - // - // Internal recursive function giving an array of subtree tree leaves. - // - // API - // void leaves_get( CvDTreeNode** leaves, int& count, CvDTreeNode* node ); - // - // INPUT - // node - current leaf. - // OUTPUT - // count - count of leaves in the subtree. - // leaves - array of pointers to leaves. - // RESULT - */ - void leaves_get( CvDTreeNode** leaves, int& count, CvDTreeNode* node ); - - - /* - // - // Get leaves of the tree. - // - // API - // CvDTreeNode** GetLeaves( const CvDTree* dtree, int& len ); - // - // INPUT - // dtree - decision tree. - // OUTPUT - // len - count of the leaves. - // RESULT - // CvDTreeNode** - array of pointers to leaves. - */ - CvDTreeNode** GetLeaves( const CvDTree* dtree, int& len ); - - - /* - // - // Is it a regression or a classification. - // - // API - // bool problem_type(); - // - // INPUT - // OUTPUT - // RESULT - // false if it is a classification problem, - // true - if regression. - */ - virtual bool problem_type() const; - - - /* - // - // Write parameters of the gtb model. - // - // API - // virtual void write_params( cv::FileStorage& fs ) const; - // - // INPUT - // fs - file storage to write parameters to. - // OUTPUT - // RESULT - */ - virtual void write_params( cv::FileStorage& fs ) const; - - - /* - // - // Read parameters of the gtb model and data. - // - // API - // virtual void read_params( const cv::FileStorage& fs ); - // - // INPUT - // fs - file storage to read parameters from. - // OUTPUT - // params - parameters of the gtb model. - // data - contains information about the structure - // of the data set (count of variables, - // their types, etc.). - // class_labels - output class labels map. - // RESULT - */ - virtual void read_params( cv::FileStorage& fs, cv::FileNode& fnode ); - int get_len(const CvMat* mat) const; - - - CvDTreeTrainData* data; - CvGBTreesParams params; - - CvSeq** weak; - CvMat* orig_response; - CvMat* sum_response; - CvMat* sum_response_tmp; - CvMat* sample_idx; - CvMat* subsample_train; - CvMat* subsample_test; - CvMat* missing; - CvMat* class_labels; - - cv::RNG* rng; - - int class_count; - float delta; - float base_value; - -}; - - - -/****************************************************************************************\ -* Artificial Neural Networks (ANN) * -\****************************************************************************************/ - -/////////////////////////////////// Multi-Layer Perceptrons ////////////////////////////// - -struct CvANN_MLP_TrainParams -{ - CvANN_MLP_TrainParams(); - CvANN_MLP_TrainParams( CvTermCriteria term_crit, int train_method, - double param1, double param2=0 ); - ~CvANN_MLP_TrainParams(); - - enum { BACKPROP=0, RPROP=1 }; - - CV_PROP_RW CvTermCriteria term_crit; - CV_PROP_RW int train_method; - - // backpropagation parameters - CV_PROP_RW double bp_dw_scale, bp_moment_scale; - - // rprop parameters - CV_PROP_RW double rp_dw0, rp_dw_plus, rp_dw_minus, rp_dw_min, rp_dw_max; -}; - - -class CvANN_MLP : public CvStatModel -{ -public: - CV_WRAP CvANN_MLP(); - CvANN_MLP( const CvMat* layerSizes, - int activateFunc=CvANN_MLP::SIGMOID_SYM, - double fparam1=0, double fparam2=0 ); - - virtual ~CvANN_MLP(); - - virtual void create( const CvMat* layerSizes, - int activateFunc=CvANN_MLP::SIGMOID_SYM, - double fparam1=0, double fparam2=0 ); - - virtual int train( const CvMat* inputs, const CvMat* outputs, - const CvMat* sampleWeights, const CvMat* sampleIdx=0, - CvANN_MLP_TrainParams params = CvANN_MLP_TrainParams(), - int flags=0 ); - virtual float predict( const CvMat* inputs, CV_OUT CvMat* outputs ) const; - - CV_WRAP CvANN_MLP( const cv::Mat& layerSizes, - int activateFunc=CvANN_MLP::SIGMOID_SYM, - double fparam1=0, double fparam2=0 ); - - CV_WRAP virtual void create( const cv::Mat& layerSizes, - int activateFunc=CvANN_MLP::SIGMOID_SYM, - double fparam1=0, double fparam2=0 ); - - CV_WRAP virtual int train( const cv::Mat& inputs, const cv::Mat& outputs, - const cv::Mat& sampleWeights, const cv::Mat& sampleIdx=cv::Mat(), - CvANN_MLP_TrainParams params = CvANN_MLP_TrainParams(), - int flags=0 ); - - CV_WRAP virtual float predict( const cv::Mat& inputs, CV_OUT cv::Mat& outputs ) const; - - CV_WRAP virtual void clear(); - - // possible activation functions - enum { IDENTITY = 0, SIGMOID_SYM = 1, GAUSSIAN = 2 }; - - // available training flags - enum { UPDATE_WEIGHTS = 1, NO_INPUT_SCALE = 2, NO_OUTPUT_SCALE = 4 }; - - virtual void read( cv::FileStorage& fs, cv::FileNode& node ); - virtual void write( cv::FileStorage& storage, const char* name ) const; - - int get_layer_count() { return layer_sizes ? layer_sizes->cols : 0; } - const CvMat* get_layer_sizes() { return layer_sizes; } - double* get_weights(int layer) - { - return layer_sizes && weights && - (unsigned)layer <= (unsigned)layer_sizes->cols ? weights[layer] : 0; - } - - virtual void calc_activ_func_deriv( CvMat* xf, CvMat* deriv, const double* bias ) const; - -protected: - - virtual bool prepare_to_train( const CvMat* _inputs, const CvMat* _outputs, - const CvMat* _sample_weights, const CvMat* sampleIdx, - CvVectors* _ivecs, CvVectors* _ovecs, double** _sw, int _flags ); - - // sequential random backpropagation - virtual int train_backprop( CvVectors _ivecs, CvVectors _ovecs, const double* _sw ); - - // RPROP algorithm - virtual int train_rprop( CvVectors _ivecs, CvVectors _ovecs, const double* _sw ); - - virtual void calc_activ_func( CvMat* xf, const double* bias ) const; - virtual void set_activ_func( int _activ_func=SIGMOID_SYM, - double _f_param1=0, double _f_param2=0 ); - virtual void init_weights(); - virtual void scale_input( const CvMat* _src, CvMat* _dst ) const; - virtual void scale_output( const CvMat* _src, CvMat* _dst ) const; - virtual void calc_input_scale( const CvVectors* vecs, int flags ); - virtual void calc_output_scale( const CvVectors* vecs, int flags ); - - virtual void write_params( cv::FileStorage& fs ) const; - virtual void read_params( cv::FileStorage& fs, cv::FileNode& node ); - - CvMat* layer_sizes; - CvMat* wbuf; - CvMat* sample_weights; - double** weights; - double f_param1, f_param2; - double min_val, max_val, min_val1, max_val1; - int activ_func; - int max_count, max_buf_sz; - CvANN_MLP_TrainParams params; - cv::RNG* rng; -}; - -/****************************************************************************************\ -* Data * -\****************************************************************************************/ - -#define CV_COUNT 0 -#define CV_PORTION 1 - -struct CvTrainTestSplit -{ - CvTrainTestSplit(); - CvTrainTestSplit( int train_sample_count, bool mix = true); - CvTrainTestSplit( float train_sample_portion, bool mix = true); - - union - { - int count; - float portion; - } train_sample_part; - int train_sample_part_mode; - - bool mix; -}; - -class CvMLData -{ -public: - CvMLData(); - virtual ~CvMLData(); - - // returns: - // 0 - OK - // -1 - file can not be opened or is not correct - int read_csv( const char* filename ); - - const CvMat* get_values() const; - const CvMat* get_responses(); - const CvMat* get_missing() const; - - void set_header_lines_number( int n ); - int get_header_lines_number() const; - - void set_response_idx( int idx ); // old response become predictors, new response_idx = idx - // if idx < 0 there will be no response - int get_response_idx() const; - - void set_train_test_split( const CvTrainTestSplit * spl ); - const CvMat* get_train_sample_idx() const; - const CvMat* get_test_sample_idx() const; - void mix_train_and_test_idx(); - - const CvMat* get_var_idx(); - void chahge_var_idx( int vi, bool state ); // misspelled (saved for back compitability), - // use change_var_idx - void change_var_idx( int vi, bool state ); // state == true to set vi-variable as predictor - - const CvMat* get_var_types(); - int get_var_type( int var_idx ) const; - // following 2 methods enable to change vars type - // use these methods to assign CV_VAR_CATEGORICAL type for categorical variable - // with numerical labels; in the other cases var types are correctly determined automatically - void set_var_types( const char* str ); // str examples: - // "ord[0-17],cat[18]", "ord[0,2,4,10-12], cat[1,3,5-9,13,14]", - // "cat", "ord" (all vars are categorical/ordered) - void change_var_type( int var_idx, int type); // type in { CV_VAR_ORDERED, CV_VAR_CATEGORICAL } - - void set_delimiter( char ch ); - char get_delimiter() const; - - void set_miss_ch( char ch ); - char get_miss_ch() const; - - const std::map& get_class_labels_map() const; - -protected: - virtual void clear(); - - void str_to_flt_elem( const char* token, float& flt_elem, int& type); - void free_train_test_idx(); - - char delimiter; - char miss_ch; - //char flt_separator; - - CvMat* values; - CvMat* missing; - CvMat* var_types; - CvMat* var_idx_mask; - - CvMat* response_out; // header - CvMat* var_idx_out; // mat - CvMat* var_types_out; // mat - - int header_lines_number; - - int response_idx; - - int train_sample_count; - bool mix; - - int total_class_count; - std::map class_map; - - CvMat* train_sample_idx; - CvMat* test_sample_idx; - int* sample_idx; // data of train_sample_idx and test_sample_idx - - cv::RNG* rng; -}; - - -namespace cv -{ - -typedef CvStatModel StatModel; -typedef CvParamGrid ParamGrid; -typedef CvNormalBayesClassifier NormalBayesClassifier; -typedef CvKNearest KNearest; -typedef CvSVMParams SVMParams; -typedef CvSVMKernel SVMKernel; -typedef CvSVMSolver SVMSolver; -typedef CvSVM SVM; -typedef CvDTreeParams DTreeParams; -typedef CvMLData TrainData; -typedef CvDTree DecisionTree; -typedef CvForestTree ForestTree; -typedef CvRTParams RandomTreeParams; -typedef CvRTrees RandomTrees; -typedef CvERTreeTrainData ERTreeTRainData; -typedef CvForestERTree ERTree; -typedef CvERTrees ERTrees; -typedef CvBoostParams BoostParams; -typedef CvBoostTree BoostTree; -typedef CvBoost Boost; -typedef CvANN_MLP_TrainParams ANN_MLP_TrainParams; -typedef CvANN_MLP NeuralNet_MLP; -typedef CvGBTreesParams GradientBoostingTreeParams; -typedef CvGBTrees GradientBoostingTrees; - -template<> struct DefaultDeleter{ void operator ()(CvDTreeSplit* obj) const; }; - -} - -#endif // __cplusplus -#endif // OPENCV_OLD_ML_HPP - -/* End of file. */ diff --git a/apps/traincascade/old_ml_boost.cpp b/apps/traincascade/old_ml_boost.cpp deleted file mode 100644 index 2f53bd9031..0000000000 --- a/apps/traincascade/old_ml_boost.cpp +++ /dev/null @@ -1,2160 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// Intel License Agreement -// -// 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 "old_ml_precomp.hpp" - -static inline double -log_ratio( double val ) -{ - const double eps = 1e-5; - - val = MAX( val, eps ); - val = MIN( val, 1. - eps ); - return log( val/(1. - val) ); -} - - -CvBoostParams::CvBoostParams() -{ - boost_type = CvBoost::REAL; - weak_count = 100; - weight_trim_rate = 0.95; - cv_folds = 0; - max_depth = 1; -} - - -CvBoostParams::CvBoostParams( int _boost_type, int _weak_count, - double _weight_trim_rate, int _max_depth, - bool _use_surrogates, const float* _priors ) -{ - boost_type = _boost_type; - weak_count = _weak_count; - weight_trim_rate = _weight_trim_rate; - split_criteria = CvBoost::DEFAULT; - cv_folds = 0; - max_depth = _max_depth; - use_surrogates = _use_surrogates; - priors = _priors; -} - - - -///////////////////////////////// CvBoostTree /////////////////////////////////// - -CvBoostTree::CvBoostTree() -{ - ensemble = 0; -} - - -CvBoostTree::~CvBoostTree() -{ - clear(); -} - - -void -CvBoostTree::clear() -{ - CvDTree::clear(); - ensemble = 0; -} - - -bool -CvBoostTree::train( CvDTreeTrainData* _train_data, - const CvMat* _subsample_idx, CvBoost* _ensemble ) -{ - clear(); - ensemble = _ensemble; - data = _train_data; - data->shared = true; - return do_train( _subsample_idx ); -} - - -bool -CvBoostTree::train( const CvMat*, int, const CvMat*, const CvMat*, - const CvMat*, const CvMat*, const CvMat*, CvDTreeParams ) -{ - assert(0); - return false; -} - - -bool -CvBoostTree::train( CvDTreeTrainData*, const CvMat* ) -{ - assert(0); - return false; -} - - -void -CvBoostTree::scale( double _scale ) -{ - CvDTreeNode* node = root; - - // traverse the tree and scale all the node values - for(;;) - { - CvDTreeNode* parent; - for(;;) - { - node->value *= _scale; - if( !node->left ) - break; - node = node->left; - } - - for( parent = node->parent; parent && parent->right == node; - node = parent, parent = parent->parent ) - ; - - if( !parent ) - break; - - node = parent->right; - } -} - - -void -CvBoostTree::try_split_node( CvDTreeNode* node ) -{ - CvDTree::try_split_node( node ); - - if( !node->left ) - { - // if the node has not been split, - // store the responses for the corresponding training samples - double* weak_eval = ensemble->get_weak_response()->data.db; - cv::AutoBuffer inn_buf(node->sample_count); - const int* labels = data->get_cv_labels(node, inn_buf.data()); - int i, count = node->sample_count; - double value = node->value; - - for( i = 0; i < count; i++ ) - weak_eval[labels[i]] = value; - } -} - - -double -CvBoostTree::calc_node_dir( CvDTreeNode* node ) -{ - char* dir = (char*)data->direction->data.ptr; - const double* weights = ensemble->get_subtree_weights()->data.db; - int i, n = node->sample_count, vi = node->split->var_idx; - double L, R; - - assert( !node->split->inversed ); - - if( data->get_var_type(vi) >= 0 ) // split on categorical var - { - cv::AutoBuffer inn_buf(n); - const int* cat_labels = data->get_cat_var_data(node, vi, inn_buf.data()); - const int* subset = node->split->subset; - double sum = 0, sum_abs = 0; - - for( i = 0; i < n; i++ ) - { - int idx = ((cat_labels[i] == 65535) && data->is_buf_16u) ? -1 : cat_labels[i]; - double w = weights[i]; - int d = idx >= 0 ? CV_DTREE_CAT_DIR(idx,subset) : 0; - sum += d*w; sum_abs += (d & 1)*w; - dir[i] = (char)d; - } - - R = (sum_abs + sum) * 0.5; - L = (sum_abs - sum) * 0.5; - } - else // split on ordered var - { - cv::AutoBuffer inn_buf(2*n*sizeof(int)+n*sizeof(float)); - float* values_buf = (float*)inn_buf.data(); - int* sorted_indices_buf = (int*)(values_buf + n); - int* sample_indices_buf = sorted_indices_buf + n; - const float* values = 0; - const int* sorted_indices = 0; - data->get_ord_var_data( node, vi, values_buf, sorted_indices_buf, &values, &sorted_indices, sample_indices_buf ); - int split_point = node->split->ord.split_point; - int n1 = node->get_num_valid(vi); - - assert( 0 <= split_point && split_point < n1-1 ); - L = R = 0; - - for( i = 0; i <= split_point; i++ ) - { - int idx = sorted_indices[i]; - double w = weights[idx]; - dir[idx] = (char)-1; - L += w; - } - - for( ; i < n1; i++ ) - { - int idx = sorted_indices[i]; - double w = weights[idx]; - dir[idx] = (char)1; - R += w; - } - - for( ; i < n; i++ ) - dir[sorted_indices[i]] = (char)0; - } - - node->maxlr = MAX( L, R ); - return node->split->quality/(L + R); -} - - -CvDTreeSplit* -CvBoostTree::find_split_ord_class( CvDTreeNode* node, int vi, float init_quality, - CvDTreeSplit* _split, uchar* _ext_buf ) -{ - const float epsilon = FLT_EPSILON*2; - - const double* weights = ensemble->get_subtree_weights()->data.db; - int n = node->sample_count; - int n1 = node->get_num_valid(vi); - - cv::AutoBuffer inn_buf; - if( !_ext_buf ) - inn_buf.allocate(n*(3*sizeof(int)+sizeof(float))); - uchar* ext_buf = _ext_buf ? _ext_buf : inn_buf.data(); - float* values_buf = (float*)ext_buf; - int* sorted_indices_buf = (int*)(values_buf + n); - int* sample_indices_buf = sorted_indices_buf + n; - const float* values = 0; - const int* sorted_indices = 0; - data->get_ord_var_data( node, vi, values_buf, sorted_indices_buf, &values, &sorted_indices, sample_indices_buf ); - int* responses_buf = sorted_indices_buf + n; - const int* responses = data->get_class_labels( node, responses_buf ); - const double* rcw0 = weights + n; - double lcw[2] = {0,0}, rcw[2]; - int i, best_i = -1; - double best_val = init_quality; - int boost_type = ensemble->get_params().boost_type; - int split_criteria = ensemble->get_params().split_criteria; - - rcw[0] = rcw0[0]; rcw[1] = rcw0[1]; - for( i = n1; i < n; i++ ) - { - int idx = sorted_indices[i]; - double w = weights[idx]; - rcw[responses[idx]] -= w; - } - - if( split_criteria != CvBoost::GINI && split_criteria != CvBoost::MISCLASS ) - split_criteria = boost_type == CvBoost::DISCRETE ? CvBoost::MISCLASS : CvBoost::GINI; - - if( split_criteria == CvBoost::GINI ) - { - double L = 0, R = rcw[0] + rcw[1]; - double lsum2 = 0, rsum2 = rcw[0]*rcw[0] + rcw[1]*rcw[1]; - - for( i = 0; i < n1 - 1; i++ ) - { - int idx = sorted_indices[i]; - double w = weights[idx], w2 = w*w; - double lv, rv; - idx = responses[idx]; - L += w; R -= w; - lv = lcw[idx]; rv = rcw[idx]; - lsum2 += 2*lv*w + w2; - rsum2 -= 2*rv*w - w2; - lcw[idx] = lv + w; rcw[idx] = rv - w; - - if( values[i] + epsilon < values[i+1] ) - { - double val = (lsum2*R + rsum2*L)/(L*R); - if( best_val < val ) - { - best_val = val; - best_i = i; - } - } - } - } - else - { - for( i = 0; i < n1 - 1; i++ ) - { - int idx = sorted_indices[i]; - double w = weights[idx]; - idx = responses[idx]; - lcw[idx] += w; - rcw[idx] -= w; - - if( values[i] + epsilon < values[i+1] ) - { - double val = lcw[0] + rcw[1], val2 = lcw[1] + rcw[0]; - val = MAX(val, val2); - if( best_val < val ) - { - best_val = val; - best_i = i; - } - } - } - } - - CvDTreeSplit* split = 0; - if( best_i >= 0 ) - { - split = _split ? _split : data->new_split_ord( 0, 0.0f, 0, 0, 0.0f ); - split->var_idx = vi; - split->ord.c = (values[best_i] + values[best_i+1])*0.5f; - split->ord.split_point = best_i; - split->inversed = 0; - split->quality = (float)best_val; - } - return split; -} - -template -class LessThanPtr -{ -public: - bool operator()(T* a, T* b) const { return *a < *b; } -}; - -CvDTreeSplit* -CvBoostTree::find_split_cat_class( CvDTreeNode* node, int vi, float init_quality, CvDTreeSplit* _split, uchar* _ext_buf ) -{ - int ci = data->get_var_type(vi); - int n = node->sample_count; - int mi = data->cat_count->data.i[ci]; - - int base_size = (2*mi+3)*sizeof(double) + mi*sizeof(double*); - cv::AutoBuffer inn_buf((2*mi+3)*sizeof(double) + mi*sizeof(double*)); - if( !_ext_buf) - inn_buf.allocate( base_size + 2*n*sizeof(int) ); - uchar* base_buf = inn_buf.data(); - uchar* ext_buf = _ext_buf ? _ext_buf : base_buf + base_size; - - int* cat_labels_buf = (int*)ext_buf; - const int* cat_labels = data->get_cat_var_data(node, vi, cat_labels_buf); - int* responses_buf = cat_labels_buf + n; - const int* responses = data->get_class_labels(node, responses_buf); - double lcw[2]={0,0}, rcw[2]={0,0}; - - double* cjk = (double*)cv::alignPtr(base_buf,sizeof(double))+2; - const double* weights = ensemble->get_subtree_weights()->data.db; - double** dbl_ptr = (double**)(cjk + 2*mi); - int i, j, k, idx; - double L = 0, R; - double best_val = init_quality; - int best_subset = -1, subset_i; - int boost_type = ensemble->get_params().boost_type; - int split_criteria = ensemble->get_params().split_criteria; - - // init array of counters: - // c_{jk} - number of samples that have vi-th input variable = j and response = k. - for( j = -1; j < mi; j++ ) - cjk[j*2] = cjk[j*2+1] = 0; - - for( i = 0; i < n; i++ ) - { - double w = weights[i]; - j = ((cat_labels[i] == 65535) && data->is_buf_16u) ? -1 : cat_labels[i]; - k = responses[i]; - cjk[j*2 + k] += w; - } - - for( j = 0; j < mi; j++ ) - { - rcw[0] += cjk[j*2]; - rcw[1] += cjk[j*2+1]; - dbl_ptr[j] = cjk + j*2 + 1; - } - - R = rcw[0] + rcw[1]; - - if( split_criteria != CvBoost::GINI && split_criteria != CvBoost::MISCLASS ) - split_criteria = boost_type == CvBoost::DISCRETE ? CvBoost::MISCLASS : CvBoost::GINI; - - // sort rows of c_jk by increasing c_j,1 - // (i.e. by the weight of samples in j-th category that belong to class 1) - std::sort(dbl_ptr, dbl_ptr + mi, LessThanPtr()); - - for( subset_i = 0; subset_i < mi-1; subset_i++ ) - { - idx = (int)(dbl_ptr[subset_i] - cjk)/2; - const double* crow = cjk + idx*2; - double w0 = crow[0], w1 = crow[1]; - double weight = w0 + w1; - - if( weight < FLT_EPSILON ) - continue; - - lcw[0] += w0; rcw[0] -= w0; - lcw[1] += w1; rcw[1] -= w1; - - if( split_criteria == CvBoost::GINI ) - { - double lsum2 = lcw[0]*lcw[0] + lcw[1]*lcw[1]; - double rsum2 = rcw[0]*rcw[0] + rcw[1]*rcw[1]; - - L += weight; - R -= weight; - - if( L > FLT_EPSILON && R > FLT_EPSILON ) - { - double val = (lsum2*R + rsum2*L)/(L*R); - if( best_val < val ) - { - best_val = val; - best_subset = subset_i; - } - } - } - else - { - double val = lcw[0] + rcw[1]; - double val2 = lcw[1] + rcw[0]; - - val = MAX(val, val2); - if( best_val < val ) - { - best_val = val; - best_subset = subset_i; - } - } - } - - CvDTreeSplit* split = 0; - if( best_subset >= 0 ) - { - split = _split ? _split : data->new_split_cat( 0, -1.0f); - split->var_idx = vi; - split->quality = (float)best_val; - memset( split->subset, 0, (data->max_c_count + 31)/32 * sizeof(int)); - for( i = 0; i <= best_subset; i++ ) - { - idx = (int)(dbl_ptr[i] - cjk) >> 1; - split->subset[idx >> 5] |= 1 << (idx & 31); - } - } - return split; -} - - -CvDTreeSplit* -CvBoostTree::find_split_ord_reg( CvDTreeNode* node, int vi, float init_quality, CvDTreeSplit* _split, uchar* _ext_buf ) -{ - const float epsilon = FLT_EPSILON*2; - const double* weights = ensemble->get_subtree_weights()->data.db; - int n = node->sample_count; - int n1 = node->get_num_valid(vi); - - cv::AutoBuffer inn_buf; - if( !_ext_buf ) - inn_buf.allocate(2*n*(sizeof(int)+sizeof(float))); - uchar* ext_buf = _ext_buf ? _ext_buf : inn_buf.data(); - - float* values_buf = (float*)ext_buf; - int* indices_buf = (int*)(values_buf + n); - int* sample_indices_buf = indices_buf + n; - const float* values = 0; - const int* indices = 0; - data->get_ord_var_data( node, vi, values_buf, indices_buf, &values, &indices, sample_indices_buf ); - float* responses_buf = (float*)(indices_buf + n); - const float* responses = data->get_ord_responses( node, responses_buf, sample_indices_buf ); - - int i, best_i = -1; - double L = 0, R = weights[n]; - double best_val = init_quality, lsum = 0, rsum = node->value*R; - - // compensate for missing values - for( i = n1; i < n; i++ ) - { - int idx = indices[i]; - double w = weights[idx]; - rsum -= responses[idx]*w; - R -= w; - } - - // find the optimal split - for( i = 0; i < n1 - 1; i++ ) - { - int idx = indices[i]; - double w = weights[idx]; - double t = responses[idx]*w; - L += w; R -= w; - lsum += t; rsum -= t; - - if( values[i] + epsilon < values[i+1] ) - { - double val = (lsum*lsum*R + rsum*rsum*L)/(L*R); - if( best_val < val ) - { - best_val = val; - best_i = i; - } - } - } - - CvDTreeSplit* split = 0; - if( best_i >= 0 ) - { - split = _split ? _split : data->new_split_ord( 0, 0.0f, 0, 0, 0.0f ); - split->var_idx = vi; - split->ord.c = (values[best_i] + values[best_i+1])*0.5f; - split->ord.split_point = best_i; - split->inversed = 0; - split->quality = (float)best_val; - } - return split; -} - - -CvDTreeSplit* -CvBoostTree::find_split_cat_reg( CvDTreeNode* node, int vi, float init_quality, CvDTreeSplit* _split, uchar* _ext_buf ) -{ - const double* weights = ensemble->get_subtree_weights()->data.db; - int ci = data->get_var_type(vi); - int n = node->sample_count; - int mi = data->cat_count->data.i[ci]; - int base_size = (2*mi+3)*sizeof(double) + mi*sizeof(double*); - cv::AutoBuffer inn_buf(base_size); - if( !_ext_buf ) - inn_buf.allocate(base_size + n*(2*sizeof(int) + sizeof(float))); - uchar* base_buf = inn_buf.data(); - uchar* ext_buf = _ext_buf ? _ext_buf : base_buf + base_size; - - int* cat_labels_buf = (int*)ext_buf; - const int* cat_labels = data->get_cat_var_data(node, vi, cat_labels_buf); - float* responses_buf = (float*)(cat_labels_buf + n); - int* sample_indices_buf = (int*)(responses_buf + n); - const float* responses = data->get_ord_responses(node, responses_buf, sample_indices_buf); - - double* sum = (double*)cv::alignPtr(base_buf,sizeof(double)) + 1; - double* counts = sum + mi + 1; - double** sum_ptr = (double**)(counts + mi); - double L = 0, R = 0, best_val = init_quality, lsum = 0, rsum = 0; - int i, best_subset = -1, subset_i; - - for( i = -1; i < mi; i++ ) - sum[i] = counts[i] = 0; - - // calculate sum response and weight of each category of the input var - for( i = 0; i < n; i++ ) - { - int idx = ((cat_labels[i] == 65535) && data->is_buf_16u) ? -1 : cat_labels[i]; - double w = weights[i]; - double s = sum[idx] + responses[i]*w; - double nc = counts[idx] + w; - sum[idx] = s; - counts[idx] = nc; - } - - // calculate average response in each category - for( i = 0; i < mi; i++ ) - { - R += counts[i]; - rsum += sum[i]; - sum[i] = fabs(counts[i]) > DBL_EPSILON ? sum[i]/counts[i] : 0; - sum_ptr[i] = sum + i; - } - - std::sort(sum_ptr, sum_ptr + mi, LessThanPtr()); - - // revert back to unnormalized sums - // (there should be a very little loss in accuracy) - for( i = 0; i < mi; i++ ) - sum[i] *= counts[i]; - - for( subset_i = 0; subset_i < mi-1; subset_i++ ) - { - int idx = (int)(sum_ptr[subset_i] - sum); - double ni = counts[idx]; - - if( ni > FLT_EPSILON ) - { - double s = sum[idx]; - lsum += s; L += ni; - rsum -= s; R -= ni; - - if( L > FLT_EPSILON && R > FLT_EPSILON ) - { - double val = (lsum*lsum*R + rsum*rsum*L)/(L*R); - if( best_val < val ) - { - best_val = val; - best_subset = subset_i; - } - } - } - } - - CvDTreeSplit* split = 0; - if( best_subset >= 0 ) - { - split = _split ? _split : data->new_split_cat( 0, -1.0f); - split->var_idx = vi; - split->quality = (float)best_val; - memset( split->subset, 0, (data->max_c_count + 31)/32 * sizeof(int)); - for( i = 0; i <= best_subset; i++ ) - { - int idx = (int)(sum_ptr[i] - sum); - split->subset[idx >> 5] |= 1 << (idx & 31); - } - } - return split; -} - - -CvDTreeSplit* -CvBoostTree::find_surrogate_split_ord( CvDTreeNode* node, int vi, uchar* _ext_buf ) -{ - const float epsilon = FLT_EPSILON*2; - int n = node->sample_count; - cv::AutoBuffer inn_buf; - if( !_ext_buf ) - inn_buf.allocate(n*(2*sizeof(int)+sizeof(float))); - uchar* ext_buf = _ext_buf ? _ext_buf : inn_buf.data(); - float* values_buf = (float*)ext_buf; - int* indices_buf = (int*)(values_buf + n); - int* sample_indices_buf = indices_buf + n; - const float* values = 0; - const int* indices = 0; - data->get_ord_var_data( node, vi, values_buf, indices_buf, &values, &indices, sample_indices_buf ); - - const double* weights = ensemble->get_subtree_weights()->data.db; - const char* dir = (char*)data->direction->data.ptr; - int n1 = node->get_num_valid(vi); - // LL - number of samples that both the primary and the surrogate splits send to the left - // LR - ... primary split sends to the left and the surrogate split sends to the right - // RL - ... primary split sends to the right and the surrogate split sends to the left - // RR - ... both send to the right - int i, best_i = -1, best_inversed = 0; - double best_val; - double LL = 0, RL = 0, LR, RR; - double worst_val = node->maxlr; - double sum = 0, sum_abs = 0; - best_val = worst_val; - - for( i = 0; i < n1; i++ ) - { - int idx = indices[i]; - double w = weights[idx]; - int d = dir[idx]; - sum += d*w; sum_abs += (d & 1)*w; - } - - // sum_abs = R + L; sum = R - L - RR = (sum_abs + sum)*0.5; - LR = (sum_abs - sum)*0.5; - - // initially all the samples are sent to the right by the surrogate split, - // LR of them are sent to the left by primary split, and RR - to the right. - // now iteratively compute LL, LR, RL and RR for every possible surrogate split value. - for( i = 0; i < n1 - 1; i++ ) - { - int idx = indices[i]; - double w = weights[idx]; - int d = dir[idx]; - - if( d < 0 ) - { - LL += w; LR -= w; - if( LL + RR > best_val && values[i] + epsilon < values[i+1] ) - { - best_val = LL + RR; - best_i = i; best_inversed = 0; - } - } - else if( d > 0 ) - { - RL += w; RR -= w; - if( RL + LR > best_val && values[i] + epsilon < values[i+1] ) - { - best_val = RL + LR; - best_i = i; best_inversed = 1; - } - } - } - - return best_i >= 0 && best_val > node->maxlr ? data->new_split_ord( vi, - (values[best_i] + values[best_i+1])*0.5f, best_i, - best_inversed, (float)best_val ) : 0; -} - - -CvDTreeSplit* -CvBoostTree::find_surrogate_split_cat( CvDTreeNode* node, int vi, uchar* _ext_buf ) -{ - const char* dir = (char*)data->direction->data.ptr; - const double* weights = ensemble->get_subtree_weights()->data.db; - int n = node->sample_count; - int i, mi = data->cat_count->data.i[data->get_var_type(vi)]; - - int base_size = (2*mi+3)*sizeof(double); - cv::AutoBuffer inn_buf(base_size); - if( !_ext_buf ) - inn_buf.allocate(base_size + n*sizeof(int)); - uchar* ext_buf = _ext_buf ? _ext_buf : inn_buf.data(); - int* cat_labels_buf = (int*)ext_buf; - const int* cat_labels = data->get_cat_var_data(node, vi, cat_labels_buf); - - // LL - number of samples that both the primary and the surrogate splits send to the left - // LR - ... primary split sends to the left and the surrogate split sends to the right - // RL - ... primary split sends to the right and the surrogate split sends to the left - // RR - ... both send to the right - CvDTreeSplit* split = data->new_split_cat( vi, 0 ); - double best_val = 0; - double* lc = (double*)cv::alignPtr(cat_labels_buf + n, sizeof(double)) + 1; - double* rc = lc + mi + 1; - - for( i = -1; i < mi; i++ ) - lc[i] = rc[i] = 0; - - // 1. for each category calculate the weight of samples - // sent to the left (lc) and to the right (rc) by the primary split - for( i = 0; i < n; i++ ) - { - int idx = ((cat_labels[i] == 65535) && data->is_buf_16u) ? -1 : cat_labels[i]; - double w = weights[i]; - int d = dir[i]; - double sum = lc[idx] + d*w; - double sum_abs = rc[idx] + (d & 1)*w; - lc[idx] = sum; rc[idx] = sum_abs; - } - - for( i = 0; i < mi; i++ ) - { - double sum = lc[i]; - double sum_abs = rc[i]; - lc[i] = (sum_abs - sum) * 0.5; - rc[i] = (sum_abs + sum) * 0.5; - } - - // 2. now form the split. - // in each category send all the samples to the same direction as majority - for( i = 0; i < mi; i++ ) - { - double lval = lc[i], rval = rc[i]; - if( lval > rval ) - { - split->subset[i >> 5] |= 1 << (i & 31); - best_val += lval; - } - else - best_val += rval; - } - - split->quality = (float)best_val; - if( split->quality <= node->maxlr ) - cvSetRemoveByPtr( data->split_heap, split ), split = 0; - - return split; -} - - -void -CvBoostTree::calc_node_value( CvDTreeNode* node ) -{ - int i, n = node->sample_count; - const double* weights = ensemble->get_weights()->data.db; - cv::AutoBuffer inn_buf(n*(sizeof(int) + ( data->is_classifier ? sizeof(int) : sizeof(int) + sizeof(float)))); - int* labels_buf = (int*)inn_buf.data(); - const int* labels = data->get_cv_labels(node, labels_buf); - double* subtree_weights = ensemble->get_subtree_weights()->data.db; - double rcw[2] = {0,0}; - int boost_type = ensemble->get_params().boost_type; - - if( data->is_classifier ) - { - int* _responses_buf = labels_buf + n; - const int* _responses = data->get_class_labels(node, _responses_buf); - int m = data->get_num_classes(); - int* cls_count = data->counts->data.i; - for( int k = 0; k < m; k++ ) - cls_count[k] = 0; - - for( i = 0; i < n; i++ ) - { - int idx = labels[i]; - double w = weights[idx]; - int r = _responses[i]; - rcw[r] += w; - cls_count[r]++; - subtree_weights[i] = w; - } - - node->class_idx = rcw[1] > rcw[0]; - - if( boost_type == CvBoost::DISCRETE ) - { - // ignore cat_map for responses, and use {-1,1}, - // as the whole ensemble response is computes as sign(sum_i(weak_response_i) - node->value = node->class_idx*2 - 1; - } - else - { - double p = rcw[1]/(rcw[0] + rcw[1]); - assert( boost_type == CvBoost::REAL ); - - // store log-ratio of the probability - node->value = 0.5*log_ratio(p); - } - } - else - { - // in case of regression tree: - // * node value is 1/n*sum_i(Y_i), where Y_i is i-th response, - // n is the number of samples in the node. - // * node risk is the sum of squared errors: sum_i((Y_i - )^2) - double sum = 0, sum2 = 0, iw; - float* values_buf = (float*)(labels_buf + n); - int* sample_indices_buf = (int*)(values_buf + n); - const float* values = data->get_ord_responses(node, values_buf, sample_indices_buf); - - for( i = 0; i < n; i++ ) - { - int idx = labels[i]; - double w = weights[idx]/*priors[values[i] > 0]*/; - double t = values[i]; - rcw[0] += w; - subtree_weights[i] = w; - sum += t*w; - sum2 += t*t*w; - } - - iw = 1./rcw[0]; - node->value = sum*iw; - node->node_risk = sum2 - (sum*iw)*sum; - - // renormalize the risk, as in try_split_node the unweighted formula - // sqrt(risk)/n is used, rather than sqrt(risk)/sum(weights_i) - node->node_risk *= n*iw*n*iw; - } - - // store summary weights - subtree_weights[n] = rcw[0]; - subtree_weights[n+1] = rcw[1]; -} - - -void CvBoostTree::read( const cv::FileNode& fnode, CvBoost* _ensemble, CvDTreeTrainData* _data ) -{ - CvDTree::read( fnode, _data ); - ensemble = _ensemble; -} - -void CvBoostTree::read( cv::FileNode& ) -{ - assert(0); -} - -void CvBoostTree::read( cv::FileNode& _node, - CvDTreeTrainData* _data ) -{ - CvDTree::read( _node, _data ); -} - - -/////////////////////////////////// CvBoost ///////////////////////////////////// - -CvBoost::CvBoost() -{ - data = 0; - weak = 0; - default_model_name = "my_boost_tree"; - - active_vars = active_vars_abs = orig_response = sum_response = weak_eval = - subsample_mask = weights = subtree_weights = 0; - have_active_cat_vars = have_subsample = false; - - clear(); -} - - -void CvBoost::prune( CvSlice slice ) -{ - if( weak && weak->total > 0 ) - { - CvSeqReader reader; - int i, count = cvSliceLength( slice, weak ); - - cvStartReadSeq( weak, &reader ); - cvSetSeqReaderPos( &reader, slice.start_index ); - - for( i = 0; i < count; i++ ) - { - CvBoostTree* w; - CV_READ_SEQ_ELEM( w, reader ); - delete w; - } - - cvSeqRemoveSlice( weak, slice ); - } -} - - -void CvBoost::clear() -{ - if( weak ) - { - prune( CV_WHOLE_SEQ ); - cvReleaseMemStorage( &weak->storage ); - } - if( data ) - delete data; - weak = 0; - data = 0; - cvReleaseMat( &active_vars ); - cvReleaseMat( &active_vars_abs ); - cvReleaseMat( &orig_response ); - cvReleaseMat( &sum_response ); - cvReleaseMat( &weak_eval ); - cvReleaseMat( &subsample_mask ); - cvReleaseMat( &weights ); - cvReleaseMat( &subtree_weights ); - - have_subsample = false; -} - - -CvBoost::~CvBoost() -{ - clear(); -} - - -CvBoost::CvBoost( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx, - const CvMat* _sample_idx, const CvMat* _var_type, - const CvMat* _missing_mask, CvBoostParams _params ) -{ - weak = 0; - data = 0; - default_model_name = "my_boost_tree"; - - active_vars = active_vars_abs = orig_response = sum_response = weak_eval = - subsample_mask = weights = subtree_weights = 0; - - train( _train_data, _tflag, _responses, _var_idx, _sample_idx, - _var_type, _missing_mask, _params ); -} - - -bool -CvBoost::set_params( const CvBoostParams& _params ) -{ - bool ok = false; - - CV_FUNCNAME( "CvBoost::set_params" ); - - __BEGIN__; - - params = _params; - if( params.boost_type != DISCRETE && params.boost_type != REAL && - params.boost_type != LOGIT && params.boost_type != GENTLE ) - CV_ERROR( CV_StsBadArg, "Unknown/unsupported boosting type" ); - - params.weak_count = MAX( params.weak_count, 1 ); - params.weight_trim_rate = MAX( params.weight_trim_rate, 0. ); - params.weight_trim_rate = MIN( params.weight_trim_rate, 1. ); - if( params.weight_trim_rate < FLT_EPSILON ) - params.weight_trim_rate = 1.f; - - if( params.boost_type == DISCRETE && - params.split_criteria != GINI && params.split_criteria != MISCLASS ) - params.split_criteria = MISCLASS; - if( params.boost_type == REAL && - params.split_criteria != GINI && params.split_criteria != MISCLASS ) - params.split_criteria = GINI; - if( (params.boost_type == LOGIT || params.boost_type == GENTLE) && - params.split_criteria != SQERR ) - params.split_criteria = SQERR; - - ok = true; - - __END__; - - return ok; -} - - -bool -CvBoost::train( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx, - const CvMat* _sample_idx, const CvMat* _var_type, - const CvMat* _missing_mask, - CvBoostParams _params, bool _update ) -{ - bool ok = false; - CvMemStorage* storage = 0; - - CV_FUNCNAME( "CvBoost::train" ); - - __BEGIN__; - - int i; - - set_params( _params ); - - cvReleaseMat( &active_vars ); - cvReleaseMat( &active_vars_abs ); - - if( !_update || !data ) - { - clear(); - data = new CvDTreeTrainData( _train_data, _tflag, _responses, _var_idx, - _sample_idx, _var_type, _missing_mask, _params, true, true ); - - if( data->get_num_classes() != 2 ) - CV_ERROR( CV_StsNotImplemented, - "Boosted trees can only be used for 2-class classification." ); - CV_CALL( storage = cvCreateMemStorage() ); - weak = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvBoostTree*), storage ); - storage = 0; - } - else - { - data->set_data( _train_data, _tflag, _responses, _var_idx, - _sample_idx, _var_type, _missing_mask, _params, true, true, true ); - } - - if ( (_params.boost_type == LOGIT) || (_params.boost_type == GENTLE) ) - data->do_responses_copy(); - - update_weights( 0 ); - - for( i = 0; i < params.weak_count; i++ ) - { - CvBoostTree* tree = new CvBoostTree; - if( !tree->train( data, subsample_mask, this ) ) - { - delete tree; - break; - } - //cvCheckArr( get_weak_response()); - cvSeqPush( weak, &tree ); - update_weights( tree ); - trim_weights(); - if( cvCountNonZero(subsample_mask) == 0 ) - break; - } - - if(weak->total > 0) - { - get_active_vars(); // recompute active_vars* maps and condensed_idx's in the splits. - data->is_classifier = true; - data->free_train_data(); - ok = true; - } - else - clear(); - - __END__; - - return ok; -} - -bool CvBoost::train( CvMLData* _data, - CvBoostParams _params, - bool update ) -{ - bool result = false; - - CV_FUNCNAME( "CvBoost::train" ); - - __BEGIN__; - - const CvMat* values = _data->get_values(); - const CvMat* response = _data->get_responses(); - const CvMat* missing = _data->get_missing(); - const CvMat* var_types = _data->get_var_types(); - const CvMat* train_sidx = _data->get_train_sample_idx(); - const CvMat* var_idx = _data->get_var_idx(); - - CV_CALL( result = train( values, CV_ROW_SAMPLE, response, var_idx, - train_sidx, var_types, missing, _params, update ) ); - - __END__; - - return result; -} - -void CvBoost::initialize_weights(double (&p)[2]) -{ - p[0] = 1.; - p[1] = 1.; -} - -void -CvBoost::update_weights( CvBoostTree* tree ) -{ - CV_FUNCNAME( "CvBoost::update_weights" ); - - __BEGIN__; - - int i, n = data->sample_count; - double sumw = 0.; - int step = 0; - float* fdata = 0; - int *sample_idx_buf; - const int* sample_idx = 0; - cv::AutoBuffer inn_buf; - size_t _buf_size = (params.boost_type == LOGIT) || (params.boost_type == GENTLE) ? (size_t)(data->sample_count)*sizeof(int) : 0; - if( !tree ) - _buf_size += n*sizeof(int); - else - { - if( have_subsample ) - _buf_size += data->get_length_subbuf()*(sizeof(float)+sizeof(uchar)); - } - inn_buf.allocate(_buf_size); - uchar* cur_buf_pos = inn_buf.data(); - - if ( (params.boost_type == LOGIT) || (params.boost_type == GENTLE) ) - { - step = CV_IS_MAT_CONT(data->responses_copy->type) ? - 1 : data->responses_copy->step / CV_ELEM_SIZE(data->responses_copy->type); - fdata = data->responses_copy->data.fl; - sample_idx_buf = (int*)cur_buf_pos; - cur_buf_pos = (uchar*)(sample_idx_buf + data->sample_count); - sample_idx = data->get_sample_indices( data->data_root, sample_idx_buf ); - } - CvMat* dtree_data_buf = data->buf; - size_t length_buf_row = data->get_length_subbuf(); - if( !tree ) // before training the first tree, initialize weights and other parameters - { - int* class_labels_buf = (int*)cur_buf_pos; - cur_buf_pos = (uchar*)(class_labels_buf + n); - const int* class_labels = data->get_class_labels(data->data_root, class_labels_buf); - // in case of logitboost and gentle adaboost each weak tree is a regression tree, - // so we need to convert class labels to floating-point values - - double w0 = 1./ n; - double p[2] = { 1., 1. }; - initialize_weights(p); - - cvReleaseMat( &orig_response ); - cvReleaseMat( &sum_response ); - cvReleaseMat( &weak_eval ); - cvReleaseMat( &subsample_mask ); - cvReleaseMat( &weights ); - cvReleaseMat( &subtree_weights ); - - CV_CALL( orig_response = cvCreateMat( 1, n, CV_32S )); - CV_CALL( weak_eval = cvCreateMat( 1, n, CV_64F )); - CV_CALL( subsample_mask = cvCreateMat( 1, n, CV_8U )); - CV_CALL( weights = cvCreateMat( 1, n, CV_64F )); - CV_CALL( subtree_weights = cvCreateMat( 1, n + 2, CV_64F )); - - if( data->have_priors ) - { - // compute weight scale for each class from their prior probabilities - int c1 = 0; - for( i = 0; i < n; i++ ) - c1 += class_labels[i]; - p[0] = data->priors->data.db[0]*(c1 < n ? 1./(n - c1) : 0.); - p[1] = data->priors->data.db[1]*(c1 > 0 ? 1./c1 : 0.); - p[0] /= p[0] + p[1]; - p[1] = 1. - p[0]; - } - - if (data->is_buf_16u) - { - unsigned short* labels = (unsigned short*)(dtree_data_buf->data.s + data->data_root->buf_idx*length_buf_row + - data->data_root->offset + (size_t)(data->work_var_count-1)*data->sample_count); - for( i = 0; i < n; i++ ) - { - // save original categorical responses {0,1}, convert them to {-1,1} - orig_response->data.i[i] = class_labels[i]*2 - 1; - // make all the samples active at start. - // later, in trim_weights() deactivate/reactive again some, if need - subsample_mask->data.ptr[i] = (uchar)1; - // make all the initial weights the same. - weights->data.db[i] = w0*p[class_labels[i]]; - // set the labels to find (from within weak tree learning proc) - // the particular sample weight, and where to store the response. - labels[i] = (unsigned short)i; - } - } - else - { - int* labels = dtree_data_buf->data.i + data->data_root->buf_idx*length_buf_row + - data->data_root->offset + (size_t)(data->work_var_count-1)*data->sample_count; - - for( i = 0; i < n; i++ ) - { - // save original categorical responses {0,1}, convert them to {-1,1} - orig_response->data.i[i] = class_labels[i]*2 - 1; - // make all the samples active at start. - // later, in trim_weights() deactivate/reactive again some, if need - subsample_mask->data.ptr[i] = (uchar)1; - // make all the initial weights the same. - weights->data.db[i] = w0*p[class_labels[i]]; - // set the labels to find (from within weak tree learning proc) - // the particular sample weight, and where to store the response. - labels[i] = i; - } - } - - if( params.boost_type == LOGIT ) - { - CV_CALL( sum_response = cvCreateMat( 1, n, CV_64F )); - - for( i = 0; i < n; i++ ) - { - sum_response->data.db[i] = 0; - fdata[sample_idx[i]*step] = orig_response->data.i[i] > 0 ? 2.f : -2.f; - } - - // in case of logitboost each weak tree is a regression tree. - // the target function values are recalculated for each of the trees - data->is_classifier = false; - } - else if( params.boost_type == GENTLE ) - { - for( i = 0; i < n; i++ ) - fdata[sample_idx[i]*step] = (float)orig_response->data.i[i]; - - data->is_classifier = false; - } - } - else - { - // at this moment, for all the samples that participated in the training of the most - // recent weak classifier we know the responses. For other samples we need to compute them - if( have_subsample ) - { - float* values = (float*)cur_buf_pos; - cur_buf_pos = (uchar*)(values + data->get_length_subbuf()); - uchar* missing = cur_buf_pos; - cur_buf_pos = missing + data->get_length_subbuf() * (size_t)CV_ELEM_SIZE(data->buf->type); - - CvMat _sample, _mask; - - // invert the subsample mask - cvXorS( subsample_mask, cvScalar(1.), subsample_mask ); - data->get_vectors( subsample_mask, values, missing, 0 ); - - _sample = cvMat( 1, data->var_count, CV_32F ); - _mask = cvMat( 1, data->var_count, CV_8U ); - - // run tree through all the non-processed samples - for( i = 0; i < n; i++ ) - if( subsample_mask->data.ptr[i] ) - { - _sample.data.fl = values; - _mask.data.ptr = missing; - values += _sample.cols; - missing += _mask.cols; - weak_eval->data.db[i] = tree->predict( &_sample, &_mask, true )->value; - } - } - - // now update weights and other parameters for each type of boosting - if( params.boost_type == DISCRETE ) - { - // Discrete AdaBoost: - // weak_eval[i] (=f(x_i)) is in {-1,1} - // err = sum(w_i*(f(x_i) != y_i))/sum(w_i) - // C = log((1-err)/err) - // w_i *= exp(C*(f(x_i) != y_i)) - - double C, err = 0.; - double scale[] = { 1., 0. }; - - for( i = 0; i < n; i++ ) - { - double w = weights->data.db[i]; - sumw += w; - err += w*(weak_eval->data.db[i] != orig_response->data.i[i]); - } - - if( sumw != 0 ) - err /= sumw; - C = err = -log_ratio( err ); - scale[1] = exp(err); - - sumw = 0; - for( i = 0; i < n; i++ ) - { - double w = weights->data.db[i]* - scale[weak_eval->data.db[i] != orig_response->data.i[i]]; - sumw += w; - weights->data.db[i] = w; - } - - tree->scale( C ); - } - else if( params.boost_type == REAL ) - { - // Real AdaBoost: - // weak_eval[i] = f(x_i) = 0.5*log(p(x_i)/(1-p(x_i))), p(x_i)=P(y=1|x_i) - // w_i *= exp(-y_i*f(x_i)) - - for( i = 0; i < n; i++ ) - weak_eval->data.db[i] *= -orig_response->data.i[i]; - - cvExp( weak_eval, weak_eval ); - - for( i = 0; i < n; i++ ) - { - double w = weights->data.db[i]*weak_eval->data.db[i]; - sumw += w; - weights->data.db[i] = w; - } - } - else if( params.boost_type == LOGIT ) - { - // LogitBoost: - // weak_eval[i] = f(x_i) in [-z_max,z_max] - // sum_response = F(x_i). - // F(x_i) += 0.5*f(x_i) - // p(x_i) = exp(F(x_i))/(exp(F(x_i)) + exp(-F(x_i))=1/(1+exp(-2*F(x_i))) - // reuse weak_eval: weak_eval[i] <- p(x_i) - // w_i = p(x_i)*1(1 - p(x_i)) - // z_i = ((y_i+1)/2 - p(x_i))/(p(x_i)*(1 - p(x_i))) - // store z_i to the data->data_root as the new target responses - - const double lb_weight_thresh = FLT_EPSILON; - const double lb_z_max = 10.; - /*float* responses_buf = data->get_resp_float_buf(); - const float* responses = 0; - data->get_ord_responses(data->data_root, responses_buf, &responses);*/ - - /*if( weak->total == 7 ) - putchar('*');*/ - - for( i = 0; i < n; i++ ) - { - double s = sum_response->data.db[i] + 0.5*weak_eval->data.db[i]; - sum_response->data.db[i] = s; - weak_eval->data.db[i] = -2*s; - } - - cvExp( weak_eval, weak_eval ); - - for( i = 0; i < n; i++ ) - { - double p = 1./(1. + weak_eval->data.db[i]); - double w = p*(1 - p), z; - w = MAX( w, lb_weight_thresh ); - weights->data.db[i] = w; - sumw += w; - if( orig_response->data.i[i] > 0 ) - { - z = 1./p; - fdata[sample_idx[i]*step] = (float)MIN(z, lb_z_max); - } - else - { - z = 1./(1-p); - fdata[sample_idx[i]*step] = (float)-MIN(z, lb_z_max); - } - } - } - else - { - // Gentle AdaBoost: - // weak_eval[i] = f(x_i) in [-1,1] - // w_i *= exp(-y_i*f(x_i)) - assert( params.boost_type == GENTLE ); - - for( i = 0; i < n; i++ ) - weak_eval->data.db[i] *= -orig_response->data.i[i]; - - cvExp( weak_eval, weak_eval ); - - for( i = 0; i < n; i++ ) - { - double w = weights->data.db[i] * weak_eval->data.db[i]; - weights->data.db[i] = w; - sumw += w; - } - } - } - - // renormalize weights - if( sumw > FLT_EPSILON ) - { - sumw = 1./sumw; - for( i = 0; i < n; ++i ) - weights->data.db[i] *= sumw; - } - - __END__; -} - - -void -CvBoost::trim_weights() -{ - //CV_FUNCNAME( "CvBoost::trim_weights" ); - - __BEGIN__; - - int i, count = data->sample_count, nz_count = 0; - double sum, threshold; - - if( params.weight_trim_rate <= 0. || params.weight_trim_rate >= 1. ) - EXIT; - - // use weak_eval as temporary buffer for sorted weights - cvCopy( weights, weak_eval ); - - std::sort(weak_eval->data.db, weak_eval->data.db + count); - - // as weight trimming occurs immediately after updating the weights, - // where they are renormalized, we assume that the weight sum = 1. - sum = 1. - params.weight_trim_rate; - - for( i = 0; i < count; i++ ) - { - double w = weak_eval->data.db[i]; - if( sum <= 0 ) - break; - sum -= w; - } - - threshold = i < count ? weak_eval->data.db[i] : DBL_MAX; - - for( i = 0; i < count; i++ ) - { - double w = weights->data.db[i]; - int f = w >= threshold; - subsample_mask->data.ptr[i] = (uchar)f; - nz_count += f; - } - - have_subsample = nz_count < count; - - __END__; -} - - -const CvMat* -CvBoost::get_active_vars( bool absolute_idx ) -{ - CvMat* mask = 0; - CvMat* inv_map = 0; - CvMat* result = 0; - - CV_FUNCNAME( "CvBoost::get_active_vars" ); - - __BEGIN__; - - if( !weak ) - CV_ERROR( CV_StsError, "The boosted tree ensemble has not been trained yet" ); - - if( !active_vars || !active_vars_abs ) - { - CvSeqReader reader; - int i, j, nactive_vars; - CvBoostTree* wtree; - const CvDTreeNode* node; - - assert(!active_vars && !active_vars_abs); - mask = cvCreateMat( 1, data->var_count, CV_8U ); - inv_map = cvCreateMat( 1, data->var_count, CV_32S ); - cvZero( mask ); - cvSet( inv_map, cvScalar(-1) ); - - // first pass: compute the mask of used variables - cvStartReadSeq( weak, &reader ); - for( i = 0; i < weak->total; i++ ) - { - CV_READ_SEQ_ELEM(wtree, reader); - - node = wtree->get_root(); - assert( node != 0 ); - for(;;) - { - const CvDTreeNode* parent; - for(;;) - { - CvDTreeSplit* split = node->split; - for( ; split != 0; split = split->next ) - mask->data.ptr[split->var_idx] = 1; - if( !node->left ) - break; - node = node->left; - } - - for( parent = node->parent; parent && parent->right == node; - node = parent, parent = parent->parent ) - ; - - if( !parent ) - break; - - node = parent->right; - } - } - - nactive_vars = cvCountNonZero(mask); - - //if ( nactive_vars > 0 ) - { - active_vars = cvCreateMat( 1, nactive_vars, CV_32S ); - active_vars_abs = cvCreateMat( 1, nactive_vars, CV_32S ); - - have_active_cat_vars = false; - - for( i = j = 0; i < data->var_count; i++ ) - { - if( mask->data.ptr[i] ) - { - active_vars->data.i[j] = i; - active_vars_abs->data.i[j] = data->var_idx ? data->var_idx->data.i[i] : i; - inv_map->data.i[i] = j; - if( data->var_type->data.i[i] >= 0 ) - have_active_cat_vars = true; - j++; - } - } - - - // second pass: now compute the condensed indices - cvStartReadSeq( weak, &reader ); - for( i = 0; i < weak->total; i++ ) - { - CV_READ_SEQ_ELEM(wtree, reader); - node = wtree->get_root(); - for(;;) - { - const CvDTreeNode* parent; - for(;;) - { - CvDTreeSplit* split = node->split; - for( ; split != 0; split = split->next ) - { - split->condensed_idx = inv_map->data.i[split->var_idx]; - assert( split->condensed_idx >= 0 ); - } - - if( !node->left ) - break; - node = node->left; - } - - for( parent = node->parent; parent && parent->right == node; - node = parent, parent = parent->parent ) - ; - - if( !parent ) - break; - - node = parent->right; - } - } - } - } - - result = absolute_idx ? active_vars_abs : active_vars; - - __END__; - - cvReleaseMat( &mask ); - cvReleaseMat( &inv_map ); - - return result; -} - - -float -CvBoost::predict( const CvMat* _sample, const CvMat* _missing, - CvMat* weak_responses, CvSlice slice, - bool raw_mode, bool return_sum ) const -{ - float value = -FLT_MAX; - - CvSeqReader reader; - double sum = 0; - int wstep = 0; - const float* sample_data; - - if( !weak ) - CV_Error( CV_StsError, "The boosted tree ensemble has not been trained yet" ); - - if( !CV_IS_MAT(_sample) || CV_MAT_TYPE(_sample->type) != CV_32FC1 || - (_sample->cols != 1 && _sample->rows != 1) || - (_sample->cols + _sample->rows - 1 != data->var_all && !raw_mode) || - (active_vars && _sample->cols + _sample->rows - 1 != active_vars->cols && raw_mode) ) - CV_Error( CV_StsBadArg, - "the input sample must be 1d floating-point vector with the same " - "number of elements as the total number of variables or " - "as the number of variables used for training" ); - - if( _missing ) - { - if( !CV_IS_MAT(_missing) || !CV_IS_MASK_ARR(_missing) || - !CV_ARE_SIZES_EQ(_missing, _sample) ) - CV_Error( CV_StsBadArg, - "the missing data mask must be 8-bit vector of the same size as input sample" ); - } - - int i, weak_count = cvSliceLength( slice, weak ); - if( weak_count >= weak->total ) - { - weak_count = weak->total; - slice.start_index = 0; - } - - if( weak_responses ) - { - if( !CV_IS_MAT(weak_responses) || - CV_MAT_TYPE(weak_responses->type) != CV_32FC1 || - (weak_responses->cols != 1 && weak_responses->rows != 1) || - weak_responses->cols + weak_responses->rows - 1 != weak_count ) - CV_Error( CV_StsBadArg, - "The output matrix of weak classifier responses must be valid " - "floating-point vector of the same number of components as the length of input slice" ); - wstep = CV_IS_MAT_CONT(weak_responses->type) ? 1 : weak_responses->step/sizeof(float); - } - - int var_count = active_vars->cols; - const int* vtype = data->var_type->data.i; - const int* cmap = data->cat_map->data.i; - const int* cofs = data->cat_ofs->data.i; - - cv::Mat sample = cv::cvarrToMat(_sample); - cv::Mat missing; - if(!_missing) - missing = cv::cvarrToMat(_missing); - - // if need, preprocess the input vector - if( !raw_mode ) - { - int sstep, mstep = 0; - const float* src_sample; - const uchar* src_mask = 0; - float* dst_sample; - uchar* dst_mask; - const int* vidx = active_vars->data.i; - const int* vidx_abs = active_vars_abs->data.i; - bool have_mask = _missing != 0; - - sample = cv::Mat(1, var_count, CV_32FC1); - missing = cv::Mat(1, var_count, CV_8UC1); - - dst_sample = sample.ptr(); - dst_mask = missing.ptr(); - - src_sample = _sample->data.fl; - sstep = CV_IS_MAT_CONT(_sample->type) ? 1 : _sample->step/sizeof(src_sample[0]); - - if( _missing ) - { - src_mask = _missing->data.ptr; - mstep = CV_IS_MAT_CONT(_missing->type) ? 1 : _missing->step; - } - - for( i = 0; i < var_count; i++ ) - { - int idx = vidx[i], idx_abs = vidx_abs[i]; - float val = src_sample[idx_abs*sstep]; - int ci = vtype[idx]; - uchar m = src_mask ? src_mask[idx_abs*mstep] : (uchar)0; - - if( ci >= 0 ) - { - int a = cofs[ci], b = (ci+1 >= data->cat_ofs->cols) ? data->cat_map->cols : cofs[ci+1], - c = a; - int ival = cvRound(val); - if ( (ival != val) && (!m) ) - CV_Error( CV_StsBadArg, - "one of input categorical variable is not an integer" ); - - while( a < b ) - { - c = (a + b) >> 1; - if( ival < cmap[c] ) - b = c; - else if( ival > cmap[c] ) - a = c+1; - else - break; - } - - if( c < 0 || ival != cmap[c] ) - { - m = 1; - have_mask = true; - } - else - { - val = (float)(c - cofs[ci]); - } - } - - dst_sample[i] = val; - dst_mask[i] = m; - } - - if( !have_mask ) - missing.release(); - } - else - { - if( !CV_IS_MAT_CONT(_sample->type & (_missing ? _missing->type : -1)) ) - CV_Error( CV_StsBadArg, "In raw mode the input vectors must be continuous" ); - } - - cvStartReadSeq( weak, &reader ); - cvSetSeqReaderPos( &reader, slice.start_index ); - - sample_data = sample.ptr(); - - if( !have_active_cat_vars && missing.empty() && !weak_responses ) - { - for( i = 0; i < weak_count; i++ ) - { - CvBoostTree* wtree; - const CvDTreeNode* node; - CV_READ_SEQ_ELEM( wtree, reader ); - - node = wtree->get_root(); - while( node->left ) - { - CvDTreeSplit* split = node->split; - int vi = split->condensed_idx; - float val = sample_data[vi]; - int dir = val <= split->ord.c ? -1 : 1; - if( split->inversed ) - dir = -dir; - node = dir < 0 ? node->left : node->right; - } - sum += node->value; - } - } - else - { - const int* avars = active_vars->data.i; - const uchar* m = !missing.empty() ? missing.ptr() : 0; - - // full-featured version - for( i = 0; i < weak_count; i++ ) - { - CvBoostTree* wtree; - const CvDTreeNode* node; - CV_READ_SEQ_ELEM( wtree, reader ); - - node = wtree->get_root(); - while( node->left ) - { - const CvDTreeSplit* split = node->split; - int dir = 0; - for( ; !dir && split != 0; split = split->next ) - { - int vi = split->condensed_idx; - int ci = vtype[avars[vi]]; - float val = sample_data[vi]; - if( m && m[vi] ) - continue; - if( ci < 0 ) // ordered - dir = val <= split->ord.c ? -1 : 1; - else // categorical - { - int c = cvRound(val); - dir = CV_DTREE_CAT_DIR(c, split->subset); - } - if( split->inversed ) - dir = -dir; - } - - if( !dir ) - { - int diff = node->right->sample_count - node->left->sample_count; - dir = diff < 0 ? -1 : 1; - } - node = dir < 0 ? node->left : node->right; - } - if( weak_responses ) - weak_responses->data.fl[i*wstep] = (float)node->value; - sum += node->value; - } - } - - if( return_sum ) - value = (float)sum; - else - { - int cls_idx = sum >= 0; - if( raw_mode ) - value = (float)cls_idx; - else - value = (float)cmap[cofs[vtype[data->var_count]] + cls_idx]; - } - - return value; -} - -float CvBoost::calc_error( CvMLData* _data, int type, std::vector *resp ) -{ - float err = 0; - const CvMat* values = _data->get_values(); - const CvMat* response = _data->get_responses(); - const CvMat* missing = _data->get_missing(); - const CvMat* sample_idx = (type == CV_TEST_ERROR) ? _data->get_test_sample_idx() : _data->get_train_sample_idx(); - const CvMat* var_types = _data->get_var_types(); - int* sidx = sample_idx ? sample_idx->data.i : 0; - int r_step = CV_IS_MAT_CONT(response->type) ? - 1 : response->step / CV_ELEM_SIZE(response->type); - bool is_classifier = var_types->data.ptr[var_types->cols-1] == CV_VAR_CATEGORICAL; - int sample_count = sample_idx ? sample_idx->cols : 0; - sample_count = (type == CV_TRAIN_ERROR && sample_count == 0) ? values->rows : sample_count; - float* pred_resp = 0; - if( resp && (sample_count > 0) ) - { - resp->resize( sample_count ); - pred_resp = &((*resp)[0]); - } - if ( is_classifier ) - { - for( int i = 0; i < sample_count; i++ ) - { - CvMat sample, miss; - int si = sidx ? sidx[i] : i; - cvGetRow( values, &sample, si ); - if( missing ) - cvGetRow( missing, &miss, si ); - float r = (float)predict( &sample, missing ? &miss : 0 ); - if( pred_resp ) - pred_resp[i] = r; - int d = fabs((double)r - response->data.fl[si*r_step]) <= FLT_EPSILON ? 0 : 1; - err += d; - } - err = sample_count ? err / (float)sample_count * 100 : -FLT_MAX; - } - else - { - for( int i = 0; i < sample_count; i++ ) - { - CvMat sample, miss; - int si = sidx ? sidx[i] : i; - cvGetRow( values, &sample, si ); - if( missing ) - cvGetRow( missing, &miss, si ); - float r = (float)predict( &sample, missing ? &miss : 0 ); - if( pred_resp ) - pred_resp[i] = r; - float d = r - response->data.fl[si*r_step]; - err += d*d; - } - err = sample_count ? err / (float)sample_count : -FLT_MAX; - } - return err; -} - -void CvBoost::write_params( cv::FileStorage& fs ) const -{ - const char* boost_type_str = - params.boost_type == DISCRETE ? "DiscreteAdaboost" : - params.boost_type == REAL ? "RealAdaboost" : - params.boost_type == LOGIT ? "LogitBoost" : - params.boost_type == GENTLE ? "GentleAdaboost" : 0; - - const char* split_crit_str = - params.split_criteria == DEFAULT ? "Default" : - params.split_criteria == GINI ? "Gini" : - params.boost_type == MISCLASS ? "Misclassification" : - params.boost_type == SQERR ? "SquaredErr" : 0; - - if( boost_type_str ) - fs.write( "boosting_type", boost_type_str ); - else - fs.write( "boosting_type", params.boost_type ); - - if( split_crit_str ) - fs.write( "splitting_criteria", split_crit_str ); - else - fs.write( "splitting_criteria", params.split_criteria ); - - fs.write( "ntrees", weak->total ); - fs.write( "weight_trimming_rate", params.weight_trim_rate ); - - data->write_params( fs ); -} - - -void CvBoost::read_params( cv::FileNode& fnode ) -{ - CV_FUNCNAME( "CvBoost::read_params" ); - - __BEGIN__; - - if( fnode.empty() || !fnode.isMap() ) - return; - - data = new CvDTreeTrainData(); - data->read_params( fnode ); - data->shared = true; - - params.max_depth = data->params.max_depth; - params.min_sample_count = data->params.min_sample_count; - params.max_categories = data->params.max_categories; - params.priors = data->params.priors; - params.regression_accuracy = data->params.regression_accuracy; - params.use_surrogates = data->params.use_surrogates; - - cv::FileNode temp = fnode[ "boosting_type" ]; - if( temp.empty() ) - return; - - if ( temp.isString() ) - { - std::string boost_type_str = temp; - params.boost_type = (boost_type_str == "DiscreteAdaboost") ? DISCRETE : - (boost_type_str == "RealAdaboost") ? REAL : - (boost_type_str == "LogitBoost") ? LOGIT : - (boost_type_str == "GentleAdaboost") ? GENTLE : -1; - } - else - params.boost_type = temp.empty() ? -1 : (int)temp; - - if( params.boost_type < DISCRETE || params.boost_type > GENTLE ) - CV_ERROR( CV_StsBadArg, "Unknown boosting type" ); - - temp = fnode[ "splitting_criteria" ]; - if( !temp.empty() && temp.isString() ) - { - std::string split_crit_str = temp; - params.split_criteria = ( split_crit_str == "Default" ) ? DEFAULT : - ( split_crit_str == "Gini" ) ? GINI : - ( split_crit_str == "Misclassification" ) ? MISCLASS : - ( split_crit_str == "SquaredErr" ) ? SQERR : -1; - } - else - params.split_criteria = temp.empty() ? -1 : (int) temp; - - if( params.split_criteria < DEFAULT || params.boost_type > SQERR ) - CV_ERROR( CV_StsBadArg, "Unknown boosting type" ); - - params.weak_count = (int) fnode[ "ntrees" ]; - params.weight_trim_rate = (double)fnode["weight_trimming_rate"]; - - __END__; -} - - - -void -CvBoost::read( cv::FileNode& node ) -{ - CV_FUNCNAME( "CvBoost::read" ); - - __BEGIN__; - - cv::FileNodeIterator reader; - cv::FileNode trees_fnode; - CvMemStorage* storage; - int ntrees; - - clear(); - read_params( node ); - - if( !data ) - EXIT; - - trees_fnode = node[ "trees" ]; - if( trees_fnode.empty() || !trees_fnode.isSeq() ) - CV_ERROR( CV_StsParseError, " tag is missing" ); - - reader = trees_fnode.begin(); - ntrees = (int) trees_fnode.size(); - - if( ntrees != params.weak_count ) - CV_ERROR( CV_StsUnmatchedSizes, - "The number of trees stored does not match tag value" ); - - CV_CALL( storage = cvCreateMemStorage() ); - weak = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvBoostTree*), storage ); - - for( int i = 0; i < ntrees; i++ ) - { - CvBoostTree* tree = new CvBoostTree(); - tree->read( *reader, this, data ); - reader++; - cvSeqPush( weak, &tree ); - } - get_active_vars(); - - __END__; -} - - -void -CvBoost::write( cv::FileStorage& fs, const char* name ) const -{ - CV_FUNCNAME( "CvBoost::write" ); - - __BEGIN__; - - CvSeqReader reader; - int i; - - fs.startWriteStruct( name, cv::FileNode::MAP, CV_TYPE_NAME_ML_BOOSTING ); - - if( !weak ) - CV_ERROR( CV_StsBadArg, "The classifier has not been trained yet" ); - - write_params( fs ); - fs.startWriteStruct( "trees", cv::FileNode::SEQ ); - - cvStartReadSeq(weak, &reader); - - for( i = 0; i < weak->total; i++ ) - { - CvBoostTree* tree; - CV_READ_SEQ_ELEM( tree, reader ); - fs.startWriteStruct( 0, cv::FileNode::MAP ); - tree->write( fs ); - fs.endWriteStruct(); - } - - fs.endWriteStruct(); - fs.endWriteStruct(); - - __END__; -} - - -CvMat* -CvBoost::get_weights() -{ - return weights; -} - - -CvMat* -CvBoost::get_subtree_weights() -{ - return subtree_weights; -} - - -CvMat* -CvBoost::get_weak_response() -{ - return weak_eval; -} - - -const CvBoostParams& -CvBoost::get_params() const -{ - return params; -} - -CvSeq* CvBoost::get_weak_predictors() -{ - return weak; -} - -const CvDTreeTrainData* CvBoost::get_data() const -{ - return data; -} - -using namespace cv; - -CvBoost::CvBoost( const Mat& _train_data, int _tflag, - const Mat& _responses, const Mat& _var_idx, - const Mat& _sample_idx, const Mat& _var_type, - const Mat& _missing_mask, - CvBoostParams _params ) -{ - weak = 0; - data = 0; - default_model_name = "my_boost_tree"; - active_vars = active_vars_abs = orig_response = sum_response = weak_eval = - subsample_mask = weights = subtree_weights = 0; - - train( _train_data, _tflag, _responses, _var_idx, _sample_idx, - _var_type, _missing_mask, _params ); -} - - -bool -CvBoost::train( const Mat& _train_data, int _tflag, - const Mat& _responses, const Mat& _var_idx, - const Mat& _sample_idx, const Mat& _var_type, - const Mat& _missing_mask, - CvBoostParams _params, bool _update ) -{ - train_data_hdr = cvMat(_train_data); - train_data_mat = _train_data; - responses_hdr = cvMat(_responses); - responses_mat = _responses; - - CvMat vidx = cvMat(_var_idx), sidx = cvMat(_sample_idx), vtype = cvMat(_var_type), mmask = cvMat(_missing_mask); - - return train(&train_data_hdr, _tflag, &responses_hdr, vidx.data.ptr ? &vidx : 0, - sidx.data.ptr ? &sidx : 0, vtype.data.ptr ? &vtype : 0, - mmask.data.ptr ? &mmask : 0, _params, _update); -} - -float -CvBoost::predict( const Mat& _sample, const Mat& _missing, - const Range& slice, bool raw_mode, bool return_sum ) const -{ - CvMat sample = cvMat(_sample), mmask = cvMat(_missing); - /*if( weak_responses ) - { - int weak_count = cvSliceLength( slice, weak ); - if( weak_count >= weak->total ) - { - weak_count = weak->total; - slice.start_index = 0; - } - - if( !(weak_responses->data && weak_responses->type() == CV_32FC1 && - (weak_responses->cols == 1 || weak_responses->rows == 1) && - weak_responses->cols + weak_responses->rows - 1 == weak_count) ) - weak_responses->create(weak_count, 1, CV_32FC1); - pwr = &(wr = *weak_responses); - }*/ - return predict(&sample, _missing.empty() ? 0 : &mmask, 0, - slice == Range::all() ? CV_WHOLE_SEQ : cvSlice(slice.start, slice.end), - raw_mode, return_sum); -} - -/* End of file. */ diff --git a/apps/traincascade/old_ml_data.cpp b/apps/traincascade/old_ml_data.cpp deleted file mode 100644 index d221dcbf0f..0000000000 --- a/apps/traincascade/old_ml_data.cpp +++ /dev/null @@ -1,792 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// Intel License Agreement -// -// 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 "old_ml_precomp.hpp" -#include - -#define MISS_VAL FLT_MAX -#define CV_VAR_MISS 0 - -CvTrainTestSplit::CvTrainTestSplit() -{ - train_sample_part_mode = CV_COUNT; - train_sample_part.count = -1; - mix = false; -} - -CvTrainTestSplit::CvTrainTestSplit( int _train_sample_count, bool _mix ) -{ - train_sample_part_mode = CV_COUNT; - train_sample_part.count = _train_sample_count; - mix = _mix; -} - -CvTrainTestSplit::CvTrainTestSplit( float _train_sample_portion, bool _mix ) -{ - train_sample_part_mode = CV_PORTION; - train_sample_part.portion = _train_sample_portion; - mix = _mix; -} - -//////////////// - -CvMLData::CvMLData() -{ - values = missing = var_types = var_idx_mask = response_out = var_idx_out = var_types_out = 0; - train_sample_idx = test_sample_idx = 0; - header_lines_number = 0; - sample_idx = 0; - response_idx = -1; - - train_sample_count = -1; - - delimiter = ','; - miss_ch = '?'; - //flt_separator = '.'; - - rng = &cv::theRNG(); -} - -CvMLData::~CvMLData() -{ - clear(); -} - -void CvMLData::free_train_test_idx() -{ - cvReleaseMat( &train_sample_idx ); - cvReleaseMat( &test_sample_idx ); - sample_idx = 0; -} - -void CvMLData::clear() -{ - class_map.clear(); - - cvReleaseMat( &values ); - cvReleaseMat( &missing ); - cvReleaseMat( &var_types ); - cvReleaseMat( &var_idx_mask ); - - cvReleaseMat( &response_out ); - cvReleaseMat( &var_idx_out ); - cvReleaseMat( &var_types_out ); - - free_train_test_idx(); - - total_class_count = 0; - - response_idx = -1; - - train_sample_count = -1; -} - - -void CvMLData::set_header_lines_number( int idx ) -{ - header_lines_number = std::max(0, idx); -} - -int CvMLData::get_header_lines_number() const -{ - return header_lines_number; -} - -static char *fgets_chomp(char *str, int n, FILE *stream) -{ - char *head = fgets(str, n, stream); - if( head ) - { - for(char *tail = head + strlen(head) - 1; tail >= head; --tail) - { - if( *tail != '\r' && *tail != '\n' ) - break; - *tail = '\0'; - } - } - return head; -} - - -int CvMLData::read_csv(const char* filename) -{ - const int M = 1000000; - const char str_delimiter[3] = { ' ', delimiter, '\0' }; - FILE* file = 0; - CvMemStorage* storage; - CvSeq* seq; - char *ptr; - float* el_ptr; - CvSeqReader reader; - int cols_count = 0; - uchar *var_types_ptr = 0; - - clear(); - - file = fopen( filename, "rt" ); - - if( !file ) - return -1; - - std::vector _buf(M); - char* buf = &_buf[0]; - - // skip header lines - for( int i = 0; i < header_lines_number; i++ ) - { - if( fgets( buf, M, file ) == 0 ) - { - fclose(file); - return -1; - } - } - - // read the first data line and determine the number of variables - if( !fgets_chomp( buf, M, file )) - { - fclose(file); - return -1; - } - - ptr = buf; - while( *ptr == ' ' ) - ptr++; - for( ; *ptr != '\0'; ) - { - if(*ptr == delimiter || *ptr == ' ') - { - cols_count++; - ptr++; - while( *ptr == ' ' ) ptr++; - } - else - ptr++; - } - - cols_count++; - - if ( cols_count == 0) - { - fclose(file); - return -1; - } - - // create temporary memory storage to store the whole database - el_ptr = new float[cols_count]; - storage = cvCreateMemStorage(); - seq = cvCreateSeq( 0, sizeof(*seq), cols_count*sizeof(float), storage ); - - var_types = cvCreateMat( 1, cols_count, CV_8U ); - cvZero( var_types ); - var_types_ptr = var_types->data.ptr; - - for(;;) - { - char *token = NULL; - int type; - token = strtok(buf, str_delimiter); - if (!token) - break; - for (int i = 0; i < cols_count-1; i++) - { - str_to_flt_elem( token, el_ptr[i], type); - var_types_ptr[i] |= type; - token = strtok(NULL, str_delimiter); - if (!token) - { - fclose(file); - delete [] el_ptr; - return -1; - } - } - str_to_flt_elem( token, el_ptr[cols_count-1], type); - var_types_ptr[cols_count-1] |= type; - cvSeqPush( seq, el_ptr ); - if( !fgets_chomp( buf, M, file ) ) - break; - } - fclose(file); - - values = cvCreateMat( seq->total, cols_count, CV_32FC1 ); - missing = cvCreateMat( seq->total, cols_count, CV_8U ); - var_idx_mask = cvCreateMat( 1, values->cols, CV_8UC1 ); - cvSet( var_idx_mask, cvRealScalar(1) ); - train_sample_count = seq->total; - - cvStartReadSeq( seq, &reader ); - for(int i = 0; i < seq->total; i++ ) - { - const float* sdata = (float*)reader.ptr; - float* ddata = values->data.fl + cols_count*i; - uchar* dm = missing->data.ptr + cols_count*i; - - for( int j = 0; j < cols_count; j++ ) - { - ddata[j] = sdata[j]; - dm[j] = ( fabs( MISS_VAL - sdata[j] ) <= FLT_EPSILON ); - } - CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); - } - - if ( cvNorm( missing, 0, CV_L1 ) <= FLT_EPSILON ) - cvReleaseMat( &missing ); - - cvReleaseMemStorage( &storage ); - delete []el_ptr; - return 0; -} - -const CvMat* CvMLData::get_values() const -{ - return values; -} - -const CvMat* CvMLData::get_missing() const -{ - CV_FUNCNAME( "CvMLData::get_missing" ); - __BEGIN__; - - if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); - - __END__; - - return missing; -} - -const std::map& CvMLData::get_class_labels_map() const -{ - return class_map; -} - -void CvMLData::str_to_flt_elem( const char* token, float& flt_elem, int& type) -{ - - char* stopstring = NULL; - flt_elem = (float)strtod( token, &stopstring ); - assert( stopstring ); - type = CV_VAR_ORDERED; - if ( *stopstring == miss_ch && strlen(stopstring) == 1 ) // missed value - { - flt_elem = MISS_VAL; - type = CV_VAR_MISS; - } - else - { - if ( (*stopstring != 0) && (*stopstring != '\n') && (strcmp(stopstring, "\r\n") != 0) ) // class label - { - int idx = class_map[token]; - if ( idx == 0) - { - total_class_count++; - idx = total_class_count; - class_map[token] = idx; - } - flt_elem = (float)idx; - type = CV_VAR_CATEGORICAL; - } - } -} - -void CvMLData::set_delimiter(char ch) -{ - CV_FUNCNAME( "CvMLData::set_delimited" ); - __BEGIN__; - - if (ch == miss_ch /*|| ch == flt_separator*/) - CV_ERROR(CV_StsBadArg, "delimited, miss_character and flt_separator must be different"); - - delimiter = ch; - - __END__; -} - -char CvMLData::get_delimiter() const -{ - return delimiter; -} - -void CvMLData::set_miss_ch(char ch) -{ - CV_FUNCNAME( "CvMLData::set_miss_ch" ); - __BEGIN__; - - if (ch == delimiter/* || ch == flt_separator*/) - CV_ERROR(CV_StsBadArg, "delimited, miss_character and flt_separator must be different"); - - miss_ch = ch; - - __END__; -} - -char CvMLData::get_miss_ch() const -{ - return miss_ch; -} - -void CvMLData::set_response_idx( int idx ) -{ - CV_FUNCNAME( "CvMLData::set_response_idx" ); - __BEGIN__; - - if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); - - if ( idx >= values->cols) - CV_ERROR( CV_StsBadArg, "idx value is not correct" ); - - if ( response_idx >= 0 ) - chahge_var_idx( response_idx, true ); - if ( idx >= 0 ) - chahge_var_idx( idx, false ); - response_idx = idx; - - __END__; -} - -int CvMLData::get_response_idx() const -{ - CV_FUNCNAME( "CvMLData::get_response_idx" ); - __BEGIN__; - - if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); - __END__; - return response_idx; -} - -void CvMLData::change_var_type( int var_idx, int type ) -{ - CV_FUNCNAME( "CvMLData::change_var_type" ); - __BEGIN__; - - int var_count = 0; - - if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); - - var_count = values->cols; - - if ( var_idx < 0 || var_idx >= var_count) - CV_ERROR( CV_StsBadArg, "var_idx is not correct" ); - - if ( type != CV_VAR_ORDERED && type != CV_VAR_CATEGORICAL) - CV_ERROR( CV_StsBadArg, "type is not correct" ); - - assert( var_types ); - if ( var_types->data.ptr[var_idx] == CV_VAR_CATEGORICAL && type == CV_VAR_ORDERED) - CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" ); - var_types->data.ptr[var_idx] = (uchar)type; - - __END__; - - return; -} - -void CvMLData::set_var_types( const char* str ) -{ - CV_FUNCNAME( "CvMLData::set_var_types" ); - __BEGIN__; - - const char* ord = 0, *cat = 0; - int var_count = 0, set_var_type_count = 0; - if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); - - var_count = values->cols; - - assert( var_types ); - - ord = strstr( str, "ord" ); - cat = strstr( str, "cat" ); - if ( !ord && !cat ) - CV_ERROR( CV_StsBadArg, "types string is not correct" ); - - if ( !ord && strlen(cat) == 3 ) // str == "cat" - { - cvSet( var_types, cvScalarAll(CV_VAR_CATEGORICAL) ); - return; - } - - if ( !cat && strlen(ord) == 3 ) // str == "ord" - { - cvSet( var_types, cvScalarAll(CV_VAR_ORDERED) ); - return; - } - - if ( ord ) // parse ord str - { - char* stopstring = NULL; - if ( ord[3] != '[') - CV_ERROR( CV_StsBadArg, "types string is not correct" ); - - ord += 4; // pass "ord[" - do - { - int b1 = (int)strtod( ord, &stopstring ); - if ( *stopstring == 0 || (*stopstring != ',' && *stopstring != ']' && *stopstring != '-') ) - CV_ERROR( CV_StsBadArg, "types string is not correct" ); - ord = stopstring + 1; - if ( (stopstring[0] == ',') || (stopstring[0] == ']')) - { - if ( var_types->data.ptr[b1] == CV_VAR_CATEGORICAL) - CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" ); - var_types->data.ptr[b1] = CV_VAR_ORDERED; - set_var_type_count++; - } - else - { - if ( stopstring[0] == '-') - { - int b2 = (int)strtod( ord, &stopstring); - if ( (*stopstring == 0) || (*stopstring != ',' && *stopstring != ']') ) - CV_ERROR( CV_StsBadArg, "types string is not correct" ); - ord = stopstring + 1; - for (int i = b1; i <= b2; i++) - { - if ( var_types->data.ptr[i] == CV_VAR_CATEGORICAL) - CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" ); - var_types->data.ptr[i] = CV_VAR_ORDERED; - } - set_var_type_count += b2 - b1 + 1; - } - else - CV_ERROR( CV_StsBadArg, "types string is not correct" ); - - } - } - while (*stopstring != ']'); - - if ( stopstring[1] != '\0' && stopstring[1] != ',') - CV_ERROR( CV_StsBadArg, "types string is not correct" ); - } - - if ( cat ) // parse cat str - { - char* stopstring = NULL; - if ( cat[3] != '[') - CV_ERROR( CV_StsBadArg, "types string is not correct" ); - - cat += 4; // pass "cat[" - do - { - int b1 = (int)strtod( cat, &stopstring ); - if ( *stopstring == 0 || (*stopstring != ',' && *stopstring != ']' && *stopstring != '-') ) - CV_ERROR( CV_StsBadArg, "types string is not correct" ); - cat = stopstring + 1; - if ( (stopstring[0] == ',') || (stopstring[0] == ']')) - { - var_types->data.ptr[b1] = CV_VAR_CATEGORICAL; - set_var_type_count++; - } - else - { - if ( stopstring[0] == '-') - { - int b2 = (int)strtod( cat, &stopstring); - if ( (*stopstring == 0) || (*stopstring != ',' && *stopstring != ']') ) - CV_ERROR( CV_StsBadArg, "types string is not correct" ); - cat = stopstring + 1; - for (int i = b1; i <= b2; i++) - var_types->data.ptr[i] = CV_VAR_CATEGORICAL; - set_var_type_count += b2 - b1 + 1; - } - else - CV_ERROR( CV_StsBadArg, "types string is not correct" ); - - } - } - while (*stopstring != ']'); - - if ( stopstring[1] != '\0' && stopstring[1] != ',') - CV_ERROR( CV_StsBadArg, "types string is not correct" ); - } - - if (set_var_type_count != var_count) - CV_ERROR( CV_StsBadArg, "types string is not correct" ); - - __END__; -} - -const CvMat* CvMLData::get_var_types() -{ - CV_FUNCNAME( "CvMLData::get_var_types" ); - __BEGIN__; - - uchar *var_types_out_ptr = 0; - int avcount, vt_size; - if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); - - assert( var_idx_mask ); - - avcount = cvFloor( cvNorm( var_idx_mask, 0, CV_L1 ) ); - vt_size = avcount + (response_idx >= 0); - - if ( avcount == values->cols || (avcount == values->cols-1 && response_idx == values->cols-1) ) - return var_types; - - if ( !var_types_out || ( var_types_out && var_types_out->cols != vt_size ) ) - { - cvReleaseMat( &var_types_out ); - var_types_out = cvCreateMat( 1, vt_size, CV_8UC1 ); - } - - var_types_out_ptr = var_types_out->data.ptr; - for( int i = 0; i < var_types->cols; i++) - { - if (i == response_idx || !var_idx_mask->data.ptr[i]) continue; - *var_types_out_ptr = var_types->data.ptr[i]; - var_types_out_ptr++; - } - if ( response_idx >= 0 ) - *var_types_out_ptr = var_types->data.ptr[response_idx]; - - __END__; - - return var_types_out; -} - -int CvMLData::get_var_type( int var_idx ) const -{ - return var_types->data.ptr[var_idx]; -} - -const CvMat* CvMLData::get_responses() -{ - CV_FUNCNAME( "CvMLData::get_responses_ptr" ); - __BEGIN__; - - int var_count = 0; - - if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); - var_count = values->cols; - - if ( response_idx < 0 || response_idx >= var_count ) - return 0; - if ( !response_out ) - response_out = cvCreateMatHeader( values->rows, 1, CV_32FC1 ); - else - cvInitMatHeader( response_out, values->rows, 1, CV_32FC1); - cvGetCol( values, response_out, response_idx ); - - __END__; - - return response_out; -} - -void CvMLData::set_train_test_split( const CvTrainTestSplit * spl) -{ - CV_FUNCNAME( "CvMLData::set_division" ); - __BEGIN__; - - int sample_count = 0; - - if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); - - sample_count = values->rows; - - float train_sample_portion; - - if (spl->train_sample_part_mode == CV_COUNT) - { - train_sample_count = spl->train_sample_part.count; - if (train_sample_count > sample_count) - CV_ERROR( CV_StsBadArg, "train samples count is not correct" ); - train_sample_count = train_sample_count<=0 ? sample_count : train_sample_count; - } - else // dtype.train_sample_part_mode == CV_PORTION - { - train_sample_portion = spl->train_sample_part.portion; - if ( train_sample_portion > 1) - CV_ERROR( CV_StsBadArg, "train samples count is not correct" ); - train_sample_portion = train_sample_portion <= FLT_EPSILON || - 1 - train_sample_portion <= FLT_EPSILON ? 1 : train_sample_portion; - train_sample_count = std::max(1, cvFloor( train_sample_portion * sample_count )); - } - - if ( train_sample_count == sample_count ) - { - free_train_test_idx(); - return; - } - - if ( train_sample_idx && train_sample_idx->cols != train_sample_count ) - free_train_test_idx(); - - if ( !sample_idx) - { - int test_sample_count = sample_count- train_sample_count; - sample_idx = (int*)cvAlloc( sample_count * sizeof(sample_idx[0]) ); - for (int i = 0; i < sample_count; i++ ) - sample_idx[i] = i; - train_sample_idx = cvCreateMatHeader( 1, train_sample_count, CV_32SC1 ); - *train_sample_idx = cvMat( 1, train_sample_count, CV_32SC1, &sample_idx[0] ); - - CV_Assert(test_sample_count > 0); - test_sample_idx = cvCreateMatHeader( 1, test_sample_count, CV_32SC1 ); - *test_sample_idx = cvMat( 1, test_sample_count, CV_32SC1, &sample_idx[train_sample_count] ); - } - - mix = spl->mix; - if ( mix ) - mix_train_and_test_idx(); - - __END__; -} - -const CvMat* CvMLData::get_train_sample_idx() const -{ - CV_FUNCNAME( "CvMLData::get_train_sample_idx" ); - __BEGIN__; - - if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); - __END__; - - return train_sample_idx; -} - -const CvMat* CvMLData::get_test_sample_idx() const -{ - CV_FUNCNAME( "CvMLData::get_test_sample_idx" ); - __BEGIN__; - - if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); - __END__; - - return test_sample_idx; -} - -void CvMLData::mix_train_and_test_idx() -{ - CV_FUNCNAME( "CvMLData::mix_train_and_test_idx" ); - __BEGIN__; - - if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); - __END__; - - if ( !sample_idx) - return; - - if ( train_sample_count > 0 && train_sample_count < values->rows ) - { - int n = values->rows; - for (int i = 0; i < n; i++) - { - int a = (*rng)(n); - int b = (*rng)(n); - int t; - CV_SWAP( sample_idx[a], sample_idx[b], t ); - } - } -} - -const CvMat* CvMLData::get_var_idx() -{ - CV_FUNCNAME( "CvMLData::get_var_idx" ); - __BEGIN__; - - int avcount = 0; - - if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); - - assert( var_idx_mask ); - - avcount = cvFloor( cvNorm( var_idx_mask, 0, CV_L1 ) ); - int* vidx; - - if ( avcount == values->cols ) - return 0; - - if ( !var_idx_out || ( var_idx_out && var_idx_out->cols != avcount ) ) - { - cvReleaseMat( &var_idx_out ); - var_idx_out = cvCreateMat( 1, avcount, CV_32SC1); - if ( response_idx >=0 ) - var_idx_mask->data.ptr[response_idx] = 0; - } - - vidx = var_idx_out->data.i; - - for(int i = 0; i < var_idx_mask->cols; i++) - if ( var_idx_mask->data.ptr[i] ) - { - *vidx = i; - vidx++; - } - - __END__; - - return var_idx_out; -} - -void CvMLData::chahge_var_idx( int vi, bool state ) -{ - change_var_idx( vi, state ); -} - -void CvMLData::change_var_idx( int vi, bool state ) -{ - CV_FUNCNAME( "CvMLData::change_var_idx" ); - __BEGIN__; - - int var_count = 0; - - if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); - - var_count = values->cols; - - if ( vi < 0 || vi >= var_count) - CV_ERROR( CV_StsBadArg, "variable index is not correct" ); - - assert( var_idx_mask ); - var_idx_mask->data.ptr[vi] = state; - - __END__; -} - -/* End of file. */ diff --git a/apps/traincascade/old_ml_inner_functions.cpp b/apps/traincascade/old_ml_inner_functions.cpp deleted file mode 100644 index ef81da3548..0000000000 --- a/apps/traincascade/old_ml_inner_functions.cpp +++ /dev/null @@ -1,1684 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// Intel License Agreement -// -// 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 "old_ml_precomp.hpp" - - -CvStatModel::CvStatModel() -{ - default_model_name = "my_stat_model"; -} - - -CvStatModel::~CvStatModel() -{ - clear(); -} - - -void CvStatModel::clear() -{ -} - - -void CvStatModel::save( const char* filename, const char* name ) const -{ - cv::FileStorage fs; - - CV_FUNCNAME( "CvStatModel::save" ); - - __BEGIN__; - - if( !fs.open( filename, cv::FileStorage::WRITE )) - CV_ERROR( CV_StsError, "Could not open the file storage. Check the path and permissions" ); - - write( fs, name ? name : default_model_name ); - - __END__; - -} - - -void CvStatModel::load( const char* filename, const char* name ) -{ - cv::FileStorage fs; - - CV_FUNCNAME( "CvStatModel::load" ); - - __BEGIN__; - - cv::FileNode model_node; - - if( !fs.open(filename, cv::FileStorage::READ) ) - CV_ERROR( CV_StsError, "Could not open the file storage. Check the path and permissions" ); - - if( name ) - model_node = fs[ name ]; - else - { - auto root = fs.root(); - if ( root.size() > 0 ) - model_node = fs[0]; - } - - read( model_node ); - - __END__; - -} - - -void CvStatModel::write( cv::FileStorage&, const char* ) const -{ - OPENCV_ERROR( CV_StsNotImplemented, "CvStatModel::write", "" ); -} - -void CvStatModel::read( const cv::FileNode& ) -{ - OPENCV_ERROR( CV_StsNotImplemented, "CvStatModel::read", "" ); -} - -CvMat* icvGenerateRandomClusterCenters ( int seed, const CvMat* data, - int num_of_clusters, CvMat* _centers ) -{ - CvMat* centers = _centers; - - CV_FUNCNAME("icvGenerateRandomClusterCenters"); - __BEGIN__; - - CvRNG rng; - CvMat data_comp, centers_comp; - CvPoint minLoc, maxLoc; // Not used, just for function "cvMinMaxLoc" - double minVal, maxVal; - int i; - int dim = data ? data->cols : 0; - - if( ICV_IS_MAT_OF_TYPE(data, CV_32FC1) ) - { - if( _centers && !ICV_IS_MAT_OF_TYPE (_centers, CV_32FC1) ) - { - CV_ERROR(CV_StsBadArg,""); - } - else if( !_centers ) - CV_CALL(centers = cvCreateMat (num_of_clusters, dim, CV_32FC1)); - } - else if( ICV_IS_MAT_OF_TYPE(data, CV_64FC1) ) - { - if( _centers && !ICV_IS_MAT_OF_TYPE (_centers, CV_64FC1) ) - { - CV_ERROR(CV_StsBadArg,""); - } - else if( !_centers ) - CV_CALL(centers = cvCreateMat (num_of_clusters, dim, CV_64FC1)); - } - else - CV_ERROR (CV_StsBadArg,""); - - if( num_of_clusters < 1 ) - CV_ERROR (CV_StsBadArg,""); - - rng = cvRNG(seed); - for (i = 0; i < dim; i++) - { - CV_CALL(cvGetCol (data, &data_comp, i)); - CV_CALL(cvMinMaxLoc (&data_comp, &minVal, &maxVal, &minLoc, &maxLoc)); - CV_CALL(cvGetCol (centers, ¢ers_comp, i)); - CV_CALL(cvRandArr (&rng, ¢ers_comp, CV_RAND_UNI, cvScalarAll(minVal), cvScalarAll(maxVal))); - } - - __END__; - - if( (cvGetErrStatus () < 0) || (centers != _centers) ) - cvReleaseMat (¢ers); - - return _centers ? _centers : centers; -} // end of icvGenerateRandomClusterCenters - -static int CV_CDECL -icvCmpIntegers( const void* a, const void* b ) -{ - return *(const int*)a - *(const int*)b; -} - - -static int CV_CDECL -icvCmpIntegersPtr( const void* _a, const void* _b ) -{ - int a = **(const int**)_a; - int b = **(const int**)_b; - return (a < b ? -1 : 0)|(a > b); -} - - -static int icvCmpSparseVecElems( const void* a, const void* b ) -{ - return ((CvSparseVecElem32f*)a)->idx - ((CvSparseVecElem32f*)b)->idx; -} - - -CvMat* -cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, bool check_for_duplicates ) -{ - CvMat* idx = 0; - - CV_FUNCNAME( "cvPreprocessIndexArray" ); - - __BEGIN__; - - int i, idx_total, idx_selected = 0, step, type, prev = INT_MIN, is_sorted = 1; - uchar* srcb = 0; - int* srci = 0; - int* dsti; - - if( !CV_IS_MAT(idx_arr) ) - CV_ERROR( CV_StsBadArg, "Invalid index array" ); - - if( idx_arr->rows != 1 && idx_arr->cols != 1 ) - CV_ERROR( CV_StsBadSize, "the index array must be 1-dimensional" ); - - idx_total = idx_arr->rows + idx_arr->cols - 1; - srcb = idx_arr->data.ptr; - srci = idx_arr->data.i; - - type = CV_MAT_TYPE(idx_arr->type); - step = CV_IS_MAT_CONT(idx_arr->type) ? 1 : idx_arr->step/CV_ELEM_SIZE(type); - - switch( type ) - { - case CV_8UC1: - case CV_8SC1: - // idx_arr is array of 1's and 0's - - // i.e. it is a mask of the selected components - if( idx_total != data_arr_size ) - CV_ERROR( CV_StsUnmatchedSizes, - "Component mask should contain as many elements as the total number of input variables" ); - - for( i = 0; i < idx_total; i++ ) - idx_selected += srcb[i*step] != 0; - - if( idx_selected == 0 ) - CV_ERROR( CV_StsOutOfRange, "No components/input_variables is selected!" ); - - break; - case CV_32SC1: - // idx_arr is array of integer indices of selected components - if( idx_total > data_arr_size ) - CV_ERROR( CV_StsOutOfRange, - "index array may not contain more elements than the total number of input variables" ); - idx_selected = idx_total; - // check if sorted already - for( i = 0; i < idx_total; i++ ) - { - int val = srci[i*step]; - if( val >= prev ) - { - is_sorted = 0; - break; - } - prev = val; - } - break; - default: - CV_ERROR( CV_StsUnsupportedFormat, "Unsupported index array data type " - "(it should be 8uC1, 8sC1 or 32sC1)" ); - } - - CV_CALL( idx = cvCreateMat( 1, idx_selected, CV_32SC1 )); - dsti = idx->data.i; - - if( type < CV_32SC1 ) - { - for( i = 0; i < idx_total; i++ ) - if( srcb[i*step] ) - *dsti++ = i; - } - else - { - for( i = 0; i < idx_total; i++ ) - dsti[i] = srci[i*step]; - - if( !is_sorted ) - qsort( dsti, idx_total, sizeof(dsti[0]), icvCmpIntegers ); - - if( dsti[0] < 0 || dsti[idx_total-1] >= data_arr_size ) - CV_ERROR( CV_StsOutOfRange, "the index array elements are out of range" ); - - if( check_for_duplicates ) - { - for( i = 1; i < idx_total; i++ ) - if( dsti[i] <= dsti[i-1] ) - CV_ERROR( CV_StsBadArg, "There are duplicated index array elements" ); - } - } - - __END__; - - if( cvGetErrStatus() < 0 ) - cvReleaseMat( &idx ); - - return idx; -} - - -CvMat* -cvPreprocessVarType( const CvMat* var_type, const CvMat* var_idx, - int var_count, int* response_type ) -{ - CvMat* out_var_type = 0; - CV_FUNCNAME( "cvPreprocessVarType" ); - - if( response_type ) - *response_type = -1; - - __BEGIN__; - - int i, tm_size, tm_step; - //int* map = 0; - const uchar* src; - uchar* dst; - - if( !CV_IS_MAT(var_type) ) - CV_ERROR( var_type ? CV_StsBadArg : CV_StsNullPtr, "Invalid or absent var_type array" ); - - if( var_type->rows != 1 && var_type->cols != 1 ) - CV_ERROR( CV_StsBadSize, "var_type array must be 1-dimensional" ); - - if( !CV_IS_MASK_ARR(var_type)) - CV_ERROR( CV_StsUnsupportedFormat, "type mask must be 8uC1 or 8sC1 array" ); - - tm_size = var_type->rows + var_type->cols - 1; - tm_step = var_type->rows == 1 ? 1 : var_type->step/CV_ELEM_SIZE(var_type->type); - - if( /*tm_size != var_count &&*/ tm_size != var_count + 1 ) - CV_ERROR( CV_StsBadArg, - "type mask must be of + 1 size" ); - - if( response_type && tm_size > var_count ) - *response_type = var_type->data.ptr[var_count*tm_step] != 0; - - if( var_idx ) - { - if( !CV_IS_MAT(var_idx) || CV_MAT_TYPE(var_idx->type) != CV_32SC1 || - (var_idx->rows != 1 && var_idx->cols != 1) || !CV_IS_MAT_CONT(var_idx->type) ) - CV_ERROR( CV_StsBadArg, "var index array should be continuous 1-dimensional integer vector" ); - if( var_idx->rows + var_idx->cols - 1 > var_count ) - CV_ERROR( CV_StsBadSize, "var index array is too large" ); - //map = var_idx->data.i; - var_count = var_idx->rows + var_idx->cols - 1; - } - - CV_CALL( out_var_type = cvCreateMat( 1, var_count, CV_8UC1 )); - src = var_type->data.ptr; - dst = out_var_type->data.ptr; - - for( i = 0; i < var_count; i++ ) - { - //int idx = map ? map[i] : i; - assert( (unsigned)/*idx*/i < (unsigned)tm_size ); - dst[i] = (uchar)(src[/*idx*/i*tm_step] != 0); - } - - __END__; - - return out_var_type; -} - - -CvMat* -cvPreprocessOrderedResponses( const CvMat* responses, const CvMat* sample_idx, int sample_all ) -{ - CvMat* out_responses = 0; - - CV_FUNCNAME( "cvPreprocessOrderedResponses" ); - - __BEGIN__; - - int i, r_type, r_step; - const int* map = 0; - float* dst; - int sample_count = sample_all; - - if( !CV_IS_MAT(responses) ) - CV_ERROR( CV_StsBadArg, "Invalid response array" ); - - if( responses->rows != 1 && responses->cols != 1 ) - CV_ERROR( CV_StsBadSize, "Response array must be 1-dimensional" ); - - if( responses->rows + responses->cols - 1 != sample_count ) - CV_ERROR( CV_StsUnmatchedSizes, - "Response array must contain as many elements as the total number of samples" ); - - r_type = CV_MAT_TYPE(responses->type); - if( r_type != CV_32FC1 && r_type != CV_32SC1 ) - CV_ERROR( CV_StsUnsupportedFormat, "Unsupported response type" ); - - r_step = responses->step ? responses->step / CV_ELEM_SIZE(responses->type) : 1; - - if( r_type == CV_32FC1 && CV_IS_MAT_CONT(responses->type) && !sample_idx ) - { - out_responses = cvCloneMat( responses ); - EXIT; - } - - if( sample_idx ) - { - if( !CV_IS_MAT(sample_idx) || CV_MAT_TYPE(sample_idx->type) != CV_32SC1 || - (sample_idx->rows != 1 && sample_idx->cols != 1) || !CV_IS_MAT_CONT(sample_idx->type) ) - CV_ERROR( CV_StsBadArg, "sample index array should be continuous 1-dimensional integer vector" ); - if( sample_idx->rows + sample_idx->cols - 1 > sample_count ) - CV_ERROR( CV_StsBadSize, "sample index array is too large" ); - map = sample_idx->data.i; - sample_count = sample_idx->rows + sample_idx->cols - 1; - } - - CV_CALL( out_responses = cvCreateMat( 1, sample_count, CV_32FC1 )); - - dst = out_responses->data.fl; - if( r_type == CV_32FC1 ) - { - const float* src = responses->data.fl; - for( i = 0; i < sample_count; i++ ) - { - int idx = map ? map[i] : i; - assert( (unsigned)idx < (unsigned)sample_all ); - dst[i] = src[idx*r_step]; - } - } - else - { - const int* src = responses->data.i; - for( i = 0; i < sample_count; i++ ) - { - int idx = map ? map[i] : i; - assert( (unsigned)idx < (unsigned)sample_all ); - dst[i] = (float)src[idx*r_step]; - } - } - - __END__; - - return out_responses; -} - -CvMat* -cvPreprocessCategoricalResponses( const CvMat* responses, - const CvMat* sample_idx, int sample_all, - CvMat** out_response_map, CvMat** class_counts ) -{ - CvMat* out_responses = 0; - int** response_ptr = 0; - - CV_FUNCNAME( "cvPreprocessCategoricalResponses" ); - - if( out_response_map ) - *out_response_map = 0; - - if( class_counts ) - *class_counts = 0; - - __BEGIN__; - - int i, r_type, r_step; - int cls_count = 1, prev_cls, prev_i; - const int* map = 0; - const int* srci; - const float* srcfl; - int* dst; - int* cls_map; - int* cls_counts = 0; - int sample_count = sample_all; - - if( !CV_IS_MAT(responses) ) - CV_ERROR( CV_StsBadArg, "Invalid response array" ); - - if( responses->rows != 1 && responses->cols != 1 ) - CV_ERROR( CV_StsBadSize, "Response array must be 1-dimensional" ); - - if( responses->rows + responses->cols - 1 != sample_count ) - CV_ERROR( CV_StsUnmatchedSizes, - "Response array must contain as many elements as the total number of samples" ); - - r_type = CV_MAT_TYPE(responses->type); - if( r_type != CV_32FC1 && r_type != CV_32SC1 ) - CV_ERROR( CV_StsUnsupportedFormat, "Unsupported response type" ); - - r_step = responses->rows == 1 ? 1 : responses->step / CV_ELEM_SIZE(responses->type); - - if( sample_idx ) - { - if( !CV_IS_MAT(sample_idx) || CV_MAT_TYPE(sample_idx->type) != CV_32SC1 || - (sample_idx->rows != 1 && sample_idx->cols != 1) || !CV_IS_MAT_CONT(sample_idx->type) ) - CV_ERROR( CV_StsBadArg, "sample index array should be continuous 1-dimensional integer vector" ); - if( sample_idx->rows + sample_idx->cols - 1 > sample_count ) - CV_ERROR( CV_StsBadSize, "sample index array is too large" ); - map = sample_idx->data.i; - sample_count = sample_idx->rows + sample_idx->cols - 1; - } - - CV_CALL( out_responses = cvCreateMat( 1, sample_count, CV_32SC1 )); - - if( !out_response_map ) - CV_ERROR( CV_StsNullPtr, "out_response_map pointer is NULL" ); - - CV_CALL( response_ptr = (int**)cvAlloc( sample_count*sizeof(response_ptr[0]))); - - srci = responses->data.i; - srcfl = responses->data.fl; - dst = out_responses->data.i; - - for( i = 0; i < sample_count; i++ ) - { - int idx = map ? map[i] : i; - assert( (unsigned)idx < (unsigned)sample_all ); - if( r_type == CV_32SC1 ) - dst[i] = srci[idx*r_step]; - else - { - float rf = srcfl[idx*r_step]; - int ri = cvRound(rf); - if( ri != rf ) - { - char buf[100]; - snprintf( buf, sizeof(buf), "response #%d is not integral", idx ); - CV_ERROR( CV_StsBadArg, buf ); - } - dst[i] = ri; - } - response_ptr[i] = dst + i; - } - - qsort( response_ptr, sample_count, sizeof(int*), icvCmpIntegersPtr ); - - // count the classes - for( i = 1; i < sample_count; i++ ) - cls_count += *response_ptr[i] != *response_ptr[i-1]; - - if( cls_count < 2 ) - CV_ERROR( CV_StsBadArg, "There is only a single class" ); - - CV_CALL( *out_response_map = cvCreateMat( 1, cls_count, CV_32SC1 )); - - if( class_counts ) - { - CV_CALL( *class_counts = cvCreateMat( 1, cls_count, CV_32SC1 )); - cls_counts = (*class_counts)->data.i; - } - - // compact the class indices and build the map - prev_cls = ~*response_ptr[0]; - cls_count = -1; - cls_map = (*out_response_map)->data.i; - - for( i = 0, prev_i = -1; i < sample_count; i++ ) - { - int cur_cls = *response_ptr[i]; - if( cur_cls != prev_cls ) - { - if( cls_counts && cls_count >= 0 ) - cls_counts[cls_count] = i - prev_i; - cls_map[++cls_count] = prev_cls = cur_cls; - prev_i = i; - } - *response_ptr[i] = cls_count; - } - - if( cls_counts ) - cls_counts[cls_count] = i - prev_i; - - __END__; - - cvFree( &response_ptr ); - - return out_responses; -} - - -const float** -cvGetTrainSamples( const CvMat* train_data, int tflag, - const CvMat* var_idx, const CvMat* sample_idx, - int* _var_count, int* _sample_count, - bool always_copy_data ) -{ - float** samples = 0; - - CV_FUNCNAME( "cvGetTrainSamples" ); - - __BEGIN__; - - int i, j, var_count, sample_count, s_step, v_step; - bool copy_data; - const float* data; - const int *s_idx, *v_idx; - - if( !CV_IS_MAT(train_data) ) - CV_ERROR( CV_StsBadArg, "Invalid or NULL training data matrix" ); - - var_count = var_idx ? var_idx->cols + var_idx->rows - 1 : - tflag == CV_ROW_SAMPLE ? train_data->cols : train_data->rows; - sample_count = sample_idx ? sample_idx->cols + sample_idx->rows - 1 : - tflag == CV_ROW_SAMPLE ? train_data->rows : train_data->cols; - - if( _var_count ) - *_var_count = var_count; - - if( _sample_count ) - *_sample_count = sample_count; - - copy_data = tflag != CV_ROW_SAMPLE || var_idx || always_copy_data; - - CV_CALL( samples = (float**)cvAlloc(sample_count*sizeof(samples[0]) + - (copy_data ? 1 : 0)*var_count*sample_count*sizeof(samples[0][0])) ); - data = train_data->data.fl; - s_step = train_data->step / sizeof(samples[0][0]); - v_step = 1; - s_idx = sample_idx ? sample_idx->data.i : 0; - v_idx = var_idx ? var_idx->data.i : 0; - - if( !copy_data ) - { - for( i = 0; i < sample_count; i++ ) - samples[i] = (float*)(data + (s_idx ? s_idx[i] : i)*s_step); - } - else - { - samples[0] = (float*)(samples + sample_count); - if( tflag != CV_ROW_SAMPLE ) - CV_SWAP( s_step, v_step, i ); - - for( i = 0; i < sample_count; i++ ) - { - float* dst = samples[i] = samples[0] + i*var_count; - const float* src = data + (s_idx ? s_idx[i] : i)*s_step; - - if( !v_idx ) - for( j = 0; j < var_count; j++ ) - dst[j] = src[j*v_step]; - else - for( j = 0; j < var_count; j++ ) - dst[j] = src[v_idx[j]*v_step]; - } - } - - __END__; - - return (const float**)samples; -} - - -void -cvCheckTrainData( const CvMat* train_data, int tflag, - const CvMat* missing_mask, - int* var_all, int* sample_all ) -{ - CV_FUNCNAME( "cvCheckTrainData" ); - - if( var_all ) - *var_all = 0; - - if( sample_all ) - *sample_all = 0; - - __BEGIN__; - - // check parameter types and sizes - if( !CV_IS_MAT(train_data) || CV_MAT_TYPE(train_data->type) != CV_32FC1 ) - CV_ERROR( CV_StsBadArg, "train data must be floating-point matrix" ); - - if( missing_mask ) - { - if( !CV_IS_MAT(missing_mask) || !CV_IS_MASK_ARR(missing_mask) || - !CV_ARE_SIZES_EQ(train_data, missing_mask) ) - CV_ERROR( CV_StsBadArg, - "missing value mask must be 8-bit matrix of the same size as training data" ); - } - - if( tflag != CV_ROW_SAMPLE && tflag != CV_COL_SAMPLE ) - CV_ERROR( CV_StsBadArg, - "Unknown training data layout (must be CV_ROW_SAMPLE or CV_COL_SAMPLE)" ); - - if( var_all ) - *var_all = tflag == CV_ROW_SAMPLE ? train_data->cols : train_data->rows; - - if( sample_all ) - *sample_all = tflag == CV_ROW_SAMPLE ? train_data->rows : train_data->cols; - - __END__; -} - - -int -cvPrepareTrainData( const char* /*funcname*/, - const CvMat* train_data, int tflag, - const CvMat* responses, int response_type, - const CvMat* var_idx, - const CvMat* sample_idx, - bool always_copy_data, - const float*** out_train_samples, - int* _sample_count, - int* _var_count, - int* _var_all, - CvMat** out_responses, - CvMat** out_response_map, - CvMat** out_var_idx, - CvMat** out_sample_idx ) -{ - int ok = 0; - CvMat* _var_idx = 0; - CvMat* _sample_idx = 0; - CvMat* _responses = 0; - int sample_all = 0, sample_count = 0, var_all = 0, var_count = 0; - - CV_FUNCNAME( "cvPrepareTrainData" ); - - // step 0. clear all the output pointers to ensure we do not try - // to call free() with uninitialized pointers - if( out_responses ) - *out_responses = 0; - - if( out_response_map ) - *out_response_map = 0; - - if( out_var_idx ) - *out_var_idx = 0; - - if( out_sample_idx ) - *out_sample_idx = 0; - - if( out_train_samples ) - *out_train_samples = 0; - - if( _sample_count ) - *_sample_count = 0; - - if( _var_count ) - *_var_count = 0; - - if( _var_all ) - *_var_all = 0; - - __BEGIN__; - - if( !out_train_samples ) - CV_ERROR( CV_StsBadArg, "output pointer to train samples is NULL" ); - - CV_CALL( cvCheckTrainData( train_data, tflag, 0, &var_all, &sample_all )); - - if( sample_idx ) - CV_CALL( _sample_idx = cvPreprocessIndexArray( sample_idx, sample_all )); - if( var_idx ) - CV_CALL( _var_idx = cvPreprocessIndexArray( var_idx, var_all )); - - if( responses ) - { - if( !out_responses ) - CV_ERROR( CV_StsNullPtr, "output response pointer is NULL" ); - - if( response_type == CV_VAR_NUMERICAL ) - { - CV_CALL( _responses = cvPreprocessOrderedResponses( responses, - _sample_idx, sample_all )); - } - else - { - CV_CALL( _responses = cvPreprocessCategoricalResponses( responses, - _sample_idx, sample_all, out_response_map, 0 )); - } - } - - CV_CALL( *out_train_samples = - cvGetTrainSamples( train_data, tflag, _var_idx, _sample_idx, - &var_count, &sample_count, always_copy_data )); - - ok = 1; - - __END__; - - if( ok ) - { - if( out_responses ) - *out_responses = _responses, _responses = 0; - - if( out_var_idx ) - *out_var_idx = _var_idx, _var_idx = 0; - - if( out_sample_idx ) - *out_sample_idx = _sample_idx, _sample_idx = 0; - - if( _sample_count ) - *_sample_count = sample_count; - - if( _var_count ) - *_var_count = var_count; - - if( _var_all ) - *_var_all = var_all; - } - else - { - if( out_response_map ) - cvReleaseMat( out_response_map ); - cvFree( out_train_samples ); - } - - if( _responses != responses ) - cvReleaseMat( &_responses ); - cvReleaseMat( &_var_idx ); - cvReleaseMat( &_sample_idx ); - - return ok; -} - - -typedef struct CvSampleResponsePair -{ - const float* sample; - const uchar* mask; - int response; - int index; -} -CvSampleResponsePair; - - -static int -CV_CDECL icvCmpSampleResponsePairs( const void* a, const void* b ) -{ - int ra = ((const CvSampleResponsePair*)a)->response; - int rb = ((const CvSampleResponsePair*)b)->response; - int ia = ((const CvSampleResponsePair*)a)->index; - int ib = ((const CvSampleResponsePair*)b)->index; - - return ra < rb ? -1 : ra > rb ? 1 : ia - ib; - //return (ra > rb ? -1 : 0)|(ra < rb); -} - - -void -cvSortSamplesByClasses( const float** samples, const CvMat* classes, - int* class_ranges, const uchar** mask ) -{ - CvSampleResponsePair* pairs = 0; - CV_FUNCNAME( "cvSortSamplesByClasses" ); - - __BEGIN__; - - int i, k = 0, sample_count; - - if( !samples || !classes || !class_ranges ) - CV_ERROR( CV_StsNullPtr, "INTERNAL ERROR: some of the args are NULL pointers" ); - - if( classes->rows != 1 || CV_MAT_TYPE(classes->type) != CV_32SC1 ) - CV_ERROR( CV_StsBadArg, "classes array must be a single row of integers" ); - - sample_count = classes->cols; - CV_CALL( pairs = (CvSampleResponsePair*)cvAlloc( (sample_count+1)*sizeof(pairs[0]))); - - for( i = 0; i < sample_count; i++ ) - { - pairs[i].sample = samples[i]; - pairs[i].mask = (mask) ? (mask[i]) : 0; - pairs[i].response = classes->data.i[i]; - pairs[i].index = i; - assert( classes->data.i[i] >= 0 ); - } - - qsort( pairs, sample_count, sizeof(pairs[0]), icvCmpSampleResponsePairs ); - pairs[sample_count].response = -1; - class_ranges[0] = 0; - - for( i = 0; i < sample_count; i++ ) - { - samples[i] = pairs[i].sample; - if (mask) - mask[i] = pairs[i].mask; - classes->data.i[i] = pairs[i].response; - - if( pairs[i].response != pairs[i+1].response ) - class_ranges[++k] = i+1; - } - - __END__; - - cvFree( &pairs ); -} - - -void -cvPreparePredictData( const CvArr* _sample, int dims_all, - const CvMat* comp_idx, int class_count, - const CvMat* prob, float** _row_sample, - int as_sparse ) -{ - float* row_sample = 0; - int* inverse_comp_idx = 0; - - CV_FUNCNAME( "cvPreparePredictData" ); - - __BEGIN__; - - const CvMat* sample = (const CvMat*)_sample; - float* sample_data; - int sample_step; - int is_sparse = CV_IS_SPARSE_MAT(sample); - int d, sizes[CV_MAX_DIM]; - int i, dims_selected; - int vec_size; - - if( !is_sparse && !CV_IS_MAT(sample) ) - CV_ERROR( !sample ? CV_StsNullPtr : CV_StsBadArg, "The sample is not a valid vector" ); - - if( cvGetElemType( sample ) != CV_32FC1 ) - CV_ERROR( CV_StsUnsupportedFormat, "Input sample must have 32fC1 type" ); - - CV_CALL( d = cvGetDims( sample, sizes )); - - if( !((is_sparse && d == 1) || (!is_sparse && d == 2 && (sample->rows == 1 || sample->cols == 1))) ) - CV_ERROR( CV_StsBadSize, "Input sample must be 1-dimensional vector" ); - - if( d == 1 ) - sizes[1] = 1; - - if( sizes[0] + sizes[1] - 1 != dims_all ) - CV_ERROR( CV_StsUnmatchedSizes, - "The sample size is different from what has been used for training" ); - - if( !_row_sample ) - CV_ERROR( CV_StsNullPtr, "INTERNAL ERROR: The row_sample pointer is NULL" ); - - if( comp_idx && (!CV_IS_MAT(comp_idx) || comp_idx->rows != 1 || - CV_MAT_TYPE(comp_idx->type) != CV_32SC1) ) - CV_ERROR( CV_StsBadArg, "INTERNAL ERROR: invalid comp_idx" ); - - dims_selected = comp_idx ? comp_idx->cols : dims_all; - - if( prob ) - { - if( !CV_IS_MAT(prob) ) - CV_ERROR( CV_StsBadArg, "The output matrix of probabilities is invalid" ); - - if( (prob->rows != 1 && prob->cols != 1) || - (CV_MAT_TYPE(prob->type) != CV_32FC1 && - CV_MAT_TYPE(prob->type) != CV_64FC1) ) - CV_ERROR( CV_StsBadSize, - "The matrix of probabilities must be 1-dimensional vector of 32fC1 type" ); - - if( prob->rows + prob->cols - 1 != class_count ) - CV_ERROR( CV_StsUnmatchedSizes, - "The vector of probabilities must contain as many elements as " - "the number of classes in the training set" ); - } - - vec_size = !as_sparse ? dims_selected*sizeof(row_sample[0]) : - (dims_selected + 1)*sizeof(CvSparseVecElem32f); - - if( CV_IS_MAT(sample) ) - { - sample_data = sample->data.fl; - sample_step = CV_IS_MAT_CONT(sample->type) ? 1 : sample->step/sizeof(row_sample[0]); - - if( !comp_idx && CV_IS_MAT_CONT(sample->type) && !as_sparse ) - *_row_sample = sample_data; - else - { - CV_CALL( row_sample = (float*)cvAlloc( vec_size )); - - if( !comp_idx ) - for( i = 0; i < dims_selected; i++ ) - row_sample[i] = sample_data[sample_step*i]; - else - { - int* comp = comp_idx->data.i; - for( i = 0; i < dims_selected; i++ ) - row_sample[i] = sample_data[sample_step*comp[i]]; - } - - *_row_sample = row_sample; - } - - if( as_sparse ) - { - const float* src = (const float*)row_sample; - CvSparseVecElem32f* dst = (CvSparseVecElem32f*)row_sample; - - dst[dims_selected].idx = -1; - for( i = dims_selected - 1; i >= 0; i-- ) - { - dst[i].idx = i; - dst[i].val = src[i]; - } - } - } - else - { - CvSparseNode* node; - CvSparseMatIterator mat_iterator; - const CvSparseMat* sparse = (const CvSparseMat*)sample; - assert( is_sparse ); - - node = cvInitSparseMatIterator( sparse, &mat_iterator ); - CV_CALL( row_sample = (float*)cvAlloc( vec_size )); - - if( comp_idx ) - { - CV_CALL( inverse_comp_idx = (int*)cvAlloc( dims_all*sizeof(int) )); - memset( inverse_comp_idx, -1, dims_all*sizeof(int) ); - for( i = 0; i < dims_selected; i++ ) - inverse_comp_idx[comp_idx->data.i[i]] = i; - } - - if( !as_sparse ) - { - memset( row_sample, 0, vec_size ); - - for( ; node != 0; node = cvGetNextSparseNode(&mat_iterator) ) - { - int idx = *CV_NODE_IDX( sparse, node ); - if( inverse_comp_idx ) - { - idx = inverse_comp_idx[idx]; - if( idx < 0 ) - continue; - } - row_sample[idx] = *(float*)CV_NODE_VAL( sparse, node ); - } - } - else - { - CvSparseVecElem32f* ptr = (CvSparseVecElem32f*)row_sample; - - for( ; node != 0; node = cvGetNextSparseNode(&mat_iterator) ) - { - int idx = *CV_NODE_IDX( sparse, node ); - if( inverse_comp_idx ) - { - idx = inverse_comp_idx[idx]; - if( idx < 0 ) - continue; - } - ptr->idx = idx; - ptr->val = *(float*)CV_NODE_VAL( sparse, node ); - ptr++; - } - - qsort( row_sample, ptr - (CvSparseVecElem32f*)row_sample, - sizeof(ptr[0]), icvCmpSparseVecElems ); - ptr->idx = -1; - } - - *_row_sample = row_sample; - } - - __END__; - - if( inverse_comp_idx ) - cvFree( &inverse_comp_idx ); - - if( cvGetErrStatus() < 0 && _row_sample ) - { - cvFree( &row_sample ); - *_row_sample = 0; - } -} - - -static void -icvConvertDataToSparse( const uchar* src, int src_step, int src_type, - uchar* dst, int dst_step, int dst_type, - CvSize size, int* idx ) -{ - CV_FUNCNAME( "icvConvertDataToSparse" ); - - __BEGIN__; - - int i, j; - src_type = CV_MAT_TYPE(src_type); - dst_type = CV_MAT_TYPE(dst_type); - - if( CV_MAT_CN(src_type) != 1 || CV_MAT_CN(dst_type) != 1 ) - CV_ERROR( CV_StsUnsupportedFormat, "The function supports only single-channel arrays" ); - - if( src_step == 0 ) - src_step = CV_ELEM_SIZE(src_type); - - if( dst_step == 0 ) - dst_step = CV_ELEM_SIZE(dst_type); - - // if there is no "idx" and if both arrays are continuous, - // do the whole processing (copying or conversion) in a single loop - if( !idx && CV_ELEM_SIZE(src_type)*size.width == src_step && - CV_ELEM_SIZE(dst_type)*size.width == dst_step ) - { - size.width *= size.height; - size.height = 1; - } - - if( src_type == dst_type ) - { - int full_width = CV_ELEM_SIZE(dst_type)*size.width; - - if( full_width == sizeof(int) ) // another common case: copy int's or float's - for( i = 0; i < size.height; i++, src += src_step ) - *(int*)(dst + dst_step*(idx ? idx[i] : i)) = *(int*)src; - else - for( i = 0; i < size.height; i++, src += src_step ) - memcpy( dst + dst_step*(idx ? idx[i] : i), src, full_width ); - } - else if( src_type == CV_32SC1 && (dst_type == CV_32FC1 || dst_type == CV_64FC1) ) - for( i = 0; i < size.height; i++, src += src_step ) - { - uchar* _dst = dst + dst_step*(idx ? idx[i] : i); - if( dst_type == CV_32FC1 ) - for( j = 0; j < size.width; j++ ) - ((float*)_dst)[j] = (float)((int*)src)[j]; - else - for( j = 0; j < size.width; j++ ) - ((double*)_dst)[j] = ((int*)src)[j]; - } - else if( (src_type == CV_32FC1 || src_type == CV_64FC1) && dst_type == CV_32SC1 ) - for( i = 0; i < size.height; i++, src += src_step ) - { - uchar* _dst = dst + dst_step*(idx ? idx[i] : i); - if( src_type == CV_32FC1 ) - for( j = 0; j < size.width; j++ ) - ((int*)_dst)[j] = cvRound(((float*)src)[j]); - else - for( j = 0; j < size.width; j++ ) - ((int*)_dst)[j] = cvRound(((double*)src)[j]); - } - else if( (src_type == CV_32FC1 && dst_type == CV_64FC1) || - (src_type == CV_64FC1 && dst_type == CV_32FC1) ) - for( i = 0; i < size.height; i++, src += src_step ) - { - uchar* _dst = dst + dst_step*(idx ? idx[i] : i); - if( src_type == CV_32FC1 ) - for( j = 0; j < size.width; j++ ) - ((double*)_dst)[j] = ((float*)src)[j]; - else - for( j = 0; j < size.width; j++ ) - ((float*)_dst)[j] = (float)((double*)src)[j]; - } - else - CV_ERROR( CV_StsUnsupportedFormat, "Unsupported combination of input and output vectors" ); - - __END__; -} - - -void -cvWritebackLabels( const CvMat* labels, CvMat* dst_labels, - const CvMat* centers, CvMat* dst_centers, - const CvMat* probs, CvMat* dst_probs, - const CvMat* sample_idx, int samples_all, - const CvMat* comp_idx, int dims_all ) -{ - CV_FUNCNAME( "cvWritebackLabels" ); - - __BEGIN__; - - int samples_selected = samples_all, dims_selected = dims_all; - - if( dst_labels && !CV_IS_MAT(dst_labels) ) - CV_ERROR( CV_StsBadArg, "Array of output labels is not a valid matrix" ); - - if( dst_centers ) - if( !ICV_IS_MAT_OF_TYPE(dst_centers, CV_32FC1) && - !ICV_IS_MAT_OF_TYPE(dst_centers, CV_64FC1) ) - CV_ERROR( CV_StsBadArg, "Array of cluster centers is not a valid matrix" ); - - if( dst_probs && !CV_IS_MAT(dst_probs) ) - CV_ERROR( CV_StsBadArg, "Probability matrix is not valid" ); - - if( sample_idx ) - { - CV_ASSERT( sample_idx->rows == 1 && CV_MAT_TYPE(sample_idx->type) == CV_32SC1 ); - samples_selected = sample_idx->cols; - } - - if( comp_idx ) - { - CV_ASSERT( comp_idx->rows == 1 && CV_MAT_TYPE(comp_idx->type) == CV_32SC1 ); - dims_selected = comp_idx->cols; - } - - if( dst_labels && (!labels || labels->data.ptr != dst_labels->data.ptr) ) - { - if( !labels ) - CV_ERROR( CV_StsNullPtr, "NULL labels" ); - - CV_ASSERT( labels->rows == 1 ); - - if( dst_labels->rows != 1 && dst_labels->cols != 1 ) - CV_ERROR( CV_StsBadSize, "Array of output labels should be 1d vector" ); - - if( dst_labels->rows + dst_labels->cols - 1 != samples_all ) - CV_ERROR( CV_StsUnmatchedSizes, - "Size of vector of output labels is not equal to the total number of input samples" ); - - CV_ASSERT( labels->cols == samples_selected ); - - CV_CALL( icvConvertDataToSparse( labels->data.ptr, labels->step, labels->type, - dst_labels->data.ptr, dst_labels->step, dst_labels->type, - cvSize( 1, samples_selected ), sample_idx ? sample_idx->data.i : 0 )); - } - - if( dst_centers && (!centers || centers->data.ptr != dst_centers->data.ptr) ) - { - int i; - - if( !centers ) - CV_ERROR( CV_StsNullPtr, "NULL centers" ); - - if( centers->rows != dst_centers->rows ) - CV_ERROR( CV_StsUnmatchedSizes, "Invalid number of rows in matrix of output centers" ); - - if( dst_centers->cols != dims_all ) - CV_ERROR( CV_StsUnmatchedSizes, - "Number of columns in matrix of output centers is " - "not equal to the total number of components in the input samples" ); - - CV_ASSERT( centers->cols == dims_selected ); - - for( i = 0; i < centers->rows; i++ ) - CV_CALL( icvConvertDataToSparse( centers->data.ptr + i*centers->step, 0, centers->type, - dst_centers->data.ptr + i*dst_centers->step, 0, dst_centers->type, - cvSize( 1, dims_selected ), comp_idx ? comp_idx->data.i : 0 )); - } - - if( dst_probs && (!probs || probs->data.ptr != dst_probs->data.ptr) ) - { - if( !probs ) - CV_ERROR( CV_StsNullPtr, "NULL probs" ); - - if( probs->cols != dst_probs->cols ) - CV_ERROR( CV_StsUnmatchedSizes, "Invalid number of columns in output probability matrix" ); - - if( dst_probs->rows != samples_all ) - CV_ERROR( CV_StsUnmatchedSizes, - "Number of rows in output probability matrix is " - "not equal to the total number of input samples" ); - - CV_ASSERT( probs->rows == samples_selected ); - - CV_CALL( icvConvertDataToSparse( probs->data.ptr, probs->step, probs->type, - dst_probs->data.ptr, dst_probs->step, dst_probs->type, - cvSize( probs->cols, samples_selected ), - sample_idx ? sample_idx->data.i : 0 )); - } - - __END__; -} - -#if 0 -CV_IMPL void -cvStatModelMultiPredict( const CvStatModel* stat_model, - const CvArr* predict_input, - int flags, CvMat* predict_output, - CvMat* probs, const CvMat* sample_idx ) -{ - CvMemStorage* storage = 0; - CvMat* sample_idx_buffer = 0; - CvSparseMat** sparse_rows = 0; - int samples_selected = 0; - - CV_FUNCNAME( "cvStatModelMultiPredict" ); - - __BEGIN__; - - int i; - int predict_output_step = 1, sample_idx_step = 1; - int type; - int d, sizes[CV_MAX_DIM]; - int tflag = flags == CV_COL_SAMPLE; - int samples_all, dims_all; - int is_sparse = CV_IS_SPARSE_MAT(predict_input); - CvMat predict_input_part; - CvArr* sample = &predict_input_part; - CvMat probs_part; - CvMat* probs1 = probs ? &probs_part : 0; - - if( !CV_IS_STAT_MODEL(stat_model) ) - CV_ERROR( !stat_model ? CV_StsNullPtr : CV_StsBadArg, "Invalid statistical model" ); - - if( !stat_model->predict ) - CV_ERROR( CV_StsNotImplemented, "There is no \"predict\" method" ); - - if( !predict_input || !predict_output ) - CV_ERROR( CV_StsNullPtr, "NULL input or output matrices" ); - - if( !is_sparse && !CV_IS_MAT(predict_input) ) - CV_ERROR( CV_StsBadArg, "predict_input should be a matrix or a sparse matrix" ); - - if( !CV_IS_MAT(predict_output) ) - CV_ERROR( CV_StsBadArg, "predict_output should be a matrix" ); - - type = cvGetElemType( predict_input ); - if( type != CV_32FC1 || - (CV_MAT_TYPE(predict_output->type) != CV_32FC1 && - CV_MAT_TYPE(predict_output->type) != CV_32SC1 )) - CV_ERROR( CV_StsUnsupportedFormat, "The input or output matrix has unsupported format" ); - - CV_CALL( d = cvGetDims( predict_input, sizes )); - if( d > 2 ) - CV_ERROR( CV_StsBadSize, "The input matrix should be 1- or 2-dimensional" ); - - if( !tflag ) - { - samples_all = samples_selected = sizes[0]; - dims_all = sizes[1]; - } - else - { - samples_all = samples_selected = sizes[1]; - dims_all = sizes[0]; - } - - if( sample_idx ) - { - if( !CV_IS_MAT(sample_idx) ) - CV_ERROR( CV_StsBadArg, "Invalid sample_idx matrix" ); - - if( sample_idx->cols != 1 && sample_idx->rows != 1 ) - CV_ERROR( CV_StsBadSize, "sample_idx must be 1-dimensional matrix" ); - - samples_selected = sample_idx->rows + sample_idx->cols - 1; - - if( CV_MAT_TYPE(sample_idx->type) == CV_32SC1 ) - { - if( samples_selected > samples_all ) - CV_ERROR( CV_StsBadSize, "sample_idx is too large vector" ); - } - else if( samples_selected != samples_all ) - CV_ERROR( CV_StsUnmatchedSizes, "sample_idx has incorrect size" ); - - sample_idx_step = sample_idx->step ? - sample_idx->step / CV_ELEM_SIZE(sample_idx->type) : 1; - } - - if( predict_output->rows != 1 && predict_output->cols != 1 ) - CV_ERROR( CV_StsBadSize, "predict_output should be a 1-dimensional matrix" ); - - if( predict_output->rows + predict_output->cols - 1 != samples_all ) - CV_ERROR( CV_StsUnmatchedSizes, "predict_output and predict_input have uncoordinated sizes" ); - - predict_output_step = predict_output->step ? - predict_output->step / CV_ELEM_SIZE(predict_output->type) : 1; - - if( probs ) - { - if( !CV_IS_MAT(probs) ) - CV_ERROR( CV_StsBadArg, "Invalid matrix of probabilities" ); - - if( probs->rows != samples_all ) - CV_ERROR( CV_StsUnmatchedSizes, - "matrix of probabilities must have as many rows as the total number of samples" ); - - if( CV_MAT_TYPE(probs->type) != CV_32FC1 ) - CV_ERROR( CV_StsUnsupportedFormat, "matrix of probabilities must have 32fC1 type" ); - } - - if( is_sparse ) - { - CvSparseNode* node; - CvSparseMatIterator mat_iterator; - CvSparseMat* sparse = (CvSparseMat*)predict_input; - - if( sample_idx && CV_MAT_TYPE(sample_idx->type) == CV_32SC1 ) - { - CV_CALL( sample_idx_buffer = cvCreateMat( 1, samples_all, CV_8UC1 )); - cvZero( sample_idx_buffer ); - for( i = 0; i < samples_selected; i++ ) - sample_idx_buffer->data.ptr[sample_idx->data.i[i*sample_idx_step]] = 1; - samples_selected = samples_all; - sample_idx = sample_idx_buffer; - sample_idx_step = 1; - } - - CV_CALL( sparse_rows = (CvSparseMat**)cvAlloc( samples_selected*sizeof(sparse_rows[0]))); - for( i = 0; i < samples_selected; i++ ) - { - if( sample_idx && sample_idx->data.ptr[i*sample_idx_step] == 0 ) - continue; - CV_CALL( sparse_rows[i] = cvCreateSparseMat( 1, &dims_all, type )); - if( !storage ) - storage = sparse_rows[i]->heap->storage; - else - { - // hack: to decrease memory footprint, make all the sparse matrices - // reside in the same storage - int elem_size = sparse_rows[i]->heap->elem_size; - cvReleaseMemStorage( &sparse_rows[i]->heap->storage ); - sparse_rows[i]->heap = cvCreateSet( 0, sizeof(CvSet), elem_size, storage ); - } - } - - // put each row (or column) of predict_input into separate sparse matrix. - node = cvInitSparseMatIterator( sparse, &mat_iterator ); - for( ; node != 0; node = cvGetNextSparseNode( &mat_iterator )) - { - int* idx = CV_NODE_IDX( sparse, node ); - int idx0 = idx[tflag ^ 1]; - int idx1 = idx[tflag]; - - if( sample_idx && sample_idx->data.ptr[idx0*sample_idx_step] == 0 ) - continue; - - assert( sparse_rows[idx0] != 0 ); - *(float*)cvPtrND( sparse, &idx1, 0, 1, 0 ) = *(float*)CV_NODE_VAL( sparse, node ); - } - } - - for( i = 0; i < samples_selected; i++ ) - { - int idx = i; - float response; - - if( sample_idx ) - { - if( CV_MAT_TYPE(sample_idx->type) == CV_32SC1 ) - { - idx = sample_idx->data.i[i*sample_idx_step]; - if( (unsigned)idx >= (unsigned)samples_all ) - CV_ERROR( CV_StsOutOfRange, "Some of sample_idx elements are out of range" ); - } - else if( CV_MAT_TYPE(sample_idx->type) == CV_8UC1 && - sample_idx->data.ptr[i*sample_idx_step] == 0 ) - continue; - } - - if( !is_sparse ) - { - if( !tflag ) - cvGetRow( predict_input, &predict_input_part, idx ); - else - { - cvGetCol( predict_input, &predict_input_part, idx ); - } - } - else - sample = sparse_rows[idx]; - - if( probs ) - cvGetRow( probs, probs1, idx ); - - CV_CALL( response = stat_model->predict( stat_model, (CvMat*)sample, probs1 )); - - if( CV_MAT_TYPE(predict_output->type) == CV_32FC1 ) - predict_output->data.fl[idx*predict_output_step] = response; - else - { - CV_ASSERT( cvRound(response) == response ); - predict_output->data.i[idx*predict_output_step] = cvRound(response); - } - } - - __END__; - - if( sparse_rows ) - { - int i; - for( i = 0; i < samples_selected; i++ ) - if( sparse_rows[i] ) - { - sparse_rows[i]->heap->storage = 0; - cvReleaseSparseMat( &sparse_rows[i] ); - } - cvFree( &sparse_rows ); - } - - cvReleaseMat( &sample_idx_buffer ); - cvReleaseMemStorage( &storage ); -} -#endif - -// By P. Yarykin - begin - - -void cvCombineResponseMaps (CvMat* _responses, - const CvMat* old_response_map, - CvMat* new_response_map, - CvMat** out_response_map) -{ - int** old_data = NULL; - int** new_data = NULL; - - CV_FUNCNAME ("cvCombineResponseMaps"); - __BEGIN__ - - int i,j; - int old_n, new_n, out_n; - int samples, free_response; - int* first; - int* responses; - int* out_data; - - if( out_response_map ) - *out_response_map = 0; - -// Check input data. - if ((!ICV_IS_MAT_OF_TYPE (_responses, CV_32SC1)) || - (!ICV_IS_MAT_OF_TYPE (old_response_map, CV_32SC1)) || - (!ICV_IS_MAT_OF_TYPE (new_response_map, CV_32SC1))) - { - CV_ERROR (CV_StsBadArg, "Some of input arguments is not the CvMat") - } - -// Prepare sorted responses. - first = new_response_map->data.i; - new_n = new_response_map->cols; - CV_CALL (new_data = (int**)cvAlloc (new_n * sizeof (new_data[0]))); - for (i = 0; i < new_n; i++) - new_data[i] = first + i; - qsort (new_data, new_n, sizeof(int*), icvCmpIntegersPtr); - - first = old_response_map->data.i; - old_n = old_response_map->cols; - CV_CALL (old_data = (int**)cvAlloc (old_n * sizeof (old_data[0]))); - for (i = 0; i < old_n; i++) - old_data[i] = first + i; - qsort (old_data, old_n, sizeof(int*), icvCmpIntegersPtr); - -// Count the number of different responses. - for (i = 0, j = 0, out_n = 0; i < old_n && j < new_n; out_n++) - { - if (*old_data[i] == *new_data[j]) - { - i++; - j++; - } - else if (*old_data[i] < *new_data[j]) - i++; - else - j++; - } - out_n += old_n - i + new_n - j; - -// Create and fill the result response maps. - CV_CALL (*out_response_map = cvCreateMat (1, out_n, CV_32SC1)); - out_data = (*out_response_map)->data.i; - memcpy (out_data, first, old_n * sizeof (int)); - - free_response = old_n; - for (i = 0, j = 0; i < old_n && j < new_n; ) - { - if (*old_data[i] == *new_data[j]) - { - *new_data[j] = (int)(old_data[i] - first); - i++; - j++; - } - else if (*old_data[i] < *new_data[j]) - i++; - else - { - out_data[free_response] = *new_data[j]; - *new_data[j] = free_response++; - j++; - } - } - for (; j < new_n; j++) - { - out_data[free_response] = *new_data[j]; - *new_data[j] = free_response++; - } - CV_ASSERT (free_response == out_n); - -// Change according to out response map. - samples = _responses->cols + _responses->rows - 1; - responses = _responses->data.i; - first = new_response_map->data.i; - for (i = 0; i < samples; i++) - { - responses[i] = first[responses[i]]; - } - - __END__ - - cvFree(&old_data); - cvFree(&new_data); - -} - - -static int icvGetNumberOfCluster( double* prob_vector, int num_of_clusters, float r, - float outlier_thresh, int normalize_probs ) -{ - int max_prob_loc = 0; - - CV_FUNCNAME("icvGetNumberOfCluster"); - __BEGIN__; - - double prob, maxprob, sum; - int i; - - CV_ASSERT(prob_vector); - CV_ASSERT(num_of_clusters >= 0); - - maxprob = prob_vector[0]; - max_prob_loc = 0; - sum = maxprob; - for( i = 1; i < num_of_clusters; i++ ) - { - prob = prob_vector[i]; - sum += prob; - if( prob > maxprob ) - { - max_prob_loc = i; - maxprob = prob; - } - } - if( normalize_probs && fabs(sum - 1.) > FLT_EPSILON ) - { - for( i = 0; i < num_of_clusters; i++ ) - prob_vector[i] /= sum; - } - if( fabs(r - 1.) > FLT_EPSILON && fabs(sum - 1.) < outlier_thresh ) - max_prob_loc = -1; - - __END__; - - return max_prob_loc; - -} // End of icvGetNumberOfCluster - - -void icvFindClusterLabels( const CvMat* probs, float outlier_thresh, float r, - const CvMat* labels ) -{ - CvMat* counts = 0; - - CV_FUNCNAME("icvFindClusterLabels"); - __BEGIN__; - - int nclusters, nsamples; - int i, j; - double* probs_data; - - CV_ASSERT( ICV_IS_MAT_OF_TYPE(probs, CV_64FC1) ); - CV_ASSERT( ICV_IS_MAT_OF_TYPE(labels, CV_32SC1) ); - - nclusters = probs->cols; - nsamples = probs->rows; - CV_ASSERT( nsamples == labels->cols ); - - CV_CALL( counts = cvCreateMat( 1, nclusters + 1, CV_32SC1 ) ); - CV_CALL( cvSetZero( counts )); - for( i = 0; i < nsamples; i++ ) - { - labels->data.i[i] = icvGetNumberOfCluster( probs->data.db + i*probs->cols, - nclusters, r, outlier_thresh, 1 ); - counts->data.i[labels->data.i[i] + 1]++; - } - CV_ASSERT((int)cvSum(counts).val[0] == nsamples); - // Filling empty clusters with the vector, that has the maximal probability - for( j = 0; j < nclusters; j++ ) // outliers are ignored - { - int maxprob_loc = -1; - double maxprob = 0; - - if( counts->data.i[j+1] ) // j-th class is not empty - continue; - // look for the presentative, which is not lonely in it's cluster - // and that has a maximal probability among all these vectors - probs_data = probs->data.db; - for( i = 0; i < nsamples; i++, probs_data++ ) - { - int label = labels->data.i[i]; - double prob; - if( counts->data.i[label+1] == 0 || - (counts->data.i[label+1] <= 1 && label != -1) ) - continue; - prob = *probs_data; - if( prob >= maxprob ) - { - maxprob = prob; - maxprob_loc = i; - } - } - // maxprob_loc == 0 <=> number of vectors less then number of clusters - CV_ASSERT( maxprob_loc >= 0 ); - counts->data.i[labels->data.i[maxprob_loc] + 1]--; - labels->data.i[maxprob_loc] = j; - counts->data.i[j + 1]++; - } - - __END__; - - cvReleaseMat( &counts ); -} // End of icvFindClusterLabels - -/* End of file */ diff --git a/apps/traincascade/old_ml_precomp.hpp b/apps/traincascade/old_ml_precomp.hpp deleted file mode 100644 index 6702e5b59f..0000000000 --- a/apps/traincascade/old_ml_precomp.hpp +++ /dev/null @@ -1,376 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// Intel License Agreement -// -// 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*/ - -#ifndef OPENCV_PRECOMP_H -#define OPENCV_PRECOMP_H - -#include "opencv2/core.hpp" -#include "old_ml.hpp" -#include "opencv2/core/core_c.h" -#include "opencv2/core/utility.hpp" - -#include "opencv2/core/private.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include - -#define ML_IMPL CV_IMPL -#define __BEGIN__ __CV_BEGIN__ -#define __END__ __CV_END__ -#define EXIT __CV_EXIT__ - -#define CV_MAT_ELEM_FLAG( mat, type, comp, vect, tflag ) \ - (( tflag == CV_ROW_SAMPLE ) \ - ? (CV_MAT_ELEM( mat, type, comp, vect )) \ - : (CV_MAT_ELEM( mat, type, vect, comp ))) - -/* Convert matrix to vector */ -#define ICV_MAT2VEC( mat, vdata, vstep, num ) \ - if( MIN( (mat).rows, (mat).cols ) != 1 ) \ - CV_ERROR( CV_StsBadArg, "" ); \ - (vdata) = ((mat).data.ptr); \ - if( (mat).rows == 1 ) \ - { \ - (vstep) = CV_ELEM_SIZE( (mat).type ); \ - (num) = (mat).cols; \ - } \ - else \ - { \ - (vstep) = (mat).step; \ - (num) = (mat).rows; \ - } - -/* get raw data */ -#define ICV_RAWDATA( mat, flags, rdata, sstep, cstep, m, n ) \ - (rdata) = (mat).data.ptr; \ - if( CV_IS_ROW_SAMPLE( flags ) ) \ - { \ - (sstep) = (mat).step; \ - (cstep) = CV_ELEM_SIZE( (mat).type ); \ - (m) = (mat).rows; \ - (n) = (mat).cols; \ - } \ - else \ - { \ - (cstep) = (mat).step; \ - (sstep) = CV_ELEM_SIZE( (mat).type ); \ - (n) = (mat).rows; \ - (m) = (mat).cols; \ - } - -#define ICV_IS_MAT_OF_TYPE( mat, mat_type) \ - (CV_IS_MAT( mat ) && CV_MAT_TYPE( mat->type ) == (mat_type) && \ - (mat)->cols > 0 && (mat)->rows > 0) - -/* - uchar* data; int sstep, cstep; - trainData->data - uchar* classes; int clstep; int ncl;- trainClasses - uchar* tmask; int tmstep; int ntm; - typeMask - uchar* missed;int msstep, mcstep; -missedMeasurements... - int mm, mn; == m,n == size,dim - uchar* sidx;int sistep; - sampleIdx - uchar* cidx;int cistep; - compIdx - int k, l; == n,m == dim,size (length of cidx, sidx) - int m, n; == size,dim -*/ -#define ICV_DECLARE_TRAIN_ARGS() \ - uchar* data; \ - int sstep, cstep; \ - uchar* classes; \ - int clstep; \ - int ncl; \ - uchar* tmask; \ - int tmstep; \ - int ntm; \ - uchar* missed; \ - int msstep, mcstep; \ - int mm, mn; \ - uchar* sidx; \ - int sistep; \ - uchar* cidx; \ - int cistep; \ - int k, l; \ - int m, n; \ - \ - data = classes = tmask = missed = sidx = cidx = NULL; \ - sstep = cstep = clstep = ncl = tmstep = ntm = msstep = mcstep = mm = mn = 0; \ - sistep = cistep = k = l = m = n = 0; - -#define ICV_TRAIN_DATA_REQUIRED( param, flags ) \ - if( !ICV_IS_MAT_OF_TYPE( (param), CV_32FC1 ) ) \ - { \ - CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \ - } \ - else \ - { \ - ICV_RAWDATA( *(param), (flags), data, sstep, cstep, m, n ); \ - k = n; \ - l = m; \ - } - -#define ICV_TRAIN_CLASSES_REQUIRED( param ) \ - if( !ICV_IS_MAT_OF_TYPE( (param), CV_32FC1 ) ) \ - { \ - CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \ - } \ - else \ - { \ - ICV_MAT2VEC( *(param), classes, clstep, ncl ); \ - if( m != ncl ) \ - { \ - CV_ERROR( CV_StsBadArg, "Unmatched sizes" ); \ - } \ - } - -#define ICV_ARG_NULL( param ) \ - if( (param) != NULL ) \ - { \ - CV_ERROR( CV_StsBadArg, #param " parameter must be NULL" ); \ - } - -#define ICV_MISSED_MEASUREMENTS_OPTIONAL( param, flags ) \ - if( param ) \ - { \ - if( !ICV_IS_MAT_OF_TYPE( param, CV_8UC1 ) ) \ - { \ - CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \ - } \ - else \ - { \ - ICV_RAWDATA( *(param), (flags), missed, msstep, mcstep, mm, mn ); \ - if( mm != m || mn != n ) \ - { \ - CV_ERROR( CV_StsBadArg, "Unmatched sizes" ); \ - } \ - } \ - } - -#define ICV_COMP_IDX_OPTIONAL( param ) \ - if( param ) \ - { \ - if( !ICV_IS_MAT_OF_TYPE( param, CV_32SC1 ) ) \ - { \ - CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \ - } \ - else \ - { \ - ICV_MAT2VEC( *(param), cidx, cistep, k ); \ - if( k > n ) \ - CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \ - } \ - } - -#define ICV_SAMPLE_IDX_OPTIONAL( param ) \ - if( param ) \ - { \ - if( !ICV_IS_MAT_OF_TYPE( param, CV_32SC1 ) ) \ - { \ - CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \ - } \ - else \ - { \ - ICV_MAT2VEC( *sampleIdx, sidx, sistep, l ); \ - if( l > m ) \ - CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \ - } \ - } - -/****************************************************************************************/ -#define ICV_CONVERT_FLOAT_ARRAY_TO_MATRICE( array, matrice ) \ -{ \ - CvMat a, b; \ - int dims = (matrice)->cols; \ - int nsamples = (matrice)->rows; \ - int type = CV_MAT_TYPE((matrice)->type); \ - int i, offset = dims; \ - \ - CV_ASSERT( type == CV_32FC1 || type == CV_64FC1 ); \ - offset *= ((type == CV_32FC1) ? sizeof(float) : sizeof(double));\ - \ - b = cvMat( 1, dims, CV_32FC1 ); \ - cvGetRow( matrice, &a, 0 ); \ - for( i = 0; i < nsamples; i++, a.data.ptr += offset ) \ - { \ - b.data.fl = (float*)array[i]; \ - CV_CALL( cvConvert( &b, &a ) ); \ - } \ -} - -/****************************************************************************************\ -* Auxiliary functions declarations * -\****************************************************************************************/ - -/* Generates a set of classes centers in quantity that are generated as - uniform random vectors in parallelepiped, where is concentrated. Vectors in - should have horizontal orientation. If != NULL, the function doesn't - allocate any memory and stores generated centers in , returns . - If == NULL, the function allocates memory and creates the matrice. Centers - are supposed to be oriented horizontally. */ -CvMat* icvGenerateRandomClusterCenters( int seed, - const CvMat* data, - int num_of_clusters, - CvMat* centers CV_DEFAULT(0)); - -/* Fills the using by choosing the maximal probability. Outliers are - fixed by and have cluster label (-1). Function also controls that there - weren't "empty" clusters by filling empty clusters with the maximal probability vector. - If probs_sums != NULL, fills it with the sums of probabilities for each sample (it is - useful for normalizing probabilities' matrice of FCM) */ -void icvFindClusterLabels( const CvMat* probs, float outlier_thresh, float r, - const CvMat* labels ); - -typedef struct CvSparseVecElem32f -{ - int idx; - float val; -} -CvSparseVecElem32f; - -/* Prepare training data and related parameters */ -#define CV_TRAIN_STATMODEL_DEFRAGMENT_TRAIN_DATA 1 -#define CV_TRAIN_STATMODEL_SAMPLES_AS_ROWS 2 -#define CV_TRAIN_STATMODEL_SAMPLES_AS_COLUMNS 4 -#define CV_TRAIN_STATMODEL_CATEGORICAL_RESPONSE 8 -#define CV_TRAIN_STATMODEL_ORDERED_RESPONSE 16 -#define CV_TRAIN_STATMODEL_RESPONSES_ON_OUTPUT 32 -#define CV_TRAIN_STATMODEL_ALWAYS_COPY_TRAIN_DATA 64 -#define CV_TRAIN_STATMODEL_SPARSE_AS_SPARSE 128 - -int -cvPrepareTrainData( const char* /*funcname*/, - const CvMat* train_data, int tflag, - const CvMat* responses, int response_type, - const CvMat* var_idx, - const CvMat* sample_idx, - bool always_copy_data, - const float*** out_train_samples, - int* _sample_count, - int* _var_count, - int* _var_all, - CvMat** out_responses, - CvMat** out_response_map, - CvMat** out_var_idx, - CvMat** out_sample_idx=0 ); - -void -cvSortSamplesByClasses( const float** samples, const CvMat* classes, - int* class_ranges, const uchar** mask CV_DEFAULT(0) ); - -void -cvCombineResponseMaps (CvMat* _responses, - const CvMat* old_response_map, - CvMat* new_response_map, - CvMat** out_response_map); - -void -cvPreparePredictData( const CvArr* sample, int dims_all, const CvMat* comp_idx, - int class_count, const CvMat* prob, float** row_sample, - int as_sparse CV_DEFAULT(0) ); - -/* copies clustering [or batch "predict"] results - (labels and/or centers and/or probs) back to the output arrays */ -void -cvWritebackLabels( const CvMat* labels, CvMat* dst_labels, - const CvMat* centers, CvMat* dst_centers, - const CvMat* probs, CvMat* dst_probs, - const CvMat* sample_idx, int samples_all, - const CvMat* comp_idx, int dims_all ); -#define cvWritebackResponses cvWritebackLabels - -#define XML_FIELD_NAME "_name" -cv::FileNode icvFileNodeGetChild( cv::FileNode& father, const char* name ); -cv::FileNode icvFileNodeGetChildArrayElem( cv::FileNode& father, const char* name,int index ); -cv::FileNode icvFileNodeGetNext( cv::FileNode& n, const char* name ); - - -void cvCheckTrainData( const CvMat* train_data, int tflag, - const CvMat* missing_mask, - int* var_all, int* sample_all ); - -CvMat* cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, bool check_for_duplicates=false ); - -CvMat* cvPreprocessVarType( const CvMat* type_mask, const CvMat* var_idx, - int var_all, int* response_type ); - -CvMat* cvPreprocessOrderedResponses( const CvMat* responses, - const CvMat* sample_idx, int sample_all ); - -CvMat* cvPreprocessCategoricalResponses( const CvMat* responses, - const CvMat* sample_idx, int sample_all, - CvMat** out_response_map, CvMat** class_counts=0 ); - -const float** cvGetTrainSamples( const CvMat* train_data, int tflag, - const CvMat* var_idx, const CvMat* sample_idx, - int* _var_count, int* _sample_count, - bool always_copy_data=false ); - -namespace cv -{ - struct DTreeBestSplitFinder - { - DTreeBestSplitFinder(){ splitSize = 0, tree = 0; node = 0; } - DTreeBestSplitFinder( CvDTree* _tree, CvDTreeNode* _node); - DTreeBestSplitFinder( const DTreeBestSplitFinder& finder, Split ); - virtual ~DTreeBestSplitFinder() {} - virtual void operator()(const BlockedRange& range); - void join( DTreeBestSplitFinder& rhs ); - Ptr bestSplit; - Ptr split; - int splitSize; - CvDTree* tree; - CvDTreeNode* node; - }; - - struct ForestTreeBestSplitFinder : DTreeBestSplitFinder - { - ForestTreeBestSplitFinder() : DTreeBestSplitFinder() {} - ForestTreeBestSplitFinder( CvForestTree* _tree, CvDTreeNode* _node ); - ForestTreeBestSplitFinder( const ForestTreeBestSplitFinder& finder, Split ); - virtual void operator()(const BlockedRange& range); - }; -} - -#endif /* __ML_H__ */ diff --git a/apps/traincascade/old_ml_tree.cpp b/apps/traincascade/old_ml_tree.cpp deleted file mode 100644 index 55052ed532..0000000000 --- a/apps/traincascade/old_ml_tree.cpp +++ /dev/null @@ -1,4153 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// Intel License Agreement -// -// 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 "old_ml_precomp.hpp" -#include - -using namespace cv; - -static const float ord_nan = FLT_MAX*0.5f; -static const int min_block_size = 1 << 16; -static const int block_size_delta = 1 << 10; - -CvDTreeTrainData::CvDTreeTrainData() -{ - var_idx = var_type = cat_count = cat_ofs = cat_map = - priors = priors_mult = counts = direction = split_buf = responses_copy = 0; - buf = 0; - tree_storage = temp_storage = 0; - - clear(); -} - - -CvDTreeTrainData::CvDTreeTrainData( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx, - const CvMat* _sample_idx, const CvMat* _var_type, - const CvMat* _missing_mask, const CvDTreeParams& _params, - bool _shared, bool _add_labels ) -{ - var_idx = var_type = cat_count = cat_ofs = cat_map = - priors = priors_mult = counts = direction = split_buf = responses_copy = 0; - buf = 0; - - tree_storage = temp_storage = 0; - - set_data( _train_data, _tflag, _responses, _var_idx, _sample_idx, - _var_type, _missing_mask, _params, _shared, _add_labels ); -} - - -CvDTreeTrainData::~CvDTreeTrainData() -{ - clear(); -} - - -bool CvDTreeTrainData::set_params( const CvDTreeParams& _params ) -{ - bool ok = false; - - CV_FUNCNAME( "CvDTreeTrainData::set_params" ); - - __BEGIN__; - - // set parameters - params = _params; - - if( params.max_categories < 2 ) - CV_ERROR( CV_StsOutOfRange, "params.max_categories should be >= 2" ); - params.max_categories = MIN( params.max_categories, 15 ); - - if( params.max_depth < 0 ) - CV_ERROR( CV_StsOutOfRange, "params.max_depth should be >= 0" ); - params.max_depth = MIN( params.max_depth, 25 ); - - params.min_sample_count = MAX(params.min_sample_count,1); - - if( params.cv_folds < 0 ) - CV_ERROR( CV_StsOutOfRange, - "params.cv_folds should be =0 (the tree is not pruned) " - "or n>0 (tree is pruned using n-fold cross-validation)" ); - - if( params.cv_folds == 1 ) - params.cv_folds = 0; - - if( params.regression_accuracy < 0 ) - CV_ERROR( CV_StsOutOfRange, "params.regression_accuracy should be >= 0" ); - - ok = true; - - __END__; - - return ok; -} - -template -class LessThanPtr -{ -public: - bool operator()(T* a, T* b) const { return *a < *b; } -}; - -template -class LessThanIdx -{ -public: - LessThanIdx( const T* _arr ) : arr(_arr) {} - bool operator()(Idx a, Idx b) const { return arr[a] < arr[b]; } - const T* arr; -}; - -class LessThanPairs -{ -public: - bool operator()(const CvPair16u32s& a, const CvPair16u32s& b) const { return *a.i < *b.i; } -}; - -void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx, const CvMat* _sample_idx, - const CvMat* _var_type, const CvMat* _missing_mask, const CvDTreeParams& _params, - bool _shared, bool _add_labels, bool _update_data ) -{ - CvMat* sample_indices = 0; - CvMat* var_type0 = 0; - CvMat* tmp_map = 0; - int** int_ptr = 0; - CvPair16u32s* pair16u32s_ptr = 0; - CvDTreeTrainData* data = 0; - float *_fdst = 0; - int *_idst = 0; - unsigned short* udst = 0; - int* idst = 0; - - CV_FUNCNAME( "CvDTreeTrainData::set_data" ); - - __BEGIN__; - - int sample_all = 0, r_type, cv_n; - int total_c_count = 0; - int tree_block_size, temp_block_size, max_split_size, nv_size, cv_size = 0; - int ds_step, dv_step, ms_step = 0, mv_step = 0; // {data|mask}{sample|var}_step - int vi, i, size; - char err[100]; - const int *sidx = 0, *vidx = 0; - - uint64 effective_buf_size = 0; - int effective_buf_height = 0, effective_buf_width = 0; - - if( _update_data && data_root ) - { - data = new CvDTreeTrainData( _train_data, _tflag, _responses, _var_idx, - _sample_idx, _var_type, _missing_mask, _params, _shared, _add_labels ); - - // compare new and old train data - if( !(data->var_count == var_count && - cvNorm( data->var_type, var_type, CV_C ) < FLT_EPSILON && - cvNorm( data->cat_count, cat_count, CV_C ) < FLT_EPSILON && - cvNorm( data->cat_map, cat_map, CV_C ) < FLT_EPSILON) ) - CV_ERROR( CV_StsBadArg, - "The new training data must have the same types and the input and output variables " - "and the same categories for categorical variables" ); - - cvReleaseMat( &priors ); - cvReleaseMat( &priors_mult ); - cvReleaseMat( &buf ); - cvReleaseMat( &direction ); - cvReleaseMat( &split_buf ); - cvReleaseMemStorage( &temp_storage ); - - priors = data->priors; data->priors = 0; - priors_mult = data->priors_mult; data->priors_mult = 0; - buf = data->buf; data->buf = 0; - buf_count = data->buf_count; buf_size = data->buf_size; - sample_count = data->sample_count; - - direction = data->direction; data->direction = 0; - split_buf = data->split_buf; data->split_buf = 0; - temp_storage = data->temp_storage; data->temp_storage = 0; - nv_heap = data->nv_heap; cv_heap = data->cv_heap; - - data_root = new_node( 0, sample_count, 0, 0 ); - EXIT; - } - - clear(); - - var_all = 0; - rng = &cv::theRNG(); - - CV_CALL( set_params( _params )); - - // check parameter types and sizes - CV_CALL( cvCheckTrainData( _train_data, _tflag, _missing_mask, &var_all, &sample_all )); - - train_data = _train_data; - responses = _responses; - - if( _tflag == CV_ROW_SAMPLE ) - { - ds_step = _train_data->step/CV_ELEM_SIZE(_train_data->type); - dv_step = 1; - if( _missing_mask ) - ms_step = _missing_mask->step, mv_step = 1; - } - else - { - dv_step = _train_data->step/CV_ELEM_SIZE(_train_data->type); - ds_step = 1; - if( _missing_mask ) - mv_step = _missing_mask->step, ms_step = 1; - } - tflag = _tflag; - - sample_count = sample_all; - var_count = var_all; - - if( _sample_idx ) - { - CV_CALL( sample_indices = cvPreprocessIndexArray( _sample_idx, sample_all )); - sidx = sample_indices->data.i; - sample_count = sample_indices->rows + sample_indices->cols - 1; - } - - if( _var_idx ) - { - CV_CALL( var_idx = cvPreprocessIndexArray( _var_idx, var_all )); - vidx = var_idx->data.i; - var_count = var_idx->rows + var_idx->cols - 1; - } - - is_buf_16u = false; - if ( sample_count < 65536 ) - is_buf_16u = true; - - if( !CV_IS_MAT(_responses) || - (CV_MAT_TYPE(_responses->type) != CV_32SC1 && - CV_MAT_TYPE(_responses->type) != CV_32FC1) || - (_responses->rows != 1 && _responses->cols != 1) || - _responses->rows + _responses->cols - 1 != sample_all ) - CV_ERROR( CV_StsBadArg, "The array of _responses must be an integer or " - "floating-point vector containing as many elements as " - "the total number of samples in the training data matrix" ); - - r_type = CV_VAR_CATEGORICAL; - if( _var_type ) - CV_CALL( var_type0 = cvPreprocessVarType( _var_type, var_idx, var_count, &r_type )); - - CV_CALL( var_type = cvCreateMat( 1, var_count+2, CV_32SC1 )); - - cat_var_count = 0; - ord_var_count = -1; - - is_classifier = r_type == CV_VAR_CATEGORICAL; - - // step 0. calc the number of categorical vars - for( vi = 0; vi < var_count; vi++ ) - { - char vt = var_type0 ? var_type0->data.ptr[vi] : CV_VAR_ORDERED; - var_type->data.i[vi] = vt == CV_VAR_CATEGORICAL ? cat_var_count++ : ord_var_count--; - } - - ord_var_count = ~ord_var_count; - cv_n = params.cv_folds; - // set the two last elements of var_type array to be able - // to locate responses and cross-validation labels using - // the corresponding get_* functions. - var_type->data.i[var_count] = cat_var_count; - var_type->data.i[var_count+1] = cat_var_count+1; - - // in case of single ordered predictor we need dummy cv_labels - // for safe split_node_data() operation - have_labels = cv_n > 0 || (ord_var_count == 1 && cat_var_count == 0) || _add_labels; - - work_var_count = var_count + (is_classifier ? 1 : 0) // for responses class_labels - + (have_labels ? 1 : 0); // for cv_labels - - shared = _shared; - buf_count = shared ? 2 : 1; - - buf_size = -1; // the member buf_size is obsolete - - effective_buf_size = (uint64)(work_var_count + 1)*(uint64)sample_count * buf_count; // this is the total size of "CvMat buf" to be allocated - effective_buf_width = sample_count; - effective_buf_height = work_var_count+1; - - if (effective_buf_width >= effective_buf_height) - effective_buf_height *= buf_count; - else - effective_buf_width *= buf_count; - - if ((uint64)effective_buf_width * (uint64)effective_buf_height != effective_buf_size) - { - CV_Error(CV_StsBadArg, "The memory buffer cannot be allocated since its size exceeds integer fields limit"); - } - - - - if ( is_buf_16u ) - { - CV_CALL( buf = cvCreateMat( effective_buf_height, effective_buf_width, CV_16UC1 )); - CV_CALL( pair16u32s_ptr = (CvPair16u32s*)cvAlloc( sample_count*sizeof(pair16u32s_ptr[0]) )); - } - else - { - CV_CALL( buf = cvCreateMat( effective_buf_height, effective_buf_width, CV_32SC1 )); - CV_CALL( int_ptr = (int**)cvAlloc( sample_count*sizeof(int_ptr[0]) )); - } - - size = is_classifier ? (cat_var_count+1) : cat_var_count; - size = !size ? 1 : size; - CV_CALL( cat_count = cvCreateMat( 1, size, CV_32SC1 )); - CV_CALL( cat_ofs = cvCreateMat( 1, size, CV_32SC1 )); - - size = is_classifier ? (cat_var_count + 1)*params.max_categories : cat_var_count*params.max_categories; - size = !size ? 1 : size; - CV_CALL( cat_map = cvCreateMat( 1, size, CV_32SC1 )); - - // now calculate the maximum size of split, - // create memory storage that will keep nodes and splits of the decision tree - // allocate root node and the buffer for the whole training data - max_split_size = cvAlign(sizeof(CvDTreeSplit) + - (MAX(0,sample_count - 33)/32)*sizeof(int),sizeof(void*)); - tree_block_size = MAX((int)sizeof(CvDTreeNode)*8, max_split_size); - tree_block_size = MAX(tree_block_size + block_size_delta, min_block_size); - CV_CALL( tree_storage = cvCreateMemStorage( tree_block_size )); - CV_CALL( node_heap = cvCreateSet( 0, sizeof(*node_heap), sizeof(CvDTreeNode), tree_storage )); - - nv_size = var_count*sizeof(int); - nv_size = cvAlign(MAX( nv_size, (int)sizeof(CvSetElem) ), sizeof(void*)); - - temp_block_size = nv_size; - - if( cv_n ) - { - if( sample_count < cv_n*MAX(params.min_sample_count,10) ) - CV_ERROR( CV_StsOutOfRange, - "The many folds in cross-validation for such a small dataset" ); - - cv_size = cvAlign( cv_n*(sizeof(int) + sizeof(double)*2), sizeof(double) ); - temp_block_size = MAX(temp_block_size, cv_size); - } - - temp_block_size = MAX( temp_block_size + block_size_delta, min_block_size ); - CV_CALL( temp_storage = cvCreateMemStorage( temp_block_size )); - CV_CALL( nv_heap = cvCreateSet( 0, sizeof(*nv_heap), nv_size, temp_storage )); - if( cv_size ) - CV_CALL( cv_heap = cvCreateSet( 0, sizeof(*cv_heap), cv_size, temp_storage )); - - CV_CALL( data_root = new_node( 0, sample_count, 0, 0 )); - - max_c_count = 1; - - _fdst = 0; - _idst = 0; - if (ord_var_count) - _fdst = (float*)cvAlloc(sample_count*sizeof(_fdst[0])); - if (is_buf_16u && (cat_var_count || is_classifier)) - _idst = (int*)cvAlloc(sample_count*sizeof(_idst[0])); - - // transform the training data to convenient representation - for( vi = 0; vi <= var_count; vi++ ) - { - int ci; - const uchar* mask = 0; - int64 m_step = 0, step; - const int* idata = 0; - const float* fdata = 0; - int num_valid = 0; - - if( vi < var_count ) // analyze i-th input variable - { - int vi0 = vidx ? vidx[vi] : vi; - ci = get_var_type(vi); - step = ds_step; m_step = ms_step; - if( CV_MAT_TYPE(_train_data->type) == CV_32SC1 ) - idata = _train_data->data.i + vi0*dv_step; - else - fdata = _train_data->data.fl + vi0*dv_step; - if( _missing_mask ) - mask = _missing_mask->data.ptr + vi0*mv_step; - } - else // analyze _responses - { - ci = cat_var_count; - step = CV_IS_MAT_CONT(_responses->type) ? - 1 : _responses->step / CV_ELEM_SIZE(_responses->type); - if( CV_MAT_TYPE(_responses->type) == CV_32SC1 ) - idata = _responses->data.i; - else - fdata = _responses->data.fl; - } - - if( (vi < var_count && ci>=0) || - (vi == var_count && is_classifier) ) // process categorical variable or response - { - int c_count, prev_label; - int* c_map; - - if (is_buf_16u) - udst = (unsigned short*)(buf->data.s + (size_t)vi*sample_count); - else - idst = buf->data.i + (size_t)vi*sample_count; - - // copy data - for( i = 0; i < sample_count; i++ ) - { - int val = INT_MAX, si = sidx ? sidx[i] : i; - if( !mask || !mask[(size_t)si*m_step] ) - { - if( idata ) - val = idata[(size_t)si*step]; - else - { - float t = fdata[(size_t)si*step]; - val = cvRound(t); - if( fabs(t - val) > FLT_EPSILON ) - { - snprintf( err, sizeof(err), "%d-th value of %d-th (categorical) " - "variable is not an integer", i, vi ); - CV_ERROR( CV_StsBadArg, err ); - } - } - - if( val == INT_MAX ) - { - snprintf( err, sizeof(err), "%d-th value of %d-th (categorical) " - "variable is too large", i, vi ); - CV_ERROR( CV_StsBadArg, err ); - } - num_valid++; - } - if (is_buf_16u) - { - _idst[i] = val; - pair16u32s_ptr[i].u = udst + i; - pair16u32s_ptr[i].i = _idst + i; - } - else - { - idst[i] = val; - int_ptr[i] = idst + i; - } - } - - c_count = num_valid > 0; - if (is_buf_16u) - { - std::sort(pair16u32s_ptr, pair16u32s_ptr + sample_count, LessThanPairs()); - // count the categories - for( i = 1; i < num_valid; i++ ) - if (*pair16u32s_ptr[i].i != *pair16u32s_ptr[i-1].i) - c_count ++ ; - } - else - { - std::sort(int_ptr, int_ptr + sample_count, LessThanPtr()); - // count the categories - for( i = 1; i < num_valid; i++ ) - c_count += *int_ptr[i] != *int_ptr[i-1]; - } - - if( vi > 0 ) - max_c_count = MAX( max_c_count, c_count ); - cat_count->data.i[ci] = c_count; - cat_ofs->data.i[ci] = total_c_count; - - // resize cat_map, if need - if( cat_map->cols < total_c_count + c_count ) - { - tmp_map = cat_map; - CV_CALL( cat_map = cvCreateMat( 1, - MAX(cat_map->cols*3/2,total_c_count+c_count), CV_32SC1 )); - for( i = 0; i < total_c_count; i++ ) - cat_map->data.i[i] = tmp_map->data.i[i]; - cvReleaseMat( &tmp_map ); - } - - c_map = cat_map->data.i + total_c_count; - total_c_count += c_count; - - c_count = -1; - if (is_buf_16u) - { - // compact the class indices and build the map - prev_label = ~*pair16u32s_ptr[0].i; - for( i = 0; i < num_valid; i++ ) - { - int cur_label = *pair16u32s_ptr[i].i; - if( cur_label != prev_label ) - c_map[++c_count] = prev_label = cur_label; - *pair16u32s_ptr[i].u = (unsigned short)c_count; - } - // replace labels for missing values with -1 - for( ; i < sample_count; i++ ) - *pair16u32s_ptr[i].u = 65535; - } - else - { - // compact the class indices and build the map - prev_label = ~*int_ptr[0]; - for( i = 0; i < num_valid; i++ ) - { - int cur_label = *int_ptr[i]; - if( cur_label != prev_label ) - c_map[++c_count] = prev_label = cur_label; - *int_ptr[i] = c_count; - } - // replace labels for missing values with -1 - for( ; i < sample_count; i++ ) - *int_ptr[i] = -1; - } - } - else if( ci < 0 ) // process ordered variable - { - if (is_buf_16u) - udst = (unsigned short*)(buf->data.s + (size_t)vi*sample_count); - else - idst = buf->data.i + (size_t)vi*sample_count; - - for( i = 0; i < sample_count; i++ ) - { - float val = ord_nan; - int si = sidx ? sidx[i] : i; - if( !mask || !mask[(size_t)si*m_step] ) - { - if( idata ) - val = (float)idata[(size_t)si*step]; - else - val = fdata[(size_t)si*step]; - - if( fabs(val) >= ord_nan ) - { - snprintf( err, sizeof(err), "%d-th value of %d-th (ordered) " - "variable (=%g) is too large", i, vi, val ); - CV_ERROR( CV_StsBadArg, err ); - } - num_valid++; - } - - if (is_buf_16u) - udst[i] = (unsigned short)i; // TODO: memory corruption may be here - else - idst[i] = i; - _fdst[i] = val; - - } - if (is_buf_16u) - std::sort(udst, udst + sample_count, LessThanIdx(_fdst)); - else - std::sort(idst, idst + sample_count, LessThanIdx(_fdst)); - } - - if( vi < var_count ) - data_root->set_num_valid(vi, num_valid); - } - - // set sample labels - if (is_buf_16u) - udst = (unsigned short*)(buf->data.s + (size_t)work_var_count*sample_count); - else - idst = buf->data.i + (size_t)work_var_count*sample_count; - - for (i = 0; i < sample_count; i++) - { - if (udst) - udst[i] = sidx ? (unsigned short)sidx[i] : (unsigned short)i; - else - idst[i] = sidx ? sidx[i] : i; - } - - if( cv_n ) - { - unsigned short* usdst = 0; - int* idst2 = 0; - - if (is_buf_16u) - { - usdst = (unsigned short*)(buf->data.s + (size_t)(get_work_var_count()-1)*sample_count); - for( i = vi = 0; i < sample_count; i++ ) - { - usdst[i] = (unsigned short)vi++; - vi &= vi < cv_n ? -1 : 0; - } - - for( i = 0; i < sample_count; i++ ) - { - int a = (*rng)(sample_count); - int b = (*rng)(sample_count); - unsigned short unsh = (unsigned short)vi; - CV_SWAP( usdst[a], usdst[b], unsh ); - } - } - else - { - idst2 = buf->data.i + (size_t)(get_work_var_count()-1)*sample_count; - for( i = vi = 0; i < sample_count; i++ ) - { - idst2[i] = vi++; - vi &= vi < cv_n ? -1 : 0; - } - - for( i = 0; i < sample_count; i++ ) - { - int a = (*rng)(sample_count); - int b = (*rng)(sample_count); - CV_SWAP( idst2[a], idst2[b], vi ); - } - } - } - - if ( cat_map ) - cat_map->cols = MAX( total_c_count, 1 ); - - max_split_size = cvAlign(sizeof(CvDTreeSplit) + - (MAX(0,max_c_count - 33)/32)*sizeof(int),sizeof(void*)); - CV_CALL( split_heap = cvCreateSet( 0, sizeof(*split_heap), max_split_size, tree_storage )); - - have_priors = is_classifier && params.priors; - if( is_classifier ) - { - int m = get_num_classes(); - double sum = 0; - CV_CALL( priors = cvCreateMat( 1, m, CV_64F )); - for( i = 0; i < m; i++ ) - { - double val = have_priors ? params.priors[i] : 1.; - if( val <= 0 ) - CV_ERROR( CV_StsOutOfRange, "Every class weight should be positive" ); - priors->data.db[i] = val; - sum += val; - } - - // normalize weights - if( have_priors ) - cvScale( priors, priors, 1./sum ); - - CV_CALL( priors_mult = cvCloneMat( priors )); - CV_CALL( counts = cvCreateMat( 1, m, CV_32SC1 )); - } - - - CV_CALL( direction = cvCreateMat( 1, sample_count, CV_8UC1 )); - CV_CALL( split_buf = cvCreateMat( 1, sample_count, CV_32SC1 )); - - __END__; - - if( data ) - delete data; - - if (_fdst) - cvFree( &_fdst ); - if (_idst) - cvFree( &_idst ); - cvFree( &int_ptr ); - cvFree( &pair16u32s_ptr); - cvReleaseMat( &var_type0 ); - cvReleaseMat( &sample_indices ); - cvReleaseMat( &tmp_map ); -} - -void CvDTreeTrainData::do_responses_copy() -{ - responses_copy = cvCreateMat( responses->rows, responses->cols, responses->type ); - cvCopy( responses, responses_copy); - responses = responses_copy; -} - -CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) -{ - CvDTreeNode* root = 0; - CvMat* isubsample_idx = 0; - CvMat* subsample_co = 0; - - bool isMakeRootCopy = true; - - CV_FUNCNAME( "CvDTreeTrainData::subsample_data" ); - - __BEGIN__; - - if( !data_root ) - CV_ERROR( CV_StsError, "No training data has been set" ); - - if( _subsample_idx ) - { - CV_CALL( isubsample_idx = cvPreprocessIndexArray( _subsample_idx, sample_count )); - - if( isubsample_idx->cols + isubsample_idx->rows - 1 == sample_count ) - { - const int* sidx = isubsample_idx->data.i; - for( int i = 0; i < sample_count; i++ ) - { - if( sidx[i] != i ) - { - isMakeRootCopy = false; - break; - } - } - } - else - isMakeRootCopy = false; - } - - if( isMakeRootCopy ) - { - // make a copy of the root node - CvDTreeNode temp; - int i; - root = new_node( 0, 1, 0, 0 ); - temp = *root; - *root = *data_root; - root->num_valid = temp.num_valid; - if( root->num_valid ) - { - for( i = 0; i < var_count; i++ ) - root->num_valid[i] = data_root->num_valid[i]; - } - root->cv_Tn = temp.cv_Tn; - root->cv_node_risk = temp.cv_node_risk; - root->cv_node_error = temp.cv_node_error; - } - else - { - int* sidx = isubsample_idx->data.i; - // co - array of count/offset pairs (to handle duplicated values in _subsample_idx) - int* co, cur_ofs = 0; - int vi, i; - int workVarCount = get_work_var_count(); - int count = isubsample_idx->rows + isubsample_idx->cols - 1; - - root = new_node( 0, count, 1, 0 ); - - CV_CALL( subsample_co = cvCreateMat( 1, sample_count*2, CV_32SC1 )); - cvZero( subsample_co ); - co = subsample_co->data.i; - for( i = 0; i < count; i++ ) - co[sidx[i]*2]++; - for( i = 0; i < sample_count; i++ ) - { - if( co[i*2] ) - { - co[i*2+1] = cur_ofs; - cur_ofs += co[i*2]; - } - else - co[i*2+1] = -1; - } - - cv::AutoBuffer inn_buf(sample_count*(2*sizeof(int) + sizeof(float))); - for( vi = 0; vi < workVarCount; vi++ ) - { - int ci = get_var_type(vi); - - if( ci >= 0 || vi >= var_count ) - { - int num_valid = 0; - const int* src = CvDTreeTrainData::get_cat_var_data(data_root, vi, (int*)inn_buf.data()); - - if (is_buf_16u) - { - unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - (size_t)vi*sample_count + root->offset); - for( i = 0; i < count; i++ ) - { - int val = src[sidx[i]]; - udst[i] = (unsigned short)val; - num_valid += val >= 0; - } - } - else - { - int* idst = buf->data.i + root->buf_idx*get_length_subbuf() + - (size_t)vi*sample_count + root->offset; - for( i = 0; i < count; i++ ) - { - int val = src[sidx[i]]; - idst[i] = val; - num_valid += val >= 0; - } - } - - if( vi < var_count ) - root->set_num_valid(vi, num_valid); - } - else - { - int *src_idx_buf = (int*)inn_buf.data(); - float *src_val_buf = (float*)(src_idx_buf + sample_count); - int* sample_indices_buf = (int*)(src_val_buf + sample_count); - const int* src_idx = 0; - const float* src_val = 0; - get_ord_var_data( data_root, vi, src_val_buf, src_idx_buf, &src_val, &src_idx, sample_indices_buf ); - int j = 0, idx, count_i; - int num_valid = data_root->get_num_valid(vi); - - if (is_buf_16u) - { - unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - (size_t)vi*sample_count + data_root->offset); - for( i = 0; i < num_valid; i++ ) - { - idx = src_idx[i]; - count_i = co[idx*2]; - if( count_i ) - for( cur_ofs = co[idx*2+1]; count_i > 0; count_i--, j++, cur_ofs++ ) - udst_idx[j] = (unsigned short)cur_ofs; - } - - root->set_num_valid(vi, j); - - for( ; i < sample_count; i++ ) - { - idx = src_idx[i]; - count_i = co[idx*2]; - if( count_i ) - for( cur_ofs = co[idx*2+1]; count_i > 0; count_i--, j++, cur_ofs++ ) - udst_idx[j] = (unsigned short)cur_ofs; - } - } - else - { - int* idst_idx = buf->data.i + root->buf_idx*get_length_subbuf() + - (size_t)vi*sample_count + root->offset; - for( i = 0; i < num_valid; i++ ) - { - idx = src_idx[i]; - count_i = co[idx*2]; - if( count_i ) - for( cur_ofs = co[idx*2+1]; count_i > 0; count_i--, j++, cur_ofs++ ) - idst_idx[j] = cur_ofs; - } - - root->set_num_valid(vi, j); - - for( ; i < sample_count; i++ ) - { - idx = src_idx[i]; - count_i = co[idx*2]; - if( count_i ) - for( cur_ofs = co[idx*2+1]; count_i > 0; count_i--, j++, cur_ofs++ ) - idst_idx[j] = cur_ofs; - } - } - } - } - // sample indices subsampling - const int* sample_idx_src = get_sample_indices(data_root, (int*)inn_buf.data()); - if (is_buf_16u) - { - unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - (size_t)workVarCount*sample_count + root->offset); - for (i = 0; i < count; i++) - sample_idx_dst[i] = (unsigned short)sample_idx_src[sidx[i]]; - } - else - { - int* sample_idx_dst = buf->data.i + root->buf_idx*get_length_subbuf() + - (size_t)workVarCount*sample_count + root->offset; - for (i = 0; i < count; i++) - sample_idx_dst[i] = sample_idx_src[sidx[i]]; - } - } - - __END__; - - cvReleaseMat( &isubsample_idx ); - cvReleaseMat( &subsample_co ); - - return root; -} - - -void CvDTreeTrainData::get_vectors( const CvMat* _subsample_idx, - float* values, uchar* missing, - float* _responses, bool get_class_idx ) -{ - CvMat* subsample_idx = 0; - CvMat* subsample_co = 0; - - CV_FUNCNAME( "CvDTreeTrainData::get_vectors" ); - - __BEGIN__; - - int i, vi, total = sample_count, count = total, cur_ofs = 0; - int* sidx = 0; - int* co = 0; - - cv::AutoBuffer inn_buf(sample_count*(2*sizeof(int) + sizeof(float))); - if( _subsample_idx ) - { - CV_CALL( subsample_idx = cvPreprocessIndexArray( _subsample_idx, sample_count )); - sidx = subsample_idx->data.i; - CV_CALL( subsample_co = cvCreateMat( 1, sample_count*2, CV_32SC1 )); - co = subsample_co->data.i; - cvZero( subsample_co ); - count = subsample_idx->cols + subsample_idx->rows - 1; - for( i = 0; i < count; i++ ) - co[sidx[i]*2]++; - for( i = 0; i < total; i++ ) - { - int count_i = co[i*2]; - if( count_i ) - { - co[i*2+1] = cur_ofs*var_count; - cur_ofs += count_i; - } - } - } - - if( missing ) - memset( missing, 1, count*var_count ); - - for( vi = 0; vi < var_count; vi++ ) - { - int ci = get_var_type(vi); - if( ci >= 0 ) // categorical - { - float* dst = values + vi; - uchar* m = missing ? missing + vi : 0; - const int* src = get_cat_var_data(data_root, vi, (int*)inn_buf.data()); - - for( i = 0; i < count; i++, dst += var_count ) - { - int idx = sidx ? sidx[i] : i; - int val = src[idx]; - *dst = (float)val; - if( m ) - { - *m = (!is_buf_16u && val < 0) || (is_buf_16u && (val == 65535)); - m += var_count; - } - } - } - else // ordered - { - float* dst = values + vi; - uchar* m = missing ? missing + vi : 0; - int count1 = data_root->get_num_valid(vi); - float *src_val_buf = (float*)inn_buf.data(); - int* src_idx_buf = (int*)(src_val_buf + sample_count); - int* sample_indices_buf = src_idx_buf + sample_count; - const float *src_val = 0; - const int* src_idx = 0; - get_ord_var_data(data_root, vi, src_val_buf, src_idx_buf, &src_val, &src_idx, sample_indices_buf); - - for( i = 0; i < count1; i++ ) - { - int idx = src_idx[i]; - int count_i = 1; - if( co ) - { - count_i = co[idx*2]; - cur_ofs = co[idx*2+1]; - } - else - cur_ofs = idx*var_count; - if( count_i ) - { - float val = src_val[i]; - for( ; count_i > 0; count_i--, cur_ofs += var_count ) - { - dst[cur_ofs] = val; - if( m ) - m[cur_ofs] = 0; - } - } - } - } - } - - // copy responses - if( _responses ) - { - if( is_classifier ) - { - const int* src = get_class_labels(data_root, (int*)inn_buf.data()); - for( i = 0; i < count; i++ ) - { - int idx = sidx ? sidx[i] : i; - int val = get_class_idx ? src[idx] : - cat_map->data.i[cat_ofs->data.i[cat_var_count]+src[idx]]; - _responses[i] = (float)val; - } - } - else - { - float* val_buf = (float*)inn_buf.data(); - int* sample_idx_buf = (int*)(val_buf + sample_count); - const float* _values = get_ord_responses(data_root, val_buf, sample_idx_buf); - for( i = 0; i < count; i++ ) - { - int idx = sidx ? sidx[i] : i; - _responses[i] = _values[idx]; - } - } - } - - __END__; - - cvReleaseMat( &subsample_idx ); - cvReleaseMat( &subsample_co ); -} - - -CvDTreeNode* CvDTreeTrainData::new_node( CvDTreeNode* parent, int count, - int storage_idx, int offset ) -{ - CvDTreeNode* node = (CvDTreeNode*)cvSetNew( node_heap ); - - node->sample_count = count; - node->depth = parent ? parent->depth + 1 : 0; - node->parent = parent; - node->left = node->right = 0; - node->split = 0; - node->value = 0; - node->class_idx = 0; - node->maxlr = 0.; - - node->buf_idx = storage_idx; - node->offset = offset; - if( nv_heap ) - node->num_valid = (int*)cvSetNew( nv_heap ); - else - node->num_valid = 0; - node->alpha = node->node_risk = node->tree_risk = node->tree_error = 0.; - node->complexity = 0; - - if( params.cv_folds > 0 && cv_heap ) - { - int cv_n = params.cv_folds; - node->Tn = INT_MAX; - node->cv_Tn = (int*)cvSetNew( cv_heap ); - node->cv_node_risk = (double*)cvAlignPtr(node->cv_Tn + cv_n, sizeof(double)); - node->cv_node_error = node->cv_node_risk + cv_n; - } - else - { - node->Tn = 0; - node->cv_Tn = 0; - node->cv_node_risk = 0; - node->cv_node_error = 0; - } - - return node; -} - - -CvDTreeSplit* CvDTreeTrainData::new_split_ord( int vi, float cmp_val, - int split_point, int inversed, float quality ) -{ - CvDTreeSplit* split = (CvDTreeSplit*)cvSetNew( split_heap ); - split->var_idx = vi; - split->condensed_idx = INT_MIN; - split->ord.c = cmp_val; - split->ord.split_point = split_point; - split->inversed = inversed; - split->quality = quality; - split->next = 0; - - return split; -} - - -CvDTreeSplit* CvDTreeTrainData::new_split_cat( int vi, float quality ) -{ - CvDTreeSplit* split = (CvDTreeSplit*)cvSetNew( split_heap ); - int i, n = (max_c_count + 31)/32; - - split->var_idx = vi; - split->condensed_idx = INT_MIN; - split->inversed = 0; - split->quality = quality; - for( i = 0; i < n; i++ ) - split->subset[i] = 0; - split->next = 0; - - return split; -} - - -void CvDTreeTrainData::free_node( CvDTreeNode* node ) -{ - CvDTreeSplit* split = node->split; - free_node_data( node ); - while( split ) - { - CvDTreeSplit* next = split->next; - cvSetRemoveByPtr( split_heap, split ); - split = next; - } - node->split = 0; - cvSetRemoveByPtr( node_heap, node ); -} - - -void CvDTreeTrainData::free_node_data( CvDTreeNode* node ) -{ - if( node->num_valid ) - { - cvSetRemoveByPtr( nv_heap, node->num_valid ); - node->num_valid = 0; - } - // do not free cv_* fields, as all the cross-validation related data is released at once. -} - - -void CvDTreeTrainData::free_train_data() -{ - cvReleaseMat( &counts ); - cvReleaseMat( &buf ); - cvReleaseMat( &direction ); - cvReleaseMat( &split_buf ); - cvReleaseMemStorage( &temp_storage ); - cvReleaseMat( &responses_copy ); - cv_heap = nv_heap = 0; -} - - -void CvDTreeTrainData::clear() -{ - free_train_data(); - - cvReleaseMemStorage( &tree_storage ); - - cvReleaseMat( &var_idx ); - cvReleaseMat( &var_type ); - cvReleaseMat( &cat_count ); - cvReleaseMat( &cat_ofs ); - cvReleaseMat( &cat_map ); - cvReleaseMat( &priors ); - cvReleaseMat( &priors_mult ); - - node_heap = split_heap = 0; - - sample_count = var_all = var_count = max_c_count = ord_var_count = cat_var_count = 0; - have_labels = have_priors = is_classifier = false; - - buf_count = buf_size = 0; - shared = false; - - data_root = 0; - - rng = &cv::theRNG(); -} - - -int CvDTreeTrainData::get_num_classes() const -{ - return is_classifier ? cat_count->data.i[cat_var_count] : 0; -} - - -int CvDTreeTrainData::get_var_type(int vi) const -{ - return var_type->data.i[vi]; -} - -void CvDTreeTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ord_values_buf, int* sorted_indices_buf, - const float** ord_values, const int** sorted_indices, int* sample_indices_buf ) -{ - int vidx = var_idx ? var_idx->data.i[vi] : vi; - int node_sample_count = n->sample_count; - int td_step = train_data->step/CV_ELEM_SIZE(train_data->type); - - const int* sample_indices = get_sample_indices(n, sample_indices_buf); - - if( !is_buf_16u ) - *sorted_indices = buf->data.i + n->buf_idx*get_length_subbuf() + - (size_t)vi*sample_count + n->offset; - else { - const unsigned short* short_indices = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + - (size_t)vi*sample_count + n->offset ); - for( int i = 0; i < node_sample_count; i++ ) - sorted_indices_buf[i] = short_indices[i]; - *sorted_indices = sorted_indices_buf; - } - - if( tflag == CV_ROW_SAMPLE ) - { - for( int i = 0; i < node_sample_count && - ((((*sorted_indices)[i] >= 0) && !is_buf_16u) || (((*sorted_indices)[i] != 65535) && is_buf_16u)); i++ ) - { - int idx = (*sorted_indices)[i]; - idx = sample_indices[idx]; - ord_values_buf[i] = *(train_data->data.fl + idx * td_step + vidx); - } - } - else - for( int i = 0; i < node_sample_count && - ((((*sorted_indices)[i] >= 0) && !is_buf_16u) || (((*sorted_indices)[i] != 65535) && is_buf_16u)); i++ ) - { - int idx = (*sorted_indices)[i]; - idx = sample_indices[idx]; - ord_values_buf[i] = *(train_data->data.fl + vidx* td_step + idx); - } - - *ord_values = ord_values_buf; -} - - -const int* CvDTreeTrainData::get_class_labels( CvDTreeNode* n, int* labels_buf ) -{ - if (is_classifier) - return get_cat_var_data( n, var_count, labels_buf); - return 0; -} - -const int* CvDTreeTrainData::get_sample_indices( CvDTreeNode* n, int* indices_buf ) -{ - return get_cat_var_data( n, get_work_var_count(), indices_buf ); -} - -const float* CvDTreeTrainData::get_ord_responses( CvDTreeNode* n, float* values_buf, int*sample_indices_buf ) -{ - int _sample_count = n->sample_count; - int r_step = CV_IS_MAT_CONT(responses->type) ? 1 : responses->step/CV_ELEM_SIZE(responses->type); - const int* indices = get_sample_indices(n, sample_indices_buf); - - for( int i = 0; i < _sample_count && - (((indices[i] >= 0) && !is_buf_16u) || ((indices[i] != 65535) && is_buf_16u)); i++ ) - { - int idx = indices[i]; - values_buf[i] = *(responses->data.fl + idx * r_step); - } - - return values_buf; -} - - -const int* CvDTreeTrainData::get_cv_labels( CvDTreeNode* n, int* labels_buf ) -{ - if (have_labels) - return get_cat_var_data( n, get_work_var_count()- 1, labels_buf); - return 0; -} - - -const int* CvDTreeTrainData::get_cat_var_data( CvDTreeNode* n, int vi, int* cat_values_buf) -{ - const int* cat_values = 0; - if( !is_buf_16u ) - cat_values = buf->data.i + n->buf_idx*get_length_subbuf() + - (size_t)vi*sample_count + n->offset; - else { - const unsigned short* short_values = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + - (size_t)vi*sample_count + n->offset); - for( int i = 0; i < n->sample_count; i++ ) - cat_values_buf[i] = short_values[i]; - cat_values = cat_values_buf; - } - return cat_values; -} - - -int CvDTreeTrainData::get_child_buf_idx( CvDTreeNode* n ) -{ - int idx = n->buf_idx + 1; - if( idx >= buf_count ) - idx = shared ? 1 : 0; - return idx; -} - - -void CvDTreeTrainData::write_params( cv::FileStorage& fs ) const -{ - CV_FUNCNAME( "CvDTreeTrainData::write_params" ); - - __BEGIN__; - - int vi, vcount = var_count; - - fs.write( "is_classifier", is_classifier ? 1 : 0 ); - fs.write( "var_all", var_all ); - fs.write( "var_count", var_count ); - fs.write( "ord_var_count", ord_var_count ); - fs.write( "cat_var_count", cat_var_count ); - - fs.startWriteStruct( "training_params", FileNode::MAP ); - fs.write( "use_surrogates", params.use_surrogates ? 1 : 0 ); - - if( is_classifier ) - { - fs.write( "max_categories", params.max_categories ); - } - else - { - fs.write( "regression_accuracy", params.regression_accuracy ); - } - - fs.write( "max_depth", params.max_depth ); - fs.write( "min_sample_count", params.min_sample_count ); - fs.write( "cross_validation_folds", params.cv_folds ); - - if( params.cv_folds > 1 ) - { - fs.write( "use_1se_rule", params.use_1se_rule ? 1 : 0 ); - fs.write( "truncate_pruned_tree", params.truncate_pruned_tree ? 1 : 0 ); - } - - if( priors ) - fs.write( "priors", cvarrToMat(priors) ); - - fs.endWriteStruct(); - - if( var_idx ) - fs.write( "var_idx", cvarrToMat(var_idx) ); - - fs.startWriteStruct("var_type", FileNode::SEQ + FileNode::FLOW ); - - for( vi = 0; vi < vcount; vi++ ) - fs.write( 0, var_type->data.i[vi] >= 0 ); - - fs.endWriteStruct(); - - if( cat_count && (cat_var_count > 0 || is_classifier) ) - { - CV_ASSERT( cat_count != 0 ); - fs.write( "cat_count", cvarrToMat(cat_count) ); - fs.write( "cat_map", cvarrToMat(cat_map) ); - } - - __END__; -} - - -void CvDTreeTrainData::read_params( const cv::FileNode& node ) -{ - CV_FUNCNAME( "CvDTreeTrainData::read_params" ); - - __BEGIN__; - - cv::FileNode tparams_node, vartype_node; - FileNodeIterator reader; - int vi, max_split_size, tree_block_size; - - is_classifier = (int) node[ "is_classifier" ] != 0; - var_all = (int) node[ "var_all" ]; - var_count = node[ "var_count" ].empty() ? var_all : (int)node[ "var_count" ]; - cat_var_count = (int) node[ "cat_var_count" ]; - ord_var_count = (int) node[ "ord_var_count" ]; - - tparams_node = node[ "training_params" ]; - - if( !tparams_node.empty() ) // training parameters are not necessary - { - params.use_surrogates = (tparams_node[ "use_surrogates" ].empty() ? 1 : (int)tparams_node[ "use_surrogates" ] ) != 0; - - if( is_classifier ) - { - params.max_categories = (int) tparams_node[ "max_categories" ]; - } - else - { - params.regression_accuracy = (float) tparams_node[ "regression_accuracy" ]; - } - - params.max_depth = (int) tparams_node[ "max_depth" ]; - params.min_sample_count = (int) tparams_node[ "min_sample_count" ]; - params.cv_folds = (int) tparams_node[ "cross_validation_folds" ]; - - if( params.cv_folds > 1 ) - { - params.use_1se_rule = (int)tparams_node[ "use_1se_rule" ] != 0; - params.truncate_pruned_tree = (int) tparams_node[ "truncate_pruned_tree" ] != 0; - } - - priors = nullptr; - if(!tparams_node[ "priors" ].empty()) - { - auto tmat = cvMat( tparams_node[ "priors" ].mat() ); - priors = cvCloneMat( &tmat ); - if( !CV_IS_MAT(priors) ) - CV_ERROR( CV_StsParseError, "priors must stored as a matrix" ); - priors_mult = cvCloneMat( priors ); - } - } - - var_idx = nullptr; - if (!node[ "var_idx" ].empty()) - { - auto tmat = cvMat( tparams_node[ "var_idx" ].mat() ); - var_idx = cvCloneMat( &tmat ); - } - if( var_idx ) - { - if( !CV_IS_MAT(var_idx) || - (var_idx->cols != 1 && var_idx->rows != 1) || - var_idx->cols + var_idx->rows - 1 != var_count || - CV_MAT_TYPE(var_idx->type) != CV_32SC1 ) - CV_ERROR( CV_StsParseError, - "var_idx (if exist) must be valid 1d integer vector containing elements" ); - - for( vi = 0; vi < var_count; vi++ ) - if( (unsigned)var_idx->data.i[vi] >= (unsigned)var_all ) - CV_ERROR( CV_StsOutOfRange, "some of var_idx elements are out of range" ); - } - - ////// read var type - CV_CALL( var_type = cvCreateMat( 1, var_count + 2, CV_32SC1 )); - - cat_var_count = 0; - ord_var_count = -1; - vartype_node = node[ "var_type" ]; - - if( !vartype_node.empty() && vartype_node.isInt() && var_count == 1 ) - var_type->data.i[0] = (int)vartype_node ? cat_var_count++ : ord_var_count--; - else - { - if( vartype_node.empty() || !vartype_node.isSeq() || - vartype_node.size() != (size_t) var_count ) - CV_ERROR( CV_StsParseError, "var_type must exist and be a sequence of 0's and 1's" ); - - reader = vartype_node.begin(); - - for( vi = 0; vi < var_count; vi++ ) - { - cv::FileNode n = *reader; - if( !n.isInt() || ((int) n & ~1) ) - CV_ERROR( CV_StsParseError, "var_type must exist and be a sequence of 0's and 1's" ); - var_type->data.i[vi] = (int) n ? cat_var_count++ : ord_var_count--; - reader++; - } - } - var_type->data.i[var_count] = cat_var_count; - - ord_var_count = ~ord_var_count; - ////// - - if( cat_var_count > 0 || is_classifier ) - { - int ccount, total_c_count = 0; - - auto cat_count_m = cvMat( node["cat_count"].mat() ); - cat_count = cvCloneMat( &cat_count_m ); - - auto cat_map_m = cvMat( node[ "cat_map" ].mat() ); - cat_map = cvCloneMat( &cat_map_m ); - - if( !CV_IS_MAT(cat_count) || !CV_IS_MAT(cat_map) || - (cat_count->cols != 1 && cat_count->rows != 1) || - CV_MAT_TYPE(cat_count->type) != CV_32SC1 || - cat_count->cols + cat_count->rows - 1 != cat_var_count + is_classifier || - (cat_map->cols != 1 && cat_map->rows != 1) || - CV_MAT_TYPE(cat_map->type) != CV_32SC1 ) - CV_ERROR( CV_StsParseError, - "Both cat_count and cat_map must exist and be valid 1d integer vectors of an appropriate size" ); - - ccount = cat_var_count + is_classifier; - - CV_CALL( cat_ofs = cvCreateMat( 1, ccount + 1, CV_32SC1 )); - cat_ofs->data.i[0] = 0; - max_c_count = 1; - - for( vi = 0; vi < ccount; vi++ ) - { - int val = cat_count->data.i[vi]; - if( val <= 0 ) - CV_ERROR( CV_StsOutOfRange, "some of cat_count elements are out of range" ); - max_c_count = MAX( max_c_count, val ); - cat_ofs->data.i[vi+1] = total_c_count += val; - } - - if( cat_map->cols + cat_map->rows - 1 != total_c_count ) - CV_ERROR( CV_StsBadSize, - "cat_map vector length is not equal to the total number of categories in all categorical vars" ); - } - - max_split_size = cvAlign(sizeof(CvDTreeSplit) + - (MAX(0,max_c_count - 33)/32)*sizeof(int),sizeof(void*)); - - tree_block_size = MAX((int)sizeof(CvDTreeNode)*8, max_split_size); - tree_block_size = MAX(tree_block_size + block_size_delta, min_block_size); - CV_CALL( tree_storage = cvCreateMemStorage( tree_block_size )); - CV_CALL( node_heap = cvCreateSet( 0, sizeof(node_heap[0]), - sizeof(CvDTreeNode), tree_storage )); - CV_CALL( split_heap = cvCreateSet( 0, sizeof(split_heap[0]), - max_split_size, tree_storage )); - - __END__; -} - -/////////////////////// Decision Tree ///////////////////////// -CvDTreeParams::CvDTreeParams() : max_categories(10), max_depth(INT_MAX), min_sample_count(10), - cv_folds(10), use_surrogates(true), use_1se_rule(true), - truncate_pruned_tree(true), regression_accuracy(0.01f), priors(0) -{} - -CvDTreeParams::CvDTreeParams( int _max_depth, int _min_sample_count, - float _regression_accuracy, bool _use_surrogates, - int _max_categories, int _cv_folds, - bool _use_1se_rule, bool _truncate_pruned_tree, - const float* _priors ) : - max_categories(_max_categories), max_depth(_max_depth), - min_sample_count(_min_sample_count), cv_folds (_cv_folds), - use_surrogates(_use_surrogates), use_1se_rule(_use_1se_rule), - truncate_pruned_tree(_truncate_pruned_tree), - regression_accuracy(_regression_accuracy), - priors(_priors) -{} - -CvDTree::CvDTree() -{ - data = 0; - var_importance = 0; - default_model_name = "my_tree"; - - clear(); -} - - -void CvDTree::clear() -{ - cvReleaseMat( &var_importance ); - if( data ) - { - if( !data->shared ) - delete data; - else - free_tree(); - data = 0; - } - root = 0; - pruned_tree_idx = -1; -} - - -CvDTree::~CvDTree() -{ - clear(); -} - - -const CvDTreeNode* CvDTree::get_root() const -{ - return root; -} - - -int CvDTree::get_pruned_tree_idx() const -{ - return pruned_tree_idx; -} - - -CvDTreeTrainData* CvDTree::get_data() -{ - return data; -} - - -bool CvDTree::train( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx, - const CvMat* _sample_idx, const CvMat* _var_type, - const CvMat* _missing_mask, CvDTreeParams _params ) -{ - bool result = false; - - CV_FUNCNAME( "CvDTree::train" ); - - __BEGIN__; - - clear(); - data = new CvDTreeTrainData( _train_data, _tflag, _responses, - _var_idx, _sample_idx, _var_type, - _missing_mask, _params, false ); - CV_CALL( result = do_train(0) ); - - __END__; - - return result; -} - -bool CvDTree::train( const Mat& _train_data, int _tflag, - const Mat& _responses, const Mat& _var_idx, - const Mat& _sample_idx, const Mat& _var_type, - const Mat& _missing_mask, CvDTreeParams _params ) -{ - train_data_hdr = cvMat(_train_data); - train_data_mat = _train_data; - responses_hdr = cvMat(_responses); - responses_mat = _responses; - - CvMat vidx=cvMat(_var_idx), sidx=cvMat(_sample_idx), vtype=cvMat(_var_type), mmask=cvMat(_missing_mask); - - return train(&train_data_hdr, _tflag, &responses_hdr, vidx.data.ptr ? &vidx : 0, sidx.data.ptr ? &sidx : 0, - vtype.data.ptr ? &vtype : 0, mmask.data.ptr ? &mmask : 0, _params); -} - - -bool CvDTree::train( CvMLData* _data, CvDTreeParams _params ) -{ - bool result = false; - - CV_FUNCNAME( "CvDTree::train" ); - - __BEGIN__; - - const CvMat* values = _data->get_values(); - const CvMat* response = _data->get_responses(); - const CvMat* missing = _data->get_missing(); - const CvMat* var_types = _data->get_var_types(); - const CvMat* train_sidx = _data->get_train_sample_idx(); - const CvMat* var_idx = _data->get_var_idx(); - - CV_CALL( result = train( values, CV_ROW_SAMPLE, response, var_idx, - train_sidx, var_types, missing, _params ) ); - - __END__; - - return result; -} - -bool CvDTree::train( CvDTreeTrainData* _data, const CvMat* _subsample_idx ) -{ - bool result = false; - - CV_FUNCNAME( "CvDTree::train" ); - - __BEGIN__; - - clear(); - data = _data; - data->shared = true; - CV_CALL( result = do_train(_subsample_idx)); - - __END__; - - return result; -} - - -bool CvDTree::do_train( const CvMat* _subsample_idx ) -{ - bool result = false; - - CV_FUNCNAME( "CvDTree::do_train" ); - - __BEGIN__; - - root = data->subsample_data( _subsample_idx ); - - CV_CALL( try_split_node(root)); - - if( root->split ) - { - CV_Assert( root->left ); - CV_Assert( root->right ); - - if( data->params.cv_folds > 0 ) - CV_CALL( prune_cv() ); - - if( !data->shared ) - data->free_train_data(); - - result = true; - } - - __END__; - - return result; -} - - -void CvDTree::try_split_node( CvDTreeNode* node ) -{ - CvDTreeSplit* best_split = 0; - int i, n = node->sample_count, vi; - bool can_split = true; - double quality_scale; - - calc_node_value( node ); - - if( node->sample_count <= data->params.min_sample_count || - node->depth >= data->params.max_depth ) - can_split = false; - - if( can_split && data->is_classifier ) - { - // check if we have a "pure" node, - // we assume that cls_count is filled by calc_node_value() - int* cls_count = data->counts->data.i; - int nz = 0, m = data->get_num_classes(); - for( i = 0; i < m; i++ ) - nz += cls_count[i] != 0; - if( nz == 1 ) // there is only one class - can_split = false; - } - else if( can_split ) - { - if( sqrt(node->node_risk)/n < data->params.regression_accuracy ) - can_split = false; - } - - if( can_split ) - { - best_split = find_best_split(node); - // TODO: check the split quality ... - node->split = best_split; - } - if( !can_split || !best_split ) - { - data->free_node_data(node); - return; - } - - quality_scale = calc_node_dir( node ); - if( data->params.use_surrogates ) - { - // find all the surrogate splits - // and sort them by their similarity to the primary one - for( vi = 0; vi < data->var_count; vi++ ) - { - CvDTreeSplit* split; - int ci = data->get_var_type(vi); - - if( vi == best_split->var_idx ) - continue; - - if( ci >= 0 ) - split = find_surrogate_split_cat( node, vi ); - else - split = find_surrogate_split_ord( node, vi ); - - if( split ) - { - // insert the split - CvDTreeSplit* prev_split = node->split; - split->quality = (float)(split->quality*quality_scale); - - while( prev_split->next && - prev_split->next->quality > split->quality ) - prev_split = prev_split->next; - split->next = prev_split->next; - prev_split->next = split; - } - } - } - split_node_data( node ); - try_split_node( node->left ); - try_split_node( node->right ); -} - - -// calculate direction (left(-1),right(1),missing(0)) -// for each sample using the best split -// the function returns scale coefficients for surrogate split quality factors. -// the scale is applied to normalize surrogate split quality relatively to the -// best (primary) split quality. That is, if a surrogate split is absolutely -// identical to the primary split, its quality will be set to the maximum value = -// quality of the primary split; otherwise, it will be lower. -// besides, the function compute node->maxlr, -// minimum possible quality (w/o considering the above mentioned scale) -// for a surrogate split. Surrogate splits with quality less than node->maxlr -// are not discarded. -double CvDTree::calc_node_dir( CvDTreeNode* node ) -{ - char* dir = (char*)data->direction->data.ptr; - int i, n = node->sample_count, vi = node->split->var_idx; - double L, R; - - assert( !node->split->inversed ); - - if( data->get_var_type(vi) >= 0 ) // split on categorical var - { - cv::AutoBuffer inn_buf(n*(!data->have_priors ? 1 : 2)); - int* labels_buf = inn_buf.data(); - const int* labels = data->get_cat_var_data( node, vi, labels_buf ); - const int* subset = node->split->subset; - if( !data->have_priors ) - { - int sum = 0, sum_abs = 0; - - for( i = 0; i < n; i++ ) - { - int idx = labels[i]; - int d = ( ((idx >= 0)&&(!data->is_buf_16u)) || ((idx != 65535)&&(data->is_buf_16u)) ) ? - CV_DTREE_CAT_DIR(idx,subset) : 0; - sum += d; sum_abs += d & 1; - dir[i] = (char)d; - } - - R = (sum_abs + sum) >> 1; - L = (sum_abs - sum) >> 1; - } - else - { - const double* priors = data->priors_mult->data.db; - double sum = 0, sum_abs = 0; - int* responses_buf = labels_buf + n; - const int* responses = data->get_class_labels(node, responses_buf); - - for( i = 0; i < n; i++ ) - { - int idx = labels[i]; - double w = priors[responses[i]]; - int d = idx >= 0 ? CV_DTREE_CAT_DIR(idx,subset) : 0; - sum += d*w; sum_abs += (d & 1)*w; - dir[i] = (char)d; - } - - R = (sum_abs + sum) * 0.5; - L = (sum_abs - sum) * 0.5; - } - } - else // split on ordered var - { - int split_point = node->split->ord.split_point; - int n1 = node->get_num_valid(vi); - cv::AutoBuffer inn_buf(n*(sizeof(int)*(data->have_priors ? 3 : 2) + sizeof(float))); - float* val_buf = (float*)inn_buf.data(); - int* sorted_buf = (int*)(val_buf + n); - int* sample_idx_buf = sorted_buf + n; - const float* val = 0; - const int* sorted = 0; - data->get_ord_var_data( node, vi, val_buf, sorted_buf, &val, &sorted, sample_idx_buf); - - assert( 0 <= split_point && split_point < n1-1 ); - - if( !data->have_priors ) - { - for( i = 0; i <= split_point; i++ ) - dir[sorted[i]] = (char)-1; - for( ; i < n1; i++ ) - dir[sorted[i]] = (char)1; - for( ; i < n; i++ ) - dir[sorted[i]] = (char)0; - - L = split_point-1; - R = n1 - split_point + 1; - } - else - { - const double* priors = data->priors_mult->data.db; - int* responses_buf = sample_idx_buf + n; - const int* responses = data->get_class_labels(node, responses_buf); - L = R = 0; - - for( i = 0; i <= split_point; i++ ) - { - int idx = sorted[i]; - double w = priors[responses[idx]]; - dir[idx] = (char)-1; - L += w; - } - - for( ; i < n1; i++ ) - { - int idx = sorted[i]; - double w = priors[responses[idx]]; - dir[idx] = (char)1; - R += w; - } - - for( ; i < n; i++ ) - dir[sorted[i]] = (char)0; - } - } - node->maxlr = MAX( L, R ); - return node->split->quality/(L + R); -} - - -namespace cv -{ - -void DefaultDeleter::operator ()(CvDTreeSplit* obj) const { fastFree(obj); } - -DTreeBestSplitFinder::DTreeBestSplitFinder( CvDTree* _tree, CvDTreeNode* _node) -{ - tree = _tree; - node = _node; - splitSize = tree->get_data()->split_heap->elem_size; - - bestSplit.reset((CvDTreeSplit*)fastMalloc(splitSize)); - memset(bestSplit.get(), 0, splitSize); - bestSplit->quality = -1; - bestSplit->condensed_idx = INT_MIN; - split.reset((CvDTreeSplit*)fastMalloc(splitSize)); - memset(split.get(), 0, splitSize); - //haveSplit = false; -} - -DTreeBestSplitFinder::DTreeBestSplitFinder( const DTreeBestSplitFinder& finder, Split ) -{ - tree = finder.tree; - node = finder.node; - splitSize = tree->get_data()->split_heap->elem_size; - - bestSplit.reset((CvDTreeSplit*)fastMalloc(splitSize)); - memcpy(bestSplit.get(), finder.bestSplit.get(), splitSize); - split.reset((CvDTreeSplit*)fastMalloc(splitSize)); - memset(split.get(), 0, splitSize); -} - -void DTreeBestSplitFinder::operator()(const BlockedRange& range) -{ - int vi, vi1 = range.begin(), vi2 = range.end(); - int n = node->sample_count; - CvDTreeTrainData* data = tree->get_data(); - AutoBuffer inn_buf(2*n*(sizeof(int) + sizeof(float))); - - for( vi = vi1; vi < vi2; vi++ ) - { - CvDTreeSplit *res; - int ci = data->get_var_type(vi); - if( node->get_num_valid(vi) <= 1 ) - continue; - - if( data->is_classifier ) - { - if( ci >= 0 ) - res = tree->find_split_cat_class( node, vi, bestSplit->quality, split, inn_buf.data() ); - else - res = tree->find_split_ord_class( node, vi, bestSplit->quality, split, inn_buf.data() ); - } - else - { - if( ci >= 0 ) - res = tree->find_split_cat_reg( node, vi, bestSplit->quality, split, inn_buf.data() ); - else - res = tree->find_split_ord_reg( node, vi, bestSplit->quality, split, inn_buf.data() ); - } - - if( res && bestSplit->quality < split->quality ) - memcpy( bestSplit.get(), split.get(), splitSize ); - } -} - -void DTreeBestSplitFinder::join( DTreeBestSplitFinder& rhs ) -{ - if( bestSplit->quality < rhs.bestSplit->quality ) - memcpy( bestSplit.get(), rhs.bestSplit.get(), splitSize ); -} -} - - -CvDTreeSplit* CvDTree::find_best_split( CvDTreeNode* node ) -{ - DTreeBestSplitFinder finder( this, node ); - - cv::parallel_reduce(cv::BlockedRange(0, data->var_count), finder); - - CvDTreeSplit *bestSplit = 0; - if( finder.bestSplit->quality > 0 ) - { - bestSplit = data->new_split_cat( 0, -1.0f ); - memcpy( bestSplit, finder.bestSplit, finder.splitSize ); - } - - return bestSplit; -} - -CvDTreeSplit* CvDTree::find_split_ord_class( CvDTreeNode* node, int vi, - float init_quality, CvDTreeSplit* _split, uchar* _ext_buf ) -{ - const float epsilon = FLT_EPSILON*2; - int n = node->sample_count; - int n1 = node->get_num_valid(vi); - int m = data->get_num_classes(); - - int base_size = 2*m*sizeof(int); - cv::AutoBuffer inn_buf(base_size); - if( !_ext_buf ) - inn_buf.allocate(base_size + n*(3*sizeof(int)+sizeof(float))); - uchar* base_buf = inn_buf.data(); - uchar* ext_buf = _ext_buf ? _ext_buf : base_buf + base_size; - float* values_buf = (float*)ext_buf; - int* sorted_indices_buf = (int*)(values_buf + n); - int* sample_indices_buf = sorted_indices_buf + n; - const float* values = 0; - const int* sorted_indices = 0; - data->get_ord_var_data( node, vi, values_buf, sorted_indices_buf, &values, - &sorted_indices, sample_indices_buf ); - int* responses_buf = sample_indices_buf + n; - const int* responses = data->get_class_labels( node, responses_buf ); - - const int* rc0 = data->counts->data.i; - int* lc = (int*)base_buf; - int* rc = lc + m; - int i, best_i = -1; - double lsum2 = 0, rsum2 = 0, best_val = init_quality; - const double* priors = data->have_priors ? data->priors_mult->data.db : 0; - - // init arrays of class instance counters on both sides of the split - for( i = 0; i < m; i++ ) - { - lc[i] = 0; - rc[i] = rc0[i]; - } - - // compensate for missing values - for( i = n1; i < n; i++ ) - { - rc[responses[sorted_indices[i]]]--; - } - - if( !priors ) - { - int L = 0, R = n1; - - for( i = 0; i < m; i++ ) - rsum2 += (double)rc[i]*rc[i]; - - for( i = 0; i < n1 - 1; i++ ) - { - int idx = responses[sorted_indices[i]]; - int lv, rv; - L++; R--; - lv = lc[idx]; rv = rc[idx]; - lsum2 += lv*2 + 1; - rsum2 -= rv*2 - 1; - lc[idx] = lv + 1; rc[idx] = rv - 1; - - if( values[i] + epsilon < values[i+1] ) - { - double val = (lsum2*R + rsum2*L)/((double)L*R); - if( best_val < val ) - { - best_val = val; - best_i = i; - } - } - } - } - else - { - double L = 0, R = 0; - for( i = 0; i < m; i++ ) - { - double wv = rc[i]*priors[i]; - R += wv; - rsum2 += wv*wv; - } - - for( i = 0; i < n1 - 1; i++ ) - { - int idx = responses[sorted_indices[i]]; - int lv, rv; - double p = priors[idx], p2 = p*p; - L += p; R -= p; - lv = lc[idx]; rv = rc[idx]; - lsum2 += p2*(lv*2 + 1); - rsum2 -= p2*(rv*2 - 1); - lc[idx] = lv + 1; rc[idx] = rv - 1; - - if( values[i] + epsilon < values[i+1] ) - { - double val = (lsum2*R + rsum2*L)/((double)L*R); - if( best_val < val ) - { - best_val = val; - best_i = i; - } - } - } - } - - CvDTreeSplit* split = 0; - if( best_i >= 0 ) - { - split = _split ? _split : data->new_split_ord( 0, 0.0f, 0, 0, 0.0f ); - split->var_idx = vi; - split->ord.c = (values[best_i] + values[best_i+1])*0.5f; - split->ord.split_point = best_i; - split->inversed = 0; - split->quality = (float)best_val; - } - return split; -} - - -void CvDTree::cluster_categories( const int* vectors, int n, int m, - int* csums, int k, int* labels ) -{ - // TODO: consider adding priors (class weights) and sample weights to the clustering algorithm - int iters = 0, max_iters = 100; - int i, j, idx; - cv::AutoBuffer buf(n + k); - double *v_weights = buf.data(), *c_weights = buf.data() + n; - bool modified = true; - RNG* r = data->rng; - - // assign labels randomly - for( i = 0; i < n; i++ ) - { - int sum = 0; - const int* v = vectors + i*m; - labels[i] = i < k ? i : r->uniform(0, k); - - // compute weight of each vector - for( j = 0; j < m; j++ ) - sum += v[j]; - v_weights[i] = sum ? 1./sum : 0.; - } - - for( i = 0; i < n; i++ ) - { - int i1 = (*r)(n); - int i2 = (*r)(n); - CV_SWAP( labels[i1], labels[i2], j ); - } - - for( iters = 0; iters <= max_iters; iters++ ) - { - // calculate csums - for( i = 0; i < k; i++ ) - { - for( j = 0; j < m; j++ ) - csums[i*m + j] = 0; - } - - for( i = 0; i < n; i++ ) - { - const int* v = vectors + i*m; - int* s = csums + labels[i]*m; - for( j = 0; j < m; j++ ) - s[j] += v[j]; - } - - // exit the loop here, when we have up-to-date csums - if( iters == max_iters || !modified ) - break; - - modified = false; - - // calculate weight of each cluster - for( i = 0; i < k; i++ ) - { - const int* s = csums + i*m; - int sum = 0; - for( j = 0; j < m; j++ ) - sum += s[j]; - c_weights[i] = sum ? 1./sum : 0; - } - - // now for each vector determine the closest cluster - for( i = 0; i < n; i++ ) - { - const int* v = vectors + i*m; - double alpha = v_weights[i]; - double min_dist2 = DBL_MAX; - int min_idx = -1; - - for( idx = 0; idx < k; idx++ ) - { - const int* s = csums + idx*m; - double dist2 = 0., beta = c_weights[idx]; - for( j = 0; j < m; j++ ) - { - double t = v[j]*alpha - s[j]*beta; - dist2 += t*t; - } - if( min_dist2 > dist2 ) - { - min_dist2 = dist2; - min_idx = idx; - } - } - - if( min_idx != labels[i] ) - modified = true; - labels[i] = min_idx; - } - } -} - - -CvDTreeSplit* CvDTree::find_split_cat_class( CvDTreeNode* node, int vi, float init_quality, - CvDTreeSplit* _split, uchar* _ext_buf ) -{ - int ci = data->get_var_type(vi); - int n = node->sample_count; - int m = data->get_num_classes(); - int _mi = data->cat_count->data.i[ci], mi = _mi; - - int base_size = m*(3 + mi)*sizeof(int) + (mi+1)*sizeof(double); - if( m > 2 && mi > data->params.max_categories ) - base_size += (m*std::min(data->params.max_categories, n) + mi)*sizeof(int); - else - base_size += mi*sizeof(int*); - cv::AutoBuffer inn_buf(base_size); - if( !_ext_buf ) - inn_buf.allocate(base_size + 2*n*sizeof(int)); - uchar* base_buf = inn_buf.data(); - uchar* ext_buf = _ext_buf ? _ext_buf : base_buf + base_size; - - int* lc = (int*)base_buf; - int* rc = lc + m; - int* _cjk = rc + m*2, *cjk = _cjk; - double* c_weights = (double*)alignPtr(cjk + m*mi, sizeof(double)); - - int* labels_buf = (int*)ext_buf; - const int* labels = data->get_cat_var_data(node, vi, labels_buf); - int* responses_buf = labels_buf + n; - const int* responses = data->get_class_labels(node, responses_buf); - - int* cluster_labels = 0; - int** int_ptr = 0; - int i, j, k, idx; - double L = 0, R = 0; - double best_val = init_quality; - int prevcode = 0, best_subset = -1, subset_i, subset_n, subtract = 0; - const double* priors = data->priors_mult->data.db; - - // init array of counters: - // c_{jk} - number of samples that have vi-th input variable = j and response = k. - for( j = -1; j < mi; j++ ) - for( k = 0; k < m; k++ ) - cjk[j*m + k] = 0; - - for( i = 0; i < n; i++ ) - { - j = ( labels[i] == 65535 && data->is_buf_16u) ? -1 : labels[i]; - k = responses[i]; - cjk[j*m + k]++; - } - - if( m > 2 ) - { - if( mi > data->params.max_categories ) - { - mi = MIN(data->params.max_categories, n); - cjk = (int*)(c_weights + _mi); - cluster_labels = cjk + m*mi; - cluster_categories( _cjk, _mi, m, cjk, mi, cluster_labels ); - } - subset_i = 1; - subset_n = 1 << mi; - } - else - { - assert( m == 2 ); - int_ptr = (int**)(c_weights + _mi); - for( j = 0; j < mi; j++ ) - int_ptr[j] = cjk + j*2 + 1; - std::sort(int_ptr, int_ptr + mi, LessThanPtr()); - subset_i = 0; - subset_n = mi; - } - - for( k = 0; k < m; k++ ) - { - int sum = 0; - for( j = 0; j < mi; j++ ) - sum += cjk[j*m + k]; - rc[k] = sum; - lc[k] = 0; - } - - for( j = 0; j < mi; j++ ) - { - double sum = 0; - for( k = 0; k < m; k++ ) - sum += cjk[j*m + k]*priors[k]; - c_weights[j] = sum; - R += c_weights[j]; - } - - for( ; subset_i < subset_n; subset_i++ ) - { - double weight; - int* crow; - double lsum2 = 0, rsum2 = 0; - - if( m == 2 ) - idx = (int)(int_ptr[subset_i] - cjk)/2; - else - { - int graycode = (subset_i>>1)^subset_i; - int diff = graycode ^ prevcode; - - // determine index of the changed bit. - Cv32suf u; - idx = diff >= (1 << 16) ? 16 : 0; - u.f = (float)(((diff >> 16) | diff) & 65535); - idx += (u.i >> 23) - 127; - subtract = graycode < prevcode; - prevcode = graycode; - } - - crow = cjk + idx*m; - weight = c_weights[idx]; - if( weight < FLT_EPSILON ) - continue; - - if( !subtract ) - { - for( k = 0; k < m; k++ ) - { - int t = crow[k]; - int lval = lc[k] + t; - int rval = rc[k] - t; - double p = priors[k], p2 = p*p; - lsum2 += p2*lval*lval; - rsum2 += p2*rval*rval; - lc[k] = lval; rc[k] = rval; - } - L += weight; - R -= weight; - } - else - { - for( k = 0; k < m; k++ ) - { - int t = crow[k]; - int lval = lc[k] - t; - int rval = rc[k] + t; - double p = priors[k], p2 = p*p; - lsum2 += p2*lval*lval; - rsum2 += p2*rval*rval; - lc[k] = lval; rc[k] = rval; - } - L -= weight; - R += weight; - } - - if( L > FLT_EPSILON && R > FLT_EPSILON ) - { - double val = (lsum2*R + rsum2*L)/((double)L*R); - if( best_val < val ) - { - best_val = val; - best_subset = subset_i; - } - } - } - - CvDTreeSplit* split = 0; - if( best_subset >= 0 ) - { - split = _split ? _split : data->new_split_cat( 0, -1.0f ); - split->var_idx = vi; - split->quality = (float)best_val; - memset( split->subset, 0, (data->max_c_count + 31)/32 * sizeof(int)); - if( m == 2 ) - { - for( i = 0; i <= best_subset; i++ ) - { - idx = (int)(int_ptr[i] - cjk) >> 1; - split->subset[idx >> 5] |= 1 << (idx & 31); - } - } - else - { - for( i = 0; i < _mi; i++ ) - { - idx = cluster_labels ? cluster_labels[i] : i; - if( best_subset & (1 << idx) ) - split->subset[i >> 5] |= 1 << (i & 31); - } - } - } - return split; -} - - -CvDTreeSplit* CvDTree::find_split_ord_reg( CvDTreeNode* node, int vi, float init_quality, CvDTreeSplit* _split, uchar* _ext_buf ) -{ - const float epsilon = FLT_EPSILON*2; - int n = node->sample_count; - int n1 = node->get_num_valid(vi); - - cv::AutoBuffer inn_buf; - if( !_ext_buf ) - inn_buf.allocate(2*n*(sizeof(int) + sizeof(float))); - uchar* ext_buf = _ext_buf ? _ext_buf : inn_buf.data(); - float* values_buf = (float*)ext_buf; - int* sorted_indices_buf = (int*)(values_buf + n); - int* sample_indices_buf = sorted_indices_buf + n; - const float* values = 0; - const int* sorted_indices = 0; - data->get_ord_var_data( node, vi, values_buf, sorted_indices_buf, &values, &sorted_indices, sample_indices_buf ); - float* responses_buf = (float*)(sample_indices_buf + n); - const float* responses = data->get_ord_responses( node, responses_buf, sample_indices_buf ); - - int i, best_i = -1; - double best_val = init_quality, lsum = 0, rsum = node->value*n; - int L = 0, R = n1; - - // compensate for missing values - for( i = n1; i < n; i++ ) - rsum -= responses[sorted_indices[i]]; - - // find the optimal split - for( i = 0; i < n1 - 1; i++ ) - { - float t = responses[sorted_indices[i]]; - L++; R--; - lsum += t; - rsum -= t; - - if( values[i] + epsilon < values[i+1] ) - { - double val = (lsum*lsum*R + rsum*rsum*L)/((double)L*R); - if( best_val < val ) - { - best_val = val; - best_i = i; - } - } - } - - CvDTreeSplit* split = 0; - if( best_i >= 0 ) - { - split = _split ? _split : data->new_split_ord( 0, 0.0f, 0, 0, 0.0f ); - split->var_idx = vi; - split->ord.c = (values[best_i] + values[best_i+1])*0.5f; - split->ord.split_point = best_i; - split->inversed = 0; - split->quality = (float)best_val; - } - return split; -} - -CvDTreeSplit* CvDTree::find_split_cat_reg( CvDTreeNode* node, int vi, float init_quality, CvDTreeSplit* _split, uchar* _ext_buf ) -{ - int ci = data->get_var_type(vi); - int n = node->sample_count; - int mi = data->cat_count->data.i[ci]; - - int base_size = (mi+2)*sizeof(double) + (mi+1)*(sizeof(int) + sizeof(double*)); - cv::AutoBuffer inn_buf(base_size); - if( !_ext_buf ) - inn_buf.allocate(base_size + n*(2*sizeof(int) + sizeof(float))); - uchar* base_buf = inn_buf.data(); - uchar* ext_buf = _ext_buf ? _ext_buf : base_buf + base_size; - int* labels_buf = (int*)ext_buf; - const int* labels = data->get_cat_var_data(node, vi, labels_buf); - float* responses_buf = (float*)(labels_buf + n); - int* sample_indices_buf = (int*)(responses_buf + n); - const float* responses = data->get_ord_responses(node, responses_buf, sample_indices_buf); - - double* sum = (double*)cv::alignPtr(base_buf,sizeof(double)) + 1; - int* counts = (int*)(sum + mi) + 1; - double** sum_ptr = (double**)(counts + mi); - int i, L = 0, R = 0; - double best_val = init_quality, lsum = 0, rsum = 0; - int best_subset = -1, subset_i; - - for( i = -1; i < mi; i++ ) - sum[i] = counts[i] = 0; - - // calculate sum response and weight of each category of the input var - for( i = 0; i < n; i++ ) - { - int idx = ( (labels[i] == 65535) && data->is_buf_16u ) ? -1 : labels[i]; - double s = sum[idx] + responses[i]; - int nc = counts[idx] + 1; - sum[idx] = s; - counts[idx] = nc; - } - - // calculate average response in each category - for( i = 0; i < mi; i++ ) - { - R += counts[i]; - rsum += sum[i]; - sum[i] /= MAX(counts[i],1); - sum_ptr[i] = sum + i; - } - - std::sort(sum_ptr, sum_ptr + mi, LessThanPtr()); - - // revert back to unnormalized sums - // (there should be a very little loss of accuracy) - for( i = 0; i < mi; i++ ) - sum[i] *= counts[i]; - - for( subset_i = 0; subset_i < mi-1; subset_i++ ) - { - int idx = (int)(sum_ptr[subset_i] - sum); - int ni = counts[idx]; - - if( ni ) - { - double s = sum[idx]; - lsum += s; L += ni; - rsum -= s; R -= ni; - - if( L && R ) - { - double val = (lsum*lsum*R + rsum*rsum*L)/((double)L*R); - if( best_val < val ) - { - best_val = val; - best_subset = subset_i; - } - } - } - } - - CvDTreeSplit* split = 0; - if( best_subset >= 0 ) - { - split = _split ? _split : data->new_split_cat( 0, -1.0f); - split->var_idx = vi; - split->quality = (float)best_val; - memset( split->subset, 0, (data->max_c_count + 31)/32 * sizeof(int)); - for( i = 0; i <= best_subset; i++ ) - { - int idx = (int)(sum_ptr[i] - sum); - split->subset[idx >> 5] |= 1 << (idx & 31); - } - } - return split; -} - -CvDTreeSplit* CvDTree::find_surrogate_split_ord( CvDTreeNode* node, int vi, uchar* _ext_buf ) -{ - const float epsilon = FLT_EPSILON*2; - const char* dir = (char*)data->direction->data.ptr; - int n = node->sample_count, n1 = node->get_num_valid(vi); - cv::AutoBuffer inn_buf; - if( !_ext_buf ) - inn_buf.allocate( n*(sizeof(int)*(data->have_priors ? 3 : 2) + sizeof(float)) ); - uchar* ext_buf = _ext_buf ? _ext_buf : inn_buf.data(); - float* values_buf = (float*)ext_buf; - int* sorted_indices_buf = (int*)(values_buf + n); - int* sample_indices_buf = sorted_indices_buf + n; - const float* values = 0; - const int* sorted_indices = 0; - data->get_ord_var_data( node, vi, values_buf, sorted_indices_buf, &values, &sorted_indices, sample_indices_buf ); - // LL - number of samples that both the primary and the surrogate splits send to the left - // LR - ... primary split sends to the left and the surrogate split sends to the right - // RL - ... primary split sends to the right and the surrogate split sends to the left - // RR - ... both send to the right - int i, best_i = -1, best_inversed = 0; - double best_val; - - if( !data->have_priors ) - { - int LL = 0, RL = 0, LR, RR; - int worst_val = cvFloor(node->maxlr), _best_val = worst_val; - int sum = 0, sum_abs = 0; - - for( i = 0; i < n1; i++ ) - { - int d = dir[sorted_indices[i]]; - sum += d; sum_abs += d & 1; - } - - // sum_abs = R + L; sum = R - L - RR = (sum_abs + sum) >> 1; - LR = (sum_abs - sum) >> 1; - - // initially all the samples are sent to the right by the surrogate split, - // LR of them are sent to the left by primary split, and RR - to the right. - // now iteratively compute LL, LR, RL and RR for every possible surrogate split value. - for( i = 0; i < n1 - 1; i++ ) - { - int d = dir[sorted_indices[i]]; - - if( d < 0 ) - { - LL++; LR--; - if( LL + RR > _best_val && values[i] + epsilon < values[i+1] ) - { - best_val = LL + RR; - best_i = i; best_inversed = 0; - } - } - else if( d > 0 ) - { - RL++; RR--; - if( RL + LR > _best_val && values[i] + epsilon < values[i+1] ) - { - best_val = RL + LR; - best_i = i; best_inversed = 1; - } - } - } - best_val = _best_val; - } - else - { - double LL = 0, RL = 0, LR, RR; - double worst_val = node->maxlr; - double sum = 0, sum_abs = 0; - const double* priors = data->priors_mult->data.db; - int* responses_buf = sample_indices_buf + n; - const int* responses = data->get_class_labels(node, responses_buf); - best_val = worst_val; - - for( i = 0; i < n1; i++ ) - { - int idx = sorted_indices[i]; - double w = priors[responses[idx]]; - int d = dir[idx]; - sum += d*w; sum_abs += (d & 1)*w; - } - - // sum_abs = R + L; sum = R - L - RR = (sum_abs + sum)*0.5; - LR = (sum_abs - sum)*0.5; - - // initially all the samples are sent to the right by the surrogate split, - // LR of them are sent to the left by primary split, and RR - to the right. - // now iteratively compute LL, LR, RL and RR for every possible surrogate split value. - for( i = 0; i < n1 - 1; i++ ) - { - int idx = sorted_indices[i]; - double w = priors[responses[idx]]; - int d = dir[idx]; - - if( d < 0 ) - { - LL += w; LR -= w; - if( LL + RR > best_val && values[i] + epsilon < values[i+1] ) - { - best_val = LL + RR; - best_i = i; best_inversed = 0; - } - } - else if( d > 0 ) - { - RL += w; RR -= w; - if( RL + LR > best_val && values[i] + epsilon < values[i+1] ) - { - best_val = RL + LR; - best_i = i; best_inversed = 1; - } - } - } - } - return best_i >= 0 && best_val > node->maxlr ? data->new_split_ord( vi, - (values[best_i] + values[best_i+1])*0.5f, best_i, best_inversed, (float)best_val ) : 0; -} - - -CvDTreeSplit* CvDTree::find_surrogate_split_cat( CvDTreeNode* node, int vi, uchar* _ext_buf ) -{ - const char* dir = (char*)data->direction->data.ptr; - int n = node->sample_count; - int i, mi = data->cat_count->data.i[data->get_var_type(vi)], l_win = 0; - - int base_size = (2*(mi+1)+1)*sizeof(double) + (!data->have_priors ? 2*(mi+1)*sizeof(int) : 0); - cv::AutoBuffer inn_buf(base_size); - if( !_ext_buf ) - inn_buf.allocate(base_size + n*(sizeof(int) + (data->have_priors ? sizeof(int) : 0))); - uchar* base_buf = inn_buf.data(); - uchar* ext_buf = _ext_buf ? _ext_buf : base_buf + base_size; - - int* labels_buf = (int*)ext_buf; - const int* labels = data->get_cat_var_data(node, vi, labels_buf); - // LL - number of samples that both the primary and the surrogate splits send to the left - // LR - ... primary split sends to the left and the surrogate split sends to the right - // RL - ... primary split sends to the right and the surrogate split sends to the left - // RR - ... both send to the right - CvDTreeSplit* split = data->new_split_cat( vi, 0 ); - double best_val = 0; - double* lc = (double*)cv::alignPtr(base_buf,sizeof(double)) + 1; - double* rc = lc + mi + 1; - - for( i = -1; i < mi; i++ ) - lc[i] = rc[i] = 0; - - // for each category calculate the weight of samples - // sent to the left (lc) and to the right (rc) by the primary split - if( !data->have_priors ) - { - int* _lc = (int*)rc + 1; - int* _rc = _lc + mi + 1; - - for( i = -1; i < mi; i++ ) - _lc[i] = _rc[i] = 0; - - for( i = 0; i < n; i++ ) - { - int idx = ( (labels[i] == 65535) && (data->is_buf_16u) ) ? -1 : labels[i]; - int d = dir[i]; - int sum = _lc[idx] + d; - int sum_abs = _rc[idx] + (d & 1); - _lc[idx] = sum; _rc[idx] = sum_abs; - } - - for( i = 0; i < mi; i++ ) - { - int sum = _lc[i]; - int sum_abs = _rc[i]; - lc[i] = (sum_abs - sum) >> 1; - rc[i] = (sum_abs + sum) >> 1; - } - } - else - { - const double* priors = data->priors_mult->data.db; - int* responses_buf = labels_buf + n; - const int* responses = data->get_class_labels(node, responses_buf); - - for( i = 0; i < n; i++ ) - { - int idx = ( (labels[i] == 65535) && (data->is_buf_16u) ) ? -1 : labels[i]; - double w = priors[responses[i]]; - int d = dir[i]; - double sum = lc[idx] + d*w; - double sum_abs = rc[idx] + (d & 1)*w; - lc[idx] = sum; rc[idx] = sum_abs; - } - - for( i = 0; i < mi; i++ ) - { - double sum = lc[i]; - double sum_abs = rc[i]; - lc[i] = (sum_abs - sum) * 0.5; - rc[i] = (sum_abs + sum) * 0.5; - } - } - - // 2. now form the split. - // in each category send all the samples to the same direction as majority - for( i = 0; i < mi; i++ ) - { - double lval = lc[i], rval = rc[i]; - if( lval > rval ) - { - split->subset[i >> 5] |= 1 << (i & 31); - best_val += lval; - l_win++; - } - else - best_val += rval; - } - - split->quality = (float)best_val; - if( split->quality <= node->maxlr || l_win == 0 || l_win == mi ) - cvSetRemoveByPtr( data->split_heap, split ), split = 0; - - return split; -} - - -void CvDTree::calc_node_value( CvDTreeNode* node ) -{ - int i, j, k, n = node->sample_count, cv_n = data->params.cv_folds; - int m = data->get_num_classes(); - - int base_size = data->is_classifier ? m*cv_n*sizeof(int) : 2*cv_n*sizeof(double)+cv_n*sizeof(int); - int ext_size = n*(sizeof(int) + (data->is_classifier ? sizeof(int) : sizeof(int)+sizeof(float))); - cv::AutoBuffer inn_buf(base_size + ext_size); - uchar* base_buf = inn_buf.data(); - uchar* ext_buf = base_buf + base_size; - - int* cv_labels_buf = (int*)ext_buf; - const int* cv_labels = data->get_cv_labels(node, cv_labels_buf); - - if( data->is_classifier ) - { - // in case of classification tree: - // * node value is the label of the class that has the largest weight in the node. - // * node risk is the weighted number of misclassified samples, - // * j-th cross-validation fold value and risk are calculated as above, - // but using the samples with cv_labels(*)!=j. - // * j-th cross-validation fold error is calculated as the weighted number of - // misclassified samples with cv_labels(*)==j. - - // compute the number of instances of each class - int* cls_count = data->counts->data.i; - int* responses_buf = cv_labels_buf + n; - const int* responses = data->get_class_labels(node, responses_buf); - int* cv_cls_count = (int*)base_buf; - double max_val = -1, total_weight = 0; - int max_k = -1; - double* priors = data->priors_mult->data.db; - - for( k = 0; k < m; k++ ) - cls_count[k] = 0; - - if( cv_n == 0 ) - { - for( i = 0; i < n; i++ ) - cls_count[responses[i]]++; - } - else - { - for( j = 0; j < cv_n; j++ ) - for( k = 0; k < m; k++ ) - cv_cls_count[j*m + k] = 0; - - for( i = 0; i < n; i++ ) - { - j = cv_labels[i]; k = responses[i]; - cv_cls_count[j*m + k]++; - } - - for( j = 0; j < cv_n; j++ ) - for( k = 0; k < m; k++ ) - cls_count[k] += cv_cls_count[j*m + k]; - } - - if( data->have_priors && node->parent == 0 ) - { - // compute priors_mult from priors, take the sample ratio into account. - double sum = 0; - for( k = 0; k < m; k++ ) - { - int n_k = cls_count[k]; - priors[k] = data->priors->data.db[k]*(n_k ? 1./n_k : 0.); - sum += priors[k]; - } - sum = 1./sum; - for( k = 0; k < m; k++ ) - priors[k] *= sum; - } - - for( k = 0; k < m; k++ ) - { - double val = cls_count[k]*priors[k]; - total_weight += val; - if( max_val < val ) - { - max_val = val; - max_k = k; - } - } - - node->class_idx = max_k; - node->value = data->cat_map->data.i[ - data->cat_ofs->data.i[data->cat_var_count] + max_k]; - node->node_risk = total_weight - max_val; - - for( j = 0; j < cv_n; j++ ) - { - double sum_k = 0, sum = 0, max_val_k = 0; - max_val = -1; max_k = -1; - - for( k = 0; k < m; k++ ) - { - double w = priors[k]; - double val_k = cv_cls_count[j*m + k]*w; - double val = cls_count[k]*w - val_k; - sum_k += val_k; - sum += val; - if( max_val < val ) - { - max_val = val; - max_val_k = val_k; - max_k = k; - } - } - - node->cv_Tn[j] = INT_MAX; - node->cv_node_risk[j] = sum - max_val; - node->cv_node_error[j] = sum_k - max_val_k; - } - } - else - { - // in case of regression tree: - // * node value is 1/n*sum_i(Y_i), where Y_i is i-th response, - // n is the number of samples in the node. - // * node risk is the sum of squared errors: sum_i((Y_i - )^2) - // * j-th cross-validation fold value and risk are calculated as above, - // but using the samples with cv_labels(*)!=j. - // * j-th cross-validation fold error is calculated - // using samples with cv_labels(*)==j as the test subset: - // error_j = sum_(i,cv_labels(i)==j)((Y_i - )^2), - // where node_value_j is the node value calculated - // as described in the previous bullet, and summation is done - // over the samples with cv_labels(*)==j. - - double sum = 0, sum2 = 0; - float* values_buf = (float*)(cv_labels_buf + n); - int* sample_indices_buf = (int*)(values_buf + n); - const float* values = data->get_ord_responses(node, values_buf, sample_indices_buf); - double *cv_sum = 0, *cv_sum2 = 0; - int* cv_count = 0; - - if( cv_n == 0 ) - { - for( i = 0; i < n; i++ ) - { - double t = values[i]; - sum += t; - sum2 += t*t; - } - } - else - { - cv_sum = (double*)base_buf; - cv_sum2 = cv_sum + cv_n; - cv_count = (int*)(cv_sum2 + cv_n); - - for( j = 0; j < cv_n; j++ ) - { - cv_sum[j] = cv_sum2[j] = 0.; - cv_count[j] = 0; - } - - for( i = 0; i < n; i++ ) - { - j = cv_labels[i]; - double t = values[i]; - double s = cv_sum[j] + t; - double s2 = cv_sum2[j] + t*t; - int nc = cv_count[j] + 1; - cv_sum[j] = s; - cv_sum2[j] = s2; - cv_count[j] = nc; - } - - for( j = 0; j < cv_n; j++ ) - { - sum += cv_sum[j]; - sum2 += cv_sum2[j]; - } - } - - node->node_risk = sum2 - (sum/n)*sum; - node->value = sum/n; - - for( j = 0; j < cv_n; j++ ) - { - double s = cv_sum[j], si = sum - s; - double s2 = cv_sum2[j], s2i = sum2 - s2; - int c = cv_count[j], ci = n - c; - double r = si/MAX(ci,1); - node->cv_node_risk[j] = s2i - r*r*ci; - node->cv_node_error[j] = s2 - 2*r*s + c*r*r; - node->cv_Tn[j] = INT_MAX; - } - } -} - - -void CvDTree::complete_node_dir( CvDTreeNode* node ) -{ - int vi, i, n = node->sample_count, nl, nr, d0 = 0, d1 = -1; - int nz = n - node->get_num_valid(node->split->var_idx); - char* dir = (char*)data->direction->data.ptr; - - // try to complete direction using surrogate splits - if( nz && data->params.use_surrogates ) - { - cv::AutoBuffer inn_buf(n*(2*sizeof(int)+sizeof(float))); - CvDTreeSplit* split = node->split->next; - for( ; split != 0 && nz; split = split->next ) - { - int inversed_mask = split->inversed ? -1 : 0; - vi = split->var_idx; - - if( data->get_var_type(vi) >= 0 ) // split on categorical var - { - int* labels_buf = (int*)inn_buf.data(); - const int* labels = data->get_cat_var_data(node, vi, labels_buf); - const int* subset = split->subset; - - for( i = 0; i < n; i++ ) - { - int idx = labels[i]; - if( !dir[i] && ( ((idx >= 0)&&(!data->is_buf_16u)) || ((idx != 65535)&&(data->is_buf_16u)) )) - - { - int d = CV_DTREE_CAT_DIR(idx,subset); - dir[i] = (char)((d ^ inversed_mask) - inversed_mask); - if( --nz ) - break; - } - } - } - else // split on ordered var - { - float* values_buf = (float*)inn_buf.data(); - int* sorted_indices_buf = (int*)(values_buf + n); - int* sample_indices_buf = sorted_indices_buf + n; - const float* values = 0; - const int* sorted_indices = 0; - data->get_ord_var_data( node, vi, values_buf, sorted_indices_buf, &values, &sorted_indices, sample_indices_buf ); - int split_point = split->ord.split_point; - int n1 = node->get_num_valid(vi); - - assert( 0 <= split_point && split_point < n-1 ); - - for( i = 0; i < n1; i++ ) - { - int idx = sorted_indices[i]; - if( !dir[idx] ) - { - int d = i <= split_point ? -1 : 1; - dir[idx] = (char)((d ^ inversed_mask) - inversed_mask); - if( --nz ) - break; - } - } - } - } - } - - // find the default direction for the rest - if( nz ) - { - for( i = nr = 0; i < n; i++ ) - nr += dir[i] > 0; - nl = n - nr - nz; - d0 = nl > nr ? -1 : nr > nl; - } - - // make sure that every sample is directed either to the left or to the right - for( i = 0; i < n; i++ ) - { - int d = dir[i]; - if( !d ) - { - d = d0; - if( !d ) - d = d1, d1 = -d1; - } - d = d > 0; - dir[i] = (char)d; // remap (-1,1) to (0,1) - } -} - - -void CvDTree::split_node_data( CvDTreeNode* node ) -{ - int vi, i, n = node->sample_count, nl, nr, scount = data->sample_count; - char* dir = (char*)data->direction->data.ptr; - CvDTreeNode *left = 0, *right = 0; - int* new_idx = data->split_buf->data.i; - int new_buf_idx = data->get_child_buf_idx( node ); - int work_var_count = data->get_work_var_count(); - CvMat* buf = data->buf; - size_t length_buf_row = data->get_length_subbuf(); - cv::AutoBuffer inn_buf(n*(3*sizeof(int) + sizeof(float))); - int* temp_buf = (int*)inn_buf.data(); - - complete_node_dir(node); - - for( i = nl = nr = 0; i < n; i++ ) - { - int d = dir[i]; - // initialize new indices for splitting ordered variables - new_idx[i] = (nl & (d-1)) | (nr & -d); // d ? ri : li - nr += d; - nl += d^1; - } - - bool split_input_data; - node->left = left = data->new_node( node, nl, new_buf_idx, node->offset ); - node->right = right = data->new_node( node, nr, new_buf_idx, node->offset + nl ); - - split_input_data = node->depth + 1 < data->params.max_depth && - (node->left->sample_count > data->params.min_sample_count || - node->right->sample_count > data->params.min_sample_count); - - // split ordered variables, keep both halves sorted. - for( vi = 0; vi < data->var_count; vi++ ) - { - int ci = data->get_var_type(vi); - - if( ci >= 0 || !split_input_data ) - continue; - - int n1 = node->get_num_valid(vi); - float* src_val_buf = (float*)(uchar*)(temp_buf + n); - int* src_sorted_idx_buf = (int*)(src_val_buf + n); - int* src_sample_idx_buf = src_sorted_idx_buf + n; - const float* src_val = 0; - const int* src_sorted_idx = 0; - data->get_ord_var_data(node, vi, src_val_buf, src_sorted_idx_buf, &src_val, &src_sorted_idx, src_sample_idx_buf); - - for(i = 0; i < n; i++) - temp_buf[i] = src_sorted_idx[i]; - - if (data->is_buf_16u) - { - unsigned short *ldst, *rdst, *ldst0, *rdst0; - //unsigned short tl, tr; - ldst0 = ldst = (unsigned short*)(buf->data.s + left->buf_idx*length_buf_row + - vi*scount + left->offset); - rdst0 = rdst = (unsigned short*)(ldst + nl); - - // split sorted - for( i = 0; i < n1; i++ ) - { - int idx = temp_buf[i]; - int d = dir[idx]; - idx = new_idx[idx]; - if (d) - { - *rdst = (unsigned short)idx; - rdst++; - } - else - { - *ldst = (unsigned short)idx; - ldst++; - } - } - - left->set_num_valid(vi, (int)(ldst - ldst0)); - right->set_num_valid(vi, (int)(rdst - rdst0)); - - // split missing - for( ; i < n; i++ ) - { - int idx = temp_buf[i]; - int d = dir[idx]; - idx = new_idx[idx]; - if (d) - { - *rdst = (unsigned short)idx; - rdst++; - } - else - { - *ldst = (unsigned short)idx; - ldst++; - } - } - } - else - { - int *ldst0, *ldst, *rdst0, *rdst; - ldst0 = ldst = buf->data.i + left->buf_idx*length_buf_row + - vi*scount + left->offset; - rdst0 = rdst = buf->data.i + right->buf_idx*length_buf_row + - vi*scount + right->offset; - - // split sorted - for( i = 0; i < n1; i++ ) - { - int idx = temp_buf[i]; - int d = dir[idx]; - idx = new_idx[idx]; - if (d) - { - *rdst = idx; - rdst++; - } - else - { - *ldst = idx; - ldst++; - } - } - - left->set_num_valid(vi, (int)(ldst - ldst0)); - right->set_num_valid(vi, (int)(rdst - rdst0)); - - // split missing - for( ; i < n; i++ ) - { - int idx = temp_buf[i]; - int d = dir[idx]; - idx = new_idx[idx]; - if (d) - { - *rdst = idx; - rdst++; - } - else - { - *ldst = idx; - ldst++; - } - } - } - } - - // split categorical vars, responses and cv_labels using new_idx relocation table - for( vi = 0; vi < work_var_count; vi++ ) - { - int ci = data->get_var_type(vi); - int n1 = node->get_num_valid(vi), nr1 = 0; - - if( ci < 0 || (vi < data->var_count && !split_input_data) ) - continue; - - int *src_lbls_buf = temp_buf + n; - const int* src_lbls = data->get_cat_var_data(node, vi, src_lbls_buf); - - for(i = 0; i < n; i++) - temp_buf[i] = src_lbls[i]; - - if (data->is_buf_16u) - { - unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*length_buf_row + - vi*scount + left->offset); - unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*length_buf_row + - vi*scount + right->offset); - - for( i = 0; i < n; i++ ) - { - int d = dir[i]; - int idx = temp_buf[i]; - if (d) - { - *rdst = (unsigned short)idx; - rdst++; - nr1 += (idx != 65535 )&d; - } - else - { - *ldst = (unsigned short)idx; - ldst++; - } - } - - if( vi < data->var_count ) - { - left->set_num_valid(vi, n1 - nr1); - right->set_num_valid(vi, nr1); - } - } - else - { - int *ldst = buf->data.i + left->buf_idx*length_buf_row + - vi*scount + left->offset; - int *rdst = buf->data.i + right->buf_idx*length_buf_row + - vi*scount + right->offset; - - for( i = 0; i < n; i++ ) - { - int d = dir[i]; - int idx = temp_buf[i]; - if (d) - { - *rdst = idx; - rdst++; - nr1 += (idx >= 0)&d; - } - else - { - *ldst = idx; - ldst++; - } - - } - - if( vi < data->var_count ) - { - left->set_num_valid(vi, n1 - nr1); - right->set_num_valid(vi, nr1); - } - } - } - - - // split sample indices - int *sample_idx_src_buf = temp_buf + n; - const int* sample_idx_src = data->get_sample_indices(node, sample_idx_src_buf); - - for(i = 0; i < n; i++) - temp_buf[i] = sample_idx_src[i]; - - int pos = data->get_work_var_count(); - if (data->is_buf_16u) - { - unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*length_buf_row + - pos*scount + left->offset); - unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*length_buf_row + - pos*scount + right->offset); - for (i = 0; i < n; i++) - { - int d = dir[i]; - unsigned short idx = (unsigned short)temp_buf[i]; - if (d) - { - *rdst = idx; - rdst++; - } - else - { - *ldst = idx; - ldst++; - } - } - } - else - { - int* ldst = buf->data.i + left->buf_idx*length_buf_row + - pos*scount + left->offset; - int* rdst = buf->data.i + right->buf_idx*length_buf_row + - pos*scount + right->offset; - for (i = 0; i < n; i++) - { - int d = dir[i]; - int idx = temp_buf[i]; - if (d) - { - *rdst = idx; - rdst++; - } - else - { - *ldst = idx; - ldst++; - } - } - } - - // deallocate the parent node data that is not needed anymore - data->free_node_data(node); -} - -float CvDTree::calc_error( CvMLData* _data, int type, std::vector *resp ) -{ - float err = 0; - const CvMat* values = _data->get_values(); - const CvMat* response = _data->get_responses(); - const CvMat* missing = _data->get_missing(); - const CvMat* sample_idx = (type == CV_TEST_ERROR) ? _data->get_test_sample_idx() : _data->get_train_sample_idx(); - const CvMat* var_types = _data->get_var_types(); - int* sidx = sample_idx ? sample_idx->data.i : 0; - int r_step = CV_IS_MAT_CONT(response->type) ? - 1 : response->step / CV_ELEM_SIZE(response->type); - bool is_classifier = var_types->data.ptr[var_types->cols-1] == CV_VAR_CATEGORICAL; - int sample_count = sample_idx ? sample_idx->cols : 0; - sample_count = (type == CV_TRAIN_ERROR && sample_count == 0) ? values->rows : sample_count; - float* pred_resp = 0; - if( resp && (sample_count > 0) ) - { - resp->resize( sample_count ); - pred_resp = &((*resp)[0]); - } - - if ( is_classifier ) - { - for( int i = 0; i < sample_count; i++ ) - { - CvMat sample, miss; - int si = sidx ? sidx[i] : i; - cvGetRow( values, &sample, si ); - if( missing ) - cvGetRow( missing, &miss, si ); - float r = (float)predict( &sample, missing ? &miss : 0 )->value; - if( pred_resp ) - pred_resp[i] = r; - int d = fabs((double)r - response->data.fl[(size_t)si*r_step]) <= FLT_EPSILON ? 0 : 1; - err += d; - } - err = sample_count ? err / (float)sample_count * 100 : -FLT_MAX; - } - else - { - for( int i = 0; i < sample_count; i++ ) - { - CvMat sample, miss; - int si = sidx ? sidx[i] : i; - cvGetRow( values, &sample, si ); - if( missing ) - cvGetRow( missing, &miss, si ); - float r = (float)predict( &sample, missing ? &miss : 0 )->value; - if( pred_resp ) - pred_resp[i] = r; - float d = r - response->data.fl[(size_t)si*r_step]; - err += d*d; - } - err = sample_count ? err / (float)sample_count : -FLT_MAX; - } - return err; -} - -void CvDTree::prune_cv() -{ - CvMat* ab = 0; - CvMat* temp = 0; - CvMat* err_jk = 0; - - // 1. build tree sequence for each cv fold, calculate error_{Tj,beta_k}. - // 2. choose the best tree index (if need, apply 1SE rule). - // 3. store the best index and cut the branches. - - CV_FUNCNAME( "CvDTree::prune_cv" ); - - __BEGIN__; - - int ti, j, tree_count = 0, cv_n = data->params.cv_folds, n = root->sample_count; - // currently, 1SE for regression is not implemented - bool use_1se = data->params.use_1se_rule != 0 && data->is_classifier; - double* err; - double min_err = 0, min_err_se = 0; - int min_idx = -1; - - CV_CALL( ab = cvCreateMat( 1, 256, CV_64F )); - - // build the main tree sequence, calculate alpha's - for(;;tree_count++) - { - double min_alpha = update_tree_rnc(tree_count, -1); - if( cut_tree(tree_count, -1, min_alpha) ) - break; - - if( ab->cols <= tree_count ) - { - CV_CALL( temp = cvCreateMat( 1, ab->cols*3/2, CV_64F )); - for( ti = 0; ti < ab->cols; ti++ ) - temp->data.db[ti] = ab->data.db[ti]; - cvReleaseMat( &ab ); - ab = temp; - temp = 0; - } - - ab->data.db[tree_count] = min_alpha; - } - - ab->data.db[0] = 0.; - - if( tree_count > 0 ) - { - for( ti = 1; ti < tree_count-1; ti++ ) - ab->data.db[ti] = sqrt(ab->data.db[ti]*ab->data.db[ti+1]); - ab->data.db[tree_count-1] = DBL_MAX*0.5; - - CV_CALL( err_jk = cvCreateMat( cv_n, tree_count, CV_64F )); - err = err_jk->data.db; - - for( j = 0; j < cv_n; j++ ) - { - int tj = 0, tk = 0; - for( ; tk < tree_count; tj++ ) - { - double min_alpha = update_tree_rnc(tj, j); - if( cut_tree(tj, j, min_alpha) ) - min_alpha = DBL_MAX; - - for( ; tk < tree_count; tk++ ) - { - if( ab->data.db[tk] > min_alpha ) - break; - err[j*tree_count + tk] = root->tree_error; - } - } - } - - for( ti = 0; ti < tree_count; ti++ ) - { - double sum_err = 0; - for( j = 0; j < cv_n; j++ ) - sum_err += err[j*tree_count + ti]; - if( ti == 0 || sum_err < min_err ) - { - min_err = sum_err; - min_idx = ti; - if( use_1se ) - min_err_se = sqrt( sum_err*(n - sum_err) ); - } - else if( sum_err < min_err + min_err_se ) - min_idx = ti; - } - } - - pruned_tree_idx = min_idx; - free_prune_data(data->params.truncate_pruned_tree != 0); - - __END__; - - cvReleaseMat( &err_jk ); - cvReleaseMat( &ab ); - cvReleaseMat( &temp ); -} - - -double CvDTree::update_tree_rnc( int T, int fold ) -{ - CvDTreeNode* node = root; - double min_alpha = DBL_MAX; - - for(;;) - { - CvDTreeNode* parent; - for(;;) - { - int t = fold >= 0 ? node->cv_Tn[fold] : node->Tn; - if( t <= T || !node->left ) - { - node->complexity = 1; - node->tree_risk = node->node_risk; - node->tree_error = 0.; - if( fold >= 0 ) - { - node->tree_risk = node->cv_node_risk[fold]; - node->tree_error = node->cv_node_error[fold]; - } - break; - } - node = node->left; - } - - for( parent = node->parent; parent && parent->right == node; - node = parent, parent = parent->parent ) - { - parent->complexity += node->complexity; - parent->tree_risk += node->tree_risk; - parent->tree_error += node->tree_error; - - parent->alpha = ((fold >= 0 ? parent->cv_node_risk[fold] : parent->node_risk) - - parent->tree_risk)/(parent->complexity - 1); - min_alpha = MIN( min_alpha, parent->alpha ); - } - - if( !parent ) - break; - - parent->complexity = node->complexity; - parent->tree_risk = node->tree_risk; - parent->tree_error = node->tree_error; - node = parent->right; - } - - return min_alpha; -} - - -int CvDTree::cut_tree( int T, int fold, double min_alpha ) -{ - CvDTreeNode* node = root; - if( !node->left ) - return 1; - - for(;;) - { - CvDTreeNode* parent; - for(;;) - { - int t = fold >= 0 ? node->cv_Tn[fold] : node->Tn; - if( t <= T || !node->left ) - break; - if( node->alpha <= min_alpha + FLT_EPSILON ) - { - if( fold >= 0 ) - node->cv_Tn[fold] = T; - else - node->Tn = T; - if( node == root ) - return 1; - break; - } - node = node->left; - } - - for( parent = node->parent; parent && parent->right == node; - node = parent, parent = parent->parent ) - ; - - if( !parent ) - break; - - node = parent->right; - } - - return 0; -} - - -void CvDTree::free_prune_data(bool _cut_tree) -{ - CvDTreeNode* node = root; - - for(;;) - { - CvDTreeNode* parent; - for(;;) - { - // do not call cvSetRemoveByPtr( cv_heap, node->cv_Tn ) - // as we will clear the whole cross-validation heap at the end - node->cv_Tn = 0; - node->cv_node_error = node->cv_node_risk = 0; - if( !node->left ) - break; - node = node->left; - } - - for( parent = node->parent; parent && parent->right == node; - node = parent, parent = parent->parent ) - { - if( _cut_tree && parent->Tn <= pruned_tree_idx ) - { - data->free_node( parent->left ); - data->free_node( parent->right ); - parent->left = parent->right = 0; - } - } - - if( !parent ) - break; - - node = parent->right; - } - - if( data->cv_heap ) - cvClearSet( data->cv_heap ); -} - - -void CvDTree::free_tree() -{ - if( root && data && data->shared ) - { - pruned_tree_idx = INT_MIN; - free_prune_data(true); - data->free_node(root); - root = 0; - } -} - -CvDTreeNode* CvDTree::predict( const CvMat* _sample, - const CvMat* _missing, bool preprocessed_input ) const -{ - cv::AutoBuffer catbuf; - - int i, mstep = 0; - const uchar* m = 0; - CvDTreeNode* node = root; - - if( !node ) - CV_Error( CV_StsError, "The tree has not been trained yet" ); - - if( !CV_IS_MAT(_sample) || CV_MAT_TYPE(_sample->type) != CV_32FC1 || - (_sample->cols != 1 && _sample->rows != 1) || - (_sample->cols + _sample->rows - 1 != data->var_all && !preprocessed_input) || - (_sample->cols + _sample->rows - 1 != data->var_count && preprocessed_input) ) - CV_Error( CV_StsBadArg, - "the input sample must be 1d floating-point vector with the same " - "number of elements as the total number of variables used for training" ); - - const float* sample = _sample->data.fl; - int step = CV_IS_MAT_CONT(_sample->type) ? 1 : _sample->step/sizeof(sample[0]); - - if( data->cat_count && !preprocessed_input ) // cache for categorical variables - { - int n = data->cat_count->cols; - catbuf.allocate(n); - for( i = 0; i < n; i++ ) - catbuf[i] = -1; - } - - if( _missing ) - { - if( !CV_IS_MAT(_missing) || !CV_IS_MASK_ARR(_missing) || - !CV_ARE_SIZES_EQ(_missing, _sample) ) - CV_Error( CV_StsBadArg, - "the missing data mask must be 8-bit vector of the same size as input sample" ); - m = _missing->data.ptr; - mstep = CV_IS_MAT_CONT(_missing->type) ? 1 : _missing->step/sizeof(m[0]); - } - - const int* vtype = data->var_type->data.i; - const int* vidx = data->var_idx && !preprocessed_input ? data->var_idx->data.i : 0; - const int* cmap = data->cat_map ? data->cat_map->data.i : 0; - const int* cofs = data->cat_ofs ? data->cat_ofs->data.i : 0; - - while( node->Tn > pruned_tree_idx && node->left ) - { - CvDTreeSplit* split = node->split; - int dir = 0; - for( ; !dir && split != 0; split = split->next ) - { - int vi = split->var_idx; - int ci = vtype[vi]; - i = vidx ? vidx[vi] : vi; - float val = sample[(size_t)i*step]; - if( m && m[(size_t)i*mstep] ) - continue; - if( ci < 0 ) // ordered - dir = val <= split->ord.c ? -1 : 1; - else // categorical - { - int c; - if( preprocessed_input ) - c = cvRound(val); - else - { - c = catbuf[ci]; - if( c < 0 ) - { - int a = c = cofs[ci]; - int b = (ci+1 >= data->cat_ofs->cols) ? data->cat_map->cols : cofs[ci+1]; - - int ival = cvRound(val); - if( ival != val ) - CV_Error( CV_StsBadArg, - "one of input categorical variable is not an integer" ); - - while( a < b ) - { - c = (a + b) >> 1; - if( ival < cmap[c] ) - b = c; - else if( ival > cmap[c] ) - a = c+1; - else - break; - } - - if( c < 0 || ival != cmap[c] ) - continue; - - catbuf[ci] = c -= cofs[ci]; - } - } - c = ( (c == 65535) && data->is_buf_16u ) ? -1 : c; - dir = CV_DTREE_CAT_DIR(c, split->subset); - } - - if( split->inversed ) - dir = -dir; - } - - if( !dir ) - { - double diff = node->right->sample_count - node->left->sample_count; - dir = diff < 0 ? -1 : 1; - } - node = dir < 0 ? node->left : node->right; - } - - return node; -} - - -CvDTreeNode* CvDTree::predict( const Mat& _sample, const Mat& _missing, bool preprocessed_input ) const -{ - CvMat sample = cvMat(_sample), mmask = cvMat(_missing); - return predict(&sample, mmask.data.ptr ? &mmask : 0, preprocessed_input); -} - - -const CvMat* CvDTree::get_var_importance() -{ - if( !var_importance ) - { - CvDTreeNode* node = root; - double* importance; - if( !node ) - return 0; - var_importance = cvCreateMat( 1, data->var_count, CV_64F ); - cvZero( var_importance ); - importance = var_importance->data.db; - - for(;;) - { - CvDTreeNode* parent; - for( ;; node = node->left ) - { - CvDTreeSplit* split = node->split; - - if( !node->left || node->Tn <= pruned_tree_idx ) - break; - - for( ; split != 0; split = split->next ) - importance[split->var_idx] += split->quality; - } - - for( parent = node->parent; parent && parent->right == node; - node = parent, parent = parent->parent ) - ; - - if( !parent ) - break; - - node = parent->right; - } - - cvNormalize( var_importance, var_importance, 1., 0, CV_L1 ); - } - - return var_importance; -} - - -void CvDTree::write_split( cv::FileStorage& fs, CvDTreeSplit* split ) const -{ - int ci; - - fs.startWriteStruct( 0, FileNode::MAP + FileNode::FLOW ); - fs.write( "var", split->var_idx ); - fs.write( "quality", split->quality ); - - ci = data->get_var_type(split->var_idx); - if( ci >= 0 ) // split on a categorical var - { - int i, n = data->cat_count->data.i[ci], to_right = 0, default_dir; - for( i = 0; i < n; i++ ) - to_right += CV_DTREE_CAT_DIR(i,split->subset) > 0; - - // ad-hoc rule when to use inverse categorical split notation - // to achieve more compact and clear representation - default_dir = to_right <= 1 || to_right <= MIN(3, n/2) || to_right <= n/3 ? -1 : 1; - - fs.startWriteStruct( default_dir*(split->inversed ? -1 : 1) > 0 ? - "in" : "not_in", FileNode::SEQ+FileNode::FLOW ); - - for( i = 0; i < n; i++ ) - { - int dir = CV_DTREE_CAT_DIR(i,split->subset); - if( dir*default_dir < 0 ) - fs.write( 0, i ); - } - fs.endWriteStruct(); - } - else - fs.write( !split->inversed ? "le" : "gt", split->ord.c ); - - fs.endWriteStruct(); -} - - -void CvDTree::write_node( cv::FileStorage& fs, CvDTreeNode* node ) const -{ - fs.startWriteStruct( 0, FileNode::MAP ); - - fs.write( "depth", node->depth ); - fs.write( "sample_count", node->sample_count ); - fs.write( "value", node->value ); - - if( data->is_classifier ) - fs.write( "norm_class_idx", node->class_idx ); - - fs.write( "Tn", node->Tn ); - fs.write( "complexity", node->complexity ); - fs.write( "alpha", node->alpha ); - fs.write( "node_risk", node->node_risk ); - fs.write( "tree_risk", node->tree_risk ); - fs.write( "tree_error", node->tree_error ); - - if( node->left ) - { - fs.startWriteStruct( "splits", FileNode::SEQ ); - - for( CvDTreeSplit* split = node->split; split != 0; split = split->next ) - write_split( fs, split ); - - fs.endWriteStruct(); - } - - fs.endWriteStruct(); -} - - -void CvDTree::write_tree_nodes( cv::FileStorage& fs ) const -{ - //CV_FUNCNAME( "CvDTree::write_tree_nodes" ); - - __BEGIN__; - - CvDTreeNode* node = root; - - // traverse the tree and save all the nodes in depth-first order - for(;;) - { - CvDTreeNode* parent; - for(;;) - { - write_node( fs, node ); - if( !node->left ) - break; - node = node->left; - } - - for( parent = node->parent; parent && parent->right == node; - node = parent, parent = parent->parent ) - ; - - if( !parent ) - break; - - node = parent->right; - } - - __END__; -} - - -void CvDTree::write( cv::FileStorage& fs, const char* name ) const -{ - //CV_FUNCNAME( "CvDTree::write" ); - - __BEGIN__; - - fs.startWriteStruct( name, FileNode::MAP, CV_TYPE_NAME_ML_TREE ); - - //get_var_importance(); - data->write_params( fs ); - //if( var_importance ) - //cvWrite( fs, "var_importance", var_importance ); - write( fs ); - - fs.endWriteStruct(); - - __END__; -} - - -void CvDTree::write( cv::FileStorage& fs ) const -{ - //CV_FUNCNAME( "CvDTree::write" ); - - __BEGIN__; - - fs.write( "best_tree_idx", pruned_tree_idx ); - - fs.startWriteStruct( "nodes", FileNode::SEQ ); - write_tree_nodes( fs ); - fs.endWriteStruct(); - - __END__; -} - - -CvDTreeSplit* CvDTree::read_split( const cv::FileNode& fnode ) -{ - CvDTreeSplit* split = 0; - - CV_FUNCNAME( "CvDTree::read_split" ); - - __BEGIN__; - - int vi, ci; - - if( fnode.empty() || !fnode.isMap() ) - CV_ERROR( CV_StsParseError, "some of the splits are not stored properly" ); - - vi = fnode[ "var" ].empty() ? -1 : (int) fnode[ "var" ]; - if( (unsigned)vi >= (unsigned)data->var_count ) - CV_ERROR( CV_StsOutOfRange, "Split variable index is out of range" ); - - ci = data->get_var_type(vi); - if( ci >= 0 ) // split on categorical var - { - int i, n = data->cat_count->data.i[ci], inversed = 0, val; - FileNodeIterator reader; - cv::FileNode inseq; - split = data->new_split_cat( vi, 0 ); - inseq = fnode[ "in" ]; - if( inseq.empty() ) - { - inseq = fnode[ "not_in" ]; - inversed = 1; - } - if( inseq.empty() || - (!inseq.isSeq() && !inseq.isInt())) - CV_ERROR( CV_StsParseError, - "Either 'in' or 'not_in' tags should be inside a categorical split data" ); - - if( inseq.isInt() ) - { - val = (int) inseq; - if( (unsigned)val >= (unsigned)n ) - CV_ERROR( CV_StsOutOfRange, "some of in/not_in elements are out of range" ); - - split->subset[val >> 5] |= 1 << (val & 31); - } - else - { - reader = inseq.begin(); - - for( i = 0; i < (int) (*reader).size(); i++ ) - { - cv::FileNode inode = *reader; - val = (int) inode; - if( !inode.isInt() || (unsigned)val >= (unsigned)n ) - CV_ERROR( CV_StsOutOfRange, "some of in/not_in elements are out of range" ); - - split->subset[val >> 5] |= 1 << (val & 31); - reader++; - } - } - - // for categorical splits we do not use inversed splits, - // instead we inverse the variable set in the split - if( inversed ) - for( i = 0; i < (n + 31) >> 5; i++ ) - split->subset[i] ^= -1; - } - else - { - cv::FileNode cmp_node; - split = data->new_split_ord( vi, 0, 0, 0, 0 ); - - cmp_node = fnode[ "le" ]; - if( cmp_node.empty() ) - { - cmp_node = fnode[ "gt" ]; - split->inversed = 1; - } - - split->ord.c = (float) cmp_node; - } - - split->quality = (float) fnode[ "quality" ]; - - __END__; - - return split; -} - - -CvDTreeNode* CvDTree::read_node( const cv::FileNode& fnode, CvDTreeNode* parent ) -{ - CvDTreeNode* node = 0; - - CV_FUNCNAME( "CvDTree::read_node" ); - - __BEGIN__; - - cv::FileNode splits; - int i, depth; - - if( fnode.empty() || !fnode.isMap() ) - CV_ERROR( CV_StsParseError, "some of the tree elements are not stored properly" ); - - CV_CALL( node = data->new_node( parent, 0, 0, 0 )); - depth = fnode[ "depth" ].empty() ? -1 : (int) fnode[ "depth" ]; - if( depth != node->depth ) - CV_ERROR( CV_StsParseError, "incorrect node depth" ); - - node->sample_count = (int) fnode[ "sample_count" ]; - node->value = (double) fnode[ "value" ]; - if( data->is_classifier ) - node->class_idx = (int) fnode[ "norm_class_idx" ]; - - node->Tn = (int) fnode[ "Tn" ]; - node->complexity = (int) fnode[ "complexity" ]; - node->alpha = (double) fnode[ "alpha" ]; - node->node_risk = (double) fnode[ "node_risk" ]; - node->tree_risk = (double) fnode[ "tree_risk" ]; - node->tree_error = (double) fnode[ "tree_error" ]; - - splits = fnode[ "splits" ]; - if( !splits.empty() ) - { - FileNodeIterator reader; - CvDTreeSplit* last_split = 0; - - if( !splits.isSeq() ) - CV_ERROR( CV_StsParseError, "splits tag must stored as a sequence" ); - - reader = splits.begin(); - for( i = 0; i < (int) (*reader).size(); i++ ) - { - CvDTreeSplit* split; - CV_CALL( split = read_split( *reader )); - if( !last_split ) - node->split = last_split = split; - else - last_split = last_split->next = split; - - reader++; - } - } - - __END__; - - return node; -} - - -void CvDTree::read_tree_nodes( const cv::FileNode& fnode ) -{ - CV_FUNCNAME( "CvDTree::read_tree_nodes" ); - - __BEGIN__; - - FileNodeIterator reader; - CvDTreeNode _root; - CvDTreeNode* parent = &_root; - int i; - parent->left = parent->right = parent->parent = 0; - - reader = fnode.begin(); - - for( i = 0; i < (int) (*reader).size(); i++ ) - { - CvDTreeNode* node; - - CV_CALL( node = read_node( *reader, parent != &_root ? parent : 0 )); - if( !parent->left ) - parent->left = node; - else - parent->right = node; - if( node->split ) - parent = node; - else - { - while( parent && parent->right ) - parent = parent->parent; - } - - reader++; - } - - root = _root.left; - - __END__; -} - - -void CvDTree::read( const cv::FileNode& fnode ) -{ - CvDTreeTrainData* _data = new CvDTreeTrainData(); - _data->read_params( fnode ); - - read( fnode, _data ); - get_var_importance(); -} - - -// a special entry point for reading weak decision trees from the tree ensembles -void CvDTree::read( const cv::FileNode& node, CvDTreeTrainData* _data ) -{ - CV_FUNCNAME( "CvDTree::read" ); - - __BEGIN__; - - cv::FileNode tree_nodes; - - clear(); - data = _data; - - tree_nodes = node[ "nodes" ]; - if( tree_nodes.empty() || !tree_nodes.isSeq() ) - CV_ERROR( CV_StsParseError, "nodes tag is missing" ); - - pruned_tree_idx = node[ "best_tree_idx" ].empty() ? -1 : node[ "best_tree_idx" ]; - read_tree_nodes( tree_nodes ); - - __END__; -} - -Mat CvDTree::getVarImportance() -{ - return cvarrToMat(get_var_importance()); -} - -/* End of file. */ diff --git a/apps/traincascade/traincascade.cpp b/apps/traincascade/traincascade.cpp deleted file mode 100644 index 0efce23b16..0000000000 --- a/apps/traincascade/traincascade.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include "opencv2/core.hpp" -#include "cascadeclassifier.h" - -using namespace std; -using namespace cv; - -/* -traincascade.cpp is the source file of the program used for cascade training. -User has to provide training input in form of positive and negative training images, -and other data related to training in form of command line argument. -*/ -int main( int argc, char* argv[] ) -{ - CvCascadeClassifier classifier; - string cascadeDirName, vecName, bgName; - int numPos = 2000; - int numNeg = 1000; - int numStages = 20; - int numThreads = getNumThreads(); - int precalcValBufSize = 1024, - precalcIdxBufSize = 1024; - bool baseFormatSave = false; - double acceptanceRatioBreakValue = -1.0; - - CvCascadeParams cascadeParams; - CvCascadeBoostParams stageParams; - Ptr featureParams[] = { makePtr(), - makePtr(), - makePtr() - }; - int fc = sizeof(featureParams)/sizeof(featureParams[0]); - if( argc == 1 ) - { - cout << "Usage: " << argv[0] << endl; - cout << " -data " << endl; - cout << " -vec " << endl; - cout << " -bg " << endl; - cout << " [-numPos ]" << endl; - cout << " [-numNeg ]" << endl; - cout << " [-numStages ]" << endl; - cout << " [-precalcValBufSize ]" << endl; - cout << " [-precalcIdxBufSize ]" << endl; - cout << " [-baseFormatSave]" << endl; - cout << " [-numThreads ]" << endl; - cout << " [-acceptanceRatioBreakValue = " << acceptanceRatioBreakValue << ">]" << endl; - cascadeParams.printDefaults(); - stageParams.printDefaults(); - for( int fi = 0; fi < fc; fi++ ) - featureParams[fi]->printDefaults(); - return 0; - } - - for( int i = 1; i < argc; i++ ) - { - bool set = false; - if( !strcmp( argv[i], "-data" ) ) - { - cascadeDirName = argv[++i]; - } - else if( !strcmp( argv[i], "-vec" ) ) - { - vecName = argv[++i]; - } - else if( !strcmp( argv[i], "-bg" ) ) - { - bgName = argv[++i]; - } - else if( !strcmp( argv[i], "-numPos" ) ) - { - numPos = atoi( argv[++i] ); - } - else if( !strcmp( argv[i], "-numNeg" ) ) - { - numNeg = atoi( argv[++i] ); - } - else if( !strcmp( argv[i], "-numStages" ) ) - { - numStages = atoi( argv[++i] ); - } - else if( !strcmp( argv[i], "-precalcValBufSize" ) ) - { - precalcValBufSize = atoi( argv[++i] ); - } - else if( !strcmp( argv[i], "-precalcIdxBufSize" ) ) - { - precalcIdxBufSize = atoi( argv[++i] ); - } - else if( !strcmp( argv[i], "-baseFormatSave" ) ) - { - baseFormatSave = true; - } - else if( !strcmp( argv[i], "-numThreads" ) ) - { - numThreads = atoi(argv[++i]); - } - else if( !strcmp( argv[i], "-acceptanceRatioBreakValue" ) ) - { - acceptanceRatioBreakValue = atof(argv[++i]); - } - else if ( cascadeParams.scanAttr( argv[i], argv[i+1] ) ) { i++; } - else if ( stageParams.scanAttr( argv[i], argv[i+1] ) ) { i++; } - else if ( !set ) - { - for( int fi = 0; fi < fc; fi++ ) - { - set = featureParams[fi]->scanAttr(argv[i], argv[i+1]); - if ( !set ) - { - i++; - break; - } - } - } - } - - setNumThreads( numThreads ); - classifier.train( cascadeDirName, - vecName, - bgName, - numPos, numNeg, - precalcValBufSize, precalcIdxBufSize, - numStages, - cascadeParams, - *featureParams[cascadeParams.featureType], - stageParams, - baseFormatSave, - acceptanceRatioBreakValue ); - return 0; -} diff --git a/apps/traincascade/traincascade_features.h b/apps/traincascade/traincascade_features.h deleted file mode 100644 index c8f024b507..0000000000 --- a/apps/traincascade/traincascade_features.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef _OPENCV_FEATURES_H_ -#define _OPENCV_FEATURES_H_ - -#include "imagestorage.h" -#include - -#define FEATURES "features" - -#define CV_SUM_OFFSETS( p0, p1, p2, p3, rect, step ) \ - /* (x, y) */ \ - (p0) = (rect).x + (step) * (rect).y; \ - /* (x + w, y) */ \ - (p1) = (rect).x + (rect).width + (step) * (rect).y; \ - /* (x + w, y) */ \ - (p2) = (rect).x + (step) * ((rect).y + (rect).height); \ - /* (x + w, y + h) */ \ - (p3) = (rect).x + (rect).width + (step) * ((rect).y + (rect).height); - -#define CV_TILTED_OFFSETS( p0, p1, p2, p3, rect, step ) \ - /* (x, y) */ \ - (p0) = (rect).x + (step) * (rect).y; \ - /* (x - h, y + h) */ \ - (p1) = (rect).x - (rect).height + (step) * ((rect).y + (rect).height);\ - /* (x + w, y + w) */ \ - (p2) = (rect).x + (rect).width + (step) * ((rect).y + (rect).width); \ - /* (x + w - h, y + w + h) */ \ - (p3) = (rect).x + (rect).width - (rect).height \ - + (step) * ((rect).y + (rect).width + (rect).height); - -float calcNormFactor( const cv::Mat& sum, const cv::Mat& sqSum ); - -template -void _writeFeatures( const std::vector features, cv::FileStorage &fs, const cv::Mat& featureMap ) -{ - fs << FEATURES << "["; - const cv::Mat_& featureMap_ = (const cv::Mat_&)featureMap; - for ( int fi = 0; fi < featureMap.cols; fi++ ) - if ( featureMap_(0, fi) >= 0 ) - { - fs << "{"; - features[fi].write( fs ); - fs << "}"; - } - fs << "]"; -} - -class CvParams -{ -public: - CvParams(); - virtual ~CvParams() {} - // from|to file - virtual void write( cv::FileStorage &fs ) const = 0; - virtual bool read( const cv::FileNode &node ) = 0; - // from|to screen - virtual void printDefaults() const; - virtual void printAttrs() const; - virtual bool scanAttr( const std::string prmName, const std::string val ); - std::string name; -}; - -class CvFeatureParams : public CvParams -{ -public: - enum { HAAR = 0, LBP = 1, HOG = 2 }; - CvFeatureParams(); - virtual void init( const CvFeatureParams& fp ); - virtual void write( cv::FileStorage &fs ) const; - virtual bool read( const cv::FileNode &node ); - static cv::Ptr create( int featureType ); - int maxCatCount; // 0 in case of numerical features - int featSize; // 1 in case of simple features (HAAR, LBP) and N_BINS(9)*N_CELLS(4) in case of Dalal's HOG features -}; - -class CvFeatureEvaluator -{ -public: - virtual ~CvFeatureEvaluator() {} - virtual void init(const CvFeatureParams *_featureParams, - int _maxSampleCount, cv::Size _winSize ); - virtual void setImage(const cv::Mat& img, uchar clsLabel, int idx); - virtual void writeFeatures( cv::FileStorage &fs, const cv::Mat& featureMap ) const = 0; - virtual float operator()(int featureIdx, int sampleIdx) const = 0; - static cv::Ptr create(int type); - - int getNumFeatures() const { return numFeatures; } - int getMaxCatCount() const { return featureParams->maxCatCount; } - int getFeatureSize() const { return featureParams->featSize; } - const cv::Mat& getCls() const { return cls; } - float getCls(int si) const { return cls.at(si, 0); } -protected: - virtual void generateFeatures() = 0; - - int npos, nneg; - int numFeatures; - cv::Size winSize; - CvFeatureParams *featureParams; - cv::Mat cls; -}; - -#endif diff --git a/doc/tutorials/others/barcode_detect_and_decode.markdown b/doc/tutorials/others/barcode_detect_and_decode.markdown index f1ea1b51de..471b020e41 100644 --- a/doc/tutorials/others/barcode_detect_and_decode.markdown +++ b/doc/tutorials/others/barcode_detect_and_decode.markdown @@ -3,7 +3,7 @@ Barcode Recognition {#tutorial_barcode_detect_and_decode} @tableofcontents -@prev_tutorial{tutorial_traincascade} +@prev_tutorial{tutorial_cascade_classifier} @next_tutorial{tutorial_introduction_to_pca} | | | diff --git a/doc/tutorials/others/cascade_classifier.markdown b/doc/tutorials/others/cascade_classifier.markdown index dd39103dc0..3ad0b425be 100644 --- a/doc/tutorials/others/cascade_classifier.markdown +++ b/doc/tutorials/others/cascade_classifier.markdown @@ -4,7 +4,7 @@ Cascade Classifier {#tutorial_cascade_classifier} @tableofcontents @prev_tutorial{tutorial_optical_flow} -@next_tutorial{tutorial_traincascade} +@next_tutorial{tutorial_barcode_detect_and_decode} | | | | -: | :- | @@ -95,8 +95,8 @@ more details or check out the references in the Additional Resources section. Haar-cascade Detection in OpenCV -------------------------------- -OpenCV provides a training method (see @ref tutorial_traincascade) or pretrained models, that can be read using the @ref cv::CascadeClassifier::load method. -The pretrained models are located in the data folder in the OpenCV installation or can be found [here](https://github.com/opencv/opencv/tree/5.x/data). +OpenCV provides pretrained models that can be read using the @ref cv::CascadeClassifier::load method. +These models are located in the data folder in the OpenCV installation or can be found [here](https://github.com/opencv/opencv/tree/5.x/data). The following code example will use pretrained Haar cascade models to detect faces and eyes in an image. First, a @ref cv::CascadeClassifier is created and the necessary XML file is loaded using the @ref cv::CascadeClassifier::load method. diff --git a/doc/tutorials/others/table_of_content_other.markdown b/doc/tutorials/others/table_of_content_other.markdown index f6fe601fa2..1e78cda308 100644 --- a/doc/tutorials/others/table_of_content_other.markdown +++ b/doc/tutorials/others/table_of_content_other.markdown @@ -7,6 +7,5 @@ Other tutorials (objdetect, photo, stitching, video) {#tutorial_table_of_content - video. @subpage tutorial_meanshift - video. @subpage tutorial_optical_flow - objdetect. @subpage tutorial_cascade_classifier -- objdetect. @subpage tutorial_traincascade - objdetect. @subpage tutorial_barcode_detect_and_decode - ml. @subpage tutorial_introduction_to_pca diff --git a/doc/tutorials/others/traincascade.markdown b/doc/tutorials/others/traincascade.markdown deleted file mode 100644 index 03d93d5b94..0000000000 --- a/doc/tutorials/others/traincascade.markdown +++ /dev/null @@ -1,224 +0,0 @@ -Cascade Classifier Training {#tutorial_traincascade} -=========================== - -@tableofcontents - -@prev_tutorial{tutorial_cascade_classifier} -@next_tutorial{tutorial_barcode_detect_and_decode} - -Introduction ------------- - -Working with a boosted cascade of weak classifiers includes two major stages: the training and the detection stage. The detection stage using either HAAR or LBP based models, is described in the @ref tutorial_cascade_classifier "object detection tutorial". This documentation gives an overview of the functionality needed to train your own boosted cascade of weak classifiers. The current guide will walk through all the different stages: collecting training data, preparation of the training data and executing the actual model training. - -To support this tutorial, several official OpenCV applications will be used: [opencv_createsamples](https://github.com/opencv/opencv/tree/5.x/apps/createsamples), [opencv_annotation](https://github.com/opencv/opencv/tree/5.x/apps/annotation), [opencv_traincascade](https://github.com/opencv/opencv/tree/5.x/apps/traincascade) and [opencv_visualisation](https://github.com/opencv/opencv/tree/5.x/apps/visualisation). - -@note Createsamples and traincascade are disabled since OpenCV 4.0. Consider using these apps for training from 3.4 branch for Cascade Classifier. Model format is the same between 3.4 and 4.x. - -### Important notes - - - If you come across any tutorial mentioning the old opencv_haartraining tool (which is deprecated and still using the OpenCV1.x interface), then please ignore that tutorial and stick to the opencv_traincascade tool. This tool is a newer version, written in C++ in accordance to the OpenCV 2.x and OpenCV 3.x API. The opencv_traincascade supports both HAAR like wavelet features @cite Viola01 and LBP (Local Binary Patterns) @cite Liao2007 features. LBP features yield integer precision in contrast to HAAR features, yielding floating point precision, so both training and detection with LBP are several times faster then with HAAR features. Regarding the LBP and HAAR detection quality, it mainly depends on the training data used and the training parameters selected. It's possible to train a LBP-based classifier that will provide almost the same quality as HAAR-based one, within a percentage of the training time. - - - The newer cascade classifier detection interface from OpenCV 2.x and OpenCV 3.x (@ref cv::CascadeClassifier) supports working with both old and new model formats. opencv_traincascade can even save (export) a trained cascade in the older format if for some reason you are stuck using the old interface. At least training the model could then be done in the most stable interface. - - - The opencv_traincascade application can use TBB for multi-threading. To use it in multicore mode OpenCV must be built with TBB support enabled. - -Preparation of the training data --------------------------------- - -For training a boosted cascade of weak classifiers we need a set of positive samples (containing actual objects you want to detect) and a set of negative images (containing everything you do not want to detect). The set of negative samples must be prepared manually, whereas set of positive samples is created using the opencv_createsamples application. - -### Negative Samples - -Negative samples are taken from arbitrary images, not containing objects you want to detect. These negative images, from which the samples are generated, should be listed in a special negative image file containing one image path per line (can be absolute or relative). Note that negative samples and sample images are also called background samples or background images, and are used interchangeably in this document. - -Described images may be of different sizes. However, each image should be equal or larger than the desired training window size (which corresponds to the model dimensions, most of the times being the average size of your object), because these images are used to subsample a given negative image into several image samples having this training window size. - -An example of such a negative description file: - -Directory structure: -@code{.text} -/img - img1.jpg - img2.jpg -bg.txt -@endcode - -File bg.txt: -@code{.text} -img/img1.jpg -img/img2.jpg -@endcode - -Your set of negative window samples will be used to tell the machine learning step, boosting in this case, what not to look for, when trying to find your objects of interest. - -### Positive Samples - -Positive samples are created by the opencv_createsamples application. They are used by the boosting process to define what the model should actually look for when trying to find your objects of interest. The application supports two ways of generating a positive sample dataset. - - 1. You can generate a bunch of positives from a single positive object image. - 2. You can supply all the positives yourself and only use the tool to cut them out, resize them and put them in the opencv needed binary format. - -While the first approach works decently for fixed objects, like very rigid logo's, it tends to fail rather soon for less rigid objects. In that case we do suggest to use the second approach. Many tutorials on the web even state that 100 real object images, can lead to a better model than 1000 artificially generated positives, by using the opencv_createsamples application. If you however do decide to take the first approach, keep some things in mind: - - - Please note that you need more than a single positive samples before you give it to the mentioned application, because it only applies perspective transformation. - - If you want a robust model, take samples that cover the wide range of varieties that can occur within your object class. For example in the case of faces you should consider different races and age groups, emotions and perhaps beard styles. This also applies when using the second approach. - -The first approach takes a single object image with for example a company logo and creates a large set of positive samples from the given object image by randomly rotating the object, changing the image intensity as well as placing the image on arbitrary backgrounds. The amount and range of randomness can be controlled by command line arguments of the opencv_createsamples application. - -Command line arguments: - - - `-vec ` : Name of the output file containing the positive samples for training. - - - `-img ` : Source object image (e.g., a company logo). - - - `-bg ` : Background description file; contains a list of images which are used as a background for randomly distorted versions of the object. - - - `-num ` : Number of positive samples to generate. - - - `-bgcolor ` : Background color (currently grayscale images are assumed); the background color denotes the transparent color. Since there might be compression artifacts, the amount of color tolerance can be specified by -bgthresh. All pixels within bgcolor-bgthresh and bgcolor+bgthresh range are interpreted as transparent. - - - `-bgthresh ` - - `-inv` : If specified, colors will be inverted. - - `-randinv` : If specified, colors will be inverted randomly. - - `-maxidev ` : Maximal intensity deviation of pixels in foreground samples. - - `-maxxangle ` : Maximal rotation angle towards x-axis, must be given in radians. - - `-maxyangle ` : Maximal rotation angle towards y-axis, must be given in radians. - - `-maxzangle ` : Maximal rotation angle towards z-axis, must be given in radians. - - `-show` : Useful debugging option. If specified, each sample will be shown. Pressing Esc will continue the samples creation process without showing each sample. - - `-w ` : Width (in pixels) of the output samples. - - `-h ` : Height (in pixels) of the output samples. - -When running opencv_createsamples in this way, the following procedure is used to create a sample object instance: The given source image is rotated randomly around all three axes. The chosen angle is limited by `-maxxangle`, `-maxyangle` and `-maxzangle`. Then pixels having the intensity from the [bg_color-bg_color_threshold; bg_color+bg_color_threshold] range are interpreted as transparent. White noise is added to the intensities of the foreground. If the `-inv` key is specified then foreground pixel intensities are inverted. If `-randinv` key is specified then algorithm randomly selects whether inversion should be applied to this sample. Finally, the obtained image is placed onto an arbitrary background from the background description file, resized to the desired size specified by `-w` and `-h` and stored to the vec-file, specified by the `-vec` command line option. - -Positive samples also may be obtained from a collection of previously marked up images, which is the desired way when building robust object models. This collection is described by a text file similar to the background description file. Each line of this file corresponds to an image. The first element of the line is the filename, followed by the number of object annotations, followed by numbers describing the coordinates of the objects bounding rectangles (x, y, width, height). - -An example of description file: - -Directory structure: -@code{.text} -/img - img1.jpg - img2.jpg -info.dat -@endcode -File info.dat: -@code{.text} -img/img1.jpg 1 140 100 45 45 -img/img2.jpg 2 100 200 50 50 50 30 25 25 -@endcode -Image img1.jpg contains single object instance with the following coordinates of bounding rectangle: -(140, 100, 45, 45). Image img2.jpg contains two object instances. - -In order to create positive samples from such collection, `-info` argument should be specified instead of `-img`: - - - `-info ` : Description file of marked up images collection. - -Note that in this case, parameters like `-bg, -bgcolor, -bgthreshold, -inv, -randinv, -maxxangle, -maxyangle, -maxzangle` are simply ignored and not used anymore. The scheme of samples creation in this case is as follows. The object instances are taken from the given images, by cutting out the supplied bounding boxes from the original images. Then they are resized to target samples size (defined by `-w` and `-h`) and stored in output vec-file, defined by the `-vec` parameter. No distortion is applied, so the only affecting arguments are `-w`, `-h`, `-show` and `-num`. - -The manual process of creating the `-info` file can also been done by using the opencv_annotation tool. This is an open source tool for visually selecting the regions of interest of your object instances in any given images. The following subsection will discuss in more detail on how to use this application. - -#### Extra remarks - - - opencv_createsamples utility may be used for examining samples stored in any given positive samples file. In order to do this only `-vec`, `-w` and `-h` parameters should be specified. - - Example of vec-file is available here `opencv/data/vec_files/trainingfaces_24-24.vec`. It can be used to train a face detector with the following window size: `-w 24 -h 24`. - -### Using OpenCV's integrated annotation tool - -Since OpenCV 3.x the community has been supplying and maintaining a open source annotation tool, used for generating the `-info` file. The tool can be accessed by the command opencv_annotation if the OpenCV applications where build. - -Using the tool is quite straightforward. The tool accepts several required and some optional parameters: - - - `--annotations` (required) : path to annotations txt file, where you want to store your annotations, which is then passed to the `-info` parameter [example - /data/annotations.txt] - - `--images` (required) : path to folder containing the images with your objects [example - /data/testimages/] - - `--maxWindowHeight` (optional) : if the input image is larger in height then the given resolution here, resize the image for easier annotation, using `--resizeFactor`. - - `--resizeFactor` (optional) : factor used to resize the input image when using the `--maxWindowHeight` parameter. - -Note that the optional parameters can only be used together. An example of a command that could be used can be seen below - -@code{.text} -opencv_annotation --annotations=/path/to/annotations/file.txt --images=/path/to/image/folder/ -@endcode - -This command will fire up a window containing the first image and your mouse cursor which will be used for annotation. A video on how to use the annotation tool can be found [here](https://www.youtube.com/watch?v=EV5gmvoCTSk). Basically there are several keystrokes that trigger an action. The left mouse button is used to select the first corner of your object, then keeps drawing until you are fine, and stops when a second left mouse button click is registered. After each selection you have the following choices: - - - Pressing `c` : confirm the annotation, turning the annotation green and confirming it is stored - - Pressing `d` : delete the last annotation from the list of annotations (easy for removing wrong annotations) - - Pressing `n` : continue to the next image - - Pressing `ESC` : this will exit the annotation software - -Finally you will end up with a usable annotation file that can be passed to the `-info` argument of opencv_createsamples. - -Cascade Training ----------------- - -The next step is the actual training of the boosted cascade of weak classifiers, based on the positive and negative dataset that was prepared beforehand. - -Command line arguments of opencv_traincascade application grouped by purposes: - -- Common arguments: - - `-data ` : Where the trained classifier should be stored. This folder should be created manually beforehand. - - `-vec ` : vec-file with positive samples (created by opencv_createsamples utility). - - `-bg ` : Background description file. This is the file containing the negative sample images. - - `-numPos ` : Number of positive samples used in training for every classifier stage. - - `-numNeg ` : Number of negative samples used in training for every classifier stage. - - `-numStages ` : Number of cascade stages to be trained. - - `-precalcValBufSize ` : Size of buffer for precalculated feature values (in Mb). The more memory you assign the faster the training process, however keep in mind that `-precalcValBufSize` and `-precalcIdxBufSize` combined should not exceed you available system memory. - - `-precalcIdxBufSize ` : Size of buffer for precalculated feature indices (in Mb). The more memory you assign the faster the training process, however keep in mind that `-precalcValBufSize` and `-precalcIdxBufSize` combined should not exceed you available system memory. - - `-baseFormatSave` : This argument is actual in case of Haar-like features. If it is specified, the cascade will be saved in the old format. This is only available for backwards compatibility reasons and to allow users stuck to the old deprecated interface, to at least train models using the newer interface. - - `-numThreads ` : Maximum number of threads to use during training. Notice that the actual number of used threads may be lower, depending on your machine and compilation options. By default, the maximum available threads are selected if you built OpenCV with TBB support, which is needed for this optimization. - - `-acceptanceRatioBreakValue ` : This argument is used to determine how precise your model should keep learning and when to stop. A good guideline is to train not further than 10e-5, to ensure the model does not overtrain on your training data. By default this value is set to -1 to disable this feature. - -- Cascade parameters: - - `-stageType ` : Type of stages. Only boosted classifiers are supported as a stage type at the moment. - - `-featureType<{HAAR(default), LBP}>` : Type of features: HAAR - Haar-like features, LBP - local binary patterns. - - `-w ` : Width of training samples (in pixels). Must have exactly the same value as used during training samples creation (opencv_createsamples utility). - - `-h ` : Height of training samples (in pixels). Must have exactly the same value as used during training samples creation (opencv_createsamples utility). - -- Boosted classifier parameters: - - `-bt <{DAB, RAB, LB, GAB(default)}>` : Type of boosted classifiers: DAB - Discrete AdaBoost, RAB - Real AdaBoost, LB - LogitBoost, GAB - Gentle AdaBoost. - - `-minHitRate ` : Minimal desired hit rate for each stage of the classifier. Overall hit rate may be estimated as (min_hit_rate ^ number_of_stages), @cite Viola04 §4.1. - - `-maxFalseAlarmRate ` : Maximal desired false alarm rate for each stage of the classifier. Overall false alarm rate may be estimated as (max_false_alarm_rate ^ number_of_stages), @cite Viola04 §4.1. - - `-weightTrimRate ` : Specifies whether trimming should be used and its weight. A decent choice is 0.95. - - `-maxDepth ` : Maximal depth of a weak tree. A decent choice is 1, that is case of stumps. - - `-maxWeakCount ` : Maximal count of weak trees for every cascade stage. The boosted classifier (stage) will have so many weak trees (<=maxWeakCount), as needed to achieve the given `-maxFalseAlarmRate`. - -- Haar-like feature parameters: - - `-mode ` : Selects the type of Haar features set used in training. BASIC use only upright features, while ALL uses the full set of upright and 45 degree rotated feature set. See @cite Lienhart02 for more details. - -- Local Binary Patterns parameters: Local Binary Patterns don't have parameters. - -After the opencv_traincascade application has finished its work, the trained cascade will be saved in `cascade.xml` file in the `-data` folder. Other files in this folder are created for the case of interrupted training, so you may delete them after completion of training. - -Training is finished and you can test your cascade classifier! - -Visualising Cascade Classifiers -------------------------------- - -From time to time it can be useful to visualise the trained cascade, to see which features it selected and how complex its stages are. For this OpenCV supplies a opencv_visualisation application. This application has the following commands: - - - `--image` (required) : path to a reference image for your object model. This should be an annotation with dimensions [`-w`,`-h`] as passed to both opencv_createsamples and opencv_traincascade application. - - `--model` (required) : path to the trained model, which should be in the folder supplied to the `-data` parameter of the opencv_traincascade application. - - `--data` (optional) : if a data folder is supplied, which has to be manually created beforehand, stage output and a video of the features will be stored. - -An example command can be seen below - -@code{.text} -opencv_visualisation --image=/data/object.png --model=/data/model.xml --data=/data/result/ -@endcode - -Some limitations of the current visualisation tool - - Only handles cascade classifier models, trained with the opencv_traincascade tool, containing __stumps__ as decision trees [default settings]. - - The image provided needs to be a sample window with the original model dimensions, passed to the `--image` parameter. - -Example of the HAAR/LBP face model ran on a given window of Angelina Jolie, which had the same preprocessing as cascade classifier files -->24x24 pixel image, grayscale conversion and histogram equalisation: - -_A video is made with for each stage each feature visualised:_ - -![](images/visualisation_video.png) - -_Each stage is stored as an image for future validation of the features:_ - -![](images/visualisation_single_stage.png) - -_This work was created for [OpenCV 3 Blueprints](https://www.packtpub.com/application-development/opencv-3-blueprints) by StevenPuttemans but Packt Publishing agreed integration into OpenCV._ diff --git a/modules/3d/src/calibration_base.cpp b/modules/3d/src/calibration_base.cpp index 37542ac40a..6847539c6b 100644 --- a/modules/3d/src/calibration_base.cpp +++ b/modules/3d/src/calibration_base.cpp @@ -41,7 +41,6 @@ //M*/ #include "precomp.hpp" -#include "opencv2/imgproc/imgproc_c.h" #include "distortion_model.hpp" #include #include @@ -146,7 +145,7 @@ void cv::Rodrigues(InputArray _src, OutputArray _dst, OutputArray _jacobian) dst.setZero(); if( depth != CV_32F && depth != CV_64F ) - CV_Error( CV_StsUnsupportedFormat, "The matrices must have 32f or 64f data type" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The matrices must have 32f or 64f data type" ); if( v2m ) { @@ -532,7 +531,7 @@ void cv::projectPoints( InputArray _objectPoints, if(total % 3 != 0) { //we have stopped support of homogeneous coordinates because it cause ambiguity in interpretation of the input data - CV_Error( CV_StsBadArg, "Homogeneous coordinates are not supported" ); + CV_Error( cv::Error::StsBadArg, "Homogeneous coordinates are not supported" ); } count = total / 3; CV_Assert(objpt_depth == CV_32F || objpt_depth == CV_64F); @@ -560,7 +559,7 @@ void cv::projectPoints( InputArray _objectPoints, (rvec.size() == Size(3, 3) || (rvec.rows == 1 && rvec.cols*rvec.channels() == 3) || (rvec.rows == 3 && rvec.cols*rvec.channels() == 1)))) { - CV_Error(CV_StsBadArg, "rvec must be 3x3 or 1x3 or 3x1 floating-point array"); + CV_Error(cv::Error::StsBadArg, "rvec must be 3x3 or 1x3 or 3x1 floating-point array"); } if( rvec.size() == Size(3, 3) ) @@ -582,7 +581,7 @@ void cv::projectPoints( InputArray _objectPoints, if(!((tvec.depth() == CV_32F || tvec.depth() == CV_64F) && ((tvec.rows == 1 && tvec.cols*tvec.channels() == 3) || (tvec.rows == 3 && tvec.cols*tvec.channels() == 1)))) { - CV_Error(CV_StsBadArg, "tvec must be 1x3 or 3x1 floating-point array"); + CV_Error(cv::Error::StsBadArg, "tvec must be 1x3 or 3x1 floating-point array"); } Mat _t(tvec.size(), CV_64FC(tvec.channels()), t); @@ -591,7 +590,7 @@ void cv::projectPoints( InputArray _objectPoints, Mat cameraMatrix = _cameraMatrix.getMat(); if(cameraMatrix.size() != Size(3, 3) || cameraMatrix.channels() != 1) - CV_Error( CV_StsBadArg, "Intrinsic parameters must be 3x3 floating-point matrix" ); + CV_Error( cv::Error::StsBadArg, "Intrinsic parameters must be 3x3 floating-point matrix" ); Mat _a(3, 3, CV_64F, a); cameraMatrix.convertTo(_a, CV_64F); @@ -609,7 +608,7 @@ void cv::projectPoints( InputArray _objectPoints, ktotal = (int)distCoeffs.total()*kcn; if( (distCoeffs.rows != 1 && distCoeffs.cols != 1) || (ktotal != 4 && ktotal != 5 && ktotal != 8 && ktotal != 12 && ktotal != 14)) - CV_Error( CV_StsBadArg, cvDistCoeffErr ); + CV_Error( cv::Error::StsBadArg, cvDistCoeffErr ); Mat _k(distCoeffs.size(), CV_64FC(kcn), k); distCoeffs.convertTo(_k, CV_64F); diff --git a/modules/3d/src/levmarq.cpp b/modules/3d/src/levmarq.cpp index b4df3b89cf..f7c147ed6e 100644 --- a/modules/3d/src/levmarq.cpp +++ b/modules/3d/src/levmarq.cpp @@ -542,7 +542,7 @@ struct LevMarqDenseLinearBackend : public detail::LevMarqBackend } else { - CV_Error(CV_StsBadArg, "Geodesic acceleration is disabled"); + CV_Error(cv::Error::StsBadArg, "Geodesic acceleration is disabled"); } } else @@ -698,7 +698,7 @@ struct LevMarqDenseLinearBackend : public detail::LevMarqBackend { if (cb_alt) { - CV_Error(CV_StsNotImplemented, "Geodesic acceleration is not implemented for normal callbacks, please use \"long\" callbacks"); + CV_Error(cv::Error::StsNotImplemented, "Geodesic acceleration is not implemented for normal callbacks, please use \"long\" callbacks"); } else { @@ -744,9 +744,9 @@ LevMarq::LevMarq(int nvars, LongCallback callback, const Settings& settings, Inp MatrixType matrixType, VariableType paramType, int nerrs, int solveMethod) { if (matrixType != MatrixType::AUTO && matrixType != MatrixType::DENSE) - CV_Error(CV_StsNotImplemented, "General purpuse sparse solver for LevMarq is not implemented yet"); + CV_Error(cv::Error::StsNotImplemented, "General purpuse sparse solver for LevMarq is not implemented yet"); if (paramType != VariableType::LINEAR) - CV_Error(CV_StsNotImplemented, "SO(3) and SE(3) params for LevMarq are not implemented yet"); + CV_Error(cv::Error::StsNotImplemented, "SO(3) and SE(3) params for LevMarq are not implemented yet"); auto backend = makePtr(nvars, callback, mask, nerrs, solveMethod); pImpl = makePtr(backend, settings); @@ -756,9 +756,9 @@ LevMarq::LevMarq(int nvars, NormalCallback callback, const Settings& settings, I MatrixType matrixType, VariableType paramType, bool LtoR, int solveMethod) { if (matrixType != MatrixType::AUTO && matrixType != MatrixType::DENSE) - CV_Error(CV_StsNotImplemented, "General purpuse sparse solver for LevMarq is not implemented yet"); + CV_Error(cv::Error::StsNotImplemented, "General purpuse sparse solver for LevMarq is not implemented yet"); if (paramType != VariableType::LINEAR) - CV_Error(CV_StsNotImplemented, "SO(3) and SE(3) params for LevMarq are not implemented yet"); + CV_Error(cv::Error::StsNotImplemented, "SO(3) and SE(3) params for LevMarq are not implemented yet"); auto backend = makePtr(nvars, callback, mask, LtoR, solveMethod); pImpl = makePtr(backend, settings); @@ -768,9 +768,9 @@ LevMarq::LevMarq(InputOutputArray param, LongCallback callback, const Settings& MatrixType matrixType, VariableType paramType, int nerrs, int solveMethod) { if (matrixType != MatrixType::AUTO && matrixType != MatrixType::DENSE) - CV_Error(CV_StsNotImplemented, "General purpuse sparse solver for LevMarq is not implemented yet"); + CV_Error(cv::Error::StsNotImplemented, "General purpuse sparse solver for LevMarq is not implemented yet"); if (paramType != VariableType::LINEAR) - CV_Error(CV_StsNotImplemented, "SO(3) and SE(3) params for LevMarq are not implemented yet"); + CV_Error(cv::Error::StsNotImplemented, "SO(3) and SE(3) params for LevMarq are not implemented yet"); auto backend = makePtr(param, callback, mask, nerrs, solveMethod); pImpl = makePtr(backend, settings); @@ -780,9 +780,9 @@ LevMarq::LevMarq(InputOutputArray param, NormalCallback callback, const Settings MatrixType matrixType, VariableType paramType, bool LtoR, int solveMethod) { if (matrixType != MatrixType::AUTO && matrixType != MatrixType::DENSE) - CV_Error(CV_StsNotImplemented, "General purpuse sparse solver for LevMarq is not implemented yet"); + CV_Error(cv::Error::StsNotImplemented, "General purpuse sparse solver for LevMarq is not implemented yet"); if (paramType != VariableType::LINEAR) - CV_Error(CV_StsNotImplemented, "SO(3) and SE(3) params for LevMarq are not implemented yet"); + CV_Error(cv::Error::StsNotImplemented, "SO(3) and SE(3) params for LevMarq are not implemented yet"); auto backend = makePtr(param, callback, mask, LtoR, solveMethod); pImpl = makePtr(backend, settings); diff --git a/modules/3d/src/rgbd/pose_graph.cpp b/modules/3d/src/rgbd/pose_graph.cpp index ff3a0de35b..2c0cb77028 100644 --- a/modules/3d/src/rgbd/pose_graph.cpp +++ b/modules/3d/src/rgbd/pose_graph.cpp @@ -761,7 +761,7 @@ public: { if (geo && !useGeo) { - CV_Error(CV_StsBadArg, "Geodesic acceleration is disabled"); + CV_Error(cv::Error::StsBadArg, "Geodesic acceleration is disabled"); } std::map& nodes = geo ? geoNodes : tempNodes; diff --git a/modules/3d/src/solvepnp.cpp b/modules/3d/src/solvepnp.cpp index ccaf8edf08..b8571251fd 100644 --- a/modules/3d/src/solvepnp.cpp +++ b/modules/3d/src/solvepnp.cpp @@ -1027,7 +1027,7 @@ int solvePnPGeneric( InputArray _opoints, InputArray _ipoints, vec_tvecs.push_back(tvec); }*/ else - CV_Error(CV_StsBadArg, "The flags argument must be one of SOLVEPNP_ITERATIVE, SOLVEPNP_P3P, " + CV_Error(cv::Error::StsBadArg, "The flags argument must be one of SOLVEPNP_ITERATIVE, SOLVEPNP_P3P, " "SOLVEPNP_EPNP, SOLVEPNP_DLS, SOLVEPNP_UPNP, SOLVEPNP_AP3P, SOLVEPNP_IPPE, SOLVEPNP_IPPE_SQUARE or SOLVEPNP_SQPNP"); CV_Assert(vec_rvecs.size() == vec_tvecs.size()); diff --git a/modules/3d/src/triangulate.cpp b/modules/3d/src/triangulate.cpp index 458cd85927..4d0c08d780 100644 --- a/modules/3d/src/triangulate.cpp +++ b/modules/3d/src/triangulate.cpp @@ -173,9 +173,9 @@ void correctMatches( InputArray _F, InputArray _points1, InputArray _points2, CV_Assert(points1.size() == points2.size()); CV_Assert(points1.rows == 1 || points1.cols == 1); if (points1.channels() != 2) - CV_Error( CV_StsUnmatchedSizes, "The first set of points must contain two channels; one for x and one for y" ); + CV_Error( cv::Error::StsUnmatchedSizes, "The first set of points must contain two channels; one for x and one for y" ); if (points2.channels() != 2) - CV_Error( CV_StsUnmatchedSizes, "The second set of points must contain two channels; one for x and one for y" ); + CV_Error( cv::Error::StsUnmatchedSizes, "The second set of points must contain two channels; one for x and one for y" ); _newPoints1.create(points1.size(), points1.type()); _newPoints2.create(points2.size(), points2.type()); diff --git a/modules/3d/test/test_fundam.cpp b/modules/3d/test/test_fundam.cpp index 04721effaf..c0c379a045 100644 --- a/modules/3d/test/test_fundam.cpp +++ b/modules/3d/test/test_fundam.cpp @@ -44,6 +44,8 @@ namespace cvtest { +using namespace cv; + static int cvTsRodrigues( const CvMat* src, CvMat* dst, CvMat* jacobian ) { int depth; @@ -223,7 +225,7 @@ static int cvTsRodrigues( const CvMat* src, CvMat* dst, CvMat* jacobian ) cvMulTransposed( &matR, &matA, 0 ); cvSetIdentity( &matI ); - if( cvNorm( &matA, &matI, CV_C ) > 1e-3 || + if( cvNorm( &matA, &matI, NORM_INF ) > 1e-3 || fabs( cvDet(&matR) - 1 ) > 1e-3 ) return 0; @@ -717,7 +719,7 @@ void CV_RodriguesTest::prepare_to_validation( int /*test_case_idx*/ ) cvtest::Rodrigues( m, vec2, m2v_jac ); cvtest::copy( vec, vec2 ); - theta0 = cvtest::norm( vec2, CV_L2 ); + theta0 = cvtest::norm( vec2, NORM_L2 ); theta1 = fmod( theta0, CV_PI*2 ); if( theta1 > CV_PI ) @@ -727,7 +729,7 @@ void CV_RodriguesTest::prepare_to_validation( int /*test_case_idx*/ ) if( calc_jacobians ) { //cvInvert( v2m_jac, m2v_jac, CV_SVD ); - double nrm = cvtest::norm(test_mat[REF_OUTPUT][3], CV_C); + double nrm = cvtest::norm(test_mat[REF_OUTPUT][3], NORM_INF); if( FLT_EPSILON < nrm && nrm < 1000 ) { gemm( test_mat[OUTPUT][1], test_mat[OUTPUT][3], diff --git a/modules/3d/test/test_undistort.cpp b/modules/3d/test/test_undistort.cpp index a07b89c83d..b95f388e68 100644 --- a/modules/3d/test/test_undistort.cpp +++ b/modules/3d/test/test_undistort.cpp @@ -41,7 +41,7 @@ //M*/ #include "test_precomp.hpp" -#include "opencv2/imgproc/imgproc_c.h" +#include "opencv2/core/core_c.h" namespace opencv_test { namespace { diff --git a/modules/3d/test/test_undistort_badarg.cpp b/modules/3d/test/test_undistort_badarg.cpp index 0ba13f1212..71bb21a0bd 100644 --- a/modules/3d/test/test_undistort_badarg.cpp +++ b/modules/3d/test/test_undistort_badarg.cpp @@ -106,15 +106,15 @@ void CV_UndistortPointsBadArgTest::run(int) src_points = cv::cvarrToMat(&_src_points_orig); src_points.create(2, 2, CV_32FC2); - errcount += run_test_case( CV_StsAssert, "Invalid input data matrix size" ); + errcount += run_test_case( cv::Error::StsAssert, "Invalid input data matrix size" ); src_points = cv::cvarrToMat(&_src_points_orig); src_points.create(1, 4, CV_64FC2); - errcount += run_test_case( CV_StsAssert, "Invalid input data matrix type" ); + errcount += run_test_case( cv::Error::StsAssert, "Invalid input data matrix type" ); src_points = cv::cvarrToMat(&_src_points_orig); src_points = cv::Mat(); - errcount += run_test_case( CV_StsBadArg, "Input data matrix is not continuous" ); + errcount += run_test_case( cv::Error::StsBadArg, "Input data matrix is not continuous" ); src_points = cv::cvarrToMat(&_src_points_orig); //------------ @@ -181,19 +181,19 @@ void CV_InitUndistortRectifyMapBadArgTest::run(int) mapy = cv::cvarrToMat(&_mapy_orig); mat_type = CV_64F; - errcount += run_test_case( CV_StsAssert, "Invalid map matrix type" ); + errcount += run_test_case( cv::Error::StsAssert, "Invalid map matrix type" ); mat_type = mat_type_orig; camera_mat.create(3, 2, CV_32F); - errcount += run_test_case( CV_StsAssert, "Invalid camera data matrix size" ); + errcount += run_test_case( cv::Error::StsAssert, "Invalid camera data matrix size" ); camera_mat = cv::cvarrToMat(&_camera_mat_orig); R.create(4, 3, CV_32F); - errcount += run_test_case( CV_StsAssert, "Invalid R data matrix size" ); + errcount += run_test_case( cv::Error::StsAssert, "Invalid R data matrix size" ); R = cv::cvarrToMat(&_R_orig); distortion_coeffs.create(6, 1, CV_32F); - errcount += run_test_case( CV_StsAssert, "Invalid distortion coefficients data matrix size" ); + errcount += run_test_case( cv::Error::StsAssert, "Invalid distortion coefficients data matrix size" ); distortion_coeffs = cv::cvarrToMat(&_distortion_coeffs_orig); //------------ @@ -256,7 +256,7 @@ void CV_UndistortBadArgTest::run(int) dst = cv::cvarrToMat(&_dst_orig); camera_mat.create(5, 5, CV_64F); - errcount += run_test_case( CV_StsAssert, "Invalid camera data matrix size" ); + errcount += run_test_case( cv::Error::StsAssert, "Invalid camera data matrix size" ); //------------ ts->set_failed_test_info(errcount > 0 ? cvtest::TS::FAIL_BAD_ARG_CHECK : cvtest::TS::OK); diff --git a/modules/calib/src/calibinit.cpp b/modules/calib/src/calibinit.cpp index 118ab17fe5..59f358764b 100644 --- a/modules/calib/src/calibinit.cpp +++ b/modules/calib/src/calibinit.cpp @@ -71,7 +71,6 @@ #include "precomp.hpp" #include "circlesgrid.hpp" -#include "opencv2/imgproc/imgproc_c.h" #include "opencv2/flann.hpp" #include diff --git a/modules/calib/src/calibration.cpp b/modules/calib/src/calibration.cpp index 4afea2f871..98a6bec066 100644 --- a/modules/calib/src/calibration.cpp +++ b/modules/calib/src/calibration.cpp @@ -70,7 +70,7 @@ static void initIntrinsicParams2D( const Mat& objectPoints, imagePoints.type() == CV_64FC2 ); if( objectPoints.rows != 1 || imagePoints.rows != 1 ) - CV_Error( CV_StsBadSize, "object points and image points must be a single-row matrices" ); + CV_Error( cv::Error::StsBadSize, "object points and image points must be a single-row matrices" ); Mat_ matA(2*nimages, 2); Mat_ matb(2*nimages, 1, CV_64F ); @@ -177,20 +177,20 @@ static double calibrateCameraInternal( const Mat& objectPoints, // 0. check the parameters & allocate buffers if( imageSize.width <= 0 || imageSize.height <= 0 ) - CV_Error( CV_StsOutOfRange, "image width and height must be positive" ); + CV_Error( cv::Error::StsOutOfRange, "image width and height must be positive" ); if(flags & CALIB_TILTED_MODEL) { //when the tilted sensor model is used the distortion coefficients matrix must have 14 parameters if (ndistCoeffs != 14) - CV_Error( CV_StsBadArg, "The tilted sensor model must have 14 parameters in the distortion matrix" ); + CV_Error( cv::Error::StsBadArg, "The tilted sensor model must have 14 parameters in the distortion matrix" ); } else { //when the thin prism model is used the distortion coefficients matrix must have 12 parameters if(flags & CALIB_THIN_PRISM_MODEL) if (ndistCoeffs != 12) - CV_Error( CV_StsBadArg, "Thin prism model must have 12 parameters in the distortion matrix" ); + CV_Error( cv::Error::StsBadArg, "Thin prism model must have 12 parameters in the distortion matrix" ); } if( !rvecs.empty() ) @@ -225,7 +225,7 @@ static double calibrateCameraInternal( const Mat& objectPoints, int ni = npoints.at(i); if( ni < 4 ) { - CV_Error_( CV_StsOutOfRange, ("The number of points in the view #%d is < 4", i)); + CV_Error_( cv::Error::StsOutOfRange, ("The number of points in the view #%d is < 4", i)); } maxPoints = MAX( maxPoints, ni ); total += ni; @@ -286,15 +286,15 @@ static double calibrateCameraInternal( const Mat& objectPoints, if( flags & CALIB_USE_INTRINSIC_GUESS ) { if( A(0, 0) <= 0 || A(1, 1) <= 0 ) - CV_Error( CV_StsOutOfRange, "Focal length (fx and fy) must be positive" ); + CV_Error( cv::Error::StsOutOfRange, "Focal length (fx and fy) must be positive" ); if( A(0, 2) < 0 || A(0, 2) >= imageSize.width || A(1, 2) < 0 || A(1, 2) >= imageSize.height ) - CV_Error( CV_StsOutOfRange, "Principal point must be within the image" ); + CV_Error( cv::Error::StsOutOfRange, "Principal point must be within the image" ); if( fabs(A(0, 1)) > 1e-5 ) - CV_Error( CV_StsOutOfRange, "Non-zero skew is not supported by the function" ); + CV_Error( cv::Error::StsOutOfRange, "Non-zero skew is not supported by the function" ); if( fabs(A(1, 0)) > 1e-5 || fabs(A(2, 0)) > 1e-5 || fabs(A(2, 1)) > 1e-5 || fabs(A(2,2)-1) > 1e-5 ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "The intrinsic matrix must have [fx 0 cx; 0 fy cy; 0 0 1] shape" ); A(0, 1) = A(1, 0) = A(2, 0) = A(2, 1) = 0.; A(2, 2) = 1.; @@ -304,7 +304,7 @@ static double calibrateCameraInternal( const Mat& objectPoints, aspectRatio = A(0, 0)/A(1, 1); if( aspectRatio < minValidAspectRatio || aspectRatio > maxValidAspectRatio ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "The specified aspect ratio (= cameraMatrix[0][0] / cameraMatrix[1][1]) is incorrect" ); } distCoeffs.convertTo(_k, CV_64F); @@ -314,7 +314,7 @@ static double calibrateCameraInternal( const Mat& objectPoints, Scalar mean, sdv; meanStdDev(matM, mean, sdv); if( fabs(mean[2]) > 1e-5 || fabs(sdv[2]) > 1e-5 ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "For non-planar calibration rigs the initial intrinsic matrix must be specified" ); for(int i = 0; i < total; i++ ) matM.at(i).z = 0.; @@ -324,7 +324,7 @@ static double calibrateCameraInternal( const Mat& objectPoints, aspectRatio = A(0, 0); aspectRatio /= A(1, 1); if( aspectRatio < minValidAspectRatio || aspectRatio > maxValidAspectRatio ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "The specified aspect ratio (= cameraMatrix[0][0] / cameraMatrix[1][1]) is incorrect" ); } initIntrinsicParams2D( matM, _m, npoints, imageSize, A, aspectRatio ); @@ -689,7 +689,7 @@ static double stereoCalibrateImpl( if( (depth != CV_32F && depth != CV_64F) || ((rvecs.rows != nimages || (rvecs.cols*cn != 3 && rvecs.cols*cn != 9)) && (rvecs.rows != 1 || rvecs.cols != nimages || cn != 3)) ) - CV_Error( CV_StsBadArg, "the output array of rotation vectors must be 3-channel " + CV_Error( cv::Error::StsBadArg, "the output array of rotation vectors must be 3-channel " "1xn or nx1 array or 1-channel nx3 or nx9 array, where n is the number of views" ); } if( !tvecs.empty() ) @@ -699,7 +699,7 @@ static double stereoCalibrateImpl( if( (depth != CV_32F && depth != CV_64F) || ((tvecs.rows != nimages || tvecs.cols*cn != 3) && (tvecs.rows != 1 || tvecs.cols != nimages || cn != 3)) ) - CV_Error( CV_StsBadArg, "the output array of translation vectors must be 3-channel " + CV_Error( cv::Error::StsBadArg, "the output array of translation vectors must be 3-channel " "1xn or nx1 array or 1-channel nx3 array, where n is the number of views" ); } @@ -1237,7 +1237,7 @@ static double registerCamerasImpl( CV_Assert(depth == CV_32F || depth == CV_64F); if(((rvecs.rows != nimages || (rvecs.cols*cn != 3 && rvecs.cols*cn != 9)) && (rvecs.rows != 1 || rvecs.cols != nimages || cn != 3)) ) - CV_Error( CV_StsBadArg, "the output array of rotation vectors must be 3-channel " + CV_Error( cv::Error::StsBadArg, "the output array of rotation vectors must be 3-channel " "1xn or nx1 array or 1-channel nx3 or nx9 array, where n is the number of views" ); } if( !tvecs.empty() ) @@ -1247,7 +1247,7 @@ static double registerCamerasImpl( CV_Assert(depth == CV_32F || depth == CV_64F); if(((tvecs.rows != nimages || tvecs.cols*cn != 3) && (tvecs.rows != 1 || tvecs.cols != nimages || cn != 3)) ) - CV_Error( CV_StsBadArg, "the output array of translation vectors must be 3-channel " + CV_Error( cv::Error::StsBadArg, "the output array of translation vectors must be 3-channel " "1xn or nx1 array or 1-channel nx3 array, where n is the number of views" ); } @@ -1308,7 +1308,7 @@ static double registerCamerasImpl( else if (cameraModels[k] == CALIB_MODEL_FISHEYE) fisheye::solvePnP(objpt_i, imgpt_ik, A[k], tdists[k], rv, T[k], false, SOLVEPNP_ITERATIVE ); else - CV_Error(CV_StsBadArg, cv::format("Camera type %d is not supported", cameraModels[k])); + CV_Error(cv::Error::StsBadArg, cv::format("Camera type %d is not supported", cameraModels[k])); Rodrigues(rv, R[k]); @@ -1596,17 +1596,17 @@ static void collectCalibrationData( InputArrayOfArrays objectPoints, { Mat objectPoint = objectPoints.getMat(i); if (objectPoint.empty()) - CV_Error(CV_StsBadSize, "objectPoints should not contain empty vector of vectors of points"); + CV_Error(cv::Error::StsBadSize, "objectPoints should not contain empty vector of vectors of points"); int numberOfObjectPoints = objectPoint.checkVector(3, CV_32F); if (numberOfObjectPoints <= 0) - CV_Error(CV_StsUnsupportedFormat, "objectPoints should contain vector of vectors of points of type Point3f"); + CV_Error(cv::Error::StsUnsupportedFormat, "objectPoints should contain vector of vectors of points of type Point3f"); Mat imagePoint1 = imagePoints1.getMat(i); if (imagePoint1.empty()) - CV_Error(CV_StsBadSize, "imagePoints1 should not contain empty vector of vectors of points"); + CV_Error(cv::Error::StsBadSize, "imagePoints1 should not contain empty vector of vectors of points"); int numberOfImagePoints = imagePoint1.checkVector(2, CV_32F); if (numberOfImagePoints <= 0) - CV_Error(CV_StsUnsupportedFormat, "imagePoints1 should contain vector of vectors of points of type Point2f"); + CV_Error(cv::Error::StsUnsupportedFormat, "imagePoints1 should contain vector of vectors of points of type Point2f"); CV_CheckEQ(numberOfObjectPoints, numberOfImagePoints, "Number of object and image points must be equal"); total += numberOfObjectPoints; @@ -1664,14 +1664,14 @@ static void collectCalibrationData( InputArrayOfArrays objectPoints, { if( nPointsMat.at(i) != ni ) { - CV_Error( CV_StsBadArg, "All objectPoints[i].size() should be equal when " + CV_Error( cv::Error::StsBadArg, "All objectPoints[i].size() should be equal when " "object-releasing method is requested." ); } Mat ocmp = objPtMat.colRange(ni * i, ni * i + ni) != objPtMat.colRange(0, ni); ocmp = ocmp.reshape(1); if( countNonZero(ocmp) ) { - CV_Error( CV_StsBadArg, "All objectPoints[i] should be identical when object-releasing" + CV_Error( cv::Error::StsBadArg, "All objectPoints[i] should be identical when object-releasing" " method is requested." ); } } @@ -1914,7 +1914,7 @@ void calibrationMatrixValues( InputArray _cameraMatrix, Size imageSize, CV_INSTRUMENT_REGION(); if(_cameraMatrix.size() != Size(3, 3)) - CV_Error(CV_StsUnmatchedSizes, "Size of cameraMatrix must be 3x3!"); + CV_Error(cv::Error::StsUnmatchedSizes, "Size of cameraMatrix must be 3x3!"); Matx33d A; _cameraMatrix.getMat().convertTo(A, CV_64F); diff --git a/modules/calib/test/test_cameracalibration.cpp b/modules/calib/test/test_cameracalibration.cpp index aa2691eb68..1a06e318ef 100644 --- a/modules/calib/test/test_cameracalibration.cpp +++ b/modules/calib/test/test_cameracalibration.cpp @@ -212,7 +212,7 @@ void CV_ProjectPointsTest::prepare_to_validation( int /*test_case_idx*/ ) cvTsProjectPoints( m, vec2, m2v_jac ); cvTsCopy( vec, vec2 ); - theta0 = cvtest::norm( cvarrtomat(vec2), 0, CV_L2 ); + theta0 = cvtest::norm( cvarrtomat(vec2), 0, NORM_L2 ); theta1 = fmod( theta0, CV_PI*2 ); if( theta1 > CV_PI ) @@ -222,7 +222,7 @@ void CV_ProjectPointsTest::prepare_to_validation( int /*test_case_idx*/ ) if( calc_jacobians ) { //cvInvert( v2m_jac, m2v_jac, CV_SVD ); - if( cvtest::norm(cvarrtomat(&test_mat[OUTPUT][3]), 0, CV_C) < 1000 ) + if( cvtest::norm(cvarrtomat(&test_mat[OUTPUT][3]), 0, NORM_INF) < 1000 ) { cvTsGEMM( &test_mat[OUTPUT][1], &test_mat[OUTPUT][3], 1, 0, 0, &test_mat[OUTPUT][4], diff --git a/modules/calib/test/test_cameracalibration_badarg.cpp b/modules/calib/test/test_cameracalibration_badarg.cpp index e38e788edb..0ded9876a6 100644 --- a/modules/calib/test/test_cameracalibration_badarg.cpp +++ b/modules/calib/test/test_cameracalibration_badarg.cpp @@ -149,49 +149,49 @@ void CV_CameraCalibrationBadArgTest::run( int /* start_from */ ) caller.initArgs(); caller.objPts_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "None passed in objPts", caller); + errors += run_test_case( cv::Error::StsBadArg, "None passed in objPts", caller); caller.initArgs(); caller.imgPts_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "None passed in imgPts", caller ); + errors += run_test_case( cv::Error::StsBadArg, "None passed in imgPts", caller ); caller.initArgs(); caller.cameraMatrix_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Zero passed in cameraMatrix", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Zero passed in cameraMatrix", caller ); caller.initArgs(); caller.distCoeffs_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Zero passed in distCoeffs", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Zero passed in distCoeffs", caller ); caller.initArgs(); caller.imageSize.width = -1; - errors += run_test_case( CV_StsOutOfRange, "Bad image width", caller ); + errors += run_test_case( cv::Error::StsOutOfRange, "Bad image width", caller ); caller.initArgs(); caller.imageSize.height = -1; - errors += run_test_case( CV_StsOutOfRange, "Bad image height", caller ); + errors += run_test_case( cv::Error::StsOutOfRange, "Bad image height", caller ); caller.initArgs(); caller.imgPts[0].clear(); - errors += run_test_case( CV_StsBadSize, "Bad imgpts[0]", caller ); + errors += run_test_case( cv::Error::StsBadSize, "Bad imgpts[0]", caller ); caller.imgPts[0] = caller.imgPts[1]; caller.initArgs(); caller.objPts[1].clear(); - errors += run_test_case( CV_StsBadSize, "Bad objpts[1]", caller ); + errors += run_test_case( cv::Error::StsBadSize, "Bad objpts[1]", caller ); caller.objPts[1] = caller.objPts[0]; caller.initArgs(); Mat badCM = Mat::zeros(4, 4, CV_64F); caller.cameraMatrix_arg = badCM; caller.flags = CALIB_USE_INTRINSIC_GUESS; - errors += run_test_case( CV_StsBadArg, "Bad camearaMatrix header", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad camearaMatrix header", caller ); caller.initArgs(); Mat badDC = Mat::zeros(10, 10, CV_64F); caller.distCoeffs_arg = badDC; caller.flags = CALIB_USE_INTRINSIC_GUESS; - errors += run_test_case( CV_StsBadArg, "Bad camearaMatrix header", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad camearaMatrix header", caller ); if (errors) ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); @@ -242,15 +242,15 @@ protected: caller.initArgs(); caller.src_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Src is empty matrix", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Src is empty matrix", caller ); caller.initArgs(); caller.src = Mat::zeros(3, 1, CV_8U); - errors += run_test_case( CV_StsUnsupportedFormat, "Bad src formart", caller ); + errors += run_test_case( cv::Error::StsUnsupportedFormat, "Bad src formart", caller ); caller.initArgs(); caller.src = Mat::zeros(1, 1, CV_32F); - errors += run_test_case( CV_StsBadSize, "Bad src size", caller ); + errors += run_test_case( cv::Error::StsBadSize, "Bad src size", caller ); if (errors) ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); @@ -329,57 +329,57 @@ protected: caller.initArgs(); caller.objectPoints_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Zero objectPoints", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Zero objectPoints", caller ); caller.initArgs(); caller.rvec_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Zero r_vec", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Zero r_vec", caller ); caller.initArgs(); caller.tvec_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Zero t_vec", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Zero t_vec", caller ); caller.initArgs(); caller.A_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Zero camMat", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Zero camMat", caller ); caller.initArgs(); caller.imagePoints_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Zero imagePoints", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Zero imagePoints", caller ); Mat save_rvec = caller.r_vec; caller.initArgs(); caller.r_vec.create(2, 2, CV_32F); - errors += run_test_case( CV_StsBadArg, "Bad rvec format", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad rvec format", caller ); caller.initArgs(); caller.r_vec.create(1, 3, CV_8U); - errors += run_test_case( CV_StsBadArg, "Bad rvec format", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad rvec format", caller ); caller.r_vec = save_rvec; /****************************/ Mat save_tvec = caller.t_vec; caller.initArgs(); caller.t_vec.create(3, 3, CV_32F); - errors += run_test_case( CV_StsBadArg, "Bad tvec format", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad tvec format", caller ); caller.initArgs(); caller.t_vec.create(1, 3, CV_8U); - errors += run_test_case( CV_StsBadArg, "Bad tvec format", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad tvec format", caller ); caller.t_vec = save_tvec; /****************************/ Mat save_A = caller.A; caller.initArgs(); caller.A.create(2, 2, CV_32F); - errors += run_test_case( CV_StsBadArg, "Bad A format", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad A format", caller ); caller.A = save_A; /****************************/ Mat save_DC = caller.distCoeffs; caller.initArgs(); caller.distCoeffs.create(3, 3, CV_32F); - errors += run_test_case( CV_StsBadArg, "Bad distCoeffs format", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad distCoeffs format", caller ); caller.distCoeffs = save_DC; if (errors) diff --git a/modules/calib/test/test_cornerssubpix.cpp b/modules/calib/test/test_cornerssubpix.cpp index 80133b0689..8b02c164f1 100644 --- a/modules/calib/test/test_cornerssubpix.cpp +++ b/modules/calib/test/test_cornerssubpix.cpp @@ -40,7 +40,6 @@ //M*/ #include "test_precomp.hpp" -#include "opencv2/imgproc/imgproc_c.h" #include "test_chessboardgenerator.hpp" namespace opencv_test { namespace { diff --git a/modules/core/include/opencv2/core/private.hpp b/modules/core/include/opencv2/core/private.hpp index 02ac1ba1e3..074607eb7d 100644 --- a/modules/core/include/opencv2/core/private.hpp +++ b/modules/core/include/opencv2/core/private.hpp @@ -134,13 +134,6 @@ static inline int cvAlign( int size, int align ) return (size + align - 1) & -align; } -#ifdef IPL_DEPTH_8U -static inline cv::Size cvGetMatSize( const CvMat* mat ) -{ - return cv::Size(mat->cols, mat->rows); -} -#endif - namespace cv { CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int unroll_to = 0); diff --git a/modules/core/perf/opencl/perf_arithm.cpp b/modules/core/perf/opencl/perf_arithm.cpp index 94af3a99cb..0e6b55af66 100644 --- a/modules/core/perf/opencl/perf_arithm.cpp +++ b/modules/core/perf/opencl/perf_arithm.cpp @@ -975,7 +975,7 @@ OCL_PERF_TEST_P(InRangeFixture, InRange, ///////////// Normalize //////////////////////// -CV_ENUM(NormalizeModes, CV_MINMAX, CV_L2, CV_L1, CV_C) +CV_ENUM(NormalizeModes, NORM_MINMAX, NORM_L2, NORM_L1, NORM_INF) typedef tuple NormalizeParams; typedef TestBaseWithParam NormalizeFixture; @@ -995,7 +995,7 @@ OCL_PERF_TEST_P(NormalizeFixture, Normalize, OCL_TEST_CYCLE() cv::normalize(src, dst, 10, 110, mode); - SANITY_CHECK(dst, 5e-2); + SANITY_CHECK_NOTHING(); } OCL_PERF_TEST_P(NormalizeFixture, NormalizeWithMask, @@ -1013,7 +1013,7 @@ OCL_PERF_TEST_P(NormalizeFixture, NormalizeWithMask, OCL_TEST_CYCLE() cv::normalize(src, dst, 10, 110, mode, -1, mask); - SANITY_CHECK(dst, 5e-2); + SANITY_CHECK_NOTHING(); } ///////////// ConvertScaleAbs //////////////////////// @@ -1232,7 +1232,7 @@ OCL_PERF_TEST_P(PSNRFixture, PSNR, ///////////// Reduce //////////////////////// -CV_ENUM(ReduceMinMaxOp, CV_REDUCE_MIN, CV_REDUCE_MAX) +CV_ENUM(ReduceMinMaxOp, REDUCE_MIN, REDUCE_MAX) typedef tuple, int, ReduceMinMaxOp> ReduceMinMaxParams; typedef TestBaseWithParam ReduceMinMaxFixture; @@ -1250,7 +1250,6 @@ OCL_PERF_TEST_P(ReduceMinMaxFixture, Reduce, dim = get<2>(params), op = get<3>(params); const Size srcSize = get<0>(params), dstSize(dim == 0 ? srcSize.width : 1, dim == 0 ? 1 : srcSize.height); - const double eps = CV_MAT_DEPTH(dtype) <= CV_32S ? 1 : 1e-5; checkDeviceMaxMemoryAllocSize(srcSize, stype); checkDeviceMaxMemoryAllocSize(srcSize, dtype); @@ -1260,7 +1259,7 @@ OCL_PERF_TEST_P(ReduceMinMaxFixture, Reduce, OCL_TEST_CYCLE() cv::reduce(src, dst, dim, op, dtype); - SANITY_CHECK(dst, eps); + SANITY_CHECK_NOTHING(); } CV_ENUM(ReduceAccOp, REDUCE_SUM, REDUCE_AVG, REDUCE_SUM2) diff --git a/modules/core/src/alloc.cpp b/modules/core/src/alloc.cpp index cb2db71e2c..f6abeeb098 100644 --- a/modules/core/src/alloc.cpp +++ b/modules/core/src/alloc.cpp @@ -70,7 +70,7 @@ namespace cv { static void* OutOfMemoryError(size_t size) { - CV_Error_(CV_StsNoMem, ("Failed to allocate %llu bytes", (unsigned long long)size)); + CV_Error_(cv::Error::StsNoMem, ("Failed to allocate %llu bytes", (unsigned long long)size)); } CV_EXPORTS cv::utils::AllocatorStatisticsInterface& getAllocatorStatistics(); diff --git a/modules/core/src/arithm.cpp b/modules/core/src/arithm.cpp index a651016abb..d1bfa10aa8 100644 --- a/modules/core/src/arithm.cpp +++ b/modules/core/src/arithm.cpp @@ -209,7 +209,7 @@ static void binary_op( InputArray _src1, InputArray _src2, OutputArray _dst, swap(sz1, sz2); } else if( !checkScalar(*psrc2, type1, kind2, kind1) ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The operation is neither 'array op array' (where arrays have the same size and type), " "nor 'array op scalar', nor 'scalar op array'" ); haveScalar = true; @@ -673,7 +673,7 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, oclop = OCL_OP_RDIV_SCALE; } else if( !checkScalar(*psrc2, type1, kind2, kind1) ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The operation is neither 'array op array' " "(where arrays have the same size and the same number of channels), " "nor 'array op scalar', nor 'scalar op array'" ); @@ -698,7 +698,7 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, else { if( !haveScalar && type1 != type2 ) - CV_Error(CV_StsBadArg, + CV_Error(cv::Error::StsBadArg, "When the input arrays in add/subtract/multiply/divide functions have different types, " "the output array type must be explicitly specified"); dtype = type1; @@ -1289,7 +1289,7 @@ void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op) return; } else if(is_src1_scalar == is_src2_scalar) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The operation is neither 'array op array' (where arrays have the same size and the same type), " "nor 'array op scalar', nor 'scalar op array'" ); haveScalar = true; @@ -1791,7 +1791,7 @@ static bool ocl_inRange( InputArray _src, InputArray _lowerb, ssize != lsize || stype != ltype ) { if( !checkScalar(_lowerb, stype, lkind, skind) ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The lower boundary is neither an array of the same size and same type as src, nor a scalar"); lbScalar = true; } @@ -1800,7 +1800,7 @@ static bool ocl_inRange( InputArray _src, InputArray _lowerb, ssize != usize || stype != utype ) { if( !checkScalar(_upperb, stype, ukind, skind) ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The upper boundary is neither an array of the same size and same type as src, nor a scalar"); ubScalar = true; } @@ -1914,7 +1914,7 @@ void cv::inRange(InputArray _src, InputArray _lowerb, src.size != lb.size || src.type() != lb.type() ) { if( !checkScalar(lb, src.type(), lkind, skind) ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The lower boundary is neither an array of the same size and same type as src, nor a scalar"); lbScalar = true; } @@ -1923,7 +1923,7 @@ void cv::inRange(InputArray _src, InputArray _lowerb, src.size != ub.size || src.type() != ub.type() ) { if( !checkScalar(ub, src.type(), ukind, skind) ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The upper boundary is neither an array of the same size and same type as src, nor a scalar"); ubScalar = true; } diff --git a/modules/core/src/array.cpp b/modules/core/src/array.cpp index d43101924e..ffb23ab441 100644 --- a/modules/core/src/array.cpp +++ b/modules/core/src/array.cpp @@ -79,7 +79,7 @@ cvSetIPLAllocators( Cv_iplCreateImageHeader createHeader, (createROI != 0) + (cloneImage != 0); if( count != 0 && count != 5 ) - CV_Error( CV_StsBadArg, "Either all the pointers should be null or " + CV_Error( cv::Error::StsBadArg, "Either all the pointers should be null or " "they all should be non-null" ); CvIPL.createHeader = createHeader; @@ -118,11 +118,11 @@ cvCreateMatHeader( int rows, int cols, int type ) type = CV_MAT_TYPE(type); if( rows < 0 || cols < 0 ) - CV_Error( CV_StsBadSize, "Non-positive width or height" ); + CV_Error( cv::Error::StsBadSize, "Non-positive width or height" ); int min_step = CV_ELEM_SIZE(type); if( min_step <= 0 ) - CV_Error( CV_StsUnsupportedFormat, "Invalid matrix type" ); + CV_Error( cv::Error::StsUnsupportedFormat, "Invalid matrix type" ); min_step *= cols; CvMat* arr = (CvMat*)cvAlloc( sizeof(*arr)); @@ -146,13 +146,13 @@ cvInitMatHeader( CvMat* arr, int rows, int cols, int type, void* data, int step ) { if( !arr ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( (unsigned)CV_MAT_DEPTH(type) > CV_DEPTH_MAX ) - CV_Error( CV_BadNumChannels, "" ); + CV_Error( cv::Error::BadNumChannels, "" ); if( rows < 0 || cols < 0 ) - CV_Error( CV_StsBadSize, "Non-positive cols or rows" ); + CV_Error( cv::Error::StsBadSize, "Non-positive cols or rows" ); type = CV_MAT_TYPE( type ); arr->type = type | CV_MAT_MAGIC_VAL; @@ -168,7 +168,7 @@ cvInitMatHeader( CvMat* arr, int rows, int cols, if( step != CV_AUTOSTEP && step != 0 ) { if( step < min_step ) - CV_Error( CV_BadStep, "" ); + CV_Error( cv::Error::BadStep, "" ); arr->step = step; } else @@ -196,7 +196,7 @@ cvReleaseMat( CvMat** array ) CvMat* arr = *array; if( !CV_IS_MAT_HDR_Z(arr) && !CV_IS_MATND_HDR(arr) ) - CV_Error( CV_StsBadFlag, "" ); + CV_Error( cv::Error::StsBadFlag, "" ); *array = 0; @@ -211,7 +211,7 @@ CV_IMPL CvMat* cvCloneMat( const CvMat* src ) { if( !CV_IS_MAT_HDR( src )) - CV_Error( CV_StsBadArg, "Bad CvMat header" ); + CV_Error( cv::Error::StsBadArg, "Bad CvMat header" ); CvMat* dst = cvCreateMatHeader( src->rows, src->cols, src->type ); @@ -237,25 +237,25 @@ cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes, int64 esz = CV_ELEM_SIZE(type), step = esz; if( !mat ) - CV_Error( CV_StsNullPtr, "NULL matrix header pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL matrix header pointer" ); if( step == 0 ) - CV_Error( CV_StsUnsupportedFormat, "invalid array data type" ); + CV_Error( cv::Error::StsUnsupportedFormat, "invalid array data type" ); if( !sizes ) - CV_Error( CV_StsNullPtr, "NULL pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL pointer" ); if( dims <= 0 || dims > CV_MAX_DIM ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "non-positive or too large number of dimensions" ); for( int i = dims - 1; i >= 0; i-- ) { if( sizes[i] < 0 ) - CV_Error( CV_StsBadSize, "one of dimension sizes is non-positive" ); + CV_Error( cv::Error::StsBadSize, "one of dimension sizes is non-positive" ); mat->dim[i].size = sizes[i]; if( step > INT_MAX ) - CV_Error( CV_StsOutOfRange, "The array is too big" ); + CV_Error( cv::Error::StsOutOfRange, "The array is too big" ); mat->dim[i].step = (int)step; step *= sizes[i]; } @@ -292,7 +292,7 @@ CV_IMPL CvMatND* cvCreateMatNDHeader( int dims, const int* sizes, int type ) { if( dims <= 0 || dims > CV_MAX_DIM ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "non-positive or too large number of dimensions" ); CvMatND* arr = (CvMatND*)cvAlloc( sizeof(*arr) ); @@ -308,7 +308,7 @@ CV_IMPL CvMatND* cvCloneMatND( const CvMatND* src ) { if( !CV_IS_MATND_HDR( src )) - CV_Error( CV_StsBadArg, "Bad CvMatND header" ); + CV_Error( cv::Error::StsBadArg, "Bad CvMatND header" ); CV_Assert( src->dims <= CV_MAX_DIM ); int sizes[CV_MAX_DIM]; @@ -349,18 +349,18 @@ cvCreateSparseMat( int dims, const int* sizes, int type ) CvMemStorage* storage; if( pix_size == 0 ) - CV_Error( CV_StsUnsupportedFormat, "invalid array data type" ); + CV_Error( cv::Error::StsUnsupportedFormat, "invalid array data type" ); if( dims <= 0 || dims > CV_MAX_DIM ) - CV_Error( CV_StsOutOfRange, "bad number of dimensions" ); + CV_Error( cv::Error::StsOutOfRange, "bad number of dimensions" ); if( !sizes ) - CV_Error( CV_StsNullPtr, "NULL pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL pointer" ); for( i = 0; i < dims; i++ ) { if( sizes[i] <= 0 ) - CV_Error( CV_StsBadSize, "one of dimension sizes is non-positive" ); + CV_Error( cv::Error::StsBadSize, "one of dimension sizes is non-positive" ); } CvSparseMat* arr = (CvSparseMat*)cvAlloc(sizeof(*arr)+MAX(0,dims-CV_MAX_DIM)*sizeof(arr->size[0])); @@ -400,7 +400,7 @@ cvReleaseSparseMat( CvSparseMat** array ) CvSparseMat* arr = *array; if( !CV_IS_SPARSE_MAT_HDR(arr) ) - CV_Error( CV_StsBadFlag, "" ); + CV_Error( cv::Error::StsBadFlag, "" ); *array = 0; @@ -417,7 +417,7 @@ CV_IMPL CvSparseMat* cvCloneSparseMat( const CvSparseMat* src ) { if( !CV_IS_SPARSE_MAT_HDR(src) ) - CV_Error( CV_StsBadArg, "Invalid sparse array header" ); + CV_Error( cv::Error::StsBadArg, "Invalid sparse array header" ); CvSparseMat* dst = cvCreateSparseMat( src->dims, src->size, src->type ); cvCopy( src, dst ); @@ -432,10 +432,10 @@ cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* iterator ) int idx; if( !CV_IS_SPARSE_MAT( mat )) - CV_Error( CV_StsBadArg, "Invalid sparse matrix header" ); + CV_Error( cv::Error::StsBadArg, "Invalid sparse matrix header" ); if( !iterator ) - CV_Error( CV_StsNullPtr, "NULL iterator pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL iterator pointer" ); iterator->mat = (CvSparseMat*)mat; iterator->node = 0; @@ -469,7 +469,7 @@ icvGetNodePtr( CvSparseMat* mat, const int* idx, int* _type, { int t = idx[i]; if( (unsigned)t >= (unsigned)mat->size[i] ) - CV_Error( CV_StsOutOfRange, "One of indices is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "One of indices is out of range" ); hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t; } } @@ -563,7 +563,7 @@ icvDeleteNode( CvSparseMat* mat, const int* idx, unsigned* precalc_hashval ) { int t = idx[i]; if( (unsigned)t >= (unsigned)mat->size[i] ) - CV_Error( CV_StsOutOfRange, "One of indices is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "One of indices is out of range" ); hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t; } } @@ -618,7 +618,7 @@ cvCreateData( CvArr* arr ) return; if( mat->data.ptr != 0 ) - CV_Error( CV_StsError, "Data is already allocated" ); + CV_Error( cv::Error::StsError, "Data is already allocated" ); if( step == 0 ) step = CV_ELEM_SIZE(mat->type)*mat->cols; @@ -626,7 +626,7 @@ cvCreateData( CvArr* arr ) int64 _total_size = (int64)step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN; total_size = (size_t)_total_size; if(_total_size != (int64)total_size) - CV_Error(CV_StsNoMem, "Too big buffer is allocated" ); + CV_Error(cv::Error::StsNoMem, "Too big buffer is allocated" ); mat->refcount = (int*)cvAlloc( (size_t)total_size ); mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN ); *mat->refcount = 1; @@ -636,13 +636,13 @@ cvCreateData( CvArr* arr ) IplImage* img = (IplImage*)arr; if( img->imageData != 0 ) - CV_Error( CV_StsError, "Data is already allocated" ); + CV_Error( cv::Error::StsError, "Data is already allocated" ); if( !CvIPL.allocateData ) { const int64 imageSize_tmp = (int64)img->widthStep*(int64)img->height; if( (int64)img->imageSize != imageSize_tmp ) - CV_Error( CV_StsNoMem, "Overflow for imageSize" ); + CV_Error( cv::Error::StsNoMem, "Overflow for imageSize" ); img->imageData = img->imageDataOrigin = (char*)cvAlloc( (size_t)img->imageSize ); } @@ -672,7 +672,7 @@ cvCreateData( CvArr* arr ) return; if( mat->data.ptr != 0 ) - CV_Error( CV_StsError, "Data is already allocated" ); + CV_Error( cv::Error::StsError, "Data is already allocated" ); if( CV_IS_MAT_CONT( mat->type )) { @@ -697,7 +697,7 @@ cvCreateData( CvArr* arr ) *mat->refcount = 1; } else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); } @@ -721,7 +721,7 @@ cvSetData( CvArr* arr, void* data, int step ) if( step != CV_AUTOSTEP && step != 0 ) { if( step < min_step && data != 0 ) - CV_Error( CV_BadStep, "" ); + CV_Error( cv::Error::BadStep, "" ); mat->step = step; } else @@ -742,7 +742,7 @@ cvSetData( CvArr* arr, void* data, int step ) if( step != CV_AUTOSTEP && img->height > 1 ) { if( step < min_step && data != 0 ) - CV_Error( CV_BadStep, "" ); + CV_Error( cv::Error::BadStep, "" ); img->widthStep = step; } else @@ -753,7 +753,7 @@ cvSetData( CvArr* arr, void* data, int step ) const int64 imageSize_tmp = (int64)img->widthStep*(int64)img->height; img->imageSize = (int)imageSize_tmp; if( (int64)img->imageSize != imageSize_tmp ) - CV_Error( CV_StsNoMem, "Overflow for imageSize" ); + CV_Error( cv::Error::StsNoMem, "Overflow for imageSize" ); img->imageData = img->imageDataOrigin = (char*)data; if( (((int)(size_t)data | step) & 7) == 0 && @@ -769,7 +769,7 @@ cvSetData( CvArr* arr, void* data, int step ) int64 cur_step; if( step != CV_AUTOSTEP ) - CV_Error( CV_BadStep, + CV_Error( cv::Error::BadStep, "For multidimensional array only CV_AUTOSTEP is allowed here" ); mat->data.ptr = (uchar*)data; @@ -778,13 +778,13 @@ cvSetData( CvArr* arr, void* data, int step ) for( i = mat->dims - 1; i >= 0; i-- ) { if( cur_step > INT_MAX ) - CV_Error( CV_StsOutOfRange, "The array is too big" ); + CV_Error( cv::Error::StsOutOfRange, "The array is too big" ); mat->dim[i].step = (int)cur_step; cur_step *= mat->dim[i].size; } } else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); } @@ -813,9 +813,13 @@ cvReleaseData( CvArr* arr ) } } else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); } +static inline cv::Size cvGetMatSize( const CvMat* mat ) +{ + return cv::Size(mat->cols, mat->rows); +} // Retrieves essential information about image ROI or CvMat data CV_IMPL void @@ -861,7 +865,7 @@ cvGetRawData( const CvArr* arr, uchar** data, int* step, CvSize* roi_size ) CvMatND* mat = (CvMatND*)arr; if( !CV_IS_MAT_CONT( mat->type )) - CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" ); + CV_Error( cv::Error::StsBadArg, "Only continuous nD arrays are supported here" ); if( data ) *data = mat->data.ptr; @@ -890,7 +894,7 @@ cvGetRawData( const CvArr* arr, uchar** data, int* step, CvSize* roi_size ) } } else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); } @@ -906,7 +910,7 @@ cvGetElemType( const CvArr* arr ) type = CV_MAKETYPE( IPL2CV_DEPTH(img->depth), img->nChannels ); } else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); return type; } @@ -960,7 +964,7 @@ cvGetDims( const CvArr* arr, int* sizes ) memcpy( sizes, mat->size, dims*sizeof(sizes[0])); } else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); return dims; } @@ -985,7 +989,7 @@ cvGetDimSize( const CvArr* arr, int index ) size = mat->cols; break; default: - CV_Error( CV_StsOutOfRange, "bad dimension index" ); + CV_Error( cv::Error::StsOutOfRange, "bad dimension index" ); } } else if( CV_IS_IMAGE( arr )) @@ -1001,7 +1005,7 @@ cvGetDimSize( const CvArr* arr, int index ) size = !img->roi ? img->width : img->roi->width; break; default: - CV_Error( CV_StsOutOfRange, "bad dimension index" ); + CV_Error( cv::Error::StsOutOfRange, "bad dimension index" ); } } else if( CV_IS_MATND_HDR( arr )) @@ -1009,7 +1013,7 @@ cvGetDimSize( const CvArr* arr, int index ) CvMatND* mat = (CvMatND*)arr; if( (unsigned)index >= (unsigned)mat->dims ) - CV_Error( CV_StsOutOfRange, "bad dimension index" ); + CV_Error( cv::Error::StsOutOfRange, "bad dimension index" ); size = mat->dim[index].size; } @@ -1018,12 +1022,12 @@ cvGetDimSize( const CvArr* arr, int index ) CvSparseMat* mat = (CvSparseMat*)arr; if( (unsigned)index >= (unsigned)mat->dims ) - CV_Error( CV_StsOutOfRange, "bad dimension index" ); + CV_Error( cv::Error::StsOutOfRange, "bad dimension index" ); size = mat->size[index]; } else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); return size; } @@ -1058,7 +1062,7 @@ cvGetSize( const CvArr* arr ) } } else - CV_Error( CV_StsBadArg, "Array should be CvMat or IplImage" ); + CV_Error( cv::Error::StsBadArg, "Array should be CvMat or IplImage" ); return size; } @@ -1075,14 +1079,14 @@ cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect ) mat = cvGetMat( mat, &stub ); if( !submat ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( (rect.x|rect.y|rect.width|rect.height) < 0 ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); if( rect.x + rect.width > mat->cols || rect.y + rect.height > mat->rows ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); { /* @@ -1120,11 +1124,11 @@ cvGetRows( const CvArr* arr, CvMat* submat, mat = cvGetMat( mat, &stub ); if( !submat ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( (unsigned)start_row >= (unsigned)mat->rows || (unsigned)end_row > (unsigned)mat->rows || delta_row <= 0 ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); { /* @@ -1172,12 +1176,12 @@ cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col ) mat = cvGetMat( mat, &stub ); if( !submat ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); cols = mat->cols; if( (unsigned)start_col >= (unsigned)cols || (unsigned)end_col > (unsigned)cols ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); { /* @@ -1216,7 +1220,7 @@ cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_1 CV_Assert( scalar && data ); if( (unsigned)(cn - 1) >= 4 ) - CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); + CV_Error( cv::Error::StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); switch( depth ) { @@ -1262,7 +1266,7 @@ cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_1 break; default: CV_Assert(0); - CV_Error( CV_BadDepth, "" ); + CV_Error( cv::Error::BadDepth, "" ); } if( extend_to_12 ) @@ -1289,7 +1293,7 @@ cvRawDataToScalar( const void* data, int flags, CvScalar* scalar ) CV_Assert( scalar && data ); if( (unsigned)(cn - 1) >= 4 ) - CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); + CV_Error( cv::Error::StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); memset( scalar->val, 0, sizeof(scalar->val)); @@ -1325,7 +1329,7 @@ cvRawDataToScalar( const void* data, int flags, CvScalar* scalar ) break; default: CV_Assert(0); - CV_Error( CV_BadDepth, "" ); + CV_Error( cv::Error::BadDepth, "" ); } } @@ -1412,7 +1416,7 @@ cvPtr1D( const CvArr* arr, int idx, int* _type ) // that the index is within the matrix if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); if( CV_IS_MAT_CONT(mat->type)) { @@ -1449,7 +1453,7 @@ cvPtr1D( const CvArr* arr, int idx, int* _type ) size *= mat->dim[j].size; if((unsigned)idx >= (unsigned)size ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); if( CV_IS_MAT_CONT(mat->type)) { @@ -1493,7 +1497,7 @@ cvPtr1D( const CvArr* arr, int idx, int* _type ) } else { - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); } return ptr; @@ -1512,7 +1516,7 @@ cvPtr2D( const CvArr* arr, int y, int x, int* _type ) if( (unsigned)y >= (unsigned)(mat->rows) || (unsigned)x >= (unsigned)(mat->cols) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); type = CV_MAT_TYPE(mat->type); if( _type ) @@ -1542,7 +1546,7 @@ cvPtr2D( const CvArr* arr, int y, int x, int* _type ) { int coi = img->roi->coi; if( !coi ) - CV_Error( CV_BadCOI, + CV_Error( cv::Error::BadCOI, "COI must be non-null in case of planar images" ); ptr += (coi - 1)*img->imageSize; } @@ -1555,7 +1559,7 @@ cvPtr2D( const CvArr* arr, int y, int x, int* _type ) if( (unsigned)y >= (unsigned)height || (unsigned)x >= (unsigned)width ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr += y*img->widthStep + x*pix_size; @@ -1563,7 +1567,7 @@ cvPtr2D( const CvArr* arr, int y, int x, int* _type ) { int type = IPL2CV_DEPTH(img->depth); if( type < 0 || (unsigned)(img->nChannels - 1) > 3 ) - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); *_type = CV_MAKETYPE( type, img->nChannels ); } @@ -1575,7 +1579,7 @@ cvPtr2D( const CvArr* arr, int y, int x, int* _type ) if( mat->dims != 2 || (unsigned)y >= (unsigned)(mat->dim[0].size) || (unsigned)x >= (unsigned)(mat->dim[1].size) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr = mat->data.ptr + (size_t)y*mat->dim[0].step + x*mat->dim[1].step; if( _type ) @@ -1589,7 +1593,7 @@ cvPtr2D( const CvArr* arr, int y, int x, int* _type ) } else { - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); } return ptr; @@ -1609,7 +1613,7 @@ cvPtr3D( const CvArr* arr, int z, int y, int x, int* _type ) (unsigned)z >= (unsigned)(mat->dim[0].size) || (unsigned)y >= (unsigned)(mat->dim[1].size) || (unsigned)x >= (unsigned)(mat->dim[2].size) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr = mat->data.ptr + (size_t)z*mat->dim[0].step + (size_t)y*mat->dim[1].step + x*mat->dim[2].step; @@ -1624,7 +1628,7 @@ cvPtr3D( const CvArr* arr, int z, int y, int x, int* _type ) } else { - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); } return ptr; @@ -1638,7 +1642,7 @@ cvPtrND( const CvArr* arr, const int* idx, int* _type, { uchar* ptr = 0; if( !idx ) - CV_Error( CV_StsNullPtr, "NULL pointer to indices" ); + CV_Error( cv::Error::StsNullPtr, "NULL pointer to indices" ); if( CV_IS_SPARSE_MAT( arr )) ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, @@ -1652,7 +1656,7 @@ cvPtrND( const CvArr* arr, const int* idx, int* _type, for( i = 0; i < mat->dims; i++ ) { if( (unsigned)idx[i] >= (unsigned)(mat->dim[i].size) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr += (size_t)idx[i]*mat->dim[i].step; } @@ -1662,7 +1666,7 @@ cvPtrND( const CvArr* arr, const int* idx, int* _type, else if( CV_IS_MAT_HDR(arr) || CV_IS_IMAGE_HDR(arr) ) ptr = cvPtr2D( arr, idx[0], idx[1], _type ); else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); return ptr; } @@ -1687,7 +1691,7 @@ cvGet1D( const CvArr* arr, int idx ) // that the index is within the matrix if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr = mat->data.ptr + (size_t)idx*pix_size; } @@ -1717,7 +1721,7 @@ cvGet2D( const CvArr* arr, int y, int x ) if( (unsigned)y >= (unsigned)(mat->rows) || (unsigned)x >= (unsigned)(mat->cols) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); type = CV_MAT_TYPE(mat->type); ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); @@ -1798,7 +1802,7 @@ cvGetReal1D( const CvArr* arr, int idx ) // that the index is within the matrix if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr = mat->data.ptr + (size_t)idx*pix_size; } @@ -1810,7 +1814,7 @@ cvGetReal1D( const CvArr* arr, int idx ) if( ptr ) { if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvGetReal* support only single-channel arrays" ); value = icvGetReal( ptr, type ); } @@ -1832,7 +1836,7 @@ cvGetReal2D( const CvArr* arr, int y, int x ) if( (unsigned)y >= (unsigned)(mat->rows) || (unsigned)x >= (unsigned)(mat->cols) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); type = CV_MAT_TYPE(mat->type); ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); @@ -1848,7 +1852,7 @@ cvGetReal2D( const CvArr* arr, int y, int x ) if( ptr ) { if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvGetReal* support only single-channel arrays" ); value = icvGetReal( ptr, type ); } @@ -1876,7 +1880,7 @@ cvGetReal3D( const CvArr* arr, int z, int y, int x ) if( ptr ) { if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvGetReal* support only single-channel arrays" ); value = icvGetReal( ptr, type ); } @@ -1901,7 +1905,7 @@ cvGetRealND( const CvArr* arr, const int* idx ) if( ptr ) { if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvGetReal* support only single-channel arrays" ); value = icvGetReal( ptr, type ); } @@ -1928,7 +1932,7 @@ cvSet1D( CvArr* arr, int idx, CvScalar scalar ) // that the index is within the matrix if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr = mat->data.ptr + (size_t)idx*pix_size; } @@ -1954,7 +1958,7 @@ cvSet2D( CvArr* arr, int y, int x, CvScalar scalar ) if( (unsigned)y >= (unsigned)(mat->rows) || (unsigned)x >= (unsigned)(mat->cols) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); type = CV_MAT_TYPE(mat->type); ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); @@ -2020,7 +2024,7 @@ cvSetReal1D( CvArr* arr, int idx, double value ) // that the index is within the matrix if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr = mat->data.ptr + (size_t)idx*pix_size; } @@ -2030,7 +2034,7 @@ cvSetReal1D( CvArr* arr, int idx, double value ) ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 ); if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvSetReal* support only single-channel arrays" ); if( ptr ) icvSetReal( value, ptr, type ); @@ -2049,7 +2053,7 @@ cvSetReal2D( CvArr* arr, int y, int x, double value ) if( (unsigned)y >= (unsigned)(mat->rows) || (unsigned)x >= (unsigned)(mat->cols) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); type = CV_MAT_TYPE(mat->type); ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); @@ -2064,7 +2068,7 @@ cvSetReal2D( CvArr* arr, int y, int x, double value ) ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); } if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvSetReal* support only single-channel arrays" ); if( ptr ) icvSetReal( value, ptr, type ); @@ -2085,7 +2089,7 @@ cvSetReal3D( CvArr* arr, int z, int y, int x, double value ) ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); } if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvSetReal* support only single-channel arrays" ); if( ptr ) icvSetReal( value, ptr, type ); @@ -2104,7 +2108,7 @@ cvSetRealND( CvArr* arr, const int* idx, double value ) ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvSetReal* support only single-channel arrays" ); if( ptr ) icvSetReal( value, ptr, type ); @@ -2141,12 +2145,12 @@ cvGetMat( const CvArr* array, CvMat* mat, int coi = 0; if( !mat || !src ) - CV_Error( CV_StsNullPtr, "NULL array pointer is passed" ); + CV_Error( cv::Error::StsNullPtr, "NULL array pointer is passed" ); if( CV_IS_MAT_HDR(src)) { if( !src->data.ptr ) - CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" ); + CV_Error( cv::Error::StsNullPtr, "The matrix has NULL data pointer" ); result = (CvMat*)src; } @@ -2156,11 +2160,11 @@ cvGetMat( const CvArr* array, CvMat* mat, int depth, order; if( img->imageData == 0 ) - CV_Error( CV_StsNullPtr, "The image has NULL data pointer" ); + CV_Error( cv::Error::StsNullPtr, "The image has NULL data pointer" ); depth = IPL2CV_DEPTH( img->depth ); if( depth < 0 ) - CV_Error( CV_BadDepth, "" ); + CV_Error( cv::Error::BadDepth, "" ); order = img->dataOrder & (img->nChannels > 1 ? -1 : 0); @@ -2171,7 +2175,7 @@ cvGetMat( const CvArr* array, CvMat* mat, int type = depth; if( img->roi->coi == 0 ) - CV_Error( CV_StsBadFlag, + CV_Error( cv::Error::StsBadFlag, "Images with planar data layout should be used with COI selected" ); cvInitMatHeader( mat, img->roi->height, @@ -2187,7 +2191,7 @@ cvGetMat( const CvArr* array, CvMat* mat, coi = img->roi->coi; if( img->nChannels > CV_CN_MAX ) - CV_Error( CV_BadNumChannels, + CV_Error( cv::Error::BadNumChannels, "The image is interleaved and has over CV_CN_MAX channels" ); cvInitMatHeader( mat, img->roi->height, img->roi->width, @@ -2202,7 +2206,7 @@ cvGetMat( const CvArr* array, CvMat* mat, int type = CV_MAKETYPE( depth, img->nChannels ); if( order != IPL_DATA_ORDER_PIXEL ) - CV_Error( CV_StsBadFlag, "Pixel order should be used with coi == 0" ); + CV_Error( cv::Error::StsBadFlag, "Pixel order should be used with coi == 0" ); cvInitMatHeader( mat, img->height, img->width, type, img->imageData, img->widthStep ); @@ -2216,10 +2220,10 @@ cvGetMat( const CvArr* array, CvMat* mat, int size1 = matnd->dim[0].size, size2 = 1; if( !src->data.ptr ) - CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" ); + CV_Error( cv::Error::StsNullPtr, "Input array has NULL data pointer" ); if( !CV_IS_MAT_CONT( matnd->type )) - CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" ); + CV_Error( cv::Error::StsBadArg, "Only continuous nD arrays are supported here" ); if( matnd->dims > 2 ) { @@ -2243,7 +2247,7 @@ cvGetMat( const CvArr* array, CvMat* mat, result = mat; } else - CV_Error( CV_StsBadFlag, "Unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadFlag, "Unrecognized or unsupported array type" ); if( pCOI ) *pCOI = coi; @@ -2261,20 +2265,20 @@ cvReshape( const CvArr* array, CvMat* header, int total_width, new_width; if( !header ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( !CV_IS_MAT( mat )) { int coi = 0; mat = cvGetMat( mat, header, &coi, 1 ); if( coi ) - CV_Error( CV_BadCOI, "COI is not supported" ); + CV_Error( cv::Error::BadCOI, "COI is not supported" ); } if( new_cn == 0 ) new_cn = CV_MAT_CN(mat->type); else if( (unsigned)(new_cn - 1) > 3 ) - CV_Error( CV_BadNumChannels, "" ); + CV_Error( cv::Error::BadNumChannels, "" ); if( mat != header ) { @@ -2298,16 +2302,16 @@ cvReshape( const CvArr* array, CvMat* header, { int total_size = total_width * mat->rows; if( !CV_IS_MAT_CONT( mat->type )) - CV_Error( CV_BadStep, + CV_Error( cv::Error::BadStep, "The matrix is not continuous, thus its number of rows can not be changed" ); if( (unsigned)new_rows > (unsigned)total_size ) - CV_Error( CV_StsOutOfRange, "Bad new number of rows" ); + CV_Error( cv::Error::StsOutOfRange, "Bad new number of rows" ); total_width = total_size / new_rows; if( total_width * new_rows != total_size ) - CV_Error( CV_StsBadArg, "The total number of matrix elements " + CV_Error( cv::Error::StsBadArg, "The total number of matrix elements " "is not divisible by the new number of rows" ); header->rows = new_rows; @@ -2317,7 +2321,7 @@ cvReshape( const CvArr* array, CvMat* header, new_width = total_width / new_cn; if( new_width * new_cn != total_width ) - CV_Error( CV_BadNumChannels, + CV_Error( cv::Error::BadNumChannels, "The total width is not divisible by the new number of channels" ); header->cols = new_width; @@ -2336,17 +2340,17 @@ cvGetImage( const CvArr* array, IplImage* img ) const IplImage* src = (const IplImage*)array; if( !img ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( !CV_IS_IMAGE_HDR(src) ) { const CvMat* mat = (const CvMat*)src; if( !CV_IS_MAT_HDR(mat)) - CV_Error( CV_StsBadFlag, "" ); + CV_Error( cv::Error::StsBadFlag, "" ); if( mat->data.ptr == 0 ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); int depth = cvIplDepth(mat->type); @@ -2479,19 +2483,19 @@ cvInitImageHeader( IplImage * image, CvSize size, int depth, } if( size.width < 0 || size.height < 0 ) - CV_Error( CV_BadROISize, "Bad input roi" ); + CV_Error( cv::Error::BadROISize, "Bad input roi" ); if( (depth != (int)IPL_DEPTH_1U && depth != (int)IPL_DEPTH_8U && depth != (int)IPL_DEPTH_8S && depth != (int)IPL_DEPTH_16U && depth != (int)IPL_DEPTH_16S && depth != (int)IPL_DEPTH_32S && depth != (int)IPL_DEPTH_32F && depth != (int)IPL_DEPTH_64F) || channels < 0 ) - CV_Error( CV_BadDepth, "Unsupported format" ); + CV_Error( cv::Error::BadDepth, "Unsupported format" ); if( origin != CV_ORIGIN_BL && origin != CV_ORIGIN_TL ) - CV_Error( CV_BadOrigin, "Bad input origin" ); + CV_Error( cv::Error::BadOrigin, "Bad input origin" ); if( align != 4 && align != 8 ) - CV_Error( CV_BadAlign, "Bad input align" ); + CV_Error( cv::Error::BadAlign, "Bad input align" ); image->width = size.width; image->height = size.height; @@ -2513,7 +2517,7 @@ cvInitImageHeader( IplImage * image, CvSize size, int depth, const int64 imageSize_tmp = (int64)image->widthStep*(int64)image->height; image->imageSize = (int)imageSize_tmp; if( (int64)image->imageSize != imageSize_tmp ) - CV_Error( CV_StsNoMem, "Overflow for imageSize" ); + CV_Error( cv::Error::StsNoMem, "Overflow for imageSize" ); return image; } @@ -2523,7 +2527,7 @@ CV_IMPL void cvReleaseImageHeader( IplImage** image ) { if( !image ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( *image ) { @@ -2547,7 +2551,7 @@ CV_IMPL void cvReleaseImage( IplImage ** image ) { if( !image ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( *image ) { @@ -2621,7 +2625,7 @@ cvGetImageROI( const IplImage* img ) { CvRect rect = {0, 0, 0, 0}; if( !img ) - CV_Error( CV_StsNullPtr, "Null pointer to image" ); + CV_Error( cv::Error::StsNullPtr, "Null pointer to image" ); if( img->roi ) rect = cvRect( img->roi->xOffset, img->roi->yOffset, @@ -2640,7 +2644,7 @@ cvSetImageCOI( IplImage* image, int coi ) CV_Error( CV_HeaderIsNull, "" ); if( (unsigned)coi > (unsigned)(image->nChannels) ) - CV_Error( CV_BadCOI, "" ); + CV_Error( cv::Error::BadCOI, "" ); if( image->roi || coi != 0 ) { @@ -2672,7 +2676,7 @@ cvCloneImage( const IplImage* src ) IplImage* dst = 0; if( !CV_IS_IMAGE_HDR( src )) - CV_Error( CV_StsBadArg, "Bad image header" ); + CV_Error( cv::Error::StsBadArg, "Bad image header" ); if( !CvIPL.cloneImage ) { @@ -2718,13 +2722,13 @@ cvCheckTermCriteria( CvTermCriteria criteria, double default_eps, crit.epsilon = (float)default_eps; if( (criteria.type & ~(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) != 0 ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "Unknown type of term criteria" ); if( (criteria.type & CV_TERMCRIT_ITER) != 0 ) { if( criteria.max_iter <= 0 ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "Iterations flag is set and maximum number of iterations is <= 0" ); crit.max_iter = criteria.max_iter; } @@ -2732,13 +2736,13 @@ cvCheckTermCriteria( CvTermCriteria criteria, double default_eps, if( (criteria.type & CV_TERMCRIT_EPS) != 0 ) { if( criteria.epsilon < 0 ) - CV_Error( CV_StsBadArg, "Accuracy flag is set and epsilon is < 0" ); + CV_Error( cv::Error::StsBadArg, "Accuracy flag is set and epsilon is < 0" ); crit.epsilon = criteria.epsilon; } if( (criteria.type & (CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) == 0 ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "Neither accuracy nor maximum iterations " "number flags are set in criteria type" ); @@ -2765,7 +2769,7 @@ CV_IMPL void cvRelease( void** struct_ptr ) { if( !struct_ptr ) - CV_Error( CV_StsNullPtr, "NULL double pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL double pointer" ); if( *struct_ptr ) { @@ -2774,7 +2778,7 @@ cvRelease( void** struct_ptr ) else if( CV_IS_IMAGE(*struct_ptr)) cvReleaseImage((IplImage**)struct_ptr); else - CV_Error( CV_StsError, "Unknown object type" ); + CV_Error( cv::Error::StsError, "Unknown object type" ); } } diff --git a/modules/core/src/batch_distance.cpp b/modules/core/src/batch_distance.cpp index 1ce2edb769..4210c672b9 100644 --- a/modules/core/src/batch_distance.cpp +++ b/modules/core/src/batch_distance.cpp @@ -377,7 +377,7 @@ void cv::batchDistance( InputArray _src1, InputArray _src2, } if( func == 0 ) - CV_Error_(CV_StsUnsupportedFormat, + CV_Error_(cv::Error::StsUnsupportedFormat, ("The combination of type=%d, dtype=%d and normType=%d is not supported", type, dtype, normType)); diff --git a/modules/core/src/command_line_parser.cpp b/modules/core/src/command_line_parser.cpp index af97232db6..a83cb3166d 100644 --- a/modules/core/src/command_line_parser.cpp +++ b/modules/core/src/command_line_parser.cpp @@ -464,7 +464,7 @@ std::vector CommandLineParser::Impl::split_range_string(const String& _s { if (begin == true) { - throw cv::Exception(CV_StsParseError, + throw cv::Exception(cv::Error::StsParseError, String("error in split_range_string(") + str + String(", ") @@ -484,7 +484,7 @@ std::vector CommandLineParser::Impl::split_range_string(const String& _s { if (begin == false) { - throw cv::Exception(CV_StsParseError, + throw cv::Exception(cv::Error::StsParseError, String("error in split_range_string(") + str + String(", ") @@ -508,7 +508,7 @@ std::vector CommandLineParser::Impl::split_range_string(const String& _s if (begin == true) { - throw cv::Exception(CV_StsParseError, + throw cv::Exception(cv::Error::StsParseError, String("error in split_range_string(") + str + String(", ") diff --git a/modules/core/src/copy.cpp b/modules/core/src/copy.cpp index 7b7c717d54..aec36b9073 100644 --- a/modules/core/src/copy.cpp +++ b/modules/core/src/copy.cpp @@ -111,7 +111,7 @@ void scalarToRawData(const Scalar& s, void* _buf, int type, int unroll_to) scalarToRawData_(s, (double*)_buf, cn, unroll_to); break; default: - CV_Error(CV_StsUnsupportedFormat,""); + CV_Error(cv::Error::StsUnsupportedFormat,""); } } @@ -826,7 +826,7 @@ int cv::borderInterpolate( int p, int len, int borderType ) else if( borderType == BORDER_CONSTANT ) p = -1; else - CV_Error( CV_StsBadArg, "Unknown/unsupported border type" ); + CV_Error( cv::Error::StsBadArg, "Unknown/unsupported border type" ); return p; } diff --git a/modules/core/src/datastructs.cpp b/modules/core/src/datastructs.cpp index 80b02283dc..17da7119a3 100644 --- a/modules/core/src/datastructs.cpp +++ b/modules/core/src/datastructs.cpp @@ -91,7 +91,7 @@ static void icvInitMemStorage( CvMemStorage* storage, int block_size ) { if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( block_size <= 0 ) block_size = CV_STORAGE_BLOCK_SIZE; @@ -120,7 +120,7 @@ CV_IMPL CvMemStorage * cvCreateChildMemStorage( CvMemStorage * parent ) { if( !parent ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); CvMemStorage* storage = cvCreateMemStorage(parent->block_size); storage->parent = parent; @@ -137,7 +137,7 @@ icvDestroyMemStorage( CvMemStorage* storage ) CvMemBlock *dst_top = 0; if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( storage->parent ) dst_top = storage->parent->top; @@ -180,7 +180,7 @@ CV_IMPL void cvReleaseMemStorage( CvMemStorage** storage ) { if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); CvMemStorage* st = *storage; *storage = 0; @@ -197,7 +197,7 @@ CV_IMPL void cvClearMemStorage( CvMemStorage * storage ) { if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( storage->parent ) icvDestroyMemStorage( storage ); @@ -215,7 +215,7 @@ static void icvGoNextMemBlock( CvMemStorage * storage ) { if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( !storage->top || !storage->top->next ) { @@ -273,7 +273,7 @@ CV_IMPL void cvSaveMemStoragePos( const CvMemStorage * storage, CvMemStoragePos * pos ) { if( !storage || !pos ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); pos->top = storage->top; pos->free_space = storage->free_space; @@ -285,9 +285,9 @@ CV_IMPL void cvRestoreMemStoragePos( CvMemStorage * storage, CvMemStoragePos * pos ) { if( !storage || !pos ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( pos->free_space > storage->block_size ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); /* // this breaks icvGoNextMemBlock, so comment it off for now @@ -324,10 +324,10 @@ cvMemStorageAlloc( CvMemStorage* storage, size_t size ) { schar *ptr = 0; if( !storage ) - CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL storage pointer" ); if( size > INT_MAX ) - CV_Error( CV_StsOutOfRange, "Too large memory block is requested" ); + CV_Error( cv::Error::StsOutOfRange, "Too large memory block is requested" ); CV_Assert( storage->free_space % CV_STRUCT_ALIGN == 0 ); @@ -335,7 +335,7 @@ cvMemStorageAlloc( CvMemStorage* storage, size_t size ) { size_t max_free_space = cvAlignLeft(storage->block_size - sizeof(CvMemBlock), CV_STRUCT_ALIGN); if( max_free_space < size ) - CV_Error( CV_StsOutOfRange, "requested size is negative or too big" ); + CV_Error( cv::Error::StsOutOfRange, "requested size is negative or too big" ); icvGoNextMemBlock( storage ); } @@ -374,9 +374,9 @@ cvCreateSeq( int seq_flags, size_t header_size, size_t elem_size, CvMemStorage* CvSeq *seq = 0; if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( header_size < sizeof( CvSeq ) || elem_size <= 0 ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); /* allocate sequence header */ seq = (CvSeq*)cvMemStorageAlloc( storage, header_size ); @@ -390,7 +390,7 @@ cvCreateSeq( int seq_flags, size_t header_size, size_t elem_size, CvMemStorage* if( elemtype != CV_SEQ_ELTYPE_GENERIC && elemtype != CV_SEQ_ELTYPE_PTR && typesize != 0 && typesize != (int)elem_size ) - CV_Error( CV_StsBadSize, + CV_Error( cv::Error::StsBadSize, "Specified element size doesn't match to the size of the specified element type " "(try to use 0 for element type)" ); } @@ -412,9 +412,9 @@ cvSetSeqBlockSize( CvSeq *seq, int delta_elements ) int useful_block_size; if( !seq || !seq->storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( delta_elements < 0 ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); useful_block_size = cvAlignLeft(seq->storage->block_size - sizeof(CvMemBlock) - sizeof(CvSeqBlock), CV_STRUCT_ALIGN); @@ -429,7 +429,7 @@ cvSetSeqBlockSize( CvSeq *seq, int delta_elements ) { delta_elements = useful_block_size / elem_size; if( delta_elements == 0 ) - CV_Error( CV_StsOutOfRange, "Storage block size is too small " + CV_Error( cv::Error::StsOutOfRange, "Storage block size is too small " "to fit the sequence elements" ); } @@ -487,7 +487,7 @@ cvSeqElemIdx( const CvSeq* seq, const void* _element, CvSeqBlock** _block ) CvSeqBlock *block; if( !seq || !element ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); block = first_block = seq->first; elem_size = seq->elem_size; @@ -548,7 +548,7 @@ cvCvtSeqToArray( const CvSeq *seq, void *array, CvSlice slice ) char *dst = (char*)array; if( !seq || !array ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); elem_size = seq->elem_size; total = cvSliceLength( slice, seq )*elem_size; @@ -587,10 +587,10 @@ cvMakeSeqHeaderForArray( int seq_flags, int header_size, int elem_size, CvSeq* result = 0; if( elem_size <= 0 || header_size < (int)sizeof( CvSeq ) || total < 0 ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); if( !seq || ((!array || !block) && total > 0) ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); memset( seq, 0, header_size ); @@ -602,7 +602,7 @@ cvMakeSeqHeaderForArray( int seq_flags, int header_size, int elem_size, if( elemtype != CV_SEQ_ELTYPE_GENERIC && typesize != 0 && typesize != elem_size ) - CV_Error( CV_StsBadSize, + CV_Error( cv::Error::StsBadSize, "Element size doesn't match to the size of predefined element type " "(try to use 0 for sequence element type)" ); } @@ -634,7 +634,7 @@ icvGrowSeq( CvSeq *seq, int in_front_of ) CvSeqBlock *block; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); block = seq->free_blocks; if( !block ) @@ -647,7 +647,7 @@ icvGrowSeq( CvSeq *seq, int in_front_of ) cvSetSeqBlockSize( seq, delta_elems*2 ); if( !storage ) - CV_Error( CV_StsNullPtr, "The sequence has NULL storage pointer" ); + CV_Error( cv::Error::StsNullPtr, "The sequence has NULL storage pointer" ); /* If there is a free space just after last allocated block and it is big enough then enlarge the last block. @@ -817,7 +817,7 @@ CV_IMPL void cvStartAppendToSeq( CvSeq *seq, CvSeqWriter * writer ) { if( !seq || !writer ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); memset( writer, 0, sizeof( *writer )); writer->header_size = sizeof( CvSeqWriter ); @@ -835,7 +835,7 @@ cvStartWriteSeq( int seq_flags, int header_size, int elem_size, CvMemStorage * storage, CvSeqWriter * writer ) { if( !storage || !writer ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); CvSeq* seq = cvCreateSeq( seq_flags, header_size, elem_size, storage ); cvStartAppendToSeq( seq, writer ); @@ -847,7 +847,7 @@ CV_IMPL void cvFlushSeqWriter( CvSeqWriter * writer ) { if( !writer ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); CvSeq* seq = writer->seq; seq->ptr = writer->ptr; @@ -878,7 +878,7 @@ CV_IMPL CvSeq * cvEndWriteSeq( CvSeqWriter * writer ) { if( !writer ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); cvFlushSeqWriter( writer ); CvSeq* seq = writer->seq; @@ -909,7 +909,7 @@ CV_IMPL void cvCreateSeqBlock( CvSeqWriter * writer ) { if( !writer || !writer->seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); CvSeq* seq = writer->seq; @@ -942,7 +942,7 @@ cvStartReadSeq( const CvSeq *seq, CvSeqReader * reader, int reverse ) } if( !seq || !reader ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); reader->header_size = sizeof( CvSeqReader ); reader->seq = (CvSeq*)seq; @@ -992,7 +992,7 @@ cvChangeSeqBlock( void* _reader, int direction ) CvSeqReader* reader = (CvSeqReader*)_reader; if( !reader ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( direction > 0 ) { @@ -1017,7 +1017,7 @@ cvGetSeqReaderPos( CvSeqReader* reader ) int index = -1; if( !reader || !reader->ptr ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); elem_size = reader->seq->elem_size; if( elem_size <= ICV_SHIFT_TAB_MAX && (index = icvPower2ShiftTab[elem_size - 1]) >= 0 ) @@ -1042,7 +1042,7 @@ cvSetSeqReaderPos( CvSeqReader* reader, int index, int is_relative ) int elem_size, count, total; if( !reader || !reader->seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); total = reader->seq->total; elem_size = reader->seq->elem_size; @@ -1052,14 +1052,14 @@ cvSetSeqReaderPos( CvSeqReader* reader, int index, int is_relative ) if( index < 0 ) { if( index < -total ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); index += total; } else if( index >= total ) { index -= total; if( index >= total ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); } block = reader->seq->first; @@ -1135,7 +1135,7 @@ cvSeqPush( CvSeq *seq, const void *element ) size_t elem_size; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); elem_size = seq->elem_size; ptr = seq->ptr; @@ -1166,9 +1166,9 @@ cvSeqPop( CvSeq *seq, void *element ) int elem_size; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( seq->total <= 0 ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); elem_size = seq->elem_size; seq->ptr = ptr = seq->ptr - elem_size; @@ -1195,7 +1195,7 @@ cvSeqPushFront( CvSeq *seq, const void *element ) CvSeqBlock *block; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); elem_size = seq->elem_size; block = seq->first; @@ -1228,9 +1228,9 @@ cvSeqPopFront( CvSeq *seq, void *element ) CvSeqBlock *block; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( seq->total <= 0 ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); elem_size = seq->elem_size; block = seq->first; @@ -1257,14 +1257,14 @@ cvSeqInsert( CvSeq *seq, int before_index, const void *element ) schar* ret_ptr = 0; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); total = seq->total; before_index += before_index < 0 ? total : 0; before_index -= before_index > total ? total : 0; if( (unsigned)before_index > (unsigned)total ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); if( before_index == total ) { @@ -1375,7 +1375,7 @@ cvSeqRemove( CvSeq *seq, int index ) int total, front = 0; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); total = seq->total; @@ -1383,7 +1383,7 @@ cvSeqRemove( CvSeq *seq, int index ) index -= index >= total ? total : 0; if( (unsigned) index >= (unsigned) total ) - CV_Error( CV_StsOutOfRange, "Invalid index" ); + CV_Error( cv::Error::StsOutOfRange, "Invalid index" ); if( index == total - 1 ) { @@ -1456,9 +1456,9 @@ cvSeqPushMulti( CvSeq *seq, const void *_elements, int count, int front ) char *elements = (char *) _elements; if( !seq ) - CV_Error( CV_StsNullPtr, "NULL sequence pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL sequence pointer" ); if( count < 0 ) - CV_Error( CV_StsBadSize, "number of removed elements is negative" ); + CV_Error( cv::Error::StsBadSize, "number of removed elements is negative" ); int elem_size = seq->elem_size; @@ -1525,9 +1525,9 @@ cvSeqPopMulti( CvSeq *seq, void *_elements, int count, int front ) char *elements = (char *) _elements; if( !seq ) - CV_Error( CV_StsNullPtr, "NULL sequence pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL sequence pointer" ); if( count < 0 ) - CV_Error( CV_StsBadSize, "number of removed elements is negative" ); + CV_Error( cv::Error::StsBadSize, "number of removed elements is negative" ); count = MIN( count, seq->total ); @@ -1593,7 +1593,7 @@ CV_IMPL void cvClearSeq( CvSeq *seq ) { if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); cvSeqPopMulti( seq, 0, seq->total ); } @@ -1607,13 +1607,13 @@ cvSeqSlice( const CvSeq* seq, CvSlice slice, CvMemStorage* storage, int copy_dat CvSeqBlock *block, *first_block = 0, *last_block = 0; if( !CV_IS_SEQ(seq) ) - CV_Error( CV_StsBadArg, "Invalid sequence header" ); + CV_Error( cv::Error::StsBadArg, "Invalid sequence header" ); if( !storage ) { storage = seq->storage; if( !storage ) - CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL storage pointer" ); } elem_size = seq->elem_size; @@ -1624,7 +1624,7 @@ cvSeqSlice( const CvSeq* seq, CvSlice slice, CvMemStorage* storage, int copy_dat slice.start_index -= seq->total; if( (unsigned)length > (unsigned)seq->total || ((unsigned)slice.start_index >= (unsigned)seq->total && length != 0) ) - CV_Error( CV_StsOutOfRange, "Bad sequence slice" ); + CV_Error( cv::Error::StsOutOfRange, "Bad sequence slice" ); subseq = cvCreateSeq( seq->flags, seq->header_size, elem_size, storage ); @@ -1680,7 +1680,7 @@ cvSeqRemoveSlice( CvSeq* seq, CvSlice slice ) int total, length; if( !CV_IS_SEQ(seq) ) - CV_Error( CV_StsBadArg, "Invalid sequence header" ); + CV_Error( cv::Error::StsBadArg, "Invalid sequence header" ); length = cvSliceLength( slice, seq ); total = seq->total; @@ -1691,7 +1691,7 @@ cvSeqRemoveSlice( CvSeq* seq, CvSlice slice ) slice.start_index -= total; if( (unsigned)slice.start_index >= (unsigned)total ) - CV_Error( CV_StsOutOfRange, "start slice index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "start slice index is out of range" ); slice.end_index = slice.start_index + length; @@ -1757,16 +1757,16 @@ cvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr ) CvSeqBlock block; if( !CV_IS_SEQ(seq) ) - CV_Error( CV_StsBadArg, "Invalid destination sequence header" ); + CV_Error( cv::Error::StsBadArg, "Invalid destination sequence header" ); if( !CV_IS_SEQ(from)) { CvMat* mat = (CvMat*)from; if( !CV_IS_MAT(mat)) - CV_Error( CV_StsBadArg, "Source is not a sequence nor matrix" ); + CV_Error( cv::Error::StsBadArg, "Source is not a sequence nor matrix" ); if( !CV_IS_MAT_CONT(mat->type) || (mat->rows != 1 && mat->cols != 1) ) - CV_Error( CV_StsBadArg, "The source array must be 1d continuous vector" ); + CV_Error( cv::Error::StsBadArg, "The source array must be 1d continuous vector" ); from = cvMakeSeqHeaderForArray( CV_SEQ_KIND_GENERIC, sizeof(from_header), CV_ELEM_SIZE(mat->type), @@ -1775,7 +1775,7 @@ cvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr ) } if( seq->elem_size != from->elem_size ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "Source and destination sequence element sizes are different." ); from_total = from->total; @@ -1788,7 +1788,7 @@ cvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr ) index -= index > total ? total : 0; if( (unsigned)index > (unsigned)total ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); elem_size = seq->elem_size; @@ -1918,10 +1918,10 @@ cvSeqSort( CvSeq* seq, CvCmpFunc cmp_func, void* aux ) stack[48]; if( !CV_IS_SEQ(seq) ) - CV_Error( !seq ? CV_StsNullPtr : CV_StsBadArg, "Bad input sequence" ); + CV_Error( !seq ? cv::Error::StsNullPtr : cv::Error::StsBadArg, "Bad input sequence" ); if( !cmp_func ) - CV_Error( CV_StsNullPtr, "Null compare function" ); + CV_Error( cv::Error::StsNullPtr, "Null compare function" ); if( seq->total <= 1 ) return; @@ -2195,10 +2195,10 @@ cvSeqSearch( CvSeq* seq, const void* _elem, CvCmpFunc cmp_func, *_idx = idx; if( !CV_IS_SEQ(seq) ) - CV_Error( !seq ? CV_StsNullPtr : CV_StsBadArg, "Bad input sequence" ); + CV_Error( !seq ? cv::Error::StsNullPtr : cv::Error::StsBadArg, "Bad input sequence" ); if( !elem ) - CV_Error( CV_StsNullPtr, "Null element pointer" ); + CV_Error( cv::Error::StsNullPtr, "Null element pointer" ); int elem_size = seq->elem_size; int total = seq->total; @@ -2256,7 +2256,7 @@ cvSeqSearch( CvSeq* seq, const void* _elem, CvCmpFunc cmp_func, else { if( !cmp_func ) - CV_Error( CV_StsNullPtr, "Null compare function" ); + CV_Error( cv::Error::StsNullPtr, "Null compare function" ); i = 0, j = total; @@ -2340,16 +2340,16 @@ cvSeqPartition( const CvSeq* seq, CvMemStorage* storage, CvSeq** labels, int is_set; if( !labels ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( !seq || !is_equal ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( !storage ) storage = seq->storage; if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); is_set = CV_IS_SET(seq); @@ -2483,11 +2483,11 @@ CV_IMPL CvSet* cvCreateSet( int set_flags, int header_size, int elem_size, CvMemStorage * storage ) { if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( header_size < (int)sizeof( CvSet ) || elem_size < (int)sizeof(void*)*2 || (elem_size & (sizeof(void*)-1)) != 0 ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); CvSet* set = (CvSet*) cvCreateSeq( set_flags, header_size, elem_size, storage ); set->flags = (set->flags & ~CV_MAGIC_MASK) | CV_SET_MAGIC_VAL; @@ -2504,7 +2504,7 @@ cvSetAdd( CvSet* set, CvSetElem* element, CvSetElem** inserted_element ) CvSetElem *free_elem; if( !set ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( !(set->free_elems) ) { @@ -2552,7 +2552,7 @@ cvSetRemove( CvSet* set, int index ) if( elem ) cvSetRemoveByPtr( set, elem ); else if( !set ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); } @@ -2583,7 +2583,7 @@ cvCreateGraph( int graph_type, int header_size, || edge_size < (int) sizeof( CvGraphEdge ) || vtx_size < (int) sizeof( CvGraphVtx ) ){ - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); } vertices = cvCreateSet( graph_type, header_size, vtx_size, storage ); @@ -2602,7 +2602,7 @@ CV_IMPL void cvClearGraph( CvGraph * graph ) { if( !graph ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); cvClearSet( graph->edges ); cvClearSet( (CvSet*)graph ); @@ -2617,7 +2617,7 @@ cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* _vertex, CvGraphVtx** _inserted int index = -1; if( !graph ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); vertex = (CvGraphVtx*)cvSetNew((CvSet*)graph); if( vertex ) @@ -2642,10 +2642,10 @@ cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx ) int count = -1; if( !graph || !vtx ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( !CV_IS_SET_ELEM(vtx)) - CV_Error( CV_StsBadArg, "The vertex does not belong to the graph" ); + CV_Error( cv::Error::StsBadArg, "The vertex does not belong to the graph" ); count = graph->edges->active_count; for( ;; ) @@ -2670,11 +2670,11 @@ cvGraphRemoveVtx( CvGraph* graph, int index ) CvGraphVtx *vtx = 0; if( !graph ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); vtx = cvGetGraphVtx( graph, index ); if( !vtx ) - CV_Error( CV_StsBadArg, "The vertex is not found" ); + CV_Error( cv::Error::StsBadArg, "The vertex is not found" ); count = graph->edges->active_count; for( ;; ) @@ -2702,7 +2702,7 @@ cvFindGraphEdgeByPtr( const CvGraph* graph, int ofs = 0; if( !graph || !start_vtx || !end_vtx ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( start_vtx == end_vtx ) return 0; @@ -2735,7 +2735,7 @@ cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx ) CvGraphVtx *end_vtx; if( !graph ) - CV_Error( CV_StsNullPtr, "graph pointer is NULL" ); + CV_Error( cv::Error::StsNullPtr, "graph pointer is NULL" ); start_vtx = cvGetGraphVtx( graph, start_idx ); end_vtx = cvGetGraphVtx( graph, end_idx ); @@ -2759,7 +2759,7 @@ cvGraphAddEdgeByPtr( CvGraph* graph, int delta; if( !graph ) - CV_Error( CV_StsNullPtr, "graph pointer is NULL" ); + CV_Error( cv::Error::StsNullPtr, "graph pointer is NULL" ); if( !CV_IS_GRAPH_ORIENTED( graph ) && (start_vtx->flags & CV_SET_ELEM_IDX_MASK) > (end_vtx->flags & CV_SET_ELEM_IDX_MASK) ) @@ -2778,7 +2778,7 @@ cvGraphAddEdgeByPtr( CvGraph* graph, } if( start_vtx == end_vtx ) - CV_Error( start_vtx ? CV_StsBadArg : CV_StsNullPtr, + CV_Error( start_vtx ? cv::Error::StsBadArg : cv::Error::StsNullPtr, "vertex pointers coincide (or set to NULL)" ); edge = (CvGraphEdge*)cvSetNew( (CvSet*)(graph->edges) ); @@ -2826,7 +2826,7 @@ cvGraphAddEdge( CvGraph* graph, CvGraphVtx *end_vtx; if( !graph ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); start_vtx = cvGetGraphVtx( graph, start_idx ); end_vtx = cvGetGraphVtx( graph, end_idx ); @@ -2843,7 +2843,7 @@ cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_v CvGraphEdge *edge, *next_edge, *prev_edge; if( !graph || !start_vtx || !end_vtx ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( start_vtx == end_vtx ) return; @@ -2902,7 +2902,7 @@ cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx ) CvGraphVtx *end_vtx; if( !graph ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); start_vtx = cvGetGraphVtx( graph, start_idx ); end_vtx = cvGetGraphVtx( graph, end_idx ); @@ -2919,7 +2919,7 @@ cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vertex ) int count; if( !graph || !vertex ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); for( edge = vertex->first, count = 0; edge; ) { @@ -2940,11 +2940,11 @@ cvGraphVtxDegree( const CvGraph* graph, int vtx_idx ) int count; if( !graph ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); vertex = cvGetGraphVtx( graph, vtx_idx ); if( !vertex ) - CV_Error( CV_StsObjectNotFound, "" ); + CV_Error( cv::Error::StsObjectNotFound, "" ); for( edge = vertex->first, count = 0; edge; ) { @@ -2971,13 +2971,13 @@ icvSeqElemsClearFlags( CvSeq* seq, int offset, int clear_mask ) int i, total, elem_size; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); elem_size = seq->elem_size; total = seq->total; if( (unsigned)offset > (unsigned)elem_size ) - CV_Error( CV_StsBadArg, "" ); + CV_Error( cv::Error::StsBadArg, "" ); cvStartReadSeq( seq, &reader ); @@ -3001,14 +3001,14 @@ icvSeqFindNextElem( CvSeq* seq, int offset, int mask, int total, elem_size, index; if( !seq || !start_index ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); elem_size = seq->elem_size; total = seq->total; index = *start_index; if( (unsigned)offset > (unsigned)elem_size ) - CV_Error( CV_StsBadArg, "" ); + CV_Error( cv::Error::StsBadArg, "" ); if( total == 0 ) return 0; @@ -3048,7 +3048,7 @@ CV_IMPL CvGraphScanner* cvCreateGraphScanner( CvGraph* graph, CvGraphVtx* vtx, int mask ) { if( !graph ) - CV_Error( CV_StsNullPtr, "Null graph pointer" ); + CV_Error( cv::Error::StsNullPtr, "Null graph pointer" ); CV_Assert( graph->storage != 0 ); @@ -3082,7 +3082,7 @@ CV_IMPL void cvReleaseGraphScanner( CvGraphScanner** scanner ) { if( !scanner ) - CV_Error( CV_StsNullPtr, "Null double pointer to graph scanner" ); + CV_Error( cv::Error::StsNullPtr, "Null double pointer to graph scanner" ); if( *scanner ) { @@ -3103,7 +3103,7 @@ cvNextGraphItem( CvGraphScanner* scanner ) CvGraphItem item; if( !scanner || !(scanner->stack)) - CV_Error( CV_StsNullPtr, "Null graph scanner" ); + CV_Error( cv::Error::StsNullPtr, "Null graph scanner" ); dst = scanner->dst; vtx = scanner->vtx; @@ -3259,13 +3259,13 @@ cvCloneGraph( const CvGraph* graph, CvMemStorage* storage ) CvSeqReader reader; if( !CV_IS_GRAPH(graph)) - CV_Error( CV_StsBadArg, "Invalid graph pointer" ); + CV_Error( cv::Error::StsBadArg, "Invalid graph pointer" ); if( !storage ) storage = graph->storage; if( !storage ) - CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL storage pointer" ); vtx_size = graph->elem_size; edge_size = graph->edges->elem_size; @@ -3343,7 +3343,7 @@ cvTreeToNodeSeq( const void* first, int header_size, CvMemStorage* storage ) CvTreeNodeIterator iterator; if( !storage ) - CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL storage pointer" ); allseq = cvCreateSeq( 0, header_size, sizeof(first), storage ); @@ -3389,7 +3389,7 @@ cvInsertNodeIntoTree( void* _node, void* _parent, void* _frame ) CvTreeNode* parent = (CvTreeNode*)_parent; if( !node || !parent ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); node->v_prev = _parent != _frame ? parent : 0; node->h_next = parent->v_next; @@ -3410,10 +3410,10 @@ cvRemoveNodeFromTree( void* _node, void* _frame ) CvTreeNode* frame = (CvTreeNode*)_frame; if( !node ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( node == frame ) - CV_Error( CV_StsBadArg, "frame node could not be deleted" ); + CV_Error( cv::Error::StsBadArg, "frame node could not be deleted" ); if( node->h_next ) node->h_next->h_prev = node->h_prev; @@ -3440,10 +3440,10 @@ cvInitTreeNodeIterator( CvTreeNodeIterator* treeIterator, const void* first, int max_level ) { if( !treeIterator || !first ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( max_level < 0 ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); treeIterator->node = (void*)first; treeIterator->level = 0; @@ -3459,7 +3459,7 @@ cvNextTreeNode( CvTreeNodeIterator* treeIterator ) int level; if( !treeIterator ) - CV_Error( CV_StsNullPtr, "NULL iterator pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL iterator pointer" ); prevNode = node = (CvTreeNode*)treeIterator->node; level = treeIterator->level; @@ -3500,7 +3500,7 @@ cvPrevTreeNode( CvTreeNodeIterator* treeIterator ) int level; if( !treeIterator ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); prevNode = node = (CvTreeNode*)treeIterator->node; level = treeIterator->level; diff --git a/modules/core/src/dxt.cpp b/modules/core/src/dxt.cpp index ce263a506f..02d0233274 100644 --- a/modules/core/src/dxt.cpp +++ b/modules/core/src/dxt.cpp @@ -3469,7 +3469,7 @@ Ptr DFT2D::create(int width, int height, int depth, { if(width == 1 && nonzero_rows > 0 ) { - CV_Error( CV_StsNotImplemented, + CV_Error( cv::Error::StsNotImplemented, "This mode (using nonzero_rows with a single-column matrix) breaks the function's logic, so it is prohibited.\n" "For fast convolution/correlation use 2-column matrix or single-row matrix instead" ); } @@ -4317,7 +4317,7 @@ public: if( len != prev_len ) { if( len > 1 && (len & 1) ) - CV_Error( CV_StsNotImplemented, "Odd-size DCT\'s are not implemented" ); + CV_Error( cv::Error::StsNotImplemented, "Odd-size DCT\'s are not implemented" ); opt.nf = DFTFactorize( len, opt.factors ); bool inplace_transform = opt.factors[0] == opt.factors[opt.nf-1]; diff --git a/modules/core/src/glob.cpp b/modules/core/src/glob.cpp index b7cf1bf236..03638d49b1 100644 --- a/modules/core/src/glob.cpp +++ b/modules/core/src/glob.cpp @@ -276,7 +276,7 @@ static void glob_rec(const cv::String& directory, const cv::String& wildchart, s } else { - CV_Error_(CV_StsObjectNotFound, ("could not open directory: %s", directory.c_str())); + CV_Error_(cv::Error::StsObjectNotFound, ("could not open directory: %s", directory.c_str())); } } #endif // OPENCV_HAVE_FILESYSTEM_SUPPORT diff --git a/modules/core/src/lapack.cpp b/modules/core/src/lapack.cpp index 138246406d..37949f9d62 100644 --- a/modules/core/src/lapack.cpp +++ b/modules/core/src/lapack.cpp @@ -1191,7 +1191,7 @@ bool solve( InputArray _src, InputArray _src2arg, OutputArray _dst, int method ) Mat dst = _dst.getMat(); if( m < n ) - CV_Error(CV_StsBadArg, "The function can not solve under-determined linear systems" ); + CV_Error(cv::Error::StsBadArg, "The function can not solve under-determined linear systems" ); if( m == n ) is_normal = false; @@ -1516,7 +1516,7 @@ void SVD::backSubst( InputArray _w, InputArray _u, InputArray _vt, vt.ptr(), vt.step, true, rhs.ptr(), rhs.step, nb, dst.ptr(), dst.step, buffer.data()); else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); } diff --git a/modules/core/src/mathfuncs.cpp b/modules/core/src/mathfuncs.cpp index 9b620743fd..1f75f3eb94 100644 --- a/modules/core/src/mathfuncs.cpp +++ b/modules/core/src/mathfuncs.cpp @@ -1566,7 +1566,7 @@ bool checkRange(InputArray _src, bool quiet, Point* pt, double minVal, double ma { cv::String value_str; value_str << src(cv::Range(badPt.y, badPt.y + 1), cv::Range(badPt.x, badPt.x + 1)); - CV_Error_( CV_StsOutOfRange, + CV_Error_( cv::Error::StsOutOfRange, ("the value at (%d, %d)=%s is out of range [%f, %f)", badPt.x, badPt.y, value_str.c_str(), minVal, maxVal)); } return false; diff --git a/modules/core/src/matmul.dispatch.cpp b/modules/core/src/matmul.dispatch.cpp index ecc5fb8231..a0045272ec 100644 --- a/modules/core/src/matmul.dispatch.cpp +++ b/modules/core/src/matmul.dispatch.cpp @@ -921,7 +921,7 @@ void mulTransposed(InputArray _src, OutputArray _dst, bool ata, { MulTransposedFunc func = getMulTransposedFunc(stype, dtype, ata); if( !func ) - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); func( src, dst, delta, scale ); completeSymm( dst, false ); @@ -1221,7 +1221,7 @@ cvCalcPCA( const CvArr* data_arr, CvArr* avg_arr, CvArr* eigenvals, CvArr* eigen pca.eigenvalues = evals; pca.eigenvectors = evects; - pca(data, (flags & CV_PCA_USE_AVG) ? mean : cv::Mat(), + pca(data, (flags & cv::PCA::USE_AVG) ? mean : cv::Mat(), flags, !evals.empty() ? evals.rows + evals.cols - 1 : 0); if( pca.mean.size() == mean.size() ) diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index c206f09fb5..2e851fd1ca 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -265,7 +265,7 @@ void setSize( Mat& m, int _dims, const int* _sz, const size_t* _steps, bool auto m.step.p[i] = total; uint64 total1 = (uint64)total*s; if( (uint64)total1 != (size_t)total1 ) - CV_Error( CV_StsOutOfRange, "The total matrix size does not fit to \"size_t\" type" ); + CV_Error( cv::Error::StsOutOfRange, "The total matrix size does not fit to \"size_t\" type" ); total = (size_t)total1; } } @@ -1101,9 +1101,9 @@ void Mat::push_back(const Mat& elems) bool eq = size == elems.size; size.p[0] = int(r); if( !eq ) - CV_Error(CV_StsUnmatchedSizes, "Pushed vector length is not equal to matrix row length"); + CV_Error(cv::Error::StsUnmatchedSizes, "Pushed vector length is not equal to matrix row length"); if( type() != elems.type() ) - CV_Error(CV_StsUnmatchedFormats, "Pushed vector type is not the same as matrix type"); + CV_Error(cv::Error::StsUnmatchedFormats, "Pushed vector type is not the same as matrix type"); if( isSubmatrix() || dataend + step.p[0]*delta > datalimit ) reserve( std::max(r + delta, (r*3+1)/2) ); @@ -1205,16 +1205,16 @@ Mat Mat::reshape(int new_cn, int new_rows) const { int total_size = total_width * rows; if( !isContinuous() ) - CV_Error( CV_BadStep, + CV_Error( cv::Error::BadStep, "The matrix is not continuous, thus its number of rows can not be changed" ); if( (unsigned)new_rows > (unsigned)total_size ) - CV_Error( CV_StsOutOfRange, "Bad new number of rows" ); + CV_Error( cv::Error::StsOutOfRange, "Bad new number of rows" ); total_width = total_size / new_rows; if( total_width * new_rows != total_size ) - CV_Error( CV_StsBadArg, "The total number of matrix elements " + CV_Error( cv::Error::StsBadArg, "The total number of matrix elements " "is not divisible by the new number of rows" ); hdr.rows = new_rows; @@ -1224,7 +1224,7 @@ Mat Mat::reshape(int new_cn, int new_rows) const int new_width = total_width / new_cn; if( new_width * new_cn != total_width ) - CV_Error( CV_BadNumChannels, + CV_Error( cv::Error::BadNumChannels, "The total width is not divisible by the new number of channels" ); hdr.dims = 2; @@ -1269,13 +1269,13 @@ Mat Mat::reshape(int _cn, int _newndims, const int* _newsz) const else if (i < dims) newsz_buf[i] = this->size[i]; else - CV_Error(CV_StsOutOfRange, "Copy dimension (which has zero size) is not present in source matrix"); + CV_Error(cv::Error::StsOutOfRange, "Copy dimension (which has zero size) is not present in source matrix"); total_elem1 *= (size_t)newsz_buf[i]; } if (total_elem1 != total_elem1_ref) - CV_Error(CV_StsUnmatchedSizes, "Requested and source matrices have different count of elements"); + CV_Error(cv::Error::StsUnmatchedSizes, "Requested and source matrices have different count of elements"); Mat hdr = *this; hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((_cn-1) << CV_CN_SHIFT); @@ -1284,7 +1284,7 @@ Mat Mat::reshape(int _cn, int _newndims, const int* _newsz) const return hdr; } - CV_Error(CV_StsNotImplemented, "Reshaping of n-dimensional non-continuous matrices is not supported yet"); + CV_Error(cv::Error::StsNotImplemented, "Reshaping of n-dimensional non-continuous matrices is not supported yet"); // TBD } diff --git a/modules/core/src/matrix_c.cpp b/modules/core/src/matrix_c.cpp index d76a80de1b..0054d0a534 100644 --- a/modules/core/src/matrix_c.cpp +++ b/modules/core/src/matrix_c.cpp @@ -163,7 +163,7 @@ Mat cvarrToMat(const CvArr* arr, bool copyData, { const IplImage* iplimg = (const IplImage*)arr; if( coiMode == 0 && iplimg->roi && iplimg->roi->coi > 0 ) - CV_Error(CV_BadCOI, "COI is not supported by the function"); + CV_Error(cv::Error::BadCOI, "COI is not supported by the function"); return iplImageToMat(iplimg, copyData); } if( CV_IS_SEQ(arr) ) @@ -187,7 +187,7 @@ Mat cvarrToMat(const CvArr* arr, bool copyData, cvCvtSeqToArray(seq, buf.ptr(), CV_WHOLE_SEQ); return buf; } - CV_Error(CV_StsBadArg, "Unknown array type"); + CV_Error(cv::Error::StsBadArg, "Unknown array type"); } void extractImageCOI(const CvArr* arr, OutputArray _ch, int coi) @@ -256,14 +256,14 @@ cvReduce( const CvArr* srcarr, CvArr* dstarr, int dim, int op ) dim = src.rows > dst.rows ? 0 : src.cols > dst.cols ? 1 : dst.cols == 1; if( dim > 1 ) - CV_Error( CV_StsOutOfRange, "The reduced dimensionality index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "The reduced dimensionality index is out of range" ); if( (dim == 0 && (dst.cols != src.cols || dst.rows != 1)) || (dim == 1 && (dst.rows != src.rows || dst.cols != 1)) ) - CV_Error( CV_StsBadSize, "The output array size is incorrect" ); + CV_Error( cv::Error::StsBadSize, "The output array size is incorrect" ); if( src.channels() != dst.channels() ) - CV_Error( CV_StsUnmatchedFormats, "Input and output arrays must have the same number of channels" ); + CV_Error( cv::Error::StsUnmatchedFormats, "Input and output arrays must have the same number of channels" ); cv::reduce(src, dst, dim, op, dst.type()); } @@ -320,7 +320,7 @@ cvRange( CvArr* arr, double start, double end ) fdata[j] = (float)val; } else - CV_Error( CV_StsUnsupportedFormat, "The function only supports 32sC1 and 32fC1 datatypes" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The function only supports 32sC1 and 32fC1 datatypes" ); return arr; } diff --git a/modules/core/src/matrix_expressions.cpp b/modules/core/src/matrix_expressions.cpp index bab989bc2d..b8ae284048 100644 --- a/modules/core/src/matrix_expressions.cpp +++ b/modules/core/src/matrix_expressions.cpp @@ -21,7 +21,7 @@ static void checkOperandsExist(const Mat& a) { if (a.empty()) { - CV_Error(CV_StsBadArg, "Matrix operand is an empty matrix."); + CV_Error(cv::Error::StsBadArg, "Matrix operand is an empty matrix."); } } @@ -29,7 +29,7 @@ static void checkOperandsExist(const Mat& a, const Mat& b) { if (a.empty() || b.empty()) { - CV_Error(CV_StsBadArg, "One or more matrix operands are empty."); + CV_Error(cv::Error::StsBadArg, "One or more matrix operands are empty."); } } @@ -1456,7 +1456,7 @@ void MatOp_Bin::assign(const MatExpr& e, Mat& m, int _type) const else if( e.flags == 'a' && !e.b.data ) cv::absdiff(e.a, e.s, dst); else - CV_Error(CV_StsError, "Unknown operation"); + CV_Error(cv::Error::StsError, "Unknown operation"); if( dst.data != m.data ) dst.convertTo(m, _type); @@ -1688,7 +1688,7 @@ void MatOp_Initializer::assign(const MatExpr& e, Mat& m, int _type) const else if( e.flags == '1' ) m = Scalar(e.alpha); else - CV_Error(CV_StsError, "Invalid matrix initializer type"); + CV_Error(cv::Error::StsError, "Invalid matrix initializer type"); } void MatOp_Initializer::multiply(const MatExpr& e, double s, MatExpr& res) const diff --git a/modules/core/src/matrix_operations.cpp b/modules/core/src/matrix_operations.cpp index d0bdbc378f..fba9102d92 100644 --- a/modules/core/src/matrix_operations.cpp +++ b/modules/core/src/matrix_operations.cpp @@ -965,7 +965,7 @@ void cv::reduce(InputArray _src, OutputArray _dst, int dim, int op, int dtype) } if( !func ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "Unsupported combination of input and output array formats" ); func( src, temp ); diff --git a/modules/core/src/matrix_sparse.cpp b/modules/core/src/matrix_sparse.cpp index 173f9ea8f6..d422fef341 100644 --- a/modules/core/src/matrix_sparse.cpp +++ b/modules/core/src/matrix_sparse.cpp @@ -758,7 +758,7 @@ double norm( const SparseMat& src, int normType ) } } else - CV_Error( CV_StsUnsupportedFormat, "Only 32f and 64f are supported" ); + CV_Error( cv::Error::StsUnsupportedFormat, "Only 32f and 64f are supported" ); if( normType == NORM_L2 ) result = std::sqrt(result); @@ -821,7 +821,7 @@ void minMaxLoc( const SparseMat& src, double* _minval, double* _maxval, int* _mi *_maxval = maxval; } else - CV_Error( CV_StsUnsupportedFormat, "Only 32f and 64f are supported" ); + CV_Error( cv::Error::StsUnsupportedFormat, "Only 32f and 64f are supported" ); if( _minidx && minidx ) for( i = 0; i < d; i++ ) @@ -837,13 +837,13 @@ void normalize( const SparseMat& src, SparseMat& dst, double a, int norm_type ) CV_INSTRUMENT_REGION(); double scale = 1; - if( norm_type == CV_L2 || norm_type == CV_L1 || norm_type == CV_C ) + if( norm_type == NORM_L2 || norm_type == NORM_L1 || norm_type == NORM_INF ) { scale = norm( src, norm_type ); scale = scale > DBL_EPSILON ? a/scale : 0.; } else - CV_Error( CV_StsBadArg, "Unknown/unsupported norm type" ); + CV_Error( cv::Error::StsBadArg, "Unknown/unsupported norm type" ); src.convertTo( dst, -1, scale ); } diff --git a/modules/core/src/matrix_wrap.cpp b/modules/core/src/matrix_wrap.cpp index 8db888c26d..bbdcbae7f8 100644 --- a/modules/core/src/matrix_wrap.cpp +++ b/modules/core/src/matrix_wrap.cpp @@ -964,7 +964,7 @@ bool _InputArray::isContinuous(int i) const if( k == CUDA_GPU_MAT ) return i < 0 ? ((const cuda::GpuMat*)obj)->isContinuous() : true; - CV_Error(CV_StsNotImplemented, "Unknown/unsupported array type"); + CV_Error(cv::Error::StsNotImplemented, "Unknown/unsupported array type"); } bool _InputArray::isSubmatrix(int i) const @@ -1002,7 +1002,7 @@ bool _InputArray::isSubmatrix(int i) const return vv[i].isSubmatrix(); } - CV_Error(CV_StsNotImplemented, ""); + CV_Error(cv::Error::StsNotImplemented, ""); } size_t _InputArray::offset(int i) const @@ -1475,14 +1475,14 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i, ((std::vector >*)v)->resize(len); break; default: - CV_Error_(CV_StsBadArg, ("Vectors with element size %d are not supported. Please, modify OutputArray::create()\n", esz)); + CV_Error_(cv::Error::StsBadArg, ("Vectors with element size %d are not supported. Please, modify OutputArray::create()\n", esz)); } return; } if( k == NONE ) { - CV_Error(CV_StsNullPtr, "create() called for the missing output array" ); + CV_Error(cv::Error::StsNullPtr, "create() called for the missing output array" ); } if( k == STD_VECTOR_MAT ) diff --git a/modules/core/src/norm.cpp b/modules/core/src/norm.cpp index 7b55e214ef..52ef62e4f7 100644 --- a/modules/core/src/norm.cpp +++ b/modules/core/src/norm.cpp @@ -1412,7 +1412,7 @@ void normalize(InputArray _src, InputOutputArray _dst, double a, double b, if( rtype < 0 ) rtype = _dst.fixedType() ? _dst.depth() : depth; - if( norm_type == CV_MINMAX ) + if( norm_type == NORM_MINMAX ) { double smin = 0, smax = 0; double dmin = MIN( a, b ), dmax = MAX( a, b ); @@ -1426,14 +1426,14 @@ void normalize(InputArray _src, InputOutputArray _dst, double a, double b, else shift = dmin - smin*scale; } - else if( norm_type == CV_L2 || norm_type == CV_L1 || norm_type == CV_C ) + else if( norm_type == NORM_L2 || norm_type == NORM_L1 || norm_type == NORM_INF ) { scale = norm( _src, norm_type, _mask ); scale = scale > DBL_EPSILON ? a/scale : 0.; shift = 0; } else - CV_Error( CV_StsBadArg, "Unknown/unsupported norm type" ); + CV_Error( cv::Error::StsBadArg, "Unknown/unsupported norm type" ); CV_OCL_RUN(_dst.isUMat(), ocl_normalize(_src, _dst, _mask, rtype, scale, shift)) diff --git a/modules/core/src/pca.cpp b/modules/core/src/pca.cpp index 79126a8f36..117002d946 100644 --- a/modules/core/src/pca.cpp +++ b/modules/core/src/pca.cpp @@ -70,7 +70,7 @@ PCA& PCA::operator()(InputArray _data, InputArray __mean, int flags, int maxComp Size mean_sz; CV_Assert( data.channels() == 1 ); - if( flags & CV_PCA_DATA_AS_COL ) + if( flags & PCA::DATA_AS_COL ) { len = data.rows; in_count = data.cols; @@ -111,8 +111,8 @@ PCA& PCA::operator()(InputArray _data, InputArray __mean, int flags, int maxComp if( !(covar_flags & CV_COVAR_NORMAL) ) { - // CV_PCA_DATA_AS_ROW: cols(A)>rows(A). x=A'*y -> x'=y'*A - // CV_PCA_DATA_AS_COL: rows(A)>cols(A). x=A''*y -> x'=y'*A' + // PCA::DATA_AS_ROW: cols(A)>rows(A). x=A'*y -> x'=y'*A + // PCA::DATA_AS_COL: rows(A)>cols(A). x=A''*y -> x'=y'*A' Mat tmp_data, tmp_mean = repeat(mean, data.rows/mean.rows, data.cols/mean.cols); if( data.type() != ctype || tmp_mean.data == mean.data ) { @@ -127,7 +127,7 @@ PCA& PCA::operator()(InputArray _data, InputArray __mean, int flags, int maxComp Mat evects1(count, len, ctype); gemm( eigenvectors, tmp_data, 1, Mat(), 0, evects1, - (flags & CV_PCA_DATA_AS_COL) ? CV_GEMM_B_T : 0); + (flags & PCA::DATA_AS_COL) ? CV_GEMM_B_T : 0); eigenvectors = evects1; // normalize eigenvectors @@ -206,7 +206,7 @@ PCA& PCA::operator()(InputArray _data, InputArray __mean, int flags, double reta Size mean_sz; CV_Assert( data.channels() == 1 ); - if( flags & CV_PCA_DATA_AS_COL ) + if( flags & PCA::DATA_AS_COL ) { len = data.rows; in_count = data.cols; @@ -247,8 +247,8 @@ PCA& PCA::operator()(InputArray _data, InputArray __mean, int flags, double reta if( !(covar_flags & CV_COVAR_NORMAL) ) { - // CV_PCA_DATA_AS_ROW: cols(A)>rows(A). x=A'*y -> x'=y'*A - // CV_PCA_DATA_AS_COL: rows(A)>cols(A). x=A''*y -> x'=y'*A' + // PCA::DATA_AS_ROW: cols(A)>rows(A). x=A'*y -> x'=y'*A + // PCA::DATA_AS_COL: rows(A)>cols(A). x=A''*y -> x'=y'*A' Mat tmp_data, tmp_mean = repeat(mean, data.rows/mean.rows, data.cols/mean.cols); if( data.type() != ctype || tmp_mean.data == mean.data ) { @@ -263,7 +263,7 @@ PCA& PCA::operator()(InputArray _data, InputArray __mean, int flags, double reta Mat evects1(count, len, ctype); gemm( eigenvectors, tmp_data, 1, Mat(), 0, evects1, - (flags & CV_PCA_DATA_AS_COL) ? CV_GEMM_B_T : 0); + (flags & PCA::DATA_AS_COL) ? CV_GEMM_B_T : 0); eigenvectors = evects1; // normalize all eigenvectors diff --git a/modules/core/src/rand.cpp b/modules/core/src/rand.cpp index 581f3b982e..7f1b5e4b81 100644 --- a/modules/core/src/rand.cpp +++ b/modules/core/src/rand.cpp @@ -670,7 +670,7 @@ void RNG::fill( InputOutputArray _mat, int disttype, } CV_Assert( func != 0 ); } - else if( disttype == CV_RAND_NORMAL ) + else if( disttype == RNG::NORMAL ) { _parambuf.allocate(MAX(n1, cn) + MAX(n2, cn)); double* parambuf = _parambuf.data(); @@ -708,7 +708,7 @@ void RNG::fill( InputOutputArray _mat, int disttype, CV_Assert( scaleFunc != 0 ); } else - CV_Error( CV_StsBadArg, "Unknown distribution type" ); + CV_Error( cv::Error::StsBadArg, "Unknown distribution type" ); const Mat* arrays[] = {&mat, 0}; uchar* ptr = 0; diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index 6c1bc053bb..1254014ced 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -1325,38 +1325,42 @@ CV_IMPL const char* cvErrorStr( int status ) switch (status) { - case CV_StsOk : return "No Error"; - case CV_StsBackTrace : return "Backtrace"; - case CV_StsError : return "Unspecified error"; - case CV_StsInternal : return "Internal error"; - case CV_StsNoMem : return "Insufficient memory"; - case CV_StsBadArg : return "Bad argument"; - case CV_StsNoConv : return "Iterations do not converge"; - case CV_StsAutoTrace : return "Autotrace call"; - case CV_StsBadSize : return "Incorrect size of input array"; - case CV_StsNullPtr : return "Null pointer"; - case CV_StsDivByZero : return "Division by zero occurred"; - case CV_BadStep : return "Image step is wrong"; - case CV_StsInplaceNotSupported : return "Inplace operation is not supported"; - case CV_StsObjectNotFound : return "Requested object was not found"; - case CV_BadDepth : return "Input image depth is not supported by function"; - case CV_StsUnmatchedFormats : return "Formats of input arguments do not match"; - case CV_StsUnmatchedSizes : return "Sizes of input arguments do not match"; - case CV_StsOutOfRange : return "One of the arguments\' values is out of range"; - case CV_StsUnsupportedFormat : return "Unsupported format or combination of formats"; - case CV_BadCOI : return "Input COI is not supported"; - case CV_BadNumChannels : return "Bad number of channels"; - case CV_StsBadFlag : return "Bad flag (parameter or structure field)"; - case CV_StsBadPoint : return "Bad parameter of type CvPoint"; - case CV_StsBadMask : return "Bad type of mask argument"; - case CV_StsParseError : return "Parsing error"; - case CV_StsNotImplemented : return "The function/feature is not implemented"; - case CV_StsBadMemBlock : return "Memory block has been corrupted"; - case CV_StsAssert : return "Assertion failed"; - case CV_GpuNotSupported : return "No CUDA support"; - case CV_GpuApiCallError : return "Gpu API call"; - case CV_OpenGlNotSupported : return "No OpenGL support"; - case CV_OpenGlApiCallError : return "OpenGL API call"; + case cv::Error::StsOk : return "No Error"; + case cv::Error::StsBackTrace : return "Backtrace"; + case cv::Error::StsError : return "Unspecified error"; + case cv::Error::StsInternal : return "Internal error"; + case cv::Error::StsNoMem : return "Insufficient memory"; + case cv::Error::StsBadArg : return "Bad argument"; + case cv::Error::StsNoConv : return "Iterations do not converge"; + case cv::Error::StsAutoTrace : return "Autotrace call"; + case cv::Error::StsBadSize : return "Incorrect size of input array"; + case cv::Error::StsNullPtr : return "Null pointer"; + case cv::Error::StsDivByZero : return "Division by zero occurred"; + case cv::Error::BadStep : return "Image step is wrong"; + case cv::Error::StsInplaceNotSupported : return "Inplace operation is not supported"; + case cv::Error::StsObjectNotFound : return "Requested object was not found"; + case cv::Error::BadDepth : return "Input image depth is not supported by function"; + case cv::Error::StsUnmatchedFormats : return "Formats of input arguments do not match"; + case cv::Error::StsUnmatchedSizes : return "Sizes of input arguments do not match"; + case cv::Error::StsOutOfRange : return "One of the arguments\' values is out of range"; + case cv::Error::StsUnsupportedFormat : return "Unsupported format or combination of formats"; + case cv::Error::BadCOI : return "Input COI is not supported"; + case cv::Error::BadNumChannels : return "Bad number of channels"; + case cv::Error::StsBadFlag : return "Bad flag (parameter or structure field)"; + case cv::Error::StsBadPoint : return "Bad parameter of type CvPoint"; + case cv::Error::StsBadMask : return "Bad type of mask argument"; + case cv::Error::StsParseError : return "Parsing error"; + case cv::Error::StsNotImplemented : return "The function/feature is not implemented"; + case cv::Error::StsBadMemBlock : return "Memory block has been corrupted"; + case cv::Error::StsAssert : return "Assertion failed"; + case cv::Error::GpuNotSupported : return "No CUDA support"; + case cv::Error::GpuApiCallError : return "Gpu API call"; + case cv::Error::OpenGlNotSupported : return "No OpenGL support"; + case cv::Error::OpenGlApiCallError : return "OpenGL API call"; + case cv::Error::OpenCLApiCallError : return "OpenCL API call error"; + case cv::Error::OpenCLDoubleNotSupported:return "OpenCL device does not support double"; + case cv::Error::OpenCLInitError : return "OpenCL initialization error"; + case cv::Error::OpenCLNoAMDBlasFft : return "Missing OpenCL AMD BLAS FFT"; }; snprintf(buf, sizeof(buf), "Unknown %s code %d", status >= 0 ? "status":"error", status); @@ -1396,29 +1400,29 @@ cvErrorFromIppStatus( int status ) { switch (status) { - case CV_BADSIZE_ERR: return CV_StsBadSize; - case CV_BADMEMBLOCK_ERR: return CV_StsBadMemBlock; - case CV_NULLPTR_ERR: return CV_StsNullPtr; - case CV_DIV_BY_ZERO_ERR: return CV_StsDivByZero; - case CV_BADSTEP_ERR: return CV_BadStep; - case CV_OUTOFMEM_ERR: return CV_StsNoMem; - case CV_BADARG_ERR: return CV_StsBadArg; - case CV_NOTDEFINED_ERR: return CV_StsError; - case CV_INPLACE_NOT_SUPPORTED_ERR: return CV_StsInplaceNotSupported; - case CV_NOTFOUND_ERR: return CV_StsObjectNotFound; - case CV_BADCONVERGENCE_ERR: return CV_StsNoConv; - case CV_BADDEPTH_ERR: return CV_BadDepth; - case CV_UNMATCHED_FORMATS_ERR: return CV_StsUnmatchedFormats; - case CV_UNSUPPORTED_COI_ERR: return CV_BadCOI; - case CV_UNSUPPORTED_CHANNELS_ERR: return CV_BadNumChannels; - case CV_BADFLAG_ERR: return CV_StsBadFlag; - case CV_BADRANGE_ERR: return CV_StsBadArg; - case CV_BADCOEF_ERR: return CV_StsBadArg; - case CV_BADFACTOR_ERR: return CV_StsBadArg; - case CV_BADPOINT_ERR: return CV_StsBadPoint; + case CV_BADSIZE_ERR: return cv::Error::StsBadSize; + case CV_BADMEMBLOCK_ERR: return cv::Error::StsBadMemBlock; + case CV_NULLPTR_ERR: return cv::Error::StsNullPtr; + case CV_DIV_BY_ZERO_ERR: return cv::Error::StsDivByZero; + case CV_BADSTEP_ERR: return cv::Error::BadStep; + case CV_OUTOFMEM_ERR: return cv::Error::StsNoMem; + case CV_BADARG_ERR: return cv::Error::StsBadArg; + case CV_NOTDEFINED_ERR: return cv::Error::StsError; + case CV_INPLACE_NOT_SUPPORTED_ERR: return cv::Error::StsInplaceNotSupported; + case CV_NOTFOUND_ERR: return cv::Error::StsObjectNotFound; + case CV_BADCONVERGENCE_ERR: return cv::Error::StsNoConv; + case CV_BADDEPTH_ERR: return cv::Error::BadDepth; + case CV_UNMATCHED_FORMATS_ERR: return cv::Error::StsUnmatchedFormats; + case CV_UNSUPPORTED_COI_ERR: return cv::Error::BadCOI; + case CV_UNSUPPORTED_CHANNELS_ERR: return cv::Error::BadNumChannels; + case CV_BADFLAG_ERR: return cv::Error::StsBadFlag; + case CV_BADRANGE_ERR: return cv::Error::StsBadArg; + case CV_BADCOEF_ERR: return cv::Error::StsBadArg; + case CV_BADFACTOR_ERR: return cv::Error::StsBadArg; + case CV_BADPOINT_ERR: return cv::Error::StsBadPoint; default: - return CV_StsError; + return cv::Error::StsError; } } diff --git a/modules/core/src/types.cpp b/modules/core/src/types.cpp index 43e25ef045..ccf3109989 100644 --- a/modules/core/src/types.cpp +++ b/modules/core/src/types.cpp @@ -83,7 +83,7 @@ void KeyPoint::convert(const std::vector& keypoints, std::vector (unsigned)total_size ) - CV_Error( CV_StsOutOfRange, "Bad new number of rows" ); + CV_Error( cv::Error::StsOutOfRange, "Bad new number of rows" ); total_width = total_size / new_rows; if( total_width * new_rows != total_size ) - CV_Error( CV_StsBadArg, "The total number of matrix elements " + CV_Error( cv::Error::StsBadArg, "The total number of matrix elements " "is not divisible by the new number of rows" ); hdr.rows = new_rows; @@ -1014,7 +1014,7 @@ UMat UMat::reshape(int new_cn, int new_rows) const int new_width = total_width / new_cn; if( new_width * new_cn != total_width ) - CV_Error( CV_BadNumChannels, + CV_Error( cv::Error::BadNumChannels, "The total width is not divisible by the new number of channels" ); hdr.dims = 2; @@ -1083,13 +1083,13 @@ UMat UMat::reshape(int _cn, int _newndims, const int* _newsz) const else if (i < dims) newsz_buf[i] = this->size[i]; else - CV_Error(CV_StsOutOfRange, "Copy dimension (which has zero size) is not present in source matrix"); + CV_Error(cv::Error::StsOutOfRange, "Copy dimension (which has zero size) is not present in source matrix"); total_elem1 *= (size_t)newsz_buf[i]; } if (total_elem1 != total_elem1_ref) - CV_Error(CV_StsUnmatchedSizes, "Requested and source matrices have different count of elements"); + CV_Error(cv::Error::StsUnmatchedSizes, "Requested and source matrices have different count of elements"); UMat hdr = *this; hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((_cn-1) << CV_CN_SHIFT); @@ -1098,7 +1098,7 @@ UMat UMat::reshape(int _cn, int _newndims, const int* _newsz) const return hdr; } - CV_Error(CV_StsNotImplemented, "Reshaping of n-dimensional non-continuous matrices is not supported yet"); + CV_Error(cv::Error::StsNotImplemented, "Reshaping of n-dimensional non-continuous matrices is not supported yet"); } Mat UMat::getMat(AccessFlag accessFlags) const diff --git a/modules/core/test/ocl/test_arithm.cpp b/modules/core/test/ocl/test_arithm.cpp index 57cd080855..8ce11c30b3 100644 --- a/modules/core/test/ocl/test_arithm.cpp +++ b/modules/core/test/ocl/test_arithm.cpp @@ -1461,7 +1461,7 @@ typedef ArithmTestBase Normalize; OCL_TEST_P(Normalize, Mat) { - static int modes[] = { CV_MINMAX, CV_L2, CV_L1, CV_C }; + static int modes[] = { NORM_MINMAX, NORM_L2, NORM_L1, NORM_INF }; for (int j = 0; j < test_loop_times; j++) { diff --git a/modules/core/test/test_arithm.cpp b/modules/core/test/test_arithm.cpp index 755d12f955..5a3191f892 100644 --- a/modules/core/test/test_arithm.cpp +++ b/modules/core/test/test_arithm.cpp @@ -3,6 +3,8 @@ // of this distribution and at http://opencv.org/license.html. #include "test_precomp.hpp" #include "ref_reduce_arg.impl.hpp" +#include "opencv2/core/core_c.h" + #include namespace opencv_test { namespace { @@ -634,7 +636,7 @@ static void inRange(const Mat& src, const Mat& lb, const Mat& rb, Mat& dst) (const cv::bfloat16_t*)bptr, dptr, total, cn); break; default: - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); } } } @@ -699,7 +701,7 @@ static void inRangeS(const Mat& src, const Scalar& lb, const Scalar& rb, Mat& ds inRangeS_((const cv::bfloat16_t*)sptr, lbuf.f, rbuf.f, dptr, total, cn); break; default: - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); } } } @@ -1781,7 +1783,7 @@ TEST(Core_ArithmMask, uninitialized) } Mat d1; d.convertTo(d1, depth); - EXPECT_LE(cvtest::norm(c, d1, CV_C), DBL_EPSILON); + EXPECT_LE(cvtest::norm(c, d1, NORM_INF), DBL_EPSILON); } Mat_ tmpSrc(100,100); diff --git a/modules/core/test/test_ds.cpp b/modules/core/test/test_ds.cpp index 3dc9e81d4f..9824b520ab 100644 --- a/modules/core/test/test_ds.cpp +++ b/modules/core/test/test_ds.cpp @@ -2,6 +2,7 @@ // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. #include "test_precomp.hpp" +#include "opencv2/core/core_c.h" namespace opencv_test { namespace { @@ -2114,8 +2115,8 @@ void Core_GraphScanTest::run( int ) cvReleaseGraphScanner( &scanner ); - CV_TS_SEQ_CHECK_CONDITION( cvtest::norm(Mat(vtx_mask),CV_L1) == graph->active_count && - cvtest::norm(Mat(edge_mask),CV_L1) == graph->edges->active_count, + CV_TS_SEQ_CHECK_CONDITION( cvtest::norm(Mat(vtx_mask),NORM_L1) == graph->active_count && + cvtest::norm(Mat(edge_mask),NORM_L1) == graph->edges->active_count, "Some vertices or edges have not been visited" ); update_progressbar(); } diff --git a/modules/core/test/test_dxt.cpp b/modules/core/test/test_dxt.cpp index a1d40e0ac9..67549ed467 100644 --- a/modules/core/test/test_dxt.cpp +++ b/modules/core/test/test_dxt.cpp @@ -2,6 +2,7 @@ // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. #include "test_precomp.hpp" +#include "opencv2/core/core_c.h" namespace opencv_test { namespace { @@ -97,7 +98,7 @@ static void DFT_1D( const Mat& _src, Mat& _dst, int flags, const Mat& _wave=Mat( } } else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); } @@ -878,7 +879,7 @@ protected: { cout << "actual:\n" << dst << endl << endl; cout << "reference:\n" << dstz << endl << endl; - CV_Error(CV_StsError, ""); + CV_Error(cv::Error::StsError, ""); } } } diff --git a/modules/core/test/test_io.cpp b/modules/core/test/test_io.cpp index 0b54b18d4f..d638a3edfc 100644 --- a/modules/core/test/test_io.cpp +++ b/modules/core/test/test_io.cpp @@ -2,7 +2,7 @@ // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. #include "test_precomp.hpp" - +#include "opencv2/core/core_c.h" #include namespace opencv_test { namespace { @@ -118,12 +118,12 @@ protected: int cn = cvtest::randInt(rng) % 4 + 1; Mat test_mat(cvtest::randInt(rng)%30+1, cvtest::randInt(rng)%30+1, CV_MAKETYPE(depth, cn)); - rng0.fill(test_mat, CV_RAND_UNI, Scalar::all(ranges[depth][0]), Scalar::all(ranges[depth][1])); + rng0.fill(test_mat, RNG::UNIFORM, Scalar::all(ranges[depth][0]), Scalar::all(ranges[depth][1])); if( depth >= CV_32F ) { exp(test_mat, test_mat); Mat test_mat_scale(test_mat.size(), test_mat.type()); - rng0.fill(test_mat_scale, CV_RAND_UNI, Scalar::all(-1), Scalar::all(1)); + rng0.fill(test_mat_scale, RNG::UNIFORM, Scalar::all(-1), Scalar::all(1)); cv::multiply(test_mat, test_mat_scale, test_mat); } @@ -136,12 +136,12 @@ protected: }; MatND test_mat_nd(3, sz, CV_MAKETYPE(depth, cn)); - rng0.fill(test_mat_nd, CV_RAND_UNI, Scalar::all(ranges[depth][0]), Scalar::all(ranges[depth][1])); + rng0.fill(test_mat_nd, RNG::UNIFORM, Scalar::all(ranges[depth][0]), Scalar::all(ranges[depth][1])); if( depth >= CV_32F ) { exp(test_mat_nd, test_mat_nd); MatND test_mat_scale(test_mat_nd.dims, test_mat_nd.size, test_mat_nd.type()); - rng0.fill(test_mat_scale, CV_RAND_UNI, Scalar::all(-1), Scalar::all(1)); + rng0.fill(test_mat_scale, RNG::UNIFORM, Scalar::all(-1), Scalar::all(1)); cv::multiply(test_mat_nd, test_mat_scale, test_mat_nd); } @@ -421,9 +421,9 @@ protected: fs["g1"] >> og1; CV_Assert( mi2.empty() ); CV_Assert( mv2.empty() ); - CV_Assert( cvtest::norm(Mat(mi3), Mat(mi4), CV_C) == 0 ); + CV_Assert( cvtest::norm(Mat(mi3), Mat(mi4), NORM_INF) == 0 ); CV_Assert( mv4.size() == 1 ); - double n = cvtest::norm(mv3[0], mv4[0], CV_C); + double n = cvtest::norm(mv3[0], mv4[0], NORM_INF); CV_Assert( vudt2.empty() ); CV_Assert( vudt3 == vudt4 ); CV_Assert( n == 0 ); diff --git a/modules/core/test/test_mat.cpp b/modules/core/test/test_mat.cpp index c77831749f..33dfcd56b7 100644 --- a/modules/core/test/test_mat.cpp +++ b/modules/core/test/test_mat.cpp @@ -11,6 +11,7 @@ #include "opencv2/core/cuda.hpp" #include "opencv2/core/bindings_utils.hpp" +#include "opencv2/core/core_c.h" namespace opencv_test { namespace { @@ -322,7 +323,7 @@ TEST(Core_PCA, accuracy) rng.fill( rPoints, RNG::UNIFORM, Scalar::all(0.0), Scalar::all(1.0) ); rng.fill( rTestPoints, RNG::UNIFORM, Scalar::all(0.0), Scalar::all(1.0) ); - PCA rPCA( rPoints, Mat(), CV_PCA_DATA_AS_ROW, maxComponents ), cPCA; + PCA rPCA( rPoints, Mat(), PCA::DATA_AS_ROW, maxComponents ), cPCA; // 1. check C++ PCA & ROW Mat rPrjTestPoints = rPCA.project( rTestPoints ); @@ -362,7 +363,7 @@ TEST(Core_PCA, accuracy) // check pca eigenvalues evalEps = 1e-5, evecEps = 5e-3; err = cvtest::norm(rPCA.eigenvalues, subEval, NORM_L2 | NORM_RELATIVE); - EXPECT_LE(err , evalEps) << "pca.eigenvalues is incorrect (CV_PCA_DATA_AS_ROW)"; + EXPECT_LE(err , evalEps) << "pca.eigenvalues is incorrect (PCA::DATA_AS_ROW)"; // check pca eigenvectors for(int i = 0; i < subEvec.rows; i++) { @@ -379,7 +380,7 @@ TEST(Core_PCA, accuracy) double mval = 0; Point mloc; minMaxLoc(tmp, 0, &mval, 0, &mloc); - EXPECT_LE(err, evecEps) << "pca.eigenvectors is incorrect (CV_PCA_DATA_AS_ROW) at " << i << " " + EXPECT_LE(err, evecEps) << "pca.eigenvectors is incorrect (PCA::DATA_AS_ROW) at " << i << " " << cv::format("max diff is %g at (i=%d, j=%d) (%g vs %g)\n", mval, mloc.y, mloc.x, rPCA.eigenvectors.at(mloc.y, mloc.x), subEvec.at(mloc.y, mloc.x)) @@ -399,7 +400,7 @@ TEST(Core_PCA, accuracy) err = cvtest::norm(rPrjTestPoints.row(i), prj, NORM_L2 | NORM_RELATIVE); if (err < prjEps) { - EXPECT_LE(err, prjEps) << "bad accuracy of project() (CV_PCA_DATA_AS_ROW)"; + EXPECT_LE(err, prjEps) << "bad accuracy of project() (PCA::DATA_AS_ROW)"; continue; } // check pca backProject @@ -407,22 +408,22 @@ TEST(Core_PCA, accuracy) err = cvtest::norm(rBackPrjTestPoints.row(i), backPrj, NORM_L2 | NORM_RELATIVE); if (err > backPrjEps) { - EXPECT_LE(err, backPrjEps) << "bad accuracy of backProject() (CV_PCA_DATA_AS_ROW)"; + EXPECT_LE(err, backPrjEps) << "bad accuracy of backProject() (PCA::DATA_AS_ROW)"; continue; } } // 2. check C++ PCA & COL - cPCA( rPoints.t(), Mat(), CV_PCA_DATA_AS_COL, maxComponents ); + cPCA( rPoints.t(), Mat(), PCA::DATA_AS_COL, maxComponents ); diffPrjEps = 1, diffBackPrjEps = 1; Mat ocvPrjTestPoints = cPCA.project(rTestPoints.t()); err = cvtest::norm(cv::abs(ocvPrjTestPoints), cv::abs(rPrjTestPoints.t()), NORM_L2 | NORM_RELATIVE); - ASSERT_LE(err, diffPrjEps) << "bad accuracy of project() (CV_PCA_DATA_AS_COL)"; + ASSERT_LE(err, diffPrjEps) << "bad accuracy of project() (PCA::DATA_AS_COL)"; err = cvtest::norm(cPCA.backProject(ocvPrjTestPoints), rBackPrjTestPoints.t(), NORM_L2 | NORM_RELATIVE); - ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of backProject() (CV_PCA_DATA_AS_COL)"; + ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of backProject() (PCA::DATA_AS_COL)"; // 3. check C++ PCA w/retainedVariance - cPCA( rPoints.t(), Mat(), CV_PCA_DATA_AS_COL, retainedVariance ); + cPCA( rPoints.t(), Mat(), PCA::DATA_AS_COL, retainedVariance ); diffPrjEps = 1, diffBackPrjEps = 1; Mat rvPrjTestPoints = cPCA.project(rTestPoints.t()); @@ -431,9 +432,9 @@ TEST(Core_PCA, accuracy) else err = cvtest::norm(cv::abs(rvPrjTestPoints), cv::abs(rPrjTestPoints.colRange(0,cPCA.eigenvectors.rows).t()), NORM_L2 | NORM_RELATIVE); - ASSERT_LE(err, diffPrjEps) << "bad accuracy of project() (CV_PCA_DATA_AS_COL); retainedVariance=" << retainedVariance; + ASSERT_LE(err, diffPrjEps) << "bad accuracy of project() (PCA::DATA_AS_COL); retainedVariance=" << retainedVariance; err = cvtest::norm(cPCA.backProject(rvPrjTestPoints), rBackPrjTestPoints.t(), NORM_L2 | NORM_RELATIVE); - ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of backProject() (CV_PCA_DATA_AS_COL); retainedVariance=" << retainedVariance; + ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of backProject() (PCA::DATA_AS_COL); retainedVariance=" << retainedVariance; #ifdef CHECK_C // 4. check C PCA & ROW @@ -447,14 +448,14 @@ TEST(Core_PCA, accuracy) _prjTestPoints = cvMat(prjTestPoints); _backPrjTestPoints = cvMat(backPrjTestPoints); - cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_ROW ); + cvCalcPCA( &_points, &_avg, &_eval, &_evec, PCA::DATA_AS_ROW ); cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints ); cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints ); err = cvtest::norm(prjTestPoints, rPrjTestPoints, NORM_L2 | NORM_RELATIVE); - ASSERT_LE(err, diffPrjEps) << "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_ROW)"; + ASSERT_LE(err, diffPrjEps) << "bad accuracy of cvProjectPCA() (PCA::DATA_AS_ROW)"; err = cvtest::norm(backPrjTestPoints, rBackPrjTestPoints, NORM_L2 | NORM_RELATIVE); - ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_ROW)"; + ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of cvBackProjectPCA() (PCA::DATA_AS_ROW)"; // 5. check C PCA & COL _points = cvMat(cPoints); @@ -465,14 +466,14 @@ TEST(Core_PCA, accuracy) prjTestPoints = prjTestPoints.t(); _prjTestPoints = cvMat(prjTestPoints); backPrjTestPoints = backPrjTestPoints.t(); _backPrjTestPoints = cvMat(backPrjTestPoints); - cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_COL ); + cvCalcPCA( &_points, &_avg, &_eval, &_evec, PCA::DATA_AS_COL ); cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints ); cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints ); err = cvtest::norm(cv::abs(prjTestPoints), cv::abs(rPrjTestPoints.t()), NORM_L2 | NORM_RELATIVE); - ASSERT_LE(err, diffPrjEps) << "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_COL)"; + ASSERT_LE(err, diffPrjEps) << "bad accuracy of cvProjectPCA() (PCA::DATA_AS_COL)"; err = cvtest::norm(backPrjTestPoints, rBackPrjTestPoints.t(), NORM_L2 | NORM_RELATIVE); - ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_COL)"; + ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of cvBackProjectPCA() (PCA::DATA_AS_COL)"; #endif // Test read and write const std::string filename = cv::tempfile("PCA_store.yml"); @@ -599,7 +600,7 @@ static void setValue(SparseMat& M, const int* idx, double value, RNG& rng) else if( M.type() == CV_64F ) *(double*)ptr = value; else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); } #if defined(__GNUC__) && (__GNUC__ == 11 || __GNUC__ == 12 || __GNUC__ == 13) @@ -651,8 +652,8 @@ void Core_ArrayOpTest::run( int /* start_from */) MatND A(3, sz3, CV_32F), B(3, sz3, CV_16SC4); CvMatND matA = cvMatND(A), matB = cvMatND(B); RNG rng; - rng.fill(A, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10)); - rng.fill(B, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10)); + rng.fill(A, RNG::UNIFORM, Scalar::all(-10), Scalar::all(10)); + rng.fill(B, RNG::UNIFORM, Scalar::all(-10), Scalar::all(10)); int idx0[] = {3,4,5}, idx1[] = {0, 9, 7}; float val0 = 130; @@ -808,7 +809,7 @@ void Core_ArrayOpTest::run( int /* start_from */) all_vals.resize(nz0); all_vals2.resize(nz0); Mat_ _all_vals(all_vals), _all_vals2(all_vals2); - rng.fill(_all_vals, CV_RAND_UNI, Scalar(-1000), Scalar(1000)); + rng.fill(_all_vals, RNG::UNIFORM, Scalar(-1000), Scalar(1000)); if( depth == CV_32F ) { Mat _all_vals_f; @@ -824,9 +825,9 @@ void Core_ArrayOpTest::run( int /* start_from */) } minMaxLoc(_all_vals, &min_val, &max_val); - double _norm0 = cv/*test*/::norm(_all_vals, CV_C); - double _norm1 = cv/*test*/::norm(_all_vals, CV_L1); - double _norm2 = cv/*test*/::norm(_all_vals, CV_L2); + double _norm0 = cv/*test*/::norm(_all_vals, NORM_INF); + double _norm1 = cv/*test*/::norm(_all_vals, NORM_L1); + double _norm2 = cv/*test*/::norm(_all_vals, NORM_L2); for( i = 0; i < nz0; i++ ) { @@ -861,9 +862,9 @@ void Core_ArrayOpTest::run( int /* start_from */) SparseMat M3; SparseMat(Md).convertTo(M3, Md.type(), 2); int nz1 = (int)M.nzcount(), nz2 = (int)M3.nzcount(); - double norm0 = cv/*test*/::norm(M, CV_C); - double norm1 = cv/*test*/::norm(M, CV_L1); - double norm2 = cv/*test*/::norm(M, CV_L2); + double norm0 = cv/*test*/::norm(M, NORM_INF); + double norm1 = cv/*test*/::norm(M, NORM_L1); + double norm2 = cv/*test*/::norm(M, NORM_L2); double eps = depth == CV_32F ? FLT_EPSILON*100 : DBL_EPSILON*1000; if( nz1 != nz0 || nz2 != nz0) diff --git a/modules/core/test/test_math.cpp b/modules/core/test/test_math.cpp index eb4a4c4123..d193c628fc 100644 --- a/modules/core/test/test_math.cpp +++ b/modules/core/test/test_math.cpp @@ -10,6 +10,7 @@ #include #include #include "opencv2/core/softfloat.hpp" +#include "opencv2/core/core_c.h" namespace opencv_test { namespace { @@ -2737,11 +2738,11 @@ TEST(Core_Invert, small) cv::Mat b = a.t()*a; cv::Mat c, i = Mat_::eye(3, 3); cv::invert(b, c, cv::DECOMP_LU); //std::cout << b*c << std::endl; - ASSERT_LT( cvtest::norm(b*c, i, CV_C), 0.1 ); + ASSERT_LT( cvtest::norm(b*c, i, NORM_INF), 0.1 ); cv::invert(b, c, cv::DECOMP_SVD); //std::cout << b*c << std::endl; - ASSERT_LT( cvtest::norm(b*c, i, CV_C), 0.1 ); + ASSERT_LT( cvtest::norm(b*c, i, NORM_INF), 0.1 ); cv::invert(b, c, cv::DECOMP_CHOLESKY); //std::cout << b*c << std::endl; - ASSERT_LT( cvtest::norm(b*c, i, CV_C), 0.1 ); + ASSERT_LT( cvtest::norm(b*c, i, NORM_INF), 0.1 ); } ///////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/modules/core/test/test_operations.cpp b/modules/core/test/test_operations.cpp index dbbf46c316..e3f64d4efd 100644 --- a/modules/core/test/test_operations.cpp +++ b/modules/core/test/test_operations.cpp @@ -42,6 +42,7 @@ #include "test_precomp.hpp" #include "opencv2/ts/ocl_test.hpp" // T-API like tests +#include "opencv2/core/core_c.h" namespace opencv_test { namespace { @@ -773,14 +774,14 @@ bool CV_OperationsTest::TestTemplateMat() mvf.push_back(Mat_::zeros(4, 3)); merge(mvf, mf2); split(mf2, mvf2); - CV_Assert( cvtest::norm(mvf2[0], mvf[0], CV_C) == 0 && - cvtest::norm(mvf2[1], mvf[1], CV_C) == 0 ); + CV_Assert( cvtest::norm(mvf2[0], mvf[0], NORM_INF) == 0 && + cvtest::norm(mvf2[1], mvf[1], NORM_INF) == 0 ); { Mat a(2,2,CV_32F,1.f); Mat b(1,2,CV_32F,1.f); Mat c = (a*b.t()).t(); - CV_Assert( cvtest::norm(c, CV_L1) == 4. ); + CV_Assert( cvtest::norm(c, NORM_L1) == 4. ); } bool badarg_catched = false; @@ -1130,13 +1131,13 @@ bool CV_OperationsTest::operations1() Matx33f b(1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f); Mat c; cv::add(Mat::zeros(3, 3, CV_32F), b, c); - CV_Assert( cvtest::norm(b, c, CV_C) == 0 ); + CV_Assert( cvtest::norm(b, c, NORM_INF) == 0 ); cv::add(Mat::zeros(3, 3, CV_64F), b, c, noArray(), c.type()); - CV_Assert( cvtest::norm(b, c, CV_C) == 0 ); + CV_Assert( cvtest::norm(b, c, NORM_INF) == 0 ); cv::add(Mat::zeros(6, 1, CV_64F), 1, c, noArray(), c.type()); - CV_Assert( cvtest::norm(Matx61f(1.f, 1.f, 1.f, 1.f, 1.f, 1.f), c, CV_C) == 0 ); + CV_Assert( cvtest::norm(Matx61f(1.f, 1.f, 1.f, 1.f, 1.f, 1.f), c, NORM_INF) == 0 ); vector pt2d(3); vector pt3d(2); @@ -1182,11 +1183,11 @@ bool CV_OperationsTest::TestSVD() Mat A = (Mat_(3,4) << 1, 2, -1, 4, 2, 4, 3, 5, -1, -2, 6, 7); Mat x; SVD::solveZ(A,x); - if( cvtest::norm(A*x, CV_C) > FLT_EPSILON ) + if( cvtest::norm(A*x, NORM_INF) > FLT_EPSILON ) throw test_excep(); SVD svd(A, SVD::FULL_UV); - if( cvtest::norm(A*svd.vt.row(3).t(), CV_C) > FLT_EPSILON ) + if( cvtest::norm(A*svd.vt.row(3).t(), NORM_INF) > FLT_EPSILON ) throw test_excep(); Mat Dp(3,3,CV_32FC1); @@ -1210,11 +1211,11 @@ bool CV_OperationsTest::TestSVD() W=decomp.w; Mat I = Mat::eye(3, 3, CV_32F); - if( cvtest::norm(U*U.t(), I, CV_C) > FLT_EPSILON || - cvtest::norm(Vt*Vt.t(), I, CV_C) > FLT_EPSILON || + if( cvtest::norm(U*U.t(), I, NORM_INF) > FLT_EPSILON || + cvtest::norm(Vt*Vt.t(), I, NORM_INF) > FLT_EPSILON || W.at(2) < 0 || W.at(1) < W.at(2) || W.at(0) < W.at(1) || - cvtest::norm(U*Mat::diag(W)*Vt, Q, CV_C) > FLT_EPSILON ) + cvtest::norm(U*Mat::diag(W)*Vt, Q, NORM_INF) > FLT_EPSILON ) throw test_excep(); } catch(const test_excep&) diff --git a/modules/core/test/test_rand.cpp b/modules/core/test/test_rand.cpp index 49062ff7c7..2ebe34b96c 100644 --- a/modules/core/test/test_rand.cpp +++ b/modules/core/test/test_rand.cpp @@ -48,7 +48,7 @@ bool Core_RandTest::check_pdf(const Mat& hist, double scale, sum += H[i]; CV_Assert( fabs(1./sum - scale) < FLT_EPSILON ); - if( dist_type == CV_RAND_UNI ) + if( dist_type == RNG::UNIFORM ) { float scale0 = (float)(1./hsz); for( i = 0; i < hsz; i++ ) @@ -79,7 +79,7 @@ bool Core_RandTest::check_pdf(const Mat& hist, double scale, } realval = chi2; - double chi2_pval = chi2_p95(hsz - 1 - (dist_type == CV_RAND_NORMAL ? 2 : 0)); + double chi2_pval = chi2_p95(hsz - 1 - (dist_type == RNG::NORMAL ? 2 : 0)); refval = chi2_pval*0.01; return realval <= refval; } @@ -108,7 +108,7 @@ void Core_RandTest::run( int ) int depth = cvtest::randInt(rng) % (CV_64F+1); int c, cn = (cvtest::randInt(rng) % 4) + 1; int type = CV_MAKETYPE(depth, cn); - int dist_type = cvtest::randInt(rng) % (CV_RAND_NORMAL+1); + int dist_type = cvtest::randInt(rng) % (RNG::NORMAL+1); int i, k, SZ = N/cn; Scalar A, B; @@ -116,18 +116,18 @@ void Core_RandTest::run( int ) if (depth == CV_64F) eps = 1.e-7; - bool do_sphere_test = dist_type == CV_RAND_UNI; + bool do_sphere_test = dist_type == RNG::UNIFORM; Mat arr[2], hist[4]; int W[] = {0,0,0,0}; arr[0].create(1, SZ, type); arr[1].create(1, SZ, type); - bool fast_algo = dist_type == CV_RAND_UNI && depth < CV_32F; + bool fast_algo = dist_type == RNG::UNIFORM && depth < CV_32F; for( c = 0; c < cn; c++ ) { int a, b, hsz; - if( dist_type == CV_RAND_UNI ) + if( dist_type == RNG::UNIFORM ) { a = (int)(cvtest::randInt(rng) % (_ranges[depth][1] - _ranges[depth][0])) + _ranges[depth][0]; @@ -188,8 +188,8 @@ void Core_RandTest::run( int ) const uchar* data = arr[0].ptr(); int* H = hist[c].ptr(); int HSZ = hist[c].cols; - double minVal = dist_type == CV_RAND_UNI ? A[c] : A[c] - B[c]*4; - double maxVal = dist_type == CV_RAND_UNI ? B[c] : A[c] + B[c]*4; + double minVal = dist_type == RNG::UNIFORM ? A[c] : A[c] - B[c]*4; + double maxVal = dist_type == RNG::UNIFORM ? B[c] : A[c] + B[c]*4; double scale = HSZ/(maxVal - minVal); double delta = -minVal*scale; @@ -210,7 +210,7 @@ void Core_RandTest::run( int ) H[ival]++; W[c]++; } - else if( dist_type == CV_RAND_UNI ) + else if( dist_type == RNG::UNIFORM ) { if( (minVal <= val && val < maxVal) || (depth >= CV_32F && val == maxVal) ) { @@ -224,14 +224,14 @@ void Core_RandTest::run( int ) } } - if( dist_type == CV_RAND_UNI && W[c] != SZ ) + if( dist_type == RNG::UNIFORM && W[c] != SZ ) { ts->printf( cvtest::TS::LOG, "Uniform RNG gave values out of the range [%g,%g) on channel %d/%d\n", A[c], B[c], c, cn); ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); return; } - if( dist_type == CV_RAND_NORMAL && W[c] < SZ*.90) + if( dist_type == RNG::NORMAL && W[c] < SZ*.90) { ts->printf( cvtest::TS::LOG, "Normal RNG gave too many values out of the range (%g+4*%g,%g+4*%g) on channel %d/%d\n", A[c], B[c], A[c], B[c], c, cn); diff --git a/modules/core/test/test_umat.cpp b/modules/core/test/test_umat.cpp index bf525c9c61..332ce7bc1e 100644 --- a/modules/core/test/test_umat.cpp +++ b/modules/core/test/test_umat.cpp @@ -41,6 +41,7 @@ #include "test_precomp.hpp" #include "opencv2/ts/ocl_test.hpp" +#include "opencv2/core/core_c.h" using namespace opencv_test; using namespace testing; diff --git a/modules/dnn/src/dnn_utils.cpp b/modules/dnn/src/dnn_utils.cpp index 99b4e77e11..3ef75fad36 100644 --- a/modules/dnn/src/dnn_utils.cpp +++ b/modules/dnn/src/dnn_utils.cpp @@ -438,7 +438,7 @@ void Image2BlobParams::blobRectsToImageRects(const std::vector &rBlob, std } } else - CV_Error(CV_StsBadArg, "Unknown padding mode"); + CV_Error(cv::Error::StsBadArg, "Unknown padding mode"); } } diff --git a/modules/dnn/src/int8layers/convolution_layer.cpp b/modules/dnn/src/int8layers/convolution_layer.cpp index 6121e971a2..a5a98c9764 100644 --- a/modules/dnn/src/int8layers/convolution_layer.cpp +++ b/modules/dnn/src/int8layers/convolution_layer.cpp @@ -548,7 +548,7 @@ public: { // for Conv1d if (group != 1) - CV_Error( CV_StsNotImplemented, " Grouped Conv1d or Depth-Wise Conv1d are not supported by " + CV_Error( cv::Error::StsNotImplemented, " Grouped Conv1d or Depth-Wise Conv1d are not supported by " "TimVX Backend. Please try OpenCV Backend."); tvConv = graph->CreateOperation( tvConvWeightShape[2], tvPadType, (uint32_t)kernel_size[0], diff --git a/modules/dnn/src/layers/cpu_kernels/convolution.cpp b/modules/dnn/src/layers/cpu_kernels/convolution.cpp index c5258ccd91..6ae304f29d 100644 --- a/modules/dnn/src/layers/cpu_kernels/convolution.cpp +++ b/modules/dnn/src/layers/cpu_kernels/convolution.cpp @@ -450,7 +450,7 @@ Ptr initFastConv( } } else - CV_Error(CV_StsUnsupportedFormat, "Unknown convolution type."); + CV_Error(cv::Error::StsUnsupportedFormat, "Unknown convolution type."); // store bias; append some zero's to make sure that // we can always read MR elements starting from any valid index diff --git a/modules/dnn/src/vkcom/src/context.cpp b/modules/dnn/src/vkcom/src/context.cpp index 2cb355a247..99aea0f922 100644 --- a/modules/dnn/src/vkcom/src/context.cpp +++ b/modules/dnn/src/vkcom/src/context.cpp @@ -225,7 +225,7 @@ void Context::createInstance() if (result != VK_SUCCESS) { - CV_Error(CV_StsError, "Vulkan: vkEnumerateInstanceLayerProperties failed!"); + CV_Error(cv::Error::StsError, "Vulkan: vkEnumerateInstanceLayerProperties failed!"); return; } @@ -234,7 +234,7 @@ void Context::createInstance() if (result != VK_SUCCESS) { - CV_Error(CV_StsError, "Vulkan: vkEnumerateInstanceLayerProperties failed!"); + CV_Error(cv::Error::StsError, "Vulkan: vkEnumerateInstanceLayerProperties failed!"); return; } @@ -388,7 +388,7 @@ Context::Context() vkEnumeratePhysicalDevices(kInstance, &deviceCount, NULL); if (deviceCount == 0) { - CV_Error(CV_StsError, "Vulkan Backend: could not find a device with vulkan support!"); + CV_Error(cv::Error::StsError, "Vulkan Backend: could not find a device with vulkan support!"); } std::vector devices(deviceCount); @@ -442,7 +442,7 @@ Context::Context() if (!cmdPoolPtr) cmdPoolPtr = CommandPool::create(kQueue, kQueueFamilyIndex); else - CV_Error(CV_StsError, "cmdPoolPtr has been created before!!"); + CV_Error(cv::Error::StsError, "cmdPoolPtr has been created before!!"); pipelineFactoryPtr = PipelineFactory::create(); } @@ -884,4 +884,4 @@ bool isAvailable() #endif // HAVE_VULKAN -}}} // namespace cv::dnn::vkcom \ No newline at end of file +}}} // namespace cv::dnn::vkcom diff --git a/modules/dnn/src/vkcom/src/op_conv.cpp b/modules/dnn/src/vkcom/src/op_conv.cpp index 9c84ffccdf..22aa537111 100644 --- a/modules/dnn/src/vkcom/src/op_conv.cpp +++ b/modules/dnn/src/vkcom/src/op_conv.cpp @@ -244,7 +244,7 @@ bool OpConv::computeGroupCount() group_z_ = 1; } else - CV_Error(CV_StsNotImplemented, "shader type is not supported at compute GroupCount."); + CV_Error(cv::Error::StsNotImplemented, "shader type is not supported at compute GroupCount."); CV_Assert(group_x_ <= MAX_GROUP_COUNT_X); CV_Assert(group_y_ <= MAX_GROUP_COUNT_Y); diff --git a/modules/dnn/src/vkcom/src/op_naryEltwise.cpp b/modules/dnn/src/vkcom/src/op_naryEltwise.cpp index 812ca097b3..bcc5cd7e2e 100644 --- a/modules/dnn/src/vkcom/src/op_naryEltwise.cpp +++ b/modules/dnn/src/vkcom/src/op_naryEltwise.cpp @@ -182,7 +182,7 @@ bool OpNary::computeGroupCount() } else { - CV_Error(CV_StsNotImplemented, "shader type is not supported at compute GroupCount."); + CV_Error(cv::Error::StsNotImplemented, "shader type is not supported at compute GroupCount."); } CV_Assert(group_x_ <= MAX_GROUP_COUNT_X); diff --git a/modules/dnn/src/vkcom/src/pipeline.cpp b/modules/dnn/src/vkcom/src/pipeline.cpp index ea29d8824a..240102fba4 100644 --- a/modules/dnn/src/vkcom/src/pipeline.cpp +++ b/modules/dnn/src/vkcom/src/pipeline.cpp @@ -279,7 +279,7 @@ Ptr PipelineFactory::getPipeline(const std::string& key, const std::ve // retrieve spv from SPVMaps with given key auto iterSPV = SPVMaps.find(key); if (iterSPV == SPVMaps.end()) - CV_Error(CV_StsError, "Can not create SPV with the given name:"+key+"!"); + CV_Error(cv::Error::StsError, "Can not create SPV with the given name:"+key+"!"); const uint32_t* spv = iterSPV->second.first; size_t length = iterSPV->second.second; @@ -292,7 +292,7 @@ Ptr PipelineFactory::getPipeline(const std::string& key, const std::ve } else { - CV_Error(CV_StsError, "Can not Created the VkPipeline "+key); + CV_Error(cv::Error::StsError, "Can not Created the VkPipeline "+key); } return pipeline; diff --git a/modules/features2d/misc/java/test/FlannBasedDescriptorMatcherTest.java b/modules/features2d/misc/java/test/FlannBasedDescriptorMatcherTest.java index 72947a85cd..bd2cd0a330 100644 --- a/modules/features2d/misc/java/test/FlannBasedDescriptorMatcherTest.java +++ b/modules/features2d/misc/java/test/FlannBasedDescriptorMatcherTest.java @@ -209,7 +209,7 @@ public class FlannBasedDescriptorMatcherTest extends OpenCVTestCase { try { matcher.clone(); - fail("Expected CvException (CV_StsNotImplemented)"); + fail("Expected CvException (cv::Error::StsNotImplemented)"); } catch (CvException cverr) { // expected } diff --git a/modules/features2d/src/mser.cpp b/modules/features2d/src/mser.cpp index 3cada4ec75..9e96e1ea2c 100644 --- a/modules/features2d/src/mser.cpp +++ b/modules/features2d/src/mser.cpp @@ -44,9 +44,9 @@ */ #include "precomp.hpp" -#include "opencv2/imgproc/imgproc_c.h" #include #include "../3rdparty/mscr/chi_table.h" +#include "opencv2/core/core_c.h" namespace cv { diff --git a/modules/gapi/src/backends/fluid/gfluidimgproc.cpp b/modules/gapi/src/backends/fluid/gfluidimgproc.cpp index bdd11b1214..7a97557051 100644 --- a/modules/gapi/src/backends/fluid/gfluidimgproc.cpp +++ b/modules/gapi/src/backends/fluid/gfluidimgproc.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include diff --git a/modules/highgui/src/precomp.hpp b/modules/highgui/src/precomp.hpp index 30510f0593..ccb0e52b45 100644 --- a/modules/highgui/src/precomp.hpp +++ b/modules/highgui/src/precomp.hpp @@ -57,7 +57,7 @@ #endif #include "opencv2/imgproc.hpp" -#include "opencv2/imgproc/imgproc_c.h" +#include "opencv2/core/core_c.h" #include #include diff --git a/modules/highgui/src/window.cpp b/modules/highgui/src/window.cpp index 8f90edcbd1..c18be77733 100644 --- a/modules/highgui/src/window.cpp +++ b/modules/highgui/src/window.cpp @@ -1088,17 +1088,17 @@ void cv::imshow(const String& winname, const ogl::Texture2D& _tex) void setOpenGLDrawCallbackImpl(const char*, CvOpenGlDrawCallback, void*) { - CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); + CV_Error(cv::Error::OpenGlNotSupported, "The library is compiled without OpenGL support"); } void setOpenGLContextImpl(const char*) { - CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); + CV_Error(cv::Error::OpenGlNotSupported, "The library is compiled without OpenGL support"); } void updateWindowImpl(const char*) { - CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); + CV_Error(cv::Error::OpenGlNotSupported, "The library is compiled without OpenGL support"); } #endif // !HAVE_OPENGL @@ -1112,52 +1112,52 @@ static const char* NO_QT_ERR_MSG = "The library is compiled without QT support"; cv::QtFont cv::fontQt(const String&, int, Scalar, int, int, int) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } void cv::addText( const Mat&, const String&, Point, const QtFont&) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } void cv::addText(const Mat&, const String&, Point, const String&, int, Scalar, int, int, int) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } void cv::displayStatusBar(const String&, const String&, int) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } void cv::displayOverlay(const String&, const String&, int ) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } int cv::startLoop(int (*)(int argc, char *argv[]), int , char**) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } void cv::stopLoop() { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } void cv::saveWindowParameters(const String&) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } void cv::loadWindowParameters(const String&) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } int cv::createButton(const String&, ButtonCallback, void*, int , bool ) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } #endif // !HAVE_QT diff --git a/modules/highgui/src/window_QT.cpp b/modules/highgui/src/window_QT.cpp index 26c0741fe9..3df702d3bb 100644 --- a/modules/highgui/src/window_QT.cpp +++ b/modules/highgui/src/window_QT.cpp @@ -136,7 +136,7 @@ void cv::addText( const Mat& img, const String& text, Point org, const QtFont& f { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); CvMat _img = cvMat(img); QMetaObject::invokeMethod( @@ -160,7 +160,7 @@ void cv::addText( const Mat& img, const String& text, Point org, const String& n void cv::displayStatusBar(const String& name, const String& text, int delayms) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "displayStatusBar", @@ -174,7 +174,7 @@ void cv::displayStatusBar(const String& name, const String& text, int delayms) void cv::displayOverlay(const String& name, const String& text, int delayms) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "displayInfo", @@ -202,7 +202,7 @@ void cv::stopLoop() void cv::saveWindowParameters(const String& windowName) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "saveWindowParameters", @@ -213,7 +213,7 @@ void cv::saveWindowParameters(const String& windowName) void cv::loadWindowParameters(const String& windowName) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "loadWindowParameters", @@ -225,7 +225,7 @@ void cv::loadWindowParameters(const String& windowName) int cv::createButton(const String& button_name, ButtonCallback on_change, void* userdata, int button_type , bool initial_button_state ) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "addButton", @@ -242,7 +242,7 @@ int cv::createButton(const String& button_name, ButtonCallback on_change, void* double cvGetRatioWindow_QT(const char* name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); double result = -1; QMetaObject::invokeMethod(guiMainThread, @@ -256,7 +256,7 @@ double cvGetRatioWindow_QT(const char* name) double cvGetPropVisible_QT(const char* name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); double result = 0; @@ -273,7 +273,7 @@ void cvSetRatioWindow_QT(const char* name,double prop_value) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "setRatioWindow", @@ -285,7 +285,7 @@ void cvSetRatioWindow_QT(const char* name,double prop_value) double cvGetPropWindow_QT(const char* name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); double result = -1; QMetaObject::invokeMethod(guiMainThread, @@ -301,7 +301,7 @@ double cvGetPropWindow_QT(const char* name) void cvSetPropWindow_QT(const char* name,double prop_value) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "setPropWindow", @@ -326,7 +326,7 @@ void setWindowTitle_QT(const String& winname, const String& title) void cvSetModeWindow_QT(const char* name, double prop_value) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "toggleFullScreen", @@ -338,7 +338,7 @@ void cvSetModeWindow_QT(const char* name, double prop_value) CvRect cvGetWindowRect_QT(const char* name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); CvRect result = cvRect(-1, -1, -1, -1); @@ -354,7 +354,7 @@ CvRect cvGetWindowRect_QT(const char* name) double cvGetModeWindow_QT(const char* name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); double result = -1; @@ -501,7 +501,7 @@ static CvTrackbar* icvFindTrackBarByName(const char* name_trackbar, const char* QPointer w = icvFindWindowByName(nameWinQt); if (!w) - CV_Error(CV_StsNullPtr, "NULL window handler"); + CV_Error(cv::Error::StsNullPtr, "NULL window handler"); if (w->param_gui_mode == cv::WINDOW_GUI_NORMAL) return (CvTrackbar*) icvFindBarByName(w->myBarLayout, nameQt, type_CvTrackbar); @@ -576,7 +576,7 @@ int namedWindowImpl(const char* name, int flags) void destroyWindowImpl(const char* name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "destroyWindow", @@ -599,7 +599,7 @@ void destroyAllWindowsImpl() void moveWindowImpl(const char* name, int x, int y) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "moveWindow", autoBlockingConnection(), @@ -611,7 +611,7 @@ void moveWindowImpl(const char* name, int x, int y) void resizeWindowImpl(const char* name, int width, int height) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "resizeWindow", autoBlockingConnection(), @@ -624,7 +624,7 @@ void resizeWindowImpl(const char* name, int width, int height) int createTrackbar2Impl(const char* name_bar, const char* window_name, int* val, int count, CvTrackbarCallback2 on_notify, void* userdata) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "addSlider2", @@ -687,7 +687,7 @@ void setMouseCallbackImpl(const char* window_name, CvMouseCallback on_mouse, voi QPointer w = icvFindWindowByName(QLatin1String(window_name)); if (!w) - CV_Error(CV_StsNullPtr, "NULL window handler"); + CV_Error(cv::Error::StsNullPtr, "NULL window handler"); w->setMouseCallBack(on_mouse, param); @@ -717,7 +717,7 @@ void showImageImpl(const char* name, const CvArr* arr) void setOpenGLDrawCallbackImpl(const char* window_name, CvOpenGlDrawCallback callback, void* userdata) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "setOpenGlDrawCallback", @@ -731,7 +731,7 @@ void setOpenGLDrawCallbackImpl(const char* window_name, CvOpenGlDrawCallback cal void setOpenGLContextImpl(const char* window_name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "setOpenGlContext", @@ -743,7 +743,7 @@ void setOpenGLContextImpl(const char* window_name) void updateWindowImpl(const char* window_name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "updateWindow", @@ -973,7 +973,7 @@ void GuiReceiver::toggleFullScreen(QString name, double arg2) void GuiReceiver::createWindow(QString name, int flags) { if (!qApp) - CV_Error(CV_StsNullPtr, "NULL session handler" ); + CV_Error(cv::Error::StsNullPtr, "NULL session handler" ); // Check the name in the storage if (icvFindWindowByName(name.toLatin1().data())) @@ -1064,7 +1064,7 @@ void GuiReceiver::destroyWindow(QString name) void GuiReceiver::destroyAllWindow() { if (!qApp) - CV_Error(CV_StsNullPtr, "NULL session handler" ); + CV_Error(cv::Error::StsNullPtr, "NULL session handler" ); if (multiThreads) { @@ -1193,7 +1193,7 @@ void GuiReceiver::addSlider2(QString bar_name, QString window_name, void* value, return; if (count <= 0) //count is the max value of the slider, so must be bigger than 0 - CV_Error(CV_StsNullPtr, "Max value of the slider must be bigger than 0" ); + CV_Error(cv::Error::StsNullPtr, "Max value of the slider must be bigger than 0" ); CvWindow::addSlider2(w, bar_name, (int*)value, count, (CvTrackbarCallback2) on_change, userdata); } @@ -1223,10 +1223,10 @@ void GuiReceiver::addSlider(QString bar_name, QString window_name, void* value, return; if (!value) - CV_Error(CV_StsNullPtr, "NULL value pointer" ); + CV_Error(cv::Error::StsNullPtr, "NULL value pointer" ); if (count <= 0) //count is the max value of the slider, so must be bigger than 0 - CV_Error(CV_StsNullPtr, "Max value of the slider must be bigger than 0" ); + CV_Error(cv::Error::StsNullPtr, "Max value of the slider must be bigger than 0" ); CvWindow::addSlider(w, bar_name, (int*)value, count, (CvTrackbarCallback) on_change); } @@ -1640,7 +1640,7 @@ CvWindow::CvWindow(QString name, int arg2) //3: my view #ifndef HAVE_QT_OPENGL if (arg2 & cv::WINDOW_OPENGL) - CV_Error( CV_OpenGlNotSupported, "Library was built without OpenGL support" ); + CV_Error( cv::Error::OpenGlNotSupported, "Library was built without OpenGL support" ); mode_display = CV_MODE_NORMAL; #else mode_display = arg2 & cv::WINDOW_OPENGL ? CV_MODE_OPENGL : CV_MODE_NORMAL; @@ -2599,19 +2599,19 @@ void DefaultViewPort::startDisplayInfo(QString text, int delayms) void DefaultViewPort::setOpenGlDrawCallback(CvOpenGlDrawCallback /*callback*/, void* /*userdata*/) { - CV_Error(CV_OpenGlNotSupported, "Window doesn't support OpenGL"); + CV_Error(cv::Error::OpenGlNotSupported, "Window doesn't support OpenGL"); } void DefaultViewPort::makeCurrentOpenGlContext() { - CV_Error(CV_OpenGlNotSupported, "Window doesn't support OpenGL"); + CV_Error(cv::Error::OpenGlNotSupported, "Window doesn't support OpenGL"); } void DefaultViewPort::updateGl() { - CV_Error(CV_OpenGlNotSupported, "Window doesn't support OpenGL"); + CV_Error(cv::Error::OpenGlNotSupported, "Window doesn't support OpenGL"); } @@ -2714,7 +2714,7 @@ void DefaultViewPort::saveView() return; } - CV_Error(CV_StsNullPtr, "file extension not recognized, please choose between JPG, JPEG, BMP or PNG"); + CV_Error(cv::Error::StsNullPtr, "file extension not recognized, please choose between JPG, JPEG, BMP or PNG"); } } diff --git a/modules/highgui/src/window_cocoa.mm b/modules/highgui/src/window_cocoa.mm index 8dc640fdd6..7c16a4e9d1 100644 --- a/modules/highgui/src/window_cocoa.mm +++ b/modules/highgui/src/window_cocoa.mm @@ -284,14 +284,11 @@ void resizeWindowImpl( const char* name, int width, int height) void moveWindowImpl( const char* name, int x, int y) { - CV_FUNCNAME("moveWindowImpl"); - __BEGIN__; - NSAutoreleasePool* localpool1 = [[NSAutoreleasePool alloc] init]; CVWindow *window = nil; if(name == NULL) - CV_ERROR( CV_StsNullPtr, "NULL window name" ); + CV_Error( cv::Error::StsNullPtr, "NULL window name" ); //cout << "moveWindowImpl"<< endl; window = cvGetWindow(name); if(window) { @@ -305,8 +302,6 @@ void moveWindowImpl( const char* name, int x, int y) } } [localpool1 drain]; - - __END__; } static int cocoa_CreateTrackbar (const char* trackbar_name, @@ -314,19 +309,17 @@ static int cocoa_CreateTrackbar (const char* trackbar_name, int* val, int count, CvTrackbarCallback on_notify) { - CV_FUNCNAME("cocoa_CreateTrackbar"); int result = 0; CVWindow *window = nil; NSAutoreleasePool* localpool2 = nil; - __BEGIN__; if (localpool2 != nil) [localpool2 drain]; localpool2 = [[NSAutoreleasePool alloc] init]; if(window_name == NULL) - CV_ERROR( CV_StsNullPtr, "NULL window name" ); + CV_Error( cv::Error::StsNullPtr, "NULL window name" ); //cout << "cocoa_CreateTrackbar" << endl ; window = cvGetWindow(window_name); @@ -338,7 +331,6 @@ static int cocoa_CreateTrackbar (const char* trackbar_name, result = 1; } [localpool2 drain]; - __END__; return result; } @@ -367,18 +359,15 @@ int createTrackbar2Impl(const char* trackbar_name, void setMouseCallbackImpl( const char* name, CvMouseCallback function, void* info) { - CV_FUNCNAME("setMouseCallbackImpl"); - CVWindow *window = nil; NSAutoreleasePool* localpool3 = nil; - __BEGIN__; //cout << "setMouseCallbackImpl" << endl; if (localpool3 != nil) [localpool3 drain]; localpool3 = [[NSAutoreleasePool alloc] init]; if(name == NULL) - CV_ERROR( CV_StsNullPtr, "NULL window name" ); + CV_Error( cv::Error::StsNullPtr, "NULL window name" ); window = cvGetWindow(name); if(window) { @@ -386,22 +375,16 @@ void setMouseCallbackImpl( const char* name, CvMouseCallback function, void* inf [window setMouseParam:info]; } [localpool3 drain]; - - __END__; } int getTrackbarPosImpl( const char* trackbar_name, const char* window_name ) { - CV_FUNCNAME("getTrackbarPosImpl"); - CVWindow *window = nil; int pos = -1; NSAutoreleasePool* localpool4 = nil; - __BEGIN__; - //cout << "getTrackbarPosImpl" << endl; if(trackbar_name == NULL || window_name == NULL) - CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); + CV_Error( cv::Error::StsNullPtr, "NULL trackbar or window name" ); if (localpool4 != nil) [localpool4 drain]; localpool4 = [[NSAutoreleasePool alloc] init]; @@ -414,25 +397,21 @@ void setMouseCallbackImpl( const char* name, CvMouseCallback function, void* inf } } [localpool4 drain]; - __END__; return pos; } void setTrackbarPosImpl(const char* trackbar_name, const char* window_name, int pos) { - CV_FUNCNAME("setTrackbarPosImpl"); - CVWindow *window = nil; CVSlider *slider = nil; NSAutoreleasePool* localpool5 = nil; - __BEGIN__; //cout << "setTrackbarPosImpl" << endl; if(trackbar_name == NULL || window_name == NULL) - CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); + CV_Error( cv::Error::StsNullPtr, "NULL trackbar or window name" ); if(pos < 0) - CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" ); + CV_Error( cv::Error::StsOutOfRange, "Bad trackbar maximal value" ); if (localpool5 != nil) [localpool5 drain]; localpool5 = [[NSAutoreleasePool alloc] init]; @@ -448,22 +427,17 @@ void setTrackbarPosImpl(const char* trackbar_name, const char* window_name, int } } [localpool5 drain]; - - __END__; } void setTrackbarMaxImpl(const char* trackbar_name, const char* window_name, int maxval) { - CV_FUNCNAME("setTrackbarMaxImpl"); - CVWindow *window = nil; CVSlider *slider = nil; NSAutoreleasePool* localpool5 = nil; - __BEGIN__; //cout << "setTrackbarPosImpl" << endl; if(trackbar_name == NULL || window_name == NULL) - CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); + CV_Error( cv::Error::StsNullPtr, "NULL trackbar or window name" ); if (localpool5 != nil) [localpool5 drain]; localpool5 = [[NSAutoreleasePool alloc] init]; @@ -480,21 +454,16 @@ void setTrackbarMaxImpl(const char* trackbar_name, const char* window_name, int } } [localpool5 drain]; - - __END__; } void setTrackbarMinImpl(const char* trackbar_name, const char* window_name, int minval) { - CV_FUNCNAME("setTrackbarMinImpl"); - CVWindow *window = nil; CVSlider *slider = nil; NSAutoreleasePool* localpool5 = nil; - __BEGIN__; if(trackbar_name == NULL || window_name == NULL) - CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); + CV_Error( cv::Error::StsNullPtr, "NULL trackbar or window name" ); if (localpool5 != nil) [localpool5 drain]; localpool5 = [[NSAutoreleasePool alloc] init]; @@ -511,8 +480,6 @@ void setTrackbarMinImpl(const char* trackbar_name, const char* window_name, int } } [localpool5 drain]; - - __END__; } int namedWindowImpl( const char* name, int flags ) @@ -616,18 +583,15 @@ CvRect cvGetWindowRect_COCOA( const char* name ) CvRect result = cvRect(-1, -1, -1, -1); CVWindow *window = nil; - CV_FUNCNAME( "cvGetWindowRect_COCOA" ); - - __BEGIN__; if( name == NULL ) { - CV_ERROR( CV_StsNullPtr, "NULL name string" ); + CV_Error( cv::Error::StsNullPtr, "NULL name string" ); } window = cvGetWindow( name ); if ( window == NULL ) { - CV_ERROR( CV_StsNullPtr, "NULL window" ); + CV_Error( cv::Error::StsNullPtr, "NULL window" ); } else { NSRect rect = [window frame]; #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6 @@ -638,8 +602,6 @@ CvRect cvGetWindowRect_COCOA( const char* name ) NSSize sz = [[[window contentView] image] size]; result = cvRect(pt.x, pt.y, sz.width, sz.height); } - - __END__; return result; } @@ -648,23 +610,18 @@ double cvGetModeWindow_COCOA( const char* name ) double result = -1; CVWindow *window = nil; - CV_FUNCNAME( "cvGetModeWindow_COCOA" ); - - __BEGIN__; if( name == NULL ) { - CV_ERROR( CV_StsNullPtr, "NULL name string" ); + CV_Error( cv::Error::StsNullPtr, "NULL name string" ); } window = cvGetWindow( name ); if ( window == NULL ) { - CV_ERROR( CV_StsNullPtr, "NULL window" ); + CV_Error( cv::Error::StsNullPtr, "NULL window" ); } result = window.status; - - __END__; return result; } @@ -678,18 +635,15 @@ void cvSetModeWindow_COCOA( const char* name, double prop_value ) NSAutoreleasePool* localpool = nil; - CV_FUNCNAME( "cvSetModeWindow_COCOA" ); - - __BEGIN__; if( name == NULL ) { - CV_ERROR( CV_StsNullPtr, "NULL name string" ); + CV_Error( cv::Error::StsNullPtr, "NULL name string" ); } window = cvGetWindow(name); if ( window == NULL ) { - CV_ERROR( CV_StsNullPtr, "NULL window" ); + CV_Error( cv::Error::StsNullPtr, "NULL window" ); } if ( [window autosize] ) @@ -737,8 +691,6 @@ void cvSetModeWindow_COCOA( const char* name, double prop_value ) } #endif [localpool drain]; - - __END__; } double cvGetPropVisible_COCOA(const char* name) @@ -746,23 +698,19 @@ double cvGetPropVisible_COCOA(const char* name) double result = -1; CVWindow* window = nil; - CV_FUNCNAME("cvGetPropVisible_COCOA"); - - __BEGIN__; if (name == NULL) { - CV_ERROR(CV_StsNullPtr, "NULL name string"); + CV_Error(cv::Error::StsNullPtr, "NULL name string"); } window = cvGetWindow(name); if (window == NULL) { - CV_ERROR(CV_StsNullPtr, "NULL window"); + CV_Error(cv::Error::StsNullPtr, "NULL window"); } result = window.isVisible ? 1 : 0; - __END__; return result; } @@ -771,23 +719,18 @@ double cvGetPropTopmost_COCOA(const char* name) double result = -1; CVWindow* window = nil; - CV_FUNCNAME("cvGetPropTopmost_COCOA"); - - __BEGIN__; if (name == NULL) { - CV_ERROR(CV_StsNullPtr, "NULL name string"); + CV_Error(cv::Error::StsNullPtr, "NULL name string"); } window = cvGetWindow(name); if (window == NULL) { - CV_ERROR(CV_StsNullPtr, "NULL window"); + CV_Error(cv::Error::StsNullPtr, "NULL window"); } result = (window.level == NSStatusWindowLevel) ? 1 : 0; - - __END__; return result; } @@ -795,23 +738,21 @@ void cvSetPropTopmost_COCOA( const char* name, const bool topmost ) { CVWindow *window = nil; NSAutoreleasePool* localpool = nil; - CV_FUNCNAME( "cvSetPropTopmost_COCOA" ); - __BEGIN__; if( name == NULL ) { - CV_ERROR( CV_StsNullPtr, "NULL name string" ); + CV_Error( cv::Error::StsNullPtr, "NULL name string" ); } window = cvGetWindow(name); if ( window == NULL ) { - CV_ERROR( CV_StsNullPtr, "NULL window" ); + CV_Error( cv::Error::StsNullPtr, "NULL window" ); } if (([window styleMask] & NSFullScreenWindowMask)) { - EXIT; + return; } localpool = [[NSAutoreleasePool alloc] init]; @@ -825,7 +766,6 @@ void cvSetPropTopmost_COCOA( const char* name, const bool topmost ) [window makeKeyAndOrderFront:nil]; } [localpool drain]; - __END__; } void setWindowTitle_COCOA(const cv::String& winname, const cv::String& title) diff --git a/modules/highgui/src/window_gtk.cpp b/modules/highgui/src/window_gtk.cpp index c631f10ae6..d666ce0227 100644 --- a/modules/highgui/src/window_gtk.cpp +++ b/modules/highgui/src/window_gtk.cpp @@ -737,7 +737,7 @@ CvRect cvGetWindowRect_GTK(const char* name) CV_LOCK_MUTEX(); const auto window = icvFindWindowByName(name); if (!window) - CV_Error( CV_StsNullPtr, "NULL window" ); + CV_Error( cv::Error::StsNullPtr, "NULL window" ); return cvRect(getImageRect_(window)); } @@ -779,7 +779,7 @@ double cvGetModeWindow_GTK(const char* name)//YV CV_LOCK_MUTEX(); const auto window = icvFindWindowByName(name); if (!window) - CV_Error( CV_StsNullPtr, "NULL window" ); + CV_Error( cv::Error::StsNullPtr, "NULL window" ); double result = window->status; return result; @@ -794,7 +794,7 @@ void cvSetModeWindow_GTK( const char* name, double prop_value)//Yannick Verdie const auto window = icvFindWindowByName(name); if (!window) - CV_Error( CV_StsNullPtr, "NULL window" ); + CV_Error( cv::Error::StsNullPtr, "NULL window" ); setModeWindow_(window, (int)prop_value); } @@ -910,11 +910,11 @@ namespace // Try double-buffered visual glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode)(GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE)); if (!glconfig) - CV_Error( CV_OpenGlApiCallError, "Can't Create A GL Device Context" ); + CV_Error( cv::Error::OpenGlApiCallError, "Can't Create A GL Device Context" ); // Set OpenGL-capability to the widget if (!gtk_widget_set_gl_capability(window->widget, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE)) - CV_Error( CV_OpenGlApiCallError, "Can't Create A GL Device Context" ); + CV_Error( cv::Error::OpenGlApiCallError, "Can't Create A GL Device Context" ); window->useGl = true; } @@ -925,7 +925,7 @@ namespace GdkGLDrawable* gldrawable = gtk_widget_get_gl_drawable(window->widget); if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) - CV_Error( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); + CV_Error( cv::Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); glViewport(0, 0, gtk_widget_get_allocated_width(window->widget), gtk_widget_get_allocated_height(window->widget)); @@ -1044,7 +1044,7 @@ static std::shared_ptr namedWindow_(const std::string& name, int flags #ifndef HAVE_OPENGL if (flags & cv::WINDOW_OPENGL) - CV_Error( CV_OpenGlNotSupported, "Library was built without OpenGL support" ); + CV_Error( cv::Error::OpenGlNotSupported, "Library was built without OpenGL support" ); #else if (flags & cv::WINDOW_OPENGL) createGlContext(window); @@ -1125,16 +1125,16 @@ void setOpenGLContextImpl(const char* name) auto window = icvFindWindowByName(name); if (!window) - CV_Error( CV_StsNullPtr, "NULL window" ); + CV_Error( cv::Error::StsNullPtr, "NULL window" ); if (!window->useGl) - CV_Error( CV_OpenGlNotSupported, "Window doesn't support OpenGL" ); + CV_Error( cv::Error::OpenGlNotSupported, "Window doesn't support OpenGL" ); glcontext = gtk_widget_get_gl_context(window->widget); gldrawable = gtk_widget_get_gl_drawable(window->widget); if (!gdk_gl_drawable_make_current(gldrawable, glcontext)) - CV_Error( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); + CV_Error( cv::Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); } void updateWindowImpl(const char* name) @@ -1162,7 +1162,7 @@ void setOpenGLDrawCallbackImpl(const char* name, CvOpenGlDrawCallback callback, return; if (!window->useGl) - CV_Error( CV_OpenGlNotSupported, "Window was created without OpenGL context" ); + CV_Error( cv::Error::OpenGlNotSupported, "Window was created without OpenGL context" ); window->glDrawCallback = callback; window->glDrawData = userdata; @@ -1376,7 +1376,7 @@ icvCreateTrackbar( const char* trackbar_name, const char* window_name, CV_Assert(trackbar_name && "NULL trackbar name"); if( count <= 0 ) - CV_Error( CV_StsOutOfRange, "Bad trackbar maximal value" ); + CV_Error( cv::Error::StsOutOfRange, "Bad trackbar maximal value" ); CV_LOCK_MUTEX(); @@ -1539,7 +1539,7 @@ void setTrackbarPosImpl( const char* trackbar_name, const char* window_name, int const auto trackbar = icvFindTrackbarByName(window, trackbar_name); if (!trackbar) { - CV_Error( CV_StsNullPtr, "No trackbar found" ); + CV_Error( cv::Error::StsNullPtr, "No trackbar found" ); } return setTrackbarPos_(trackbar, pos); diff --git a/modules/highgui/src/window_winrt.cpp b/modules/highgui/src/window_winrt.cpp index ee9b3ae7a3..cc08ae503d 100644 --- a/modules/highgui/src/window_winrt.cpp +++ b/modules/highgui/src/window_winrt.cpp @@ -36,12 +36,12 @@ #define CV_WINRT_NO_GUI_ERROR( funcname ) \ { \ - cvError( CV_StsNotImplemented, funcname, \ + cvError( cv::Error::StsNotImplemented, funcname, \ "The function is not implemented. ", \ __FILE__, __LINE__ ); \ } -#define CV_ERROR( Code, Msg ) \ +#define CV_Error( Code, Msg ) \ { \ cvError( (Code), cvFuncName, Msg, __FILE__, __LINE__ ); \ }; @@ -65,7 +65,7 @@ void showImageImpl(const char* name, const CvArr* arr) CvMat stub, *image; if (!name) - CV_ERROR(CV_StsNullPtr, "NULL name"); + CV_Error(cv::Error::StsNullPtr, "NULL name"); CvWindow* window = HighguiBridge::getInstance().namedWindow(name); @@ -89,7 +89,7 @@ int namedWindowImpl(const char* name, int flags) CV_FUNCNAME("namedWindowImpl"); if (!name) - CV_ERROR(CV_StsNullPtr, "NULL name"); + CV_Error(cv::Error::StsNullPtr, "NULL name"); HighguiBridge::getInstance().namedWindow(name); @@ -101,7 +101,7 @@ void destroyWindowImpl(const char* name) CV_FUNCNAME("destroyWindowImpl"); if (!name) - CV_ERROR(CV_StsNullPtr, "NULL name string"); + CV_Error(cv::Error::StsNullPtr, "NULL name string"); HighguiBridge::getInstance().destroyWindow(name); } @@ -119,16 +119,16 @@ int createTrackbar2Impl(const char* trackbar_name, const char* window_name, int pos = 0; if (!window_name || !trackbar_name) - CV_ERROR(CV_StsNullPtr, "NULL window or trackbar name"); + CV_Error(cv::Error::StsNullPtr, "NULL window or trackbar name"); if (count < 0) - CV_ERROR(CV_StsOutOfRange, "Bad trackbar max value"); + CV_Error(cv::Error::StsOutOfRange, "Bad trackbar max value"); CvWindow* window = HighguiBridge::getInstance().namedWindow(window_name); if (!window) { - CV_ERROR(CV_StsNullPtr, "NULL window"); + CV_Error(cv::Error::StsNullPtr, "NULL window"); } window->createSlider(trackbar_name, val, count, on_notify, userdata); @@ -143,7 +143,7 @@ void setTrackbarPosImpl(const char* trackbar_name, const char* window_name, int CvTrackbar* trackbar = 0; if (trackbar_name == 0 || window_name == 0) - CV_ERROR(CV_StsNullPtr, "NULL trackbar or window name"); + CV_Error(cv::Error::StsNullPtr, "NULL trackbar or window name"); CvWindow* window = HighguiBridge::getInstance().findWindowByName(window_name); if (window) @@ -160,7 +160,7 @@ void setTrackbarMaxImpl(const char* trackbar_name, const char* window_name, int if (maxval >= 0) { if (trackbar_name == 0 || window_name == 0) - CV_ERROR(CV_StsNullPtr, "NULL trackbar or window name"); + CV_Error(cv::Error::StsNullPtr, "NULL trackbar or window name"); CvTrackbar* trackbar = HighguiBridge::getInstance().findTrackbarByName(trackbar_name, window_name); @@ -176,7 +176,7 @@ void setTrackbarMinImpl(const char* trackbar_name, const char* window_name, int if (minval >= 0) { if (trackbar_name == 0 || window_name == 0) - CV_ERROR(CV_StsNullPtr, "NULL trackbar or window name"); + CV_Error(cv::Error::StsNullPtr, "NULL trackbar or window name"); CvTrackbar* trackbar = HighguiBridge::getInstance().findTrackbarByName(trackbar_name, window_name); @@ -192,7 +192,7 @@ int getTrackbarPosImpl(const char* trackbar_name, const char* window_name) CV_FUNCNAME("getTrackbarPosImpl"); if (trackbar_name == 0 || window_name == 0) - CV_ERROR(CV_StsNullPtr, "NULL trackbar or window name"); + CV_Error(cv::Error::StsNullPtr, "NULL trackbar or window name"); CvTrackbar* trackbar = HighguiBridge::getInstance().findTrackbarByName(trackbar_name, window_name); @@ -229,7 +229,7 @@ void setMouseCallbackImpl(const char* window_name, CvMouseCallback on_mouse, voi CV_FUNCNAME("setMouseCallbackImpl"); if (!window_name) - CV_ERROR(CV_StsNullPtr, "NULL window name"); + CV_Error(cv::Error::StsNullPtr, "NULL window name"); CvWindow* window = HighguiBridge::getInstance().findWindowByName(window_name); if (!window) @@ -256,5 +256,5 @@ void cvSetModeWindow_WinRT(const char* name, double prop_value) { double cvGetModeWindow_WinRT(const char* name) { CV_WINRT_NO_GUI_ERROR("cvGetModeWindow"); - return CV_StsNotImplemented; + return cv::Error::StsNotImplemented; } diff --git a/modules/imgcodecs/test/test_precomp.hpp b/modules/imgcodecs/test/test_precomp.hpp index 3bd4221dae..7e9a8edd71 100644 --- a/modules/imgcodecs/test/test_precomp.hpp +++ b/modules/imgcodecs/test/test_precomp.hpp @@ -6,7 +6,6 @@ #include "opencv2/ts.hpp" #include "opencv2/imgcodecs.hpp" -#include "opencv2/imgproc/imgproc_c.h" namespace cv { diff --git a/modules/imgproc/include/opencv2/imgproc/imgproc_c.h b/modules/imgproc/include/opencv2/imgproc/imgproc_c.h deleted file mode 100644 index 4b4ccedd2f..0000000000 --- a/modules/imgproc/include/opencv2/imgproc/imgproc_c.h +++ /dev/null @@ -1,48 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// 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*/ - -#ifndef OPENCV_IMGPROC_IMGPROC_C_H -#define OPENCV_IMGPROC_IMGPROC_C_H - -#include "opencv2/imgproc/types_c.h" - -#endif diff --git a/modules/imgproc/include/opencv2/imgproc/types_c.h b/modules/imgproc/include/opencv2/imgproc/types_c.h deleted file mode 100644 index 1c0a17a7e6..0000000000 --- a/modules/imgproc/include/opencv2/imgproc/types_c.h +++ /dev/null @@ -1,48 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// 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*/ - -#ifndef OPENCV_IMGPROC_TYPES_C_H -#define OPENCV_IMGPROC_TYPES_C_H - -#include "opencv2/core/core_c.h" - -#endif diff --git a/modules/imgproc/perf/perf_houghcircles.cpp b/modules/imgproc/perf/perf_houghcircles.cpp index a5ca36dbc0..81b577636b 100644 --- a/modules/imgproc/perf/perf_houghcircles.cpp +++ b/modules/imgproc/perf/perf_houghcircles.cpp @@ -2,7 +2,6 @@ // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. #include "perf_precomp.hpp" -#include "opencv2/imgproc/types_c.h" namespace opencv_test { diff --git a/modules/imgproc/src/_geom.h b/modules/imgproc/src/_geom.h index cdbbfef3cc..6b20bb1a64 100644 --- a/modules/imgproc/src/_geom.h +++ b/modules/imgproc/src/_geom.h @@ -42,6 +42,8 @@ #ifndef _CV_GEOM_H_ #define _CV_GEOM_H_ +#include "opencv2/core/core_c.h" + /* curvature: 0 - 1-curvature, 1 - k-cosine curvature. */ CvSeq* icvApproximateChainTC89( CvChain* chain, int header_size, CvMemStorage* storage, int method ); diff --git a/modules/imgproc/src/approx.cpp b/modules/imgproc/src/approx.cpp index d30437020c..3b6db3bd2e 100644 --- a/modules/imgproc/src/approx.cpp +++ b/modules/imgproc/src/approx.cpp @@ -71,10 +71,10 @@ static void cvStartReadChainPoints( CvChain * chain, CvChainPtReader * reader ) int i; if( !chain || !reader ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( chain->elem_size != 1 || chain->header_size < (int)sizeof(CvChain)) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); cvStartReadSeq( (CvSeq *) chain, (CvSeqReader *) reader, 0 ); @@ -623,7 +623,7 @@ void cv::approxPolyDP( InputArray _curve, OutputArray _approxCurve, //from being used. if (epsilon < 0.0 || !(epsilon < 1e30)) { - CV_Error(CV_StsOutOfRange, "Epsilon not valid."); + CV_Error(cv::Error::StsOutOfRange, "Epsilon not valid."); } Mat curve = _curve.getMat(); @@ -646,7 +646,7 @@ void cv::approxPolyDP( InputArray _curve, OutputArray _approxCurve, else if( depth == CV_32F ) nout = approxPolyDP_(curve.ptr(), npoints, (Point2f*)buf, closed, epsilon, _stack); else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); Mat(nout, 1, CV_MAKETYPE(depth, 2), buf).copyTo(_approxCurve); } diff --git a/modules/imgproc/src/bilateral_filter.dispatch.cpp b/modules/imgproc/src/bilateral_filter.dispatch.cpp index e2a9dcba39..501af5b244 100644 --- a/modules/imgproc/src/bilateral_filter.dispatch.cpp +++ b/modules/imgproc/src/bilateral_filter.dispatch.cpp @@ -422,7 +422,7 @@ void bilateralFilter( InputArray _src, OutputArray _dst, int d, else if( src.depth() == CV_32F ) bilateralFilter_32f( src, dst, d, sigmaColor, sigmaSpace, borderType ); else - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "Bilateral filtering is only implemented for 8u and 32f images" ); } diff --git a/modules/imgproc/src/box_filter.simd.hpp b/modules/imgproc/src/box_filter.simd.hpp index f7c8f66a35..ac0b0f1b56 100644 --- a/modules/imgproc/src/box_filter.simd.hpp +++ b/modules/imgproc/src/box_filter.simd.hpp @@ -1200,7 +1200,7 @@ Ptr getRowSumFilter(int srcType, int sumType, int ksize, int anch if( sdepth == CV_64F && ddepth == CV_64F ) return makePtr >(ksize, anchor); - CV_Error_( CV_StsNotImplemented, + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported combination of source format (=%d), and buffer format (=%d)", srcType, sumType)); } @@ -1241,7 +1241,7 @@ Ptr getColumnSumFilter(int sumType, int dstType, int ksize, in if( ddepth == CV_64F && sdepth == CV_64F ) return makePtr >(ksize, anchor, scale); - CV_Error_( CV_StsNotImplemented, + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported combination of sum format (=%d), and destination format (=%d)", sumType, dstType)); } @@ -1339,7 +1339,7 @@ Ptr getSqrRowSumFilter(int srcType, int sumType, int ksize, int a if( sdepth == CV_64F && ddepth == CV_64F ) return makePtr >(ksize, anchor); - CV_Error_( CV_StsNotImplemented, + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported combination of source format (=%d), and buffer format (=%d)", srcType, sumType)); } diff --git a/modules/imgproc/src/canny.cpp b/modules/imgproc/src/canny.cpp index a4c16c6b8c..1eaa169e2b 100644 --- a/modules/imgproc/src/canny.cpp +++ b/modules/imgproc/src/canny.cpp @@ -844,7 +844,7 @@ void Canny( InputArray _src, OutputArray _dst, } if ((aperture_size & 1) == 0 || (aperture_size != -1 && (aperture_size < 3 || aperture_size > 7))) - CV_Error(CV_StsBadFlag, "Aperture size should be odd between 3 and 7"); + CV_Error(cv::Error::StsBadFlag, "Aperture size should be odd between 3 and 7"); if (aperture_size == 7) { diff --git a/modules/imgproc/src/clahe.cpp b/modules/imgproc/src/clahe.cpp index 677b6a0738..b787378ee3 100644 --- a/modules/imgproc/src/clahe.cpp +++ b/modules/imgproc/src/clahe.cpp @@ -415,7 +415,7 @@ namespace else if (_src.type() == CV_16UC1) calcLutBody = cv::makePtr >(srcForLut, lut_, tileSize, tilesX_, clipLimit, lutScale); else - CV_Error( CV_StsBadArg, "Unsupported type" ); + CV_Error( cv::Error::StsBadArg, "Unsupported type" ); cv::parallel_for_(cv::Range(0, tilesX_ * tilesY_), *calcLutBody); diff --git a/modules/imgproc/src/color.cpp b/modules/imgproc/src/color.cpp index 88bfb1a575..5ef269d2ab 100644 --- a/modules/imgproc/src/color.cpp +++ b/modules/imgproc/src/color.cpp @@ -177,7 +177,7 @@ void cvtColorTwoPlane( InputArray _ysrc, InputArray _uvsrc, OutputArray _dst, in case COLOR_YUV2BGRA_NV21: case COLOR_YUV2RGBA_NV21: case COLOR_YUV2BGRA_NV12: case COLOR_YUV2RGBA_NV12: break; default: - CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); + CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported color conversion code" ); return; } @@ -379,7 +379,7 @@ void cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) cvtColormRGBA2RGBA(_src, _dst); break; default: - CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); + CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported color conversion code" ); } } } //namespace cv diff --git a/modules/imgproc/src/color_yuv.simd.hpp b/modules/imgproc/src/color_yuv.simd.hpp index 03f1b653e5..f80b3d931c 100644 --- a/modules/imgproc/src/color_yuv.simd.hpp +++ b/modules/imgproc/src/color_yuv.simd.hpp @@ -2029,7 +2029,7 @@ void cvtTwoPlaneYUVtoBGR(const uchar * y_data, size_t y_step, const uchar * uv_d case 401: cvtPtr = cvtYUV420sp2RGB<0, 1, 4>; break; case 420: cvtPtr = cvtYUV420sp2RGB<2, 0, 4>; break; case 421: cvtPtr = cvtYUV420sp2RGB<2, 1, 4>; break; - default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + default: CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported color conversion code" ); break; }; cvtPtr(dst_data, dst_step, dst_width, dst_height, y_data, y_step, uv_data, uv_step); @@ -2069,7 +2069,7 @@ void cvtThreePlaneYUVtoBGR(const uchar * src_data, size_t src_step, case 32: cvtPtr = cvtYUV420p2RGB<2, 3>; break; case 40: cvtPtr = cvtYUV420p2RGB<0, 4>; break; case 42: cvtPtr = cvtYUV420p2RGB<2, 4>; break; - default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + default: CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported color conversion code" ); break; }; cvtPtr(dst_data, dst_step, dst_width, dst_height, src_step, src_data, u, v, ustepIdx, vstepIdx); @@ -2139,7 +2139,7 @@ void cvtOnePlaneYUVtoBGR(const uchar * src_data, size_t src_step, case 4200: cvtPtr = cvtYUV422toRGB<2,0,0,4>; break; case 4201: cvtPtr = cvtYUV422toRGB<2,0,1,4>; break; case 4210: cvtPtr = cvtYUV422toRGB<2,1,0,4>; break; - default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + default: CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported color conversion code" ); break; }; cvtPtr(dst_data, dst_step, src_data, src_step, width, height); @@ -2168,7 +2168,7 @@ void cvtOnePlaneBGRtoYUV(const uchar * src_data, size_t src_step, case 4200: cvtPtr = cvtRGBtoYUV422<2,0,0,4>; break; case 4201: cvtPtr = cvtRGBtoYUV422<2,0,1,4>; break; case 4210: cvtPtr = cvtRGBtoYUV422<2,1,0,4>; break; - default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + default: CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported color conversion code" ); break; }; cvtPtr(dst_data, dst_step, src_data, src_step, width, height); diff --git a/modules/imgproc/src/connectedcomponents.cpp b/modules/imgproc/src/connectedcomponents.cpp index a2f4b6e890..d402ea91c3 100644 --- a/modules/imgproc/src/connectedcomponents.cpp +++ b/modules/imgproc/src/connectedcomponents.cpp @@ -5716,7 +5716,7 @@ namespace cv{ } } - CV_Error(CV_StsUnsupportedFormat, "unsupported label/image type"); + CV_Error(cv::Error::StsUnsupportedFormat, "unsupported label/image type"); } } @@ -5738,7 +5738,7 @@ int cv::connectedComponents(InputArray img_, OutputArray _labels, int connectivi return connectedComponents_sub1(img, labels, connectivity, ccltype, sop); } else{ - CV_Error(CV_StsUnsupportedFormat, "the type of labels must be 16u or 32s"); + CV_Error(cv::Error::StsUnsupportedFormat, "the type of labels must be 16u or 32s"); } } @@ -5763,7 +5763,7 @@ int cv::connectedComponentsWithStats(InputArray img_, OutputArray _labels, Outpu return connectedComponents_sub1(img, labels, connectivity, ccltype, sop); } else{ - CV_Error(CV_StsUnsupportedFormat, "the type of labels must be 16u or 32s"); + CV_Error(cv::Error::StsUnsupportedFormat, "the type of labels must be 16u or 32s"); return 0; } } diff --git a/modules/imgproc/src/contours.cpp b/modules/imgproc/src/contours.cpp index 421aeffd5c..f8bb56ded5 100644 --- a/modules/imgproc/src/contours.cpp +++ b/modules/imgproc/src/contours.cpp @@ -40,6 +40,8 @@ //M*/ #include "precomp.hpp" #include "opencv2/core/hal/intrin.hpp" +#include "opencv2/core/types_c.h" +#include "opencv2/core/core_c.h" using namespace cv; @@ -345,19 +347,19 @@ static CvSeq* cvPointSeqFromMat( int seq_kind, const CvArr* arr, CvMat* mat = (CvMat*)arr; if( !CV_IS_MAT( mat )) - CV_Error( CV_StsBadArg, "Input array is not a valid matrix" ); + CV_Error( cv::Error::StsBadArg, "Input array is not a valid matrix" ); if( CV_MAT_CN(mat->type) == 1 && mat->width == 2 ) mat = cvReshape(mat, &hdr, 2); eltype = CV_MAT_TYPE( mat->type ); if( eltype != CV_32SC2 && eltype != CV_32FC2 ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "The matrix can not be converted to point sequence because of " "inappropriate element type" ); if( (mat->width != 1 && mat->height != 1) || !CV_IS_MAT_CONT(mat->type)) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "The matrix converted to point sequence must be " "1-dimensional and continuous" ); @@ -384,7 +386,7 @@ static CvRect cvBoundingRect( CvArr* array, int update ) { ptseq = (CvSeq*)array; if( !CV_IS_SEQ_POINT_SET( ptseq )) - CV_Error( CV_StsBadArg, "Unsupported sequence type" ); + CV_Error( cv::Error::StsBadArg, "Unsupported sequence type" ); if( ptseq->header_size < (int)sizeof(CvContour)) { @@ -403,7 +405,7 @@ static CvRect cvBoundingRect( CvArr* array, int update ) } else if( CV_MAT_TYPE(mat->type) != CV_8UC1 && CV_MAT_TYPE(mat->type) != CV_8SC1 ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "The image/matrix format is not supported by the function" ); update = 0; calculate = 1; @@ -520,7 +522,7 @@ cvStartFindContours_Impl( void* _img, CvMemStorage* storage, int method, CvPoint offset, int needFillBorder ) { if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); CvMat stub, *mat = cvGetMat( _img, &stub ); @@ -529,7 +531,7 @@ cvStartFindContours_Impl( void* _img, CvMemStorage* storage, if( !((CV_IS_MASK_ARR( mat ) && mode < cv::RETR_FLOODFILL) || (CV_MAT_TYPE(mat->type) == CV_32SC1 && mode == cv::RETR_FLOODFILL)) ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "[Start]FindContours supports only CV_8UC1 images when mode != cv::RETR_FLOODFILL " "otherwise supports CV_32SC1 images only" ); @@ -538,10 +540,10 @@ cvStartFindContours_Impl( void* _img, CvMemStorage* storage, uchar* img = (uchar*)(mat->data.ptr); if( method < 0 || method > cv::CHAIN_APPROX_TC89_KCOS ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); if( header_size < (int) (method == cv::CHAIN_CODE ? sizeof( CvChain ) : sizeof( CvContour ))) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); CvContourScanner scanner = (CvContourScanner)cvAlloc( sizeof( *scanner )); memset( scanner, 0, sizeof(*scanner) ); @@ -1207,7 +1209,7 @@ icvFetchContourEx_32s( int* ptr, static CvSeq * cvFindNextContour( CvContourScanner scanner ) { if( !scanner ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); CV_Assert(scanner->img_step >= 0); @@ -1490,7 +1492,7 @@ static CvSeq * cvEndFindContours( CvContourScanner * _scanner ) CvSeq *first = 0; if( !_scanner ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); scanner = *_scanner; if( scanner ) @@ -1571,6 +1573,11 @@ inline int findEndContourPoint(uchar *src_data, CvSize img_size, int j) return j; } +static inline cv::Size cvGetMatSize( const CvMat* mat ) +{ + return cv::Size(mat->cols, mat->rows); +} + static int icvFindContoursInInterval( const CvArr* src, /*int minValue, int maxValue,*/ @@ -1615,13 +1622,13 @@ icvFindContoursInInterval( const CvArr* src, CvSeq* prev = 0; if( !storage ) - CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL storage pointer" ); if( !result ) - CV_Error( CV_StsNullPtr, "NULL double CvSeq pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL double CvSeq pointer" ); if( contourHeaderSize < (int)sizeof(CvContour)) - CV_Error( CV_StsBadSize, "Contour header size must be >= sizeof(CvContour)" ); + CV_Error( cv::Error::StsBadSize, "Contour header size must be >= sizeof(CvContour)" ); storage00.reset(cvCreateChildMemStorage(storage)); storage01.reset(cvCreateChildMemStorage(storage)); @@ -1630,7 +1637,7 @@ icvFindContoursInInterval( const CvArr* src, mat = cvGetMat( src, &stub ); if( !CV_IS_MASK_ARR(mat)) - CV_Error( CV_StsBadArg, "Input array must be 8uC1 or 8sC1" ); + CV_Error( cv::Error::StsBadArg, "Input array must be 8uC1 or 8sC1" ); src_data = mat->data.ptr; img_step = mat->step; img_size = cvGetMatSize(mat); @@ -1922,14 +1929,14 @@ cvFindContours_Impl( void* img, CvMemStorage* storage, int count = -1; if( !firstContour ) - CV_Error( CV_StsNullPtr, "NULL double CvSeq pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL double CvSeq pointer" ); *firstContour = 0; if( method == cv::LINK_RUNS ) { if( offset.x != 0 || offset.y != 0 ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "Nonzero offset is not supported in cv::LINK_RUNS yet" ); count = icvFindContoursInInterval( img, storage, firstContour, cntHeaderSize ); diff --git a/modules/imgproc/src/demosaicing.cpp b/modules/imgproc/src/demosaicing.cpp index 148df552e4..2bfa705b8a 100644 --- a/modules/imgproc/src/demosaicing.cpp +++ b/modules/imgproc/src/demosaicing.cpp @@ -1708,7 +1708,7 @@ void cv::demosaicing(InputArray _src, OutputArray _dst, int code, int dcn) else if( depth == CV_16U ) Bayer2Gray_ >(src, dst, code); else - CV_Error(CV_StsUnsupportedFormat, "Bayer->Gray demosaicing only supports 8u and 16u types"); + CV_Error(cv::Error::StsUnsupportedFormat, "Bayer->Gray demosaicing only supports 8u and 16u types"); break; case COLOR_BayerBG2BGRA: case COLOR_BayerGB2BGRA: case COLOR_BayerRG2BGRA: case COLOR_BayerGR2BGRA: @@ -1735,7 +1735,7 @@ void cv::demosaicing(InputArray _src, OutputArray _dst, int code, int dcn) else if( depth == CV_16U ) Bayer2RGB_ >(src, dst_, code); else - CV_Error(CV_StsUnsupportedFormat, "Bayer->RGB demosaicing only supports 8u and 16u types"); + CV_Error(cv::Error::StsUnsupportedFormat, "Bayer->RGB demosaicing only supports 8u and 16u types"); } else { @@ -1758,11 +1758,11 @@ void cv::demosaicing(InputArray _src, OutputArray _dst, int code, int dcn) else if (depth == CV_16U) Bayer2RGB_EdgeAware_T >(src, dst, code); else - CV_Error(CV_StsUnsupportedFormat, "Bayer->RGB Edge-Aware demosaicing only currently supports 8u and 16u types"); + CV_Error(cv::Error::StsUnsupportedFormat, "Bayer->RGB Edge-Aware demosaicing only currently supports 8u and 16u types"); break; default: - CV_Error( CV_StsBadFlag, "Unknown / unsupported color conversion code" ); + CV_Error( cv::Error::StsBadFlag, "Unknown / unsupported color conversion code" ); } } diff --git a/modules/imgproc/src/deriv.cpp b/modules/imgproc/src/deriv.cpp index 5488141c50..8fa297a841 100644 --- a/modules/imgproc/src/deriv.cpp +++ b/modules/imgproc/src/deriv.cpp @@ -101,7 +101,7 @@ static void getSobelKernels( OutputArray _kx, OutputArray _ky, Mat ky = _ky.getMat(); if( _ksize % 2 == 0 || _ksize > 31 ) - CV_Error( CV_StsOutOfRange, "The kernel size must be odd and not larger than 31" ); + CV_Error( cv::Error::StsOutOfRange, "The kernel size must be odd and not larger than 31" ); std::vector kerI(std::max(ksizeX, ksizeY) + 1); CV_Assert( dx >= 0 && dy >= 0 && dx+dy > 0 ); diff --git a/modules/imgproc/src/distransform.cpp b/modules/imgproc/src/distransform.cpp index 67935e4e5a..c7871cd54c 100755 --- a/modules/imgproc/src/distransform.cpp +++ b/modules/imgproc/src/distransform.cpp @@ -448,7 +448,7 @@ static void getDistanceTransformMask( int maskType, float *metrics ) metrics[2] = 2.1969f; break; default: - CV_Error(CV_StsBadArg, "Unknown metric type"); + CV_Error(cv::Error::StsBadArg, "Unknown metric type"); } } @@ -766,7 +766,7 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labe float _mask[5] = {0}; if( maskSize != cv::DIST_MASK_3 && maskSize != cv::DIST_MASK_5 && maskSize != cv::DIST_MASK_PRECISE ) - CV_Error( CV_StsBadSize, "Mask size should be 3 or 5 or 0 (precise)" ); + CV_Error( cv::Error::StsBadSize, "Mask size should be 3 or 5 or 0 (precise)" ); if ((distType == cv::DIST_C || distType == cv::DIST_L1) && !need_labels) maskSize = cv::DIST_MASK_3; diff --git a/modules/imgproc/src/emd.cpp b/modules/imgproc/src/emd.cpp index 15899c6abe..63fea546b4 100644 --- a/modules/imgproc/src/emd.cpp +++ b/modules/imgproc/src/emd.cpp @@ -176,28 +176,28 @@ static float cvCalcEMD2( const CvArr* signature_arr1, signature2 = cvGetMat( signature2, &sign_stub2 ); if( signature1->cols != signature2->cols ) - CV_Error( CV_StsUnmatchedSizes, "The arrays must have equal number of columns (which is number of dimensions but 1)" ); + CV_Error( cv::Error::StsUnmatchedSizes, "The arrays must have equal number of columns (which is number of dimensions but 1)" ); dims = signature1->cols - 1; size1 = signature1->rows; size2 = signature2->rows; if( !CV_ARE_TYPES_EQ( signature1, signature2 )) - CV_Error( CV_StsUnmatchedFormats, "The array must have equal types" ); + CV_Error( cv::Error::StsUnmatchedFormats, "The array must have equal types" ); if( CV_MAT_TYPE( signature1->type ) != CV_32FC1 ) - CV_Error( CV_StsUnsupportedFormat, "The signatures must be 32fC1" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The signatures must be 32fC1" ); if( flow ) { flow = cvGetMat( flow, &flow_stub ); if( flow->rows != size1 || flow->cols != size2 ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The flow matrix size does not match to the signatures' sizes" ); if( CV_MAT_TYPE( flow->type ) != CV_32FC1 ) - CV_Error( CV_StsUnsupportedFormat, "The flow matrix must be 32fC1" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The flow matrix must be 32fC1" ); } cost->data.fl = 0; @@ -208,28 +208,28 @@ static float cvCalcEMD2( const CvArr* signature_arr1, if( cost_matrix ) { if( dist_func ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "Only one of cost matrix or distance function should be non-NULL in case of user-defined distance" ); if( lower_bound ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "The lower boundary can not be calculated if the cost matrix is used" ); cost = cvGetMat( cost_matrix, &cost_stub ); if( cost->rows != size1 || cost->cols != size2 ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The cost matrix size does not match to the signatures' sizes" ); if( CV_MAT_TYPE( cost->type ) != CV_32FC1 ) - CV_Error( CV_StsUnsupportedFormat, "The cost matrix must be 32fC1" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The cost matrix must be 32fC1" ); } else if( !dist_func ) - CV_Error( CV_StsNullPtr, "In case of user-defined distance Distance function is undefined" ); + CV_Error( cv::Error::StsNullPtr, "In case of user-defined distance Distance function is undefined" ); } else { if( dims == 0 ) - CV_Error( CV_StsBadSize, + CV_Error( cv::Error::StsBadSize, "Number of dimensions can be 0 only if a user-defined metric is used" ); user_param = (void *) (size_t)dims; switch (dist_type) @@ -244,7 +244,7 @@ static float cvCalcEMD2( const CvArr* signature_arr1, dist_func = icvDistC; break; default: - CV_Error( CV_StsBadFlag, "Bad or unsupported metric type" ); + CV_Error( cv::Error::StsBadFlag, "Bad or unsupported metric type" ); } } @@ -281,7 +281,7 @@ static float cvCalcEMD2( const CvArr* signature_arr1, state.ssize, state.dsize, state.enter_x ); if( min_delta == CV_EMD_INF ) - CV_Error( CV_StsNoConv, "" ); + CV_Error( cv::Error::StsNoConv, "" ); /* if no negative deltamin, we found the optimal solution */ if( min_delta >= -eps ) @@ -289,7 +289,7 @@ static float cvCalcEMD2( const CvArr* signature_arr1, /* improve solution */ if(!icvNewSolution( &state )) - CV_Error( CV_StsNoConv, "" ); + CV_Error( cv::Error::StsNoConv, "" ); } } @@ -389,7 +389,7 @@ static int icvInitEMD( const float* signature1, int size1, } else if( weight < 0 ) - CV_Error(CV_StsBadArg, "signature1 must not contain negative weights"); + CV_Error(cv::Error::StsBadArg, "signature1 must not contain negative weights"); } for( i = 0; i < size2; i++ ) @@ -403,13 +403,13 @@ static int icvInitEMD( const float* signature1, int size1, state->idx2[dsize++] = i; } else if( weight < 0 ) - CV_Error(CV_StsBadArg, "signature2 must not contain negative weights"); + CV_Error(cv::Error::StsBadArg, "signature2 must not contain negative weights"); } if( ssize == 0 ) - CV_Error(CV_StsBadArg, "signature1 must contain at least one non-zero value"); + CV_Error(cv::Error::StsBadArg, "signature1 must contain at least one non-zero value"); if( dsize == 0 ) - CV_Error(CV_StsBadArg, "signature2 must contain at least one non-zero value"); + CV_Error(cv::Error::StsBadArg, "signature2 must contain at least one non-zero value"); /* if supply different than the demand, add a zero-cost dummy cluster */ diff = s_sum - d_sum; diff --git a/modules/imgproc/src/filter.simd.hpp b/modules/imgproc/src/filter.simd.hpp index 9306c78a30..21dab519af 100644 --- a/modules/imgproc/src/filter.simd.hpp +++ b/modules/imgproc/src/filter.simd.hpp @@ -3039,7 +3039,7 @@ Ptr getLinearRowFilter( if( sdepth == CV_64F && ddepth == CV_64F ) return makePtr >(kernel, anchor); - CV_Error_( CV_StsNotImplemented, + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported combination of source format (=%d), and buffer format (=%d)", srcType, bufType)); } @@ -3137,7 +3137,7 @@ Ptr getLinearColumnFilter( (kernel, anchor, delta, symmetryType); } - CV_Error_( CV_StsNotImplemented, + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported combination of buffer format (=%d), and destination format (=%d)", bufType, dstType)); } @@ -3291,7 +3291,7 @@ Ptr getLinearFilter( return makePtr, FilterNoVec> >(kernel, anchor, delta); - CV_Error_( CV_StsNotImplemented, + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported combination of source format (=%d), and destination format (=%d)", srcType, dstType)); } diff --git a/modules/imgproc/src/floodfill.cpp b/modules/imgproc/src/floodfill.cpp index 11e44cb95e..3e2f2fcad0 100644 --- a/modules/imgproc/src/floodfill.cpp +++ b/modules/imgproc/src/floodfill.cpp @@ -487,12 +487,12 @@ int cv::floodFill( InputOutputArray _image, InputOutputArray _mask, if ( (cn != 1) && (cn != 3) ) { - CV_Error( CV_StsBadArg, "Number of channels in input image must be 1 or 3" ); + CV_Error( cv::Error::StsBadArg, "Number of channels in input image must be 1 or 3" ); } const int connectivity = flags & 255; if( connectivity != 0 && connectivity != 4 && connectivity != 8 ) - CV_Error( CV_StsBadFlag, "Connectivity must be 4, 0(=4) or 8" ); + CV_Error( cv::Error::StsBadFlag, "Connectivity must be 4, 0(=4) or 8" ); if( _mask.empty() ) { @@ -513,13 +513,13 @@ int cv::floodFill( InputOutputArray _image, InputOutputArray _mask, for( i = 0; i < cn; i++ ) { if( loDiff[i] < 0 || upDiff[i] < 0 ) - CV_Error( CV_StsBadArg, "lo_diff and up_diff must be non-negative" ); + CV_Error( cv::Error::StsBadArg, "lo_diff and up_diff must be non-negative" ); is_simple = is_simple && fabs(loDiff[i]) < DBL_EPSILON && fabs(upDiff[i]) < DBL_EPSILON; } if( (unsigned)seedPoint.x >= (unsigned)size.width || (unsigned)seedPoint.y >= (unsigned)size.height ) - CV_Error( CV_StsOutOfRange, "Seed point is outside of image" ); + CV_Error( cv::Error::StsOutOfRange, "Seed point is outside of image" ); scalarToRawData( newVal, &nv_buf, type, 0); size_t buffer_size = MAX( size.width, size.height ) * 2; @@ -550,7 +550,7 @@ int cv::floodFill( InputOutputArray _image, InputOutputArray _mask, else if( type == CV_32FC3 ) floodFill_CnIR(img, seedPoint, Vec3f(nv_buf.f), &comp, flags, &buffer); else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); if( rect ) *rect = comp.rect; return comp.area; @@ -583,7 +583,7 @@ int cv::floodFill( InputOutputArray _image, InputOutputArray _mask, ud_buf.f[i] = (float)upDiff[i]; } else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); uchar newMaskVal = (uchar)((flags & 0xff00) == 0 ? 1 : ((flags >> 8) & 255)); @@ -618,7 +618,7 @@ int cv::floodFill( InputOutputArray _image, InputOutputArray _mask, Diff32fC3(ld_buf.f, ud_buf.f), &comp, flags, &buffer); else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); if( rect ) *rect = comp.rect; diff --git a/modules/imgproc/src/grabcut.cpp b/modules/imgproc/src/grabcut.cpp index 5ec5af2be4..695c0dd6c5 100644 --- a/modules/imgproc/src/grabcut.cpp +++ b/modules/imgproc/src/grabcut.cpp @@ -96,7 +96,7 @@ GMM::GMM( Mat& _model ) _model.setTo(Scalar(0)); } else if( (_model.type() != CV_64FC1) || (_model.rows != 1) || (_model.cols != modelSize*componentsCount) ) - CV_Error( CV_StsBadArg, "_model must have CV_64FC1 type, rows == 1 and cols == 13*componentsCount" ); + CV_Error( cv::Error::StsBadArg, "_model must have CV_64FC1 type, rows == 1 and cols == 13*componentsCount" ); model = _model; @@ -329,18 +329,18 @@ static void calcNWeights( const Mat& img, Mat& leftW, Mat& upleftW, Mat& upW, Ma static void checkMask( const Mat& img, const Mat& mask ) { if( mask.empty() ) - CV_Error( CV_StsBadArg, "mask is empty" ); + CV_Error( cv::Error::StsBadArg, "mask is empty" ); if( mask.type() != CV_8UC1 ) - CV_Error( CV_StsBadArg, "mask must have CV_8UC1 type" ); + CV_Error( cv::Error::StsBadArg, "mask must have CV_8UC1 type" ); if( mask.cols != img.cols || mask.rows != img.rows ) - CV_Error( CV_StsBadArg, "mask must have as many rows and cols as img" ); + CV_Error( cv::Error::StsBadArg, "mask must have as many rows and cols as img" ); for( int y = 0; y < mask.rows; y++ ) { for( int x = 0; x < mask.cols; x++ ) { uchar val = mask.at(y,x); if( val!=GC_BGD && val!=GC_FGD && val!=GC_PR_BGD && val!=GC_PR_FGD ) - CV_Error( CV_StsBadArg, "mask element value must be equal " + CV_Error( cv::Error::StsBadArg, "mask element value must be equal " "GC_BGD or GC_FGD or GC_PR_BGD or GC_PR_FGD" ); } } @@ -552,9 +552,9 @@ void cv::grabCut( InputArray _img, InputOutputArray _mask, Rect rect, Mat& fgdModel = _fgdModel.getMatRef(); if( img.empty() ) - CV_Error( CV_StsBadArg, "image is empty" ); + CV_Error( cv::Error::StsBadArg, "image is empty" ); if( img.type() != CV_8UC3 ) - CV_Error( CV_StsBadArg, "image must have CV_8UC3 type" ); + CV_Error( cv::Error::StsBadArg, "image must have CV_8UC3 type" ); GMM bgdGMM( bgdModel ), fgdGMM( fgdModel ); Mat compIdxs( img.size(), CV_32SC1 ); diff --git a/modules/imgproc/src/histogram.cpp b/modules/imgproc/src/histogram.cpp index 449909b945..da80cd0738 100644 --- a/modules/imgproc/src/histogram.cpp +++ b/modules/imgproc/src/histogram.cpp @@ -1007,7 +1007,7 @@ void cv::calcHist( const Mat* images, int nimages, const int* channels, else if( depth == CV_32F ) calcHist_(ptrs, deltas, imsize, ihist, dims, ranges, _uniranges, uniform ); else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); ihist.convertTo(hist, CV_32F); } @@ -1184,7 +1184,7 @@ static void calcHist( const Mat* images, int nimages, const int* channels, else if( depth == CV_32F ) calcSparseHist_(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, uniform ); else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); if( !keepInt ) { @@ -1645,7 +1645,7 @@ void cv::calcBackProject( const Mat* images, int nimages, const int* channels, else if( depth == CV_32F ) calcBackProj_(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, (float)scale, uniform ); else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); } @@ -1818,7 +1818,7 @@ void cv::calcBackProject( const Mat* images, int nimages, const int* channels, calcSparseBackProj_(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, (float)scale, uniform ); else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); } #ifdef HAVE_OPENCL @@ -2224,7 +2224,7 @@ double cv::compareHist( InputArray _H1, InputArray _H2, int method ) } } else - CV_Error( CV_StsBadArg, "Unknown comparison method" ); + CV_Error( cv::Error::StsBadArg, "Unknown comparison method" ); } if( method == cv::HISTCMP_CHISQR_ALT ) @@ -2363,7 +2363,7 @@ double cv::compareHist( const SparseMat& H1, const SparseMat& H2, int method ) } } else - CV_Error( CV_StsBadArg, "Unknown comparison method" ); + CV_Error( cv::Error::StsBadArg, "Unknown comparison method" ); if( method == cv::HISTCMP_CHISQR_ALT ) result *= 2; @@ -2379,10 +2379,10 @@ void cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform ) int i, j; if( !ranges ) - CV_Error( CV_StsNullPtr, "NULL ranges pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL ranges pointer" ); if( !CV_IS_HIST(hist) ) - CV_Error( CV_StsBadArg, "Invalid histogram header" ); + CV_Error( cv::Error::StsBadArg, "Invalid histogram header" ); dims = cvGetDims( hist->bins, size ); for( i = 0; i < dims; i++ ) @@ -2393,7 +2393,7 @@ void cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform ) for( i = 0; i < dims; i++ ) { if( !ranges[i] ) - CV_Error( CV_StsNullPtr, "One of elements is NULL" ); + CV_Error( cv::Error::StsNullPtr, "One of elements is NULL" ); hist->thresh[i][0] = ranges[i][0]; hist->thresh[i][1] = ranges[i][1]; } @@ -2417,13 +2417,13 @@ void cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform ) float val0 = -FLT_MAX; if( !ranges[i] ) - CV_Error( CV_StsNullPtr, "One of elements is NULL" ); + CV_Error( cv::Error::StsNullPtr, "One of elements is NULL" ); for( j = 0; j <= size[i]; j++ ) { float val = ranges[i][j]; if( val <= val0 ) - CV_Error(CV_StsOutOfRange, "Bin ranges should go in ascenting order"); + CV_Error(cv::Error::StsOutOfRange, "Bin ranges should go in ascenting order"); val0 = dim_ranges[j] = val; } diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp index d46c66ef8c..4710515f9b 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp @@ -206,7 +206,7 @@ static void initInterTab1D(int method, float* tab, int tabsz) interpolateLanczos4( i*scale, tab ); } else - CV_Error( CV_StsBadArg, "Unknown interpolation method" ); + CV_Error( cv::Error::StsBadArg, "Unknown interpolation method" ); } @@ -223,7 +223,7 @@ static const void* initInterTab2D( int method, bool fixpt ) else if( method == INTER_LANCZOS4 ) tab = Lanczos4Tab_f[0][0], itab = Lanczos4Tab_i[0][0], ksize=8; else - CV_Error( CV_StsBadArg, "Unknown/unsupported interpolation type" ); + CV_Error( cv::Error::StsBadArg, "Unknown/unsupported interpolation type" ); if( !inittab[method] ) { @@ -1502,7 +1502,7 @@ static bool ocl_logPolar(InputArray _src, OutputArray _dst, Point2f center, double M, int flags) { if (M <= 0) - CV_Error(CV_StsOutOfRange, "M should be >0"); + CV_Error(cv::Error::StsOutOfRange, "M should be >0"); UMat src_with_border; // don't scope this variable (it holds image data) UMat mapx, mapy, r, cp_sp; @@ -1649,12 +1649,12 @@ static bool openvx_remap(Mat src, Mat dst, Mat map1, Mat map2, int interpolation } catch (const ivx::RuntimeError & e) { - CV_Error(CV_StsInternal, e.what()); + CV_Error(cv::Error::StsInternal, e.what()); return false; } catch (const ivx::WrapperError & e) { - CV_Error(CV_StsInternal, e.what()); + CV_Error(cv::Error::StsInternal, e.what()); return false; } return true; @@ -1888,7 +1888,7 @@ void cv::remap( InputArray _src, OutputArray _dst, CV_Assert( _src.channels() <= 4 ); } else - CV_Error( CV_StsBadArg, "Unknown interpolation method" ); + CV_Error( cv::Error::StsBadArg, "Unknown interpolation method" ); CV_Assert( ifunc != 0 ); ctab = initInterTab2D( interpolation, fixpt ); } @@ -2236,7 +2236,7 @@ void cv::convertMaps( InputArray _map1, InputArray _map2, } } else - CV_Error( CV_StsNotImplemented, "Unsupported combination of input/output matrices" ); + CV_Error( cv::Error::StsNotImplemented, "Unsupported combination of input/output matrices" ); } } @@ -3610,7 +3610,7 @@ void cv::invertAffineTransform(InputArray _matM, OutputArray __iM) iM[istep] = A21; iM[istep+1] = A22; iM[istep+2] = b2; } else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); } cv::Mat cv::getPerspectiveTransform(InputArray _src, InputArray _dst, int solveMethod) diff --git a/modules/imgproc/src/linefit.cpp b/modules/imgproc/src/linefit.cpp index ca1db9c7d8..c39411d000 100644 --- a/modules/imgproc/src/linefit.cpp +++ b/modules/imgproc/src/linefit.cpp @@ -358,7 +358,7 @@ static void fitLine2D( const Point2f * points, int count, int dist, calc_weights = (void ( * )(float *, int, float *)) _PFP.fp; break;*/ default: - CV_Error(CV_StsBadArg, "Unknown distance type"); + CV_Error(cv::Error::StsBadArg, "Unknown distance type"); } AutoBuffer wr(count*2); @@ -499,7 +499,7 @@ static void fitLine3D( Point3f * points, int count, int dist, break; default: - CV_Error(CV_StsBadArg, "Unknown distance"); + CV_Error(cv::Error::StsBadArg, "Unknown distance"); } AutoBuffer buf(count*2); diff --git a/modules/imgproc/src/matchcontours.cpp b/modules/imgproc/src/matchcontours.cpp index 43dae74eb2..7fcdbd6e43 100644 --- a/modules/imgproc/src/matchcontours.cpp +++ b/modules/imgproc/src/matchcontours.cpp @@ -158,7 +158,7 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou } break; default: - CV_Error( CV_StsBadArg, "Unknown comparison method" ); + CV_Error( cv::Error::StsBadArg, "Unknown comparison method" ); } //If anyA and anyB are both true, the result is correct. diff --git a/modules/imgproc/src/median_blur.simd.hpp b/modules/imgproc/src/median_blur.simd.hpp index 1fe2e4060c..1069d8abab 100644 --- a/modules/imgproc/src/median_blur.simd.hpp +++ b/modules/imgproc/src/median_blur.simd.hpp @@ -867,7 +867,7 @@ void medianBlur(const Mat& src0, /*const*/ Mat& dst, int ksize) else if( src.depth() == CV_32F ) medianBlur_SortNet( src, dst, ksize ); else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); return; } diff --git a/modules/imgproc/src/moments.cpp b/modules/imgproc/src/moments.cpp index 2bca8701f8..ed18e55969 100644 --- a/modules/imgproc/src/moments.cpp +++ b/modules/imgproc/src/moments.cpp @@ -584,7 +584,7 @@ cv::Moments cv::moments( InputArray _src, bool binary ) return contourMoments(mat); if( cn > 1 ) - CV_Error( CV_StsBadArg, "Invalid image type (must be single-channel)" ); + CV_Error( cv::Error::StsBadArg, "Invalid image type (must be single-channel)" ); CV_IPP_RUN(!binary, ipp_moments(mat, m), m); @@ -599,7 +599,7 @@ cv::Moments cv::moments( InputArray _src, bool binary ) else if( depth == CV_64F ) func = momentsInTile; else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); Mat src0(mat); diff --git a/modules/imgproc/src/morph.dispatch.cpp b/modules/imgproc/src/morph.dispatch.cpp index f2dca5aa00..5b5b4dbbc8 100644 --- a/modules/imgproc/src/morph.dispatch.cpp +++ b/modules/imgproc/src/morph.dispatch.cpp @@ -1076,7 +1076,7 @@ static bool ocl_morphologyEx(InputArray _src, OutputArray _dst, int op, return false; break; default: - CV_Error( CV_StsBadArg, "unknown morphological operation" ); + CV_Error( cv::Error::StsBadArg, "unknown morphological operation" ); } return true; @@ -1249,7 +1249,7 @@ void morphologyEx( InputArray _src, OutputArray _dst, int op, } break; default: - CV_Error( CV_StsBadArg, "unknown morphological operation" ); + CV_Error( cv::Error::StsBadArg, "unknown morphological operation" ); } } diff --git a/modules/imgproc/src/morph.simd.hpp b/modules/imgproc/src/morph.simd.hpp index ef813dccec..e93f829daa 100644 --- a/modules/imgproc/src/morph.simd.hpp +++ b/modules/imgproc/src/morph.simd.hpp @@ -753,7 +753,7 @@ Ptr getMorphologyRowFilter(int op, int type, int ksize, int ancho DilateRowVec64f> >(ksize, anchor); } - CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type)); + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported data type (=%d)", type)); } Ptr getMorphologyColumnFilter(int op, int type, int ksize, int anchor) @@ -801,7 +801,7 @@ Ptr getMorphologyColumnFilter(int op, int type, int ksize, int DilateColumnVec64f> >(ksize, anchor); } - CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type)); + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported data type (=%d)", type)); } Ptr getMorphologyFilter(int op, int type, const Mat& kernel, Point anchor) @@ -838,7 +838,7 @@ Ptr getMorphologyFilter(int op, int type, const Mat& kernel, Point a return makePtr, DilateVec64f> >(kernel, anchor); } - CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type)); + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported data type (=%d)", type)); } #endif diff --git a/modules/imgproc/src/precomp.hpp b/modules/imgproc/src/precomp.hpp index a72d2a4d2a..68d41f8c7e 100644 --- a/modules/imgproc/src/precomp.hpp +++ b/modules/imgproc/src/precomp.hpp @@ -46,7 +46,6 @@ #include "opencv2/imgproc.hpp" #include "opencv2/core/utility.hpp" -#include "opencv2/imgproc/imgproc_c.h" #include "opencv2/core/private.hpp" #include "opencv2/core/ocl.hpp" #include "opencv2/core/hal/hal.hpp" @@ -112,7 +111,7 @@ inline bool isStorageOrMat(void * arr) return true; else if (CV_IS_MAT( arr )) return false; - CV_Error( CV_StsBadArg, "Destination is not CvMemStorage* nor CvMat*" ); + CV_Error( cv::Error::StsBadArg, "Destination is not CvMemStorage* nor CvMat*" ); } diff --git a/modules/imgproc/src/pyramids.cpp b/modules/imgproc/src/pyramids.cpp index 0e65a81278..9b810d464f 100644 --- a/modules/imgproc/src/pyramids.cpp +++ b/modules/imgproc/src/pyramids.cpp @@ -1448,7 +1448,7 @@ void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borde else if( depth == CV_64F ) func = pyrDown_< FltCast >; else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); func( src, dst, borderType ); } @@ -1551,7 +1551,7 @@ void cv::pyrUp( InputArray _src, OutputArray _dst, const Size& _dsz, int borderT else if( depth == CV_64F ) func = pyrUp_< FltCast >; else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); func( src, dst, borderType ); } diff --git a/modules/imgproc/src/resize.cpp b/modules/imgproc/src/resize.cpp index 6b6f74506f..49914ad415 100644 --- a/modules/imgproc/src/resize.cpp +++ b/modules/imgproc/src/resize.cpp @@ -4024,7 +4024,7 @@ void resize(int src_type, else if( interpolation == INTER_LINEAR || interpolation == INTER_AREA ) ksize = 2, func = linear_tab[depth]; else - CV_Error( CV_StsBadArg, "Unknown interpolation method" ); + CV_Error( cv::Error::StsBadArg, "Unknown interpolation method" ); ksize2 = ksize/2; CV_Assert( func != 0 ); diff --git a/modules/imgproc/src/rotcalipers.cpp b/modules/imgproc/src/rotcalipers.cpp index 7594975ba6..3866279706 100644 --- a/modules/imgproc/src/rotcalipers.cpp +++ b/modules/imgproc/src/rotcalipers.cpp @@ -245,7 +245,7 @@ static void rotatingCalipers( const Point2f* points, int n, int mode, float* out base_b = lead_x; break; default: - CV_Error(CV_StsError, "main_element should be 0, 1, 2 or 3"); + CV_Error(cv::Error::StsError, "main_element should be 0, 1, 2 or 3"); } } /* change base point of main edge */ diff --git a/modules/imgproc/src/samplers.cpp b/modules/imgproc/src/samplers.cpp index d741017407..662284fb2c 100644 --- a/modules/imgproc/src/samplers.cpp +++ b/modules/imgproc/src/samplers.cpp @@ -325,5 +325,5 @@ void cv::getRectSubPix( InputArray _image, Size patchSize, Point2f center, getRectSubPix_Cn_, nop > (image.ptr(), image.step, image.size(), patch.ptr(), patch.step, patch.size(), center, cn); else - CV_Error( CV_StsUnsupportedFormat, "Unsupported combination of input and output formats"); + CV_Error( cv::Error::StsUnsupportedFormat, "Unsupported combination of input and output formats"); } diff --git a/modules/imgproc/src/segmentation.cpp b/modules/imgproc/src/segmentation.cpp index 00f2a00937..2ff69f1193 100644 --- a/modules/imgproc/src/segmentation.cpp +++ b/modules/imgproc/src/segmentation.cpp @@ -348,7 +348,7 @@ void cv::pyrMeanShiftFiltering( InputArray _src, OutputArray _dst, const int MAX_LEVELS = 8; if( (unsigned)max_level > (unsigned)MAX_LEVELS ) - CV_Error( CV_StsOutOfRange, "The number of pyramid levels is too large or negative" ); + CV_Error( cv::Error::StsOutOfRange, "The number of pyramid levels is too large or negative" ); std::vector src_pyramid(max_level+1); std::vector dst_pyramid(max_level+1); @@ -365,13 +365,13 @@ void cv::pyrMeanShiftFiltering( InputArray _src, OutputArray _dst, if( src0.type() != CV_8UC3 ) - CV_Error( CV_StsUnsupportedFormat, "Only 8-bit, 3-channel images are supported" ); + CV_Error( cv::Error::StsUnsupportedFormat, "Only 8-bit, 3-channel images are supported" ); if( src0.type() != dst0.type() ) - CV_Error( CV_StsUnmatchedFormats, "The input and output images must have the same type" ); + CV_Error( cv::Error::StsUnmatchedFormats, "The input and output images must have the same type" ); if( src0.size() != dst0.size() ) - CV_Error( CV_StsUnmatchedSizes, "The input and output images must have the same size" ); + CV_Error( cv::Error::StsUnmatchedSizes, "The input and output images must have the same size" ); if( !(termcrit.type & CV_TERMCRIT_ITER) ) termcrit.maxCount = 5; diff --git a/modules/imgproc/src/shapedescr.cpp b/modules/imgproc/src/shapedescr.cpp index 6681410dfb..f1df8df27b 100644 --- a/modules/imgproc/src/shapedescr.cpp +++ b/modules/imgproc/src/shapedescr.cpp @@ -357,7 +357,7 @@ static RotatedRect fitEllipseNoDirect( InputArray _points ) RotatedRect box; if( n < 5 ) - CV_Error( CV_StsBadSize, "There should be at least 5 points to fit the ellipse" ); + CV_Error( cv::Error::StsBadSize, "There should be at least 5 points to fit the ellipse" ); // New fitellipse algorithm, contributed by Dr. Daniel Weiss Point2f c(0,0); @@ -520,7 +520,7 @@ cv::RotatedRect cv::fitEllipseAMS( InputArray _points ) RotatedRect box; if( n < 5 ) - CV_Error( CV_StsBadSize, "There should be at least 5 points to fit the ellipse" ); + CV_Error( cv::Error::StsBadSize, "There should be at least 5 points to fit the ellipse" ); Point2f c(0,0); @@ -705,7 +705,7 @@ cv::RotatedRect cv::fitEllipseDirect( InputArray _points ) RotatedRect box; if( n < 5 ) - CV_Error( CV_StsBadSize, "There should be at least 5 points to fit the ellipse" ); + CV_Error( cv::Error::StsBadSize, "There should be at least 5 points to fit the ellipse" ); Point2d c(0., 0.); diff --git a/modules/imgproc/src/subdivision2d.cpp b/modules/imgproc/src/subdivision2d.cpp index 24075ac6eb..2a2ab1dfeb 100644 --- a/modules/imgproc/src/subdivision2d.cpp +++ b/modules/imgproc/src/subdivision2d.cpp @@ -282,10 +282,10 @@ int Subdiv2D::locate(Point2f pt, int& _edge, int& _vertex) int i, maxEdges = (int)(qedges.size() * 4); if( qedges.size() < (size_t)4 ) - CV_Error( CV_StsError, "Subdivision is empty" ); + CV_Error( cv::Error::StsError, "Subdivision is empty" ); if( pt.x < topLeft.x || pt.y < topLeft.y || pt.x >= bottomRight.x || pt.y >= bottomRight.y ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); int edge = recentEdge; CV_Assert(edge > 0); @@ -417,10 +417,10 @@ int Subdiv2D::insert(Point2f pt) int location = locate( pt, curr_edge, curr_point ); if( location == PTLOC_ERROR ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); if( location == PTLOC_OUTSIDE_RECT ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); if( location == PTLOC_VERTEX ) return curr_point; @@ -434,7 +434,7 @@ int Subdiv2D::insert(Point2f pt) else if( location == PTLOC_INSIDE ) ; else - CV_Error_(CV_StsError, ("Subdiv2D::locate returned invalid location = %d", location) ); + CV_Error_(cv::Error::StsError, ("Subdiv2D::locate returned invalid location = %d", location) ); CV_Assert( curr_edge != 0 ); validGeometry = false; diff --git a/modules/imgproc/src/templmatch.cpp b/modules/imgproc/src/templmatch.cpp index a6e5ed4447..7b394c23ec 100644 --- a/modules/imgproc/src/templmatch.cpp +++ b/modules/imgproc/src/templmatch.cpp @@ -145,7 +145,7 @@ void ConvolveBuf::create(Size image_size, Size templ_size) dft_size.width = std::max(getOptimalDFTSize(block_size.width + templ_size.width - 1), 2); dft_size.height = getOptimalDFTSize(block_size.height + templ_size.height - 1); if( dft_size.width <= 0 || dft_size.height <= 0 ) - CV_Error( CV_StsOutOfRange, "the input arrays are too big" ); + CV_Error( cv::Error::StsOutOfRange, "the input arrays are too big" ); // recompute block size block_size.width = dft_size.width - templ_size.width + 1; @@ -602,7 +602,7 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr, dftsize.width = std::max(getOptimalDFTSize(blocksize.width + templ.cols - 1), 2); dftsize.height = getOptimalDFTSize(blocksize.height + templ.rows - 1); if( dftsize.width <= 0 || dftsize.height <= 0 ) - CV_Error( CV_StsOutOfRange, "the input arrays are too big" ); + CV_Error( cv::Error::StsOutOfRange, "the input arrays are too big" ); // recompute block size blocksize.width = dftsize.width - templ.cols + 1; diff --git a/modules/imgproc/src/thresh.cpp b/modules/imgproc/src/thresh.cpp index b2a4661772..f1c1b1069a 100644 --- a/modules/imgproc/src/thresh.cpp +++ b/modules/imgproc/src/thresh.cpp @@ -117,7 +117,7 @@ static void threshGeneric(Size roi, const T* src, size_t src_step, T* dst, return; default: - CV_Error( CV_StsBadArg, "" ); return; + CV_Error( cv::Error::StsBadArg, "" ); return; } } @@ -719,7 +719,7 @@ thresh_16s( const Mat& _src, Mat& _dst, short thresh, short maxval, int type ) } break; default: - CV_Error( CV_StsBadArg, "" ); return; + CV_Error( cv::Error::StsBadArg, "" ); return; } #else threshGeneric(roi, src, src_step, dst, dst_step, thresh, maxval, type); @@ -925,7 +925,7 @@ thresh_32f( const Mat& _src, Mat& _dst, float thresh, float maxval, int type ) } break; default: - CV_Error( CV_StsBadArg, "" ); return; + CV_Error( cv::Error::StsBadArg, "" ); return; } #else threshGeneric(roi, src, src_step, dst, dst_step, thresh, maxval, type); @@ -1096,7 +1096,7 @@ thresh_64f(const Mat& _src, Mat& _dst, double thresh, double maxval, int type) } break; default: - CV_Error(CV_StsBadArg, ""); return; + CV_Error(cv::Error::StsBadArg, ""); return; } #else threshGeneric(roi, src, src_step, dst, dst_step, thresh, maxval, type); @@ -1656,7 +1656,7 @@ double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double m else if( src.depth() == CV_64F ) ; else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); parallel_for_(Range(0, dst.rows), ThresholdRunner(src, dst, thresh, maxval, type), @@ -1704,7 +1704,7 @@ void cv::adaptiveThreshold( InputArray _src, OutputArray _dst, double maxValue, meanfloat.convertTo(mean, src.type()); } else - CV_Error( CV_StsBadFlag, "Unknown/unsupported adaptive threshold method" ); + CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported adaptive threshold method" ); int i, j; uchar imaxval = saturate_cast(maxValue); @@ -1718,7 +1718,7 @@ void cv::adaptiveThreshold( InputArray _src, OutputArray _dst, double maxValue, for( i = 0; i < 768; i++ ) tab[i] = (uchar)(i - 255 <= -idelta ? imaxval : 0); else - CV_Error( CV_StsBadFlag, "Unknown/unsupported threshold type" ); + CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported threshold type" ); if( src.isContinuous() && mean.isContinuous() && dst.isContinuous() ) { diff --git a/modules/imgproc/test/test_canny.cpp b/modules/imgproc/test/test_canny.cpp index 7e4fffbf30..be46efe7b9 100644 --- a/modules/imgproc/test/test_canny.cpp +++ b/modules/imgproc/test/test_canny.cpp @@ -40,6 +40,7 @@ //M*/ #include "test_precomp.hpp" +#include "opencv2/core/core_c.h" namespace opencv_test { namespace { @@ -290,7 +291,7 @@ 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); + double err = cvtest::norm(test_mat[OUTPUT][0], test_mat[REF_OUTPUT][0], NORM_L1); if( err == 0 ) return code; @@ -301,7 +302,7 @@ int CV_CannyTest::validate_test_results( int test_case_idx ) return code; } - nz0 = cvRound(cvtest::norm(test_mat[REF_OUTPUT][0], CV_L1)/255); + nz0 = cvRound(cvtest::norm(test_mat[REF_OUTPUT][0], NORM_L1)/255); err = (err/255/MAX(nz0,100))*100; if( err > 1 ) { diff --git a/modules/imgproc/test/test_color.cpp b/modules/imgproc/test/test_color.cpp index 5a4ee5efbb..d4ff3c387e 100644 --- a/modules/imgproc/test/test_color.cpp +++ b/modules/imgproc/test/test_color.cpp @@ -40,6 +40,7 @@ //M*/ #include "test_precomp.hpp" +#include "opencv2/core/core_c.h" namespace opencv_test { namespace { @@ -1810,7 +1811,7 @@ void CV_ColorBayerTest::prepare_to_validation( int /*test_case_idx*/ ) else if( depth == CV_16U ) bayer2BGR_(src, dst, fwd_code); else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); } diff --git a/modules/imgproc/test/test_convhull.cpp b/modules/imgproc/test/test_convhull.cpp index dfb2e34d3a..1697ced954 100644 --- a/modules/imgproc/test/test_convhull.cpp +++ b/modules/imgproc/test/test_convhull.cpp @@ -40,6 +40,7 @@ //M*/ #include "test_precomp.hpp" +#include "opencv2/core/core_c.h" namespace opencv_test { namespace { diff --git a/modules/imgproc/test/test_filter.cpp b/modules/imgproc/test/test_filter.cpp index 242b0d3a9a..12fa2164cf 100644 --- a/modules/imgproc/test/test_filter.cpp +++ b/modules/imgproc/test/test_filter.cpp @@ -40,6 +40,7 @@ //M*/ #include "test_precomp.hpp" +#include "opencv2/core/core_c.h" namespace opencv_test { namespace { diff --git a/modules/imgproc/test/test_imgwarp.cpp b/modules/imgproc/test/test_imgwarp.cpp index ce7741e1db..4a17abd36d 100644 --- a/modules/imgproc/test/test_imgwarp.cpp +++ b/modules/imgproc/test/test_imgwarp.cpp @@ -40,6 +40,7 @@ //M*/ #include "test_precomp.hpp" +#include "opencv2/core/core_c.h" namespace opencv_test { namespace { diff --git a/modules/imgproc/test/test_pc.cpp b/modules/imgproc/test/test_pc.cpp index 9e2c7f5b82..6dd7eb987b 100644 --- a/modules/imgproc/test/test_pc.cpp +++ b/modules/imgproc/test/test_pc.cpp @@ -41,6 +41,7 @@ //M*/ #include "test_precomp.hpp" +#include "opencv2/core/core_c.h" namespace opencv_test { namespace { diff --git a/modules/imgproc/test/test_precomp.hpp b/modules/imgproc/test/test_precomp.hpp index ce51009145..11f9e36b9c 100644 --- a/modules/imgproc/test/test_precomp.hpp +++ b/modules/imgproc/test/test_precomp.hpp @@ -6,7 +6,6 @@ #include "opencv2/ts.hpp" #include "opencv2/imgproc.hpp" -#include "opencv2/imgproc/imgproc_c.h" #include "opencv2/core/private.hpp" diff --git a/modules/imgproc/test/test_templmatch.cpp b/modules/imgproc/test/test_templmatch.cpp index 93a1cdb5e8..0eb7e57940 100644 --- a/modules/imgproc/test/test_templmatch.cpp +++ b/modules/imgproc/test/test_templmatch.cpp @@ -40,6 +40,7 @@ //M*/ #include "test_precomp.hpp" +#include "opencv2/core/core_c.h" namespace opencv_test { namespace { diff --git a/modules/photo/src/inpaint.cpp b/modules/photo/src/inpaint.cpp index b436168212..3206770830 100644 --- a/modules/photo/src/inpaint.cpp +++ b/modules/photo/src/inpaint.cpp @@ -46,7 +46,7 @@ // */ #include "precomp.hpp" -#include "opencv2/imgproc/imgproc_c.h" +#include "opencv2/core/core_c.h" #include "opencv2/photo/legacy/constants_c.h" #undef CV_MAT_ELEM_PTR_FAST @@ -753,18 +753,18 @@ icvInpaint( const CvArr* _input_img, const CvArr* _inpaint_mask, CvArr* _output_ output_img = cvGetMat( _output_img, &output_hdr ); if( !CV_ARE_SIZES_EQ(input_img,output_img) || !CV_ARE_SIZES_EQ(input_img,inpaint_mask)) - CV_Error( CV_StsUnmatchedSizes, "All the input and output images must have the same size" ); + CV_Error( cv::Error::StsUnmatchedSizes, "All the input and output images must have the same size" ); if( (CV_MAT_TYPE(input_img->type) != CV_8U && CV_MAT_TYPE(input_img->type) != CV_16U && CV_MAT_TYPE(input_img->type) != CV_32F && CV_MAT_TYPE(input_img->type) != CV_8UC3) || !CV_ARE_TYPES_EQ(input_img,output_img) ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "8-bit, 16-bit unsigned or 32-bit float 1-channel and 8-bit 3-channel input/output images are supported" ); if( CV_MAT_TYPE(inpaint_mask->type) != CV_8UC1 ) - CV_Error( CV_StsUnsupportedFormat, "The mask must be 8-bit 1-channel image" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The mask must be 8-bit 1-channel image" ); range = MAX(range,1); range = MIN(range,100); diff --git a/modules/stitching/src/motion_estimators.cpp b/modules/stitching/src/motion_estimators.cpp index be4a5fb4ce..f6800b645a 100644 --- a/modules/stitching/src/motion_estimators.cpp +++ b/modules/stitching/src/motion_estimators.cpp @@ -947,7 +947,7 @@ void waveCorrect(std::vector &rmats, WaveCorrectKind kind) else if (kind == WAVE_CORRECT_VERT) rg1 = eigen_vecs.row(0).t(); else - CV_Error(CV_StsBadArg, "unsupported kind of wave correction"); + CV_Error(cv::Error::StsBadArg, "unsupported kind of wave correction"); Mat img_k = Mat::zeros(3, 1, CV_32F); for (size_t i = 0; i < rmats.size(); ++i) diff --git a/modules/ts/include/opencv2/ts/ocl_test.hpp b/modules/ts/include/opencv2/ts/ocl_test.hpp index d5b4616059..4149962155 100644 --- a/modules/ts/include/opencv2/ts/ocl_test.hpp +++ b/modules/ts/include/opencv2/ts/ocl_test.hpp @@ -48,7 +48,6 @@ #include "opencv2/videoio.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" -#include "opencv2/imgproc/types_c.h" #include "opencv2/core/ocl.hpp" namespace cvtest { diff --git a/modules/ts/src/ts.cpp b/modules/ts/src/ts.cpp index eb6932499f..781ffc02f4 100644 --- a/modules/ts/src/ts.cpp +++ b/modules/ts/src/ts.cpp @@ -643,7 +643,7 @@ void TS::update_context( BaseTest* test, int test_case_idx, bool update_ts_conte current_test_info.test = test; current_test_info.test_case_idx = test_case_idx; current_test_info.code = 0; - cvSetErrStatus( CV_StsOk ); + cvSetErrStatus( cv::Error::StsOk ); } diff --git a/modules/ts/src/ts_func.cpp b/modules/ts/src/ts_func.cpp index 706c7cfb1f..bc88801cc9 100644 --- a/modules/ts/src/ts_func.cpp +++ b/modules/ts/src/ts_func.cpp @@ -1,7 +1,6 @@ #include "precomp.hpp" #include #include -#include "opencv2/imgproc/types_c.h" using namespace cv; @@ -407,7 +406,7 @@ void convert(const Mat& src, cv::OutputArray _dst, convertTo((const cv::bfloat16_t*)sptr, dptr, dtype, total, alpha, beta); break; default: - CV_Error(CV_StsNotImplemented, "unknown/unsupported depth"); + CV_Error(cv::Error::StsNotImplemented, "unknown/unsupported depth"); } } } diff --git a/modules/videoio/src/cap_mjpeg_encoder.cpp b/modules/videoio/src/cap_mjpeg_encoder.cpp index 2e7452cf17..2bb01f4a81 100644 --- a/modules/videoio/src/cap_mjpeg_encoder.cpp +++ b/modules/videoio/src/cap_mjpeg_encoder.cpp @@ -95,7 +95,7 @@ static bool createEncodeHuffmanTable( const int* src, unsigned* table, int max_s if( size > max_size ) { - CV_Error(CV_StsOutOfRange, "too big maximum Huffman code size"); + CV_Error(cv::Error::StsOutOfRange, "too big maximum Huffman code size"); } memset( table, 0, size*sizeof(table[0])); @@ -487,7 +487,7 @@ public: colorspace = COLORSPACE_YUV444P; } else - CV_Error(CV_StsBadArg, "Invalid combination of specified video colorspace and the input image colorspace"); + CV_Error(cv::Error::StsBadArg, "Invalid combination of specified video colorspace and the input image colorspace"); if( !rawstream ) { int avi_index = container.getAVIIndex(0, dc); diff --git a/modules/videoio/src/cap_msmf.cpp b/modules/videoio/src/cap_msmf.cpp index 93545c615e..d4afa23440 100644 --- a/modules/videoio/src/cap_msmf.cpp +++ b/modules/videoio/src/cap_msmf.cpp @@ -707,7 +707,7 @@ public: if (FAILED(MFCreateAttributes(&attr, 1)) || FAILED(attr->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, sourceType))) { - CV_Error(CV_StsError, "Failed to create attributes"); + CV_Error(cv::Error::StsError, "Failed to create attributes"); } if (FAILED(MFEnumDeviceSources(attr.Get(), &devices, &count))) { @@ -961,14 +961,14 @@ _ComPtr CvCapture_MSMF::getDefaultSourceConfig(UINT32 num) FAILED(res->SetUINT32(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, true)) ) { - CV_Error(CV_StsError, "Failed to create attributes"); + CV_Error(cv::Error::StsError, "Failed to create attributes"); } #ifdef HAVE_MSMF_DXVA if (D3DMgr) { if (FAILED(res->SetUnknown(MF_SOURCE_READER_D3D_MANAGER, D3DMgr.Get()))) { - CV_Error(CV_StsError, "Failed to create attributes"); + CV_Error(cv::Error::StsError, "Failed to create attributes"); } } #endif diff --git a/modules/videoio/src/cap_openni2.cpp b/modules/videoio/src/cap_openni2.cpp index 034509cdf7..214cc1a559 100644 --- a/modules/videoio/src/cap_openni2.cpp +++ b/modules/videoio/src/cap_openni2.cpp @@ -90,7 +90,7 @@ private: openni::Status status = openni::OpenNI::initialize(); if (status != openni::STATUS_OK) { - CV_Error(CV_StsError, std::string("Failed to initialize:") + openni::OpenNI::getExtendedError()); + CV_Error(cv::Error::StsError, std::string("Failed to initialize:") + openni::OpenNI::getExtendedError()); } } @@ -274,7 +274,7 @@ CvCapture_OpenNI2::CvCapture_OpenNI2(int index, const char * filename) : deviceURI = ldevs[index].getUri(); else { - CV_Error(CV_StsError, "OpenCVKinect2: Device index exceeds the number of available OpenNI devices"); + CV_Error(cv::Error::StsError, "OpenCVKinect2: Device index exceeds the number of available OpenNI devices"); } } } @@ -287,7 +287,7 @@ CvCapture_OpenNI2::CvCapture_OpenNI2(int index, const char * filename) : status = device.open(deviceURI); if (status != openni::STATUS_OK) { - CV_Error(CV_StsError, std::string("OpenCVKinect2: Failed to open device: ") + openni::OpenNI::getExtendedError()); + CV_Error(cv::Error::StsError, std::string("OpenCVKinect2: Failed to open device: ") + openni::OpenNI::getExtendedError()); } toggleStream(CV_DEPTH_STREAM, true); @@ -361,7 +361,7 @@ void CvCapture_OpenNI2::toggleStream(int stream, bool toggle) if (status != openni::STATUS_OK) { streams[stream].destroy(); - CV_Error(CV_StsError, std::string("OpenCVKinect2 : Couldn't set ") + + CV_Error(cv::Error::StsError, std::string("OpenCVKinect2 : Couldn't set ") + stream_names[stream] + std::string(" stream output mode: ") + std::string(openni::OpenNI::getExtendedError())); } @@ -373,14 +373,14 @@ void CvCapture_OpenNI2::toggleStream(int stream, bool toggle) if (status != openni::STATUS_OK) { streams[stream].destroy(); - CV_Error(CV_StsError, std::string("CvCapture_OpenNI2::CvCapture_OpenNI2 : Couldn't start ") + + CV_Error(cv::Error::StsError, std::string("CvCapture_OpenNI2::CvCapture_OpenNI2 : Couldn't start ") + stream_names[stream] + std::string(" stream: ") + std::string(openni::OpenNI::getExtendedError())); } } else { - CV_Error(CV_StsError, std::string("CvCapture_OpenNI2::CvCapture_OpenNI2 : Couldn't find ") + + CV_Error(cv::Error::StsError, std::string("CvCapture_OpenNI2::CvCapture_OpenNI2 : Couldn't find ") + stream_names[stream] + " stream: " + std::string(openni::OpenNI::getExtendedError())); } @@ -1026,7 +1026,7 @@ inline void getBGRImageFromMetaData( const openni::VideoFrameRef& imageMetaData, { cv::Mat bufferImage; if( imageMetaData.getVideoMode().getPixelFormat() != openni::PIXEL_FORMAT_RGB888 ) - CV_Error( CV_StsUnsupportedFormat, "Unsupported format of grabbed image." ); + CV_Error( cv::Error::StsUnsupportedFormat, "Unsupported format of grabbed image." ); bgrImage.create(imageMetaData.getHeight(), imageMetaData.getWidth(), CV_8UC3); bufferImage.create(imageMetaData.getHeight(), imageMetaData.getWidth(), CV_8UC3); @@ -1049,7 +1049,7 @@ inline void getGrayImageFromMetaData(const openni::VideoFrameRef& imageMetaData, } else { - CV_Error(CV_StsUnsupportedFormat, "Unsupported format of grabbed image."); + CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported format of grabbed image."); } } diff --git a/modules/videoio/src/precomp.hpp b/modules/videoio/src/precomp.hpp index 737073706f..c03673610a 100644 --- a/modules/videoio/src/precomp.hpp +++ b/modules/videoio/src/precomp.hpp @@ -74,7 +74,6 @@ #include "opencv2/imgcodecs.hpp" #include "opencv2/imgproc.hpp" -#include "opencv2/imgproc/imgproc_c.h" #include "opencv2/videoio/videoio_c.h" #include