From 893fb90b87a93a68022e5af8d1f4e1cf53948a79 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Fri, 29 Oct 2010 13:09:49 +0000 Subject: [PATCH] extended Python bindings; not merged into cv.cpp yet; and many of the helper functions, like pyopencv_to_*, pyopencv_from_* etc. are still missing --- modules/core/include/opencv2/core/core.hpp | 8 +- .../imgproc/include/opencv2/imgproc/imgproc.hpp | 10 +- modules/ml/include/opencv2/ml/ml.hpp | 428 ++++++------- modules/python/gen2.py | 689 +++++++++++++++++++++ modules/python/hdr_parser.py | 216 +++++-- modules/python/opencv2x.h | 356 +++++++++++ modules/video/include/opencv2/video/tracking.hpp | 4 +- 7 files changed, 1433 insertions(+), 278 deletions(-) create mode 100644 modules/python/gen2.py create mode 100644 modules/python/opencv2x.h diff --git a/modules/core/include/opencv2/core/core.hpp b/modules/core/include/opencv2/core/core.hpp index 00bde78..2361387 100644 --- a/modules/core/include/opencv2/core/core.hpp +++ b/modules/core/include/opencv2/core/core.hpp @@ -2202,11 +2202,11 @@ public: SVD& operator ()( const Mat& src, int flags=0 ); //! decomposes matrix and stores the results to user-provided matrices - CV_WRAP_AS(SVDecomp) static void compute( const Mat& src, CV_OUT Mat& w, CV_OUT Mat& u, CV_OUT Mat& vt, int flags=0 ); + static void compute( const Mat& src, CV_OUT Mat& w, CV_OUT Mat& u, CV_OUT Mat& vt, int flags=0 ); //! computes singular values of a matrix - CV_WRAP_AS(SVDecomp) static void compute( const Mat& src, CV_OUT Mat& w, int flags=0 ); + static void compute( const Mat& src, CV_OUT Mat& w, int flags=0 ); //! performs back substitution - CV_WRAP_AS(SVBackSubst) static void backSubst( const Mat& w, const Mat& u, const Mat& vt, + static void backSubst( const Mat& w, const Mat& u, const Mat& vt, const Mat& rhs, CV_OUT Mat& dst ); template static void compute( const Matx<_Tp, m, n>& a, @@ -3757,7 +3757,7 @@ public: void writeObj( const string& name, const void* obj ); //! returns the normalized object name for the specified file name - CV_WRAP static string getDefaultObjectName(const string& filename); + static string getDefaultObjectName(const string& filename); Ptr fs; //!< the underlying C FileStorage structure string elname; //!< the currently written element diff --git a/modules/imgproc/include/opencv2/imgproc/imgproc.hpp b/modules/imgproc/include/opencv2/imgproc/imgproc.hpp index ab0d54f..85c0bf8 100644 --- a/modules/imgproc/include/opencv2/imgproc/imgproc.hpp +++ b/modules/imgproc/include/opencv2/imgproc/imgproc.hpp @@ -565,15 +565,15 @@ CV_EXPORTS_AS(integral2) void integral( const Mat& src, CV_OUT Mat& sum, CV_OUT CV_EXPORTS_AS(integral3) void integral( const Mat& src, CV_OUT Mat& sum, CV_OUT Mat& sqsum, CV_OUT Mat& tilted, int sdepth=-1 ); //! adds image to the accumulator (dst += src). Unlike cv::add, dst and src can have different types. -CV_EXPORTS_W void accumulate( const Mat& src, CV_OUT Mat& dst, const Mat& mask=Mat() ); +CV_EXPORTS_W void accumulate( const Mat& src, CV_IN_OUT Mat& dst, const Mat& mask=Mat() ); //! adds squared src image to the accumulator (dst += src*src). -CV_EXPORTS_W void accumulateSquare( const Mat& src, CV_OUT Mat& dst, const Mat& mask=Mat() ); +CV_EXPORTS_W void accumulateSquare( const Mat& src, CV_IN_OUT Mat& dst, const Mat& mask=Mat() ); //! adds product of the 2 images to the accumulator (dst += src1*src2). CV_EXPORTS_W void accumulateProduct( const Mat& src1, const Mat& src2, - CV_OUT Mat& dst, const Mat& mask=Mat() ); + CV_IN_OUT Mat& dst, const Mat& mask=Mat() ); //! updates the running average (dst = dst*(1-alpha) + src*alpha) -CV_EXPORTS_W void accumulateWeighted( const Mat& src, CV_OUT Mat& dst, - double alpha, const Mat& mask=Mat() ); +CV_EXPORTS_W void accumulateWeighted( const Mat& src, CV_IN_OUT Mat& dst, + double alpha, const Mat& mask=Mat() ); //! type of the threshold operation enum { THRESH_BINARY=0, THRESH_BINARY_INV=1, THRESH_TRUNC=2, THRESH_TOZERO=3, diff --git a/modules/ml/include/opencv2/ml/ml.hpp b/modules/ml/include/opencv2/ml/ml.hpp index 2f4eb7d..66b9741 100644 --- a/modules/ml/include/opencv2/ml/ml.hpp +++ b/modules/ml/include/opencv2/ml/ml.hpp @@ -247,22 +247,22 @@ public: CV_WRAP CvNormalBayesClassifier(); virtual ~CvNormalBayesClassifier(); - CvNormalBayesClassifier( const CvMat* _train_data, const CvMat* _responses, - const CvMat* _var_idx=0, const CvMat* _sample_idx=0 ); + CvNormalBayesClassifier( const CvMat* trainData, const CvMat* responses, + const CvMat* varIdx=0, const CvMat* sampleIdx=0 ); - virtual bool train( const CvMat* _train_data, const CvMat* _responses, - const CvMat* _var_idx = 0, const CvMat* _sample_idx=0, bool update=false ); + 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 ) const; + virtual float predict( const CvMat* samples, CV_OUT CvMat* results=0 ) const; CV_WRAP virtual void clear(); #ifndef SWIG - CV_WRAP CvNormalBayesClassifier( const cv::Mat& _train_data, const cv::Mat& _responses, - const cv::Mat& _var_idx=cv::Mat(), const cv::Mat& _sample_idx=cv::Mat() ); - CV_WRAP virtual bool train( const cv::Mat& _train_data, const cv::Mat& _responses, - const cv::Mat& _var_idx = cv::Mat(), const cv::Mat& _sample_idx=cv::Mat(), + 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::Mat* results=0 ) const; + CV_WRAP virtual float predict( const cv::Mat& samples, cv::Mat* results=0 ) const; #endif virtual void write( CvFileStorage* storage, const char* name ) const; @@ -294,27 +294,26 @@ public: CV_WRAP CvKNearest(); virtual ~CvKNearest(); - CvKNearest( const CvMat* _train_data, const CvMat* _responses, - const CvMat* _sample_idx=0, bool _is_regression=false, int max_k=32 ); + CvKNearest( const CvMat* trainData, const CvMat* responses, + const CvMat* sampleIdx=0, bool isRegression=false, int max_k=32 ); - virtual bool train( const CvMat* _train_data, const CvMat* _responses, - const CvMat* _sample_idx=0, bool is_regression=false, - int _max_k=32, bool _update_base=false ); + 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* neighbor_responses=0, CV_OUT CvMat* dist=0 ) const; + 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; #ifndef SWIG - CV_WRAP CvKNearest( const cv::Mat& _train_data, const cv::Mat& _responses, - const cv::Mat& _sample_idx=cv::Mat(), bool _is_regression=false, int max_k=32 ); + 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& _train_data, const cv::Mat& _responses, - const cv::Mat& _sample_idx=cv::Mat(), bool is_regression=false, - int _max_k=32, bool _update_base=false ); + 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 ); - CV_WRAP virtual float find_nearest( const cv::Mat& _samples, int k, cv::Mat* results=0, - const float** neighbors=0, - cv::Mat* neighbor_responses=0, + CV_WRAP 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; #endif @@ -372,8 +371,8 @@ struct CV_EXPORTS 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 ); + CvSVMKernel( const CvSVMParams* params, Calc _calc_func ); + virtual bool create( const CvSVMParams* params, Calc _calc_func ); virtual ~CvSVMKernel(); virtual void clear(); @@ -523,45 +522,45 @@ public: CV_WRAP CvSVM(); virtual ~CvSVM(); - CvSVM( const CvMat* _train_data, const CvMat* _responses, - const CvMat* _var_idx=0, const CvMat* _sample_idx=0, - CvSVMParams _params=CvSVMParams() ); + CvSVM( const CvMat* trainData, const CvMat* responses, + const CvMat* varIdx=0, const CvMat* sampleIdx=0, + CvSVMParams params=CvSVMParams() ); - virtual bool train( const CvMat* _train_data, const CvMat* _responses, - const CvMat* _var_idx=0, const CvMat* _sample_idx=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* _train_data, const CvMat* _responses, - const CvMat* _var_idx, const CvMat* _sample_idx, CvSVMParams _params, - int k_fold = 10, - CvParamGrid C_grid = get_default_grid(CvSVM::C), - CvParamGrid gamma_grid = get_default_grid(CvSVM::GAMMA), - CvParamGrid p_grid = get_default_grid(CvSVM::P), - CvParamGrid nu_grid = get_default_grid(CvSVM::NU), - CvParamGrid coef_grid = get_default_grid(CvSVM::COEF), - CvParamGrid degree_grid = get_default_grid(CvSVM::DEGREE) ); - - virtual float predict( const CvMat* _sample, bool returnDFVal=false ) const; + 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) ); + + virtual float predict( const CvMat* sample, bool returnDFVal=false ) const; #ifndef SWIG - CV_WRAP CvSVM( const cv::Mat& _train_data, const cv::Mat& _responses, - const cv::Mat& _var_idx=cv::Mat(), const cv::Mat& _sample_idx=cv::Mat(), - CvSVMParams _params=CvSVMParams() ); + 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& _train_data, const cv::Mat& _responses, - const cv::Mat& _var_idx=cv::Mat(), const cv::Mat& _sample_idx=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& _train_data, const cv::Mat& _responses, - const cv::Mat& _var_idx, const cv::Mat& _sample_idx, CvSVMParams _params, + 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 C_grid = get_default_grid(CvSVM::C), - CvParamGrid gamma_grid = get_default_grid(CvSVM::GAMMA), - CvParamGrid p_grid = get_default_grid(CvSVM::P), - CvParamGrid nu_grid = get_default_grid(CvSVM::NU), - CvParamGrid coef_grid = get_default_grid(CvSVM::COEF), - CvParamGrid degree_grid = get_default_grid(CvSVM::DEGREE) ); - CV_WRAP virtual float predict( const cv::Mat& _sample, bool returnDFVal=false ) const; + 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) ); + CV_WRAP virtual float predict( const cv::Mat& sample, bool returnDFVal=false ) const; #endif CV_WRAP virtual int get_support_vector_count() const; @@ -577,12 +576,12 @@ public: protected: - virtual bool set_params( const CvSVMParams& _params ); + 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, + 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 ); + const CvMat* responses, CvMemStorage* _storage, double* alpha ); virtual void create_kernel(); virtual void create_solver(); @@ -646,23 +645,23 @@ public: enum { START_E_STEP=1, START_M_STEP=2, START_AUTO_STEP=0 }; CV_WRAP CvEM(); - CvEM( const CvMat* samples, const CvMat* sample_idx=0, + CvEM( const CvMat* samples, const CvMat* sampleIdx=0, CvEMParams params=CvEMParams(), CvMat* labels=0 ); //CvEM (CvEMParams params, CvMat * means, CvMat ** covs, CvMat * weights, // CvMat * probs, CvMat * log_weight_div_det, CvMat * inv_eigen_values, CvMat** cov_rotate_mats); virtual ~CvEM(); - virtual bool train( const CvMat* samples, const CvMat* sample_idx=0, + virtual bool train( const CvMat* samples, const CvMat* sampleIdx=0, CvEMParams params=CvEMParams(), CvMat* labels=0 ); virtual float predict( const CvMat* sample, CV_OUT CvMat* probs ) const; #ifndef SWIG - CV_WRAP CvEM( const cv::Mat& samples, const cv::Mat& sample_idx=cv::Mat(), + CV_WRAP CvEM( const cv::Mat& samples, const cv::Mat& sampleIdx=cv::Mat(), CvEMParams params=CvEMParams(), cv::Mat* labels=0 ); - CV_WRAP virtual bool train( const cv::Mat& samples, const cv::Mat& sample_idx=cv::Mat(), + CV_WRAP virtual bool train( const cv::Mat& samples, const cv::Mat& sampleIdx=cv::Mat(), CvEMParams params=CvEMParams(), cv::Mat* labels=0 ); CV_WRAP virtual float predict( const cv::Mat& sample, cv::Mat* probs ) const; @@ -807,19 +806,19 @@ struct CV_EXPORTS_AS_MAP CvDTreeParams struct CV_EXPORTS CvDTreeTrainData { CvDTreeTrainData(); - CvDTreeTrainData( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx=0, - const CvMat* _sample_idx=0, const CvMat* _var_type=0, - const CvMat* _missing_mask=0, - const CvDTreeParams& _params=CvDTreeParams(), + 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* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx=0, - const CvMat* _sample_idx=0, const CvMat* _var_type=0, - const CvMat* _missing_mask=0, - const CvDTreeParams& _params=CvDTreeParams(), + 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(); @@ -921,30 +920,31 @@ public: CV_WRAP CvDTree(); virtual ~CvDTree(); - virtual bool train( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx=0, - const CvMat* _sample_idx=0, const CvMat* _var_type=0, - const CvMat* _missing_mask=0, + 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* _data, CvDTreeParams _params=CvDTreeParams() ); + virtual bool train( CvMLData* trainData, CvDTreeParams params=CvDTreeParams() ); - virtual float calc_error( CvMLData* _data, int type , std::vector *resp = 0 ); // type in {CV_TRAIN_ERROR, CV_TEST_ERROR} + // type in {CV_TRAIN_ERROR, CV_TEST_ERROR} + virtual float calc_error( CvMLData* trainData, int type, std::vector *resp = 0 ); - virtual bool train( CvDTreeTrainData* _train_data, const CvMat* _subsample_idx ); + virtual bool train( CvDTreeTrainData* trainData, const CvMat* subsampleIdx ); - virtual CvDTreeNode* predict( const CvMat* _sample, const CvMat* _missing_data_mask=0, - bool preprocessed_input=false ) const; + virtual CvDTreeNode* predict( const CvMat* sample, const CvMat* missingDataMask=0, + bool preprocessedInput=false ) const; #ifndef SWIG - CV_WRAP virtual bool train( const cv::Mat& _train_data, int _tflag, - const cv::Mat& _responses, const cv::Mat& _var_idx=cv::Mat(), - const cv::Mat& _sample_idx=cv::Mat(), const cv::Mat& _var_type=cv::Mat(), - const cv::Mat& _missing_mask=cv::Mat(), + 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& _missing_data_mask=cv::Mat(), - bool preprocessed_input=false ) const; + CV_WRAP virtual CvDTreeNode* predict( const cv::Mat& sample, const cv::Mat& missingDataMask=cv::Mat(), + bool preprocessedInput=false ) const; #endif CV_WRAP virtual const CvMat* get_var_importance(); @@ -1021,19 +1021,19 @@ public: CvForestTree(); virtual ~CvForestTree(); - virtual bool train( CvDTreeTrainData* _train_data, const CvMat* _subsample_idx, CvRTrees* forest ); + 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( CvFileStorage* fs, CvFileNode* node, CvRTrees* forest, CvDTreeTrainData* _data ); /* dummy methods to avoid warnings: BEGIN */ - virtual bool train( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx=0, - const CvMat* _sample_idx=0, const CvMat* _var_type=0, - const CvMat* _missing_mask=0, + 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* _train_data, const CvMat* _subsample_idx ); + virtual bool train( CvDTreeTrainData* trainData, const CvMat* _subsample_idx ); virtual void read( CvFileStorage* fs, CvFileNode* node ); virtual void read( CvFileStorage* fs, CvFileNode* node, CvDTreeTrainData* data ); @@ -1082,10 +1082,10 @@ class CV_EXPORTS_AS(RTrees) CvRTrees : public CvStatModel public: CV_WRAP CvRTrees(); virtual ~CvRTrees(); - virtual bool train( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx=0, - const CvMat* _sample_idx=0, const CvMat* _var_type=0, - const CvMat* _missing_mask=0, + 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() ); @@ -1093,10 +1093,10 @@ public: virtual float predict_prob( const CvMat* sample, const CvMat* missing = 0 ) const; #ifndef SWIG - CV_WRAP virtual bool train( const cv::Mat& _train_data, int _tflag, - const cv::Mat& _responses, const cv::Mat& _var_idx=cv::Mat(), - const cv::Mat& _sample_idx=cv::Mat(), const cv::Mat& _var_type=cv::Mat(), - const cv::Mat& _missing_mask=cv::Mat(), + 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; @@ -1143,11 +1143,11 @@ protected: \****************************************************************************************/ struct CV_EXPORTS CvERTreeTrainData : public CvDTreeTrainData { - virtual void set_data( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx=0, - const CvMat* _sample_idx=0, const CvMat* _var_type=0, - const CvMat* _missing_mask=0, - const CvDTreeParams& _params=CvDTreeParams(), + 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, @@ -1181,16 +1181,16 @@ class CV_EXPORTS_AS(ERTrees) CvERTrees : public CvRTrees public: CV_WRAP CvERTrees(); virtual ~CvERTrees(); - virtual bool train( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx=0, - const CvMat* _sample_idx=0, const CvMat* _var_type=0, - const CvMat* _missing_mask=0, + 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()); #ifndef SWIG - CV_WRAP virtual bool train( const cv::Mat& _train_data, int _tflag, - const cv::Mat& _responses, const cv::Mat& _var_idx=cv::Mat(), - const cv::Mat& _sample_idx=cv::Mat(), const cv::Mat& _var_type=cv::Mat(), - const cv::Mat& _missing_mask=cv::Mat(), + 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()); #endif virtual bool train( CvMLData* data, CvRTParams params=CvRTParams() ); @@ -1224,7 +1224,7 @@ public: CvBoostTree(); virtual ~CvBoostTree(); - virtual bool train( CvDTreeTrainData* _train_data, + virtual bool train( CvDTreeTrainData* trainData, const CvMat* subsample_idx, CvBoost* ensemble ); virtual void scale( double s ); @@ -1233,12 +1233,12 @@ public: virtual void clear(); /* dummy methods to avoid warnings: BEGIN */ - virtual bool train( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx=0, - const CvMat* _sample_idx=0, const CvMat* _var_type=0, - const CvMat* _missing_mask=0, + 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* _train_data, const CvMat* _subsample_idx ); + virtual bool train( CvDTreeTrainData* trainData, const CvMat* _subsample_idx ); virtual void read( CvFileStorage* fs, CvFileNode* node ); virtual void read( CvFileStorage* fs, CvFileNode* node, @@ -1277,16 +1277,16 @@ public: CV_WRAP CvBoost(); virtual ~CvBoost(); - CvBoost( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx=0, - const CvMat* _sample_idx=0, const CvMat* _var_type=0, - const CvMat* _missing_mask=0, + 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* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx=0, - const CvMat* _sample_idx=0, const CvMat* _var_type=0, - const CvMat* _missing_mask=0, + 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 ); @@ -1294,27 +1294,27 @@ public: CvBoostParams params=CvBoostParams(), bool update=false ); - virtual float predict( const CvMat* _sample, const CvMat* _missing=0, + 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; #ifndef SWIG - CV_WRAP CvBoost( const cv::Mat& _train_data, int _tflag, - const cv::Mat& _responses, const cv::Mat& _var_idx=cv::Mat(), - const cv::Mat& _sample_idx=cv::Mat(), const cv::Mat& _var_type=cv::Mat(), - const cv::Mat& _missing_mask=cv::Mat(), + 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& _train_data, int _tflag, - const cv::Mat& _responses, const cv::Mat& _var_idx=cv::Mat(), - const cv::Mat& _sample_idx=cv::Mat(), const cv::Mat& _var_type=cv::Mat(), - const cv::Mat& _missing_mask=cv::Mat(), + 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(), + CV_WRAP virtual float predict( const cv::Mat& sample, const cv::Mat& missing=cv::Mat(), cv::Mat* weak_responses=0, CvSlice slice=CV_WHOLE_SEQ, - bool raw_mode=false, bool return_sum=false ) const; + bool rawMode=false, bool returnSum=false ) const; #endif virtual float calc_error( CvMLData* _data, int type , std::vector *resp = 0 ); // type in {CV_TRAIN_ERROR, CV_TEST_ERROR} @@ -1337,7 +1337,7 @@ public: protected: - virtual bool set_params( const CvBoostParams& _params ); + virtual bool set_params( const CvBoostParams& params ); virtual void update_weights( CvBoostTree* tree ); virtual void trim_weights(); virtual void write_params( CvFileStorage* fs ) const; @@ -1409,7 +1409,7 @@ struct CV_EXPORTS_AS_MAP CvGBTreesParams : public CvDTreeParams // computed via sum_responses values. When the current // step is complete sum_response values become equal to // sum_responses_tmp. -// sample_idx - indices of samples used for training the ensemble. +// 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 @@ -1491,42 +1491,42 @@ public: // train. // // API - // CvGBTrees( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx=0, - const CvMat* _sample_idx=0, const CvMat* _var_type=0, - const CvMat* _missing_mask=0, + // 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 - // _train_data - a set of input feature vectors. + // trainData - a set of input feature vectors. // size of matrix is // x // or x - // depending on the _tflag parameter. + // depending on the tflag parameter. // matrix values are float. - // _tflag - a flag showing how do samples stored in the - // _train_data matrix row by row (tflag=CV_ROW_SAMPLE) + // 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 _train_data. - // _var_idx - indices of used variables. zero value means that all + // responses - a vector of responses corresponding to the samples + // in trainData. + // varIdx - indices of used variables. zero value means that all // variables are active. - // _sample_idx - indices of used samples. zero value means that all - // samples from _train_data are in the training set. - // _var_type - vector of length. gives every + // 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. - // _var_type = 0 means all variables are numerical. - // _missing_mask - a mask of misiing values in _train_data. - // _missing_mask = 0 means that there are no missing + // 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 */ - CV_WRAP CvGBTrees( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx=0, - const CvMat* _sample_idx=0, const CvMat* _var_type=0, - const CvMat* _missing_mask=0, + CV_WRAP 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() ); @@ -1540,34 +1540,34 @@ public: // Gradient tree boosting model training // // API - // virtual bool train( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx=0, - const CvMat* _sample_idx=0, const CvMat* _var_type=0, - const CvMat* _missing_mask=0, + // 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 - // _train_data - a set of input feature vectors. + // trainData - a set of input feature vectors. // size of matrix is // x // or x - // depending on the _tflag parameter. + // depending on the tflag parameter. // matrix values are float. - // _tflag - a flag showing how do samples stored in the - // _train_data matrix row by row (tflag=CV_ROW_SAMPLE) + // 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 _train_data. - // _var_idx - indices of used variables. zero value means that all + // responses - a vector of responses corresponding to the samples + // in trainData. + // varIdx - indices of used variables. zero value means that all // variables are active. - // _sample_idx - indices of used samples. zero value means that all - // samples from _train_data are in the training set. - // _var_type - vector of length. gives every + // 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. - // _var_type = 0 means all variables are numerical. - // _missing_mask - a mask of misiing values in _train_data. - // _missing_mask = 0 means that there are no missing + // 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. (!) @@ -1575,10 +1575,10 @@ public: // RESULT // Error state. */ - CV_WRAP virtual bool train( const CvMat* _train_data, int _tflag, - const CvMat* _responses, const CvMat* _var_idx=0, - const CvMat* _sample_idx=0, const CvMat* _var_type=0, - const CvMat* _missing_mask=0, + CV_WRAP 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 ); @@ -1608,14 +1608,14 @@ public: // Response value prediction // // API - // virtual float predict( const CvMat* _sample, const CvMat* _missing=0, + // 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. + // 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. @@ -1631,8 +1631,8 @@ public: // RESULT // Predicted value. */ - CV_WRAP virtual float predict( const CvMat* _sample, const CvMat* _missing=0, - CvMat* weak_responses=0, CvSlice slice = CV_WHOLE_SEQ, + CV_WRAP virtual float predict( const CvMat* sample, const CvMat* missing=0, + CvMat* weakResponses=0, CvSlice slice = CV_WHOLE_SEQ, int k=-1 ) const; /* @@ -1917,37 +1917,37 @@ class CV_EXPORTS_AS(ANN_MLP) CvANN_MLP : public CvStatModel { public: CV_WRAP CvANN_MLP(); - CvANN_MLP( const CvMat* _layer_sizes, - int _activ_func=SIGMOID_SYM, - double _f_param1=0, double _f_param2=0 ); + CvANN_MLP( const CvMat* layerSizes, + int activateFunc=SIGMOID_SYM, + double fparam1=0, double fparam2=0 ); virtual ~CvANN_MLP(); - virtual void create( const CvMat* _layer_sizes, - int _activ_func=SIGMOID_SYM, - double _f_param1=0, double _f_param2=0 ); + virtual void create( const CvMat* layerSizes, + int activateFunc=SIGMOID_SYM, + double fparam1=0, double fparam2=0 ); - virtual int train( const CvMat* _inputs, const CvMat* _outputs, - const CvMat* _sample_weights, const CvMat* _sample_idx=0, - CvANN_MLP_TrainParams _params = CvANN_MLP_TrainParams(), + 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; + virtual float predict( const CvMat* inputs, CV_OUT CvMat* outputs ) const; #ifndef SWIG - CV_WRAP CvANN_MLP( const cv::Mat& _layer_sizes, - int _activ_func=SIGMOID_SYM, - double _f_param1=0, double _f_param2=0 ); + CV_WRAP CvANN_MLP( const cv::Mat& layerSizes, + int activateFunc=SIGMOID_SYM, + double fparam1=0, double fparam2=0 ); - CV_WRAP virtual void create( const cv::Mat& _layer_sizes, - int _activ_func=SIGMOID_SYM, - double _f_param1=0, double _f_param2=0 ); + CV_WRAP virtual void create( const cv::Mat& layerSizes, + int activateFunc=SIGMOID_SYM, + double fparam1=0, double fparam2=0 ); - CV_WRAP virtual int train( const cv::Mat& _inputs, const cv::Mat& _outputs, - const cv::Mat& _sample_weights, const cv::Mat& _sample_idx=cv::Mat(), - CvANN_MLP_TrainParams _params = CvANN_MLP_TrainParams(), + 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::Mat& _outputs ) const; + CV_WRAP virtual float predict( const cv::Mat& inputs, cv::Mat& outputs ) const; #endif CV_WRAP virtual void clear(); @@ -1972,7 +1972,7 @@ public: protected: virtual bool prepare_to_train( const CvMat* _inputs, const CvMat* _outputs, - const CvMat* _sample_weights, const CvMat* _sample_idx, + const CvMat* _sample_weights, const CvMat* sampleIdx, CvVectors* _ivecs, CvVectors* _ovecs, double** _sw, int _flags ); // sequential random backpropagation diff --git a/modules/python/gen2.py b/modules/python/gen2.py new file mode 100644 index 0000000..f17c64d --- /dev/null +++ b/modules/python/gen2.py @@ -0,0 +1,689 @@ +import opencv_parser, sys, re, cStringIO +from string import Template + +gen_template_check_self = Template(""" if(!PyObject_TypeCheck(self, &pyopencv_${name}_Type)) + return failmsg("Incorrect type of self (must be '${name}' or its derivative)"); + $cname* _self_ = ((pyopencv_${name}_t*)self)->v; +""") + +gen_template_call_constructor = Template("""self = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type); + if(self) ERRWRAP2(self->v = new $cname""") + +gen_template_parse_args = Template("""const char* keywords[] = { $kw_list, NULL }; + if( PyArg_ParseTupleAndKeywords(args, kw, "$fmtspec", (char**)keywords, $parse_arglist)$code_cvt )""") + +gen_template_func_body = Template("""$code_decl + $code_parse + { + $code_fcall; + return $code_retval; + } +""") + +gen_template_set_prop_from_map = Template(""" + if( PyMapping_HasKeyString(src, "$propname") ) + { + tmp = PyMapping_GetItemString(src, "$propname"); + ok = tmp && pyopencv_to_$proptype(tmp, dst.$propname); + Py_DECREF(tmp); + if(!ok) return false; + }""") + +gen_template_decl_type = Template(""" +/* + $cname is the OpenCV C struct + pyopencv_${name}_t is the Python object +*/ + +struct pyopencv_${name}_t +{ + PyObject_HEAD + ${cname}* v; +}; + +static void pyopencv_${name}_dealloc(PyObject* self) +{ + delete ((pyopencv_${name}_t*)self)->v; + PyObject_Del(self); +} + +static PyObject* pyopencv_${name}_repr(PyObject* self) +{ + char str[1000]; + sprintf(str, "<$wname %p>", self); + return PyString_FromString(str); +} + +${getset_code} + +static PyGetSetDef pyopencv_${name}_getseters[] = +{${getset_inits} + {NULL} /* Sentinel */ +}; + +${methods_code} + +static PyMethodDef pyopencv_${name}_methods[] = +{ +${methods_inits} + {NULL, NULL} +}; + +static PyTypeObject pyopencv_${name}_Type = +{ + PyObject_HEAD_INIT(&PyType_Type) + 0, + MODULESTR".$wname", + sizeof(pyopencv_${name}_t), +}; + +static void pyopencv_${name}_specials(void) +{ + pyopencv_${name}_Type.tp_base = ${baseptr}; + pyopencv_${name}_Type.tp_dealloc = pyopencv_${name}_dealloc; + pyopencv_${name}_Type.tp_repr = pyopencv_${name}_repr; + pyopencv_${name}_Type.tp_getset = pyopencv_${name}_getseters; + pyopencv_${name}_Type.tp_methods = pyopencv_${name}_methods;${extra_specials} +} + +static PyObject* pyopencv_from_${name}_ptr(<$cname>* r) +{ + pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type); + m->v = r; + return (PyObject*)m; +} + +static bool pyopencv_to_${name}_ptr(PyObject* src, <$cname>*& dst, const char* name="") +{ + if( src == NULL or src == Py_None ) + { + dst = 0; + return true; + } + if(!PyObject_TypeCheck(src, &pyopencv_${name}_Type)) + return failmsg("Expected ${cname} for argument '%s'", name); + dst = ((pyopencv_${name}_t*)src)->v; + return true; +} +""") + +gen_template_get_prop = Template(""" +static PyObject* pyopencv_${name}_get_${member}(pyopencv_${name}_t* p, void *closure) +{ + return pyopencv_from_${membertype}(p->v->${member}); +} +""") + +gen_template_set_prop = Template(""" +static int pyopencv_${name}_set_${member}(pyopencv_${name}_t* p, PyObject *value, void *closure) +{ + if (value == NULL) + { + PyErr_SetString(PyExc_TypeError, "Cannot delete the ${member} attribute"); + return -1; + } + return pyopencv_to_${membertype}(value, p->v->${member}) ? 0 : -1; +} +""") + +gen_template_prop_init = Template(""" + {(char*)"${member}", (getter)pyopencv_${name}_get_${member}, NULL, (char*)"${member}", NULL},""") + +gen_template_rw_prop_init = Template(""" + {(char*)"${member}", (getter)pyopencv_${name}_get_${member}, (setter)pyopencv_${name}_set_${member}, (char*)"${member}", NULL},""") + +simple_argtype_mapping = { + "bool": ("bool", "b", "pyopencv_from_bool", "0"), + "int": ("int", "i", "pyopencv_from_int", "0"), + "float": ("float", "f", "pyopencv_from_float", "0.f"), + "double": ("double", "d", "pyopencv_from_double", "0"), + "c_string": ("char*", "s", "pyopencv_from_c_string", '""') +} + +class ClassProp(object): + def __init__(self, decl): + self.tp = decl[0] + self.name = decl[1] + self.readonly = True + if "/RW" in decl[3]: + self.readonly = False + +class ClassInfo(object): + def __init__(self, name, decl=None): + self.cname = name.replace(".", "::") + self.name = self.wname = re.sub(r"^cv\.", "", name) + self.ismap = False + self.methods = {} + self.props = [] + self.consts = {} + customname = False + + if decl: + self.bases = decl[1].split()[1:] + if len(self.bases) > 1: + print "Error: class %s has more than 1 base class (not supported by Python C extensions)" % (self.name,) + print "Bases: ", self.bases + return sys.exit(-1) + for m in decl[2]: + if m.startswith("="): + self.wname = m[1:] + customname = True + elif m == "/Map": + self.ismap = True + self.props = [ClassProp(p) for p in decl[3]] + + if not customname and self.wname.startswith("Cv"): + self.wname = self.wname[2:] + + def gen_map_code(self): + code = "static bool pyopencv_to_%s(PyObject* src, %s& dst)\n{\n PyObject* tmp;\n bool ok;\n" % (self.name, self.cname) + code += "".join([gen_template_set_prop_from_map.substitute(propname=p.name,proptype=p.tp) for p in self.props]) + code += "\n return true;\n}" + return code + + def gen_code(self, all_classes): + if self.ismap: + return self.gen_map_code() + + getset_code = "" + getset_inits = "" + + sorted_props = [(p.name, p) for p in self.props] + sorted_props.sort() + + for pname, p in sorted_props: + getset_code += gen_template_get_prop.substitute(name=self.name, member=pname, membertype=p.tp) + if p.readonly: + getset_inits += gen_template_prop_init.substitute(name=self.name, member=pname) + else: + getset_code += gen_template_set_prop.substitute(name=self.name, member=pname, membertype=p.tp) + getset_inits += gen_template_rw_prop_init.substitute(name=self.name, member=pname) + + methods_code = "" + methods_inits = "" + + sorted_methods = self.methods.items() + sorted_methods.sort() + + for mname, m in sorted_methods: + methods_code += m.gen_code(all_classes) + methods_inits += m.get_tab_entry() + + baseptr = "NULL" + if self.bases and all_classes.has_key(self.bases[0]): + baseptr = "&pyopencv_" + all_classes[self.bases[0]].name + "_Type" + + code = gen_template_decl_type.substitute(name=self.name, wname=self.wname, cname=self.cname, + getset_code=getset_code, getset_inits=getset_inits, + methods_code=methods_code, methods_inits=methods_inits, + baseptr=baseptr, extra_specials="") + + return code + + +class ConstInfo(object): + def __init__(self, name, val): + self.cname = name.replace(".", "::") + self.name = re.sub(r"^cv\.", "", name).replace(".", "_") + if self.name.startswith("Cv"): + self.name = self.name[2:] + self.name = re.sub(r"([a-z])([A-Z])", r"\1_\2", self.name) + self.name = self.name.upper() + self.value = val + +class ArgInfo(object): + def __init__(self, arg_tuple): + self.tp = arg_tuple[0] + self.name = arg_tuple[1] + self.defval = arg_tuple[2] + self.isarray = False + self.arraylen = 0 + self.arraycvt = None + self.inputarg = True + self.outputarg = False + for m in arg_tuple[3]: + if m == "/O": + self.inputarg = False + self.outputarg = True + elif m == "/IO": + self.inputarg = True + self.outputarg = True + elif m.startswith("/A"): + self.isarray = True + self.arraylen = m[2:].strip() + elif m.startswith("/CA"): + self.isarray = True + self.arraycvt = m[2:].strip() + self.py_inputarg = False + self.py_outputarg = False + + def isbig(self): + return self.tp == "Mat" or self.tp.startswith("vector") + + +class FuncVariant(object): + def __init__(self, name, decl, isconstructor): + self.name = name + self.isconstructor = isconstructor + self.rettype = decl[1] + if self.rettype == "void": + self.rettype = "" + self.args = [] + self.array_counters = {} + for a in decl[3]: + ainfo = ArgInfo(a) + if ainfo.isarray and not ainfo.arraycvt: + c = ainfo.arraylen + c_arrlist = self.array_counters.get(c, []) + if c_arrlist: + c_arrlist.append(ainfo.name) + else: + self.array_counters[c] = [ainfo.name] + self.args.append(ainfo) + self.init_pyproto() + + def init_pyproto(self): + # string representation of argument list, with '[', ']' symbols denoting optional arguments, e.g. + # "src1, src2[, dst[, mask]]" for cv.add + argstr = "" + + # list of all input arguments of the Python function, with the argument numbers: + # [("src1", 0), ("src2", 1), ("dst", 2), ("mask", 3)] + # we keep an argument number to find the respective argument quickly, because + # some of the arguments of C function may not present in the Python function (such as array counters) + # or even go in a different order ("heavy" output parameters of the C function + # become the first optional input parameters of the Python function, and thus they are placed right after + # non-optional input parameters) + arglist = [] + + # the list of "heavy" output parameters. Heavy parameters are the parameters + # that can be expensive to allocate each time, such as vectors and matrices (see isbig). + outarr_list = [] + + # the list of output parameters. Also includes input/output parameters. + outlist = [] + + firstoptarg = 0 + argno = -1 + for a in self.args: + argno += 1 + if a.name in self.array_counters: + continue + if a.outputarg: + outlist.append((a.name, argno)) + if not a.inputarg: + if a.isbig(): + outarr_list.append((a.name, argno)) + continue + if not a.defval: + arglist.append((a.name, argno)) + firstoptarg = argno+1 + else: + # if there are some array output parameters before the first default parameter, they + # are added as optional parameters before the first optional parameter + if outarr_list: + arglist += outarr_list + outarr_list = [] + arglist.append((a.name, argno)) + + if outarr_list: + arglist += outarr_list + noptargs = len(arglist) - firstoptarg + argnamelist = [aname for aname, argno in arglist] + argstr = ", ".join(argnamelist[:firstoptarg]) + argstr = "[, ".join([argstr] + argnamelist[firstoptarg:]) + argstr += "]" * noptargs + if self.rettype: + outlist = [("retval", -1)] + outlist + elif self.isconstructor: + assert outlist == [] + outlist = [("self", -1)] + if outlist: + outstr = ", ".join([o[0] for o in outlist]) + elif self.isconstructor: + outstr = self.classname + " object" + else: + outstr = "None" + self.py_docstring = "%s(%s) -> %s" % (self.name, argstr, outstr) + self.py_noptargs = noptargs + self.py_arglist = arglist + for aname, argno in arglist: + self.args[argno].py_inputarg = True + for aname, argno in outlist: + if argno >= 0: + self.args[argno].py_outputarg = True + self.py_outlist = outlist + + +class FuncInfo(object): + def __init__(self, classname, name, cname, isconstructor): + self.classname = classname + self.name = name + self.cname = cname + self.isconstructor = isconstructor + self.variants = [] + + def add_variant(self, decl): + self.variants.append(FuncVariant(self.name, decl, self.isconstructor)) + + def get_wrapper_name(self): + if self.classname: + cn = self.classname + "_" + else: + cn = "" + return "pyopencv_" + cn + self.name + + def get_wrapper_prototype(self): + full_fname = self.get_wrapper_name() + if self.classname and not self.isconstructor: + self_arg = "self" + else: + self_arg = "" + return "static PyObject* %s(PyObject* %s, PyObject* args, PyObject* kw)" % (full_fname, self_arg) + + def get_tab_entry(self): + docstring_list = [] + have_empty_constructor = False + for v in self.variants: + s = v.py_docstring + if (not v.py_arglist) and self.isconstructor: + have_empty_constructor = True + if s not in docstring_list: + docstring_list.append(s) + # if there are just 2 constructors: default one and some other, + # we simplify the notation. + # Instead of ClassName(args ...) -> object or ClassName() -> object + # we write ClassName([args ...]) -> object + if have_empty_constructor and len(self.variants) == 2: + idx = self.variants[1].arglist != [] + docstring_list = ["[" + self.variants[idx].py_docstring + "]"] + + return Template(' {"$py_funcname", (PyCFunction)$wrap_funcname, METH_KEYWORDS, "$py_docstring"},\n' + ).substitute(py_funcname = self.name, wrap_funcname=self.get_wrapper_name(), + py_docstring = " or ".join(docstring_list)) + + def gen_code(self, all_classes): + proto = self.get_wrapper_prototype() + code = "%s\n{\n" % (proto,) + + selfinfo = ClassInfo("") + ismethod = self.classname != "" and not self.isconstructor + # full name is needed for error diagnostic in PyArg_ParseTupleAndKeywords + fullname = self.name + + if self.classname: + selfinfo = all_classes[self.classname] + if not self.isconstructor: + code += gen_template_check_self.substitute(name=selfinfo.name, cname=selfinfo.cname) + fullname = selfinfo.wname + "." + fullname + + all_code_variants = [] + declno = -1 + for v in self.variants: + code_decl = "" + code_fcall = "" + code_ret = "" + code_cvt_list = [] + + if self.isconstructor: + code_decl += " pyopencv_%s_t* self = 0;\n" % selfinfo.name + code_fcall = gen_template_call_constructor.substitute(name=selfinfo.name, cname=selfinfo.cname) + else: + code_fcall = "ERRWRAP2( " + if v.rettype: + code_decl += " " + v.rettype + " retval;\n" + code_fcall += "retval = " + if ismethod: + code_fcall += "_self_->" + self.cname + else: + code_fcall += self.cname + code_fcall += "(" + all_cargs = [] + parse_arglist = [] + + # declare all the C function arguments, + # add necessary conversions from Python objects to code_cvt_list, + # form the function/method call, + # for the list of type mappings + for a in v.args: + tp1 = tp = a.tp + amp = "" + defval0 = "" + if tp.endswith("*"): + tp = tp1 = tp[:-1] + amp = "&" + if tp.endswith("*"): + defval0 = "0" + tp1 = tp.replace("*", "_ptr") + if tp1.endswith("*"): + print "Error: type with star: a.tp=%s, tp=%s, tp1=%s" % (a.tp, tp, tp1) + sys.exit(-1) + + amapping = simple_argtype_mapping.get(tp, (tp, "O", "pyopencv_from_" + tp1, defval0)) + all_cargs.append(amapping) + if a.py_inputarg: + if amapping[1] == "O": + code_decl += " PyObject* pyobj_%s = NULL;\n" % (a.name,) + parse_arglist.append("pyobj_" + a.name) + code_cvt_list.append("pyopencv_to_%s(pyobj_%s, %s)" % (tp1, a.name, a.name)) + else: + parse_arglist.append(a.name) + + defval = a.defval + if not defval: + defval = amapping[3] + # "tp arg = tp();" is equivalent to "tp arg;" in the case of complex types + if defval == tp + "()" and amapping[1] == "O": + defval = "" + if defval: + code_decl += " %s %s=%s;\n" % (amapping[0], a.name, defval) + else: + code_decl += " %s %s;\n" % (amapping[0], a.name) + + if not code_fcall.endswith("("): + code_fcall += ", " + code_fcall += amp + a.name + + code_fcall += "))" + + if code_cvt_list: + code_cvt_list = [""] + code_cvt_list + + # add info about return value, if any, to all_cargs. if there non-void return value, + # it is encoded in v.py_outlist as ("retval", -1) pair. + # As [-1] in Python accesses the last element of a list, we automatically handle the return value by + # adding the necessary info to the end of all_cargs list. + if v.rettype: + tp = v.rettype + tp1 = tp.replace("*", "_ptr") + amapping = simple_argtype_mapping.get(tp, (tp, "O", "pyopencv_from_" + tp1, "0")) + all_cargs.append(amapping) + + if v.args: + # form the format spec for PyArg_ParseTupleAndKeywords + fmtspec = "".join([all_cargs[argno][1] for aname, argno in v.py_arglist]) + if v.py_noptargs > 0: + fmtspec = fmtspec[:-v.py_noptargs] + "|" + fmtspec[-v.py_noptargs:] + fmtspec += ":" + fullname + + # form the argument parse code that: + # - declares the list of keyword parameters + # - calls PyArg_ParseTupleAndKeywords + # - converts complex arguments from PyObject's to native OpenCV types + code_parse = gen_template_parse_args.substitute( + kw_list = ", ".join(['"' + aname + '"' for aname, argno in v.py_arglist]), + fmtspec = fmtspec, + parse_arglist = ", ".join(["&" + aname for aname in parse_arglist]), + code_cvt = " &&\n ".join(code_cvt_list)) + else: + code_parse = "if(PyObject_Size(args) == 0 && PyObject_Size(kw) == 0)" + + if len(v.py_outlist) == 0: + code_retval = "Py_RETURN_NONE" + elif len(v.py_outlist) == 1: + if self.isconstructor: + code_retval = "self" + else: + aname, argno = v.py_outlist[0] + code_retval = "%s(%s)" % (all_cargs[argno][2], aname) + else: + # ther is more than 1 return parameter; form the tuple out of them + fmtspec = "N"*len(v.py_outlist) + backcvt_arg_list = [] + for aname, argno in v.py_outlist: + amapping = all_cargs[argno] + backcvt_arg_list.append("%s(%s)" % (amapping[2], aname)) + code_retval = "Py_BuildTuple(\"(%s)\", %s)" % \ + (fmtspec, ", ".join([all_cargs[argno][2] + "(" + aname + ")" for aname, argno in v.py_outlist])) + + all_code_variants.append(gen_template_func_body.substitute(code_decl=code_decl, + code_parse=code_parse, code_fcall=code_fcall, code_retval=code_retval)) + + if len(all_code_variants)==1: + # if the function/method has only 1 signature, then just put it + code += all_code_variants[0] + else: + # try to execute each signature + code += " PyErr_Clear();\n\n".join([" {\n" + v + " }\n" for v in all_code_variants]) + code += "\n return NULL;\n}\n\n" + return code + + +class PythonWrapperGenerator(object): + def __init__(self): + self.clear() + + def clear(self): + self.classes = {} + self.funcs = {} + self.consts = {} + self.code_types = cStringIO.StringIO() + self.code_funcs = cStringIO.StringIO() + self.code_functab = cStringIO.StringIO() + self.code_type_reg = cStringIO.StringIO() + self.code_const_reg = cStringIO.StringIO() + + def add_class(self, stype, name, decl): + classinfo = ClassInfo(name, decl) + + if self.classes.has_key(classinfo.name): + print "Generator error: class %s (cname=%s) already exists" \ + % (classinfo.name, classinfo.cname) + sys.exit(-1) + self.classes[classinfo.name] = classinfo + + def add_const(self, name, decl): + constinfo = ConstInfo(name, decl[1]) + + if self.consts.has_key(constinfo.name): + print "Generator error: constant %s (cname=%s) already exists" \ + % (constinfo.name, constinfo.cname) + sys.exit(-1) + self.consts[constinfo.name] = constinfo + + def add_func(self, decl): + classname = "" + name = decl[0] + dpos = name.rfind(".") + if dpos >= 0 and name[:dpos] != "cv": + classname = re.sub(r"^cv\.", "", name[:dpos]) + name = name[dpos+1:] + cname = name + name = re.sub(r"^cv\.", "", name) + isconstructor = cname == classname + cname = cname.replace(".", "::") + isclassmethod = False + customname = False + for m in decl[2]: + if m == "/S": + isclassmethod = True + elif m.startswith("="): + name = m[1:] + customname = True + func_map = self.funcs + + if not classname or isconstructor: + pass + elif isclassmethod: + if not customname: + name = classname + "_" + name + cname = classname + "::" + cname + classname = "" + else: + classinfo = self.classes.get(classname, ClassInfo("")) + if not classinfo.name: + print "Generator error: the class for method %s is missing" % (name,) + sys.exit(-1) + func_map = classinfo.methods + + func = func_map.get(name, FuncInfo(classname, name, cname, isconstructor)) + func.add_variant(decl) + if len(func.variants) == 1: + func_map[name] = func + + def gen_const_reg(self, constinfo): + self.code_const_reg.write("PUBLISH2(%s,%s);\n" % (constinfo.name, constinfo.cname)) + + def save(self, path, name, buf): + f = open(path + "/" + name, "wt") + f.write(buf.getvalue()) + f.close() + + def gen(self, api_list, output_path): + self.clear() + + # step 1: scan the list of declarations and build more descriptive maps of classes, consts, functions + for decl in api_list: + name = decl[0] + if name.startswith("struct") or name.startswith("class"): + # class/struct + p = name.find(" ") + stype = name[:p] + name = name[p+1:].strip() + self.add_class(stype, name, decl) + elif name.startswith("const"): + # constant + self.add_const(name.replace("const ", "").strip(), decl) + else: + # function + self.add_func(decl) + + # step 2: generate code for the classes and their methods + classlist = self.classes.items() + classlist.sort() + for name, classinfo in classlist: + code = classinfo.gen_code(self.classes) + self.code_types.write(code) + if not classinfo.ismap: + self.code_type_reg.write("MKTYPE2(%s);\n" % (classinfo.name,) ) + + # step 3: generate the code for all the global functions + funclist = self.funcs.items() + funclist.sort() + for name, func in funclist: + code = func.gen_code(self.classes) + self.code_funcs.write(code) + + # step 4: generate the code for constants + constlist = self.consts.items() + constlist.sort() + for name, constinfo in constlist: + self.gen_const_reg(constinfo) + + # That's it. Now save all the files + self.save(output_path, "pyopencv_generated_funcs.h", self.code_funcs) + self.save(output_path, "pyopencv_generated_func_tab.h", self.code_functab) + self.save(output_path, "pyopencv_generated_const_reg.h", self.code_const_reg) + self.save(output_path, "pyopencv_generated_types.h", self.code_types) + self.save(output_path, "pyopencv_generated_type_reg.h", self.code_type_reg) + +def generate_all(): + decls = opencv_parser.parse_all() + generator = PythonWrapperGenerator() + generator.gen(decls, "/Users/vp/tmp") + +if __name__ == "__main__": + generate_all() + + + diff --git a/modules/python/hdr_parser.py b/modules/python/hdr_parser.py index 191e3e1..4a72b1f 100755 --- a/modules/python/hdr_parser.py +++ b/modules/python/hdr_parser.py @@ -1,22 +1,23 @@ import os, sys, re -hdr_list = [ +opencv_hdr_list = [ "../core/include/opencv2/core/core.hpp", -"../core/include/opencv2/core/core_c.h", +#"../core/include/opencv2/core/core_c.h", "../ml/include/opencv2/ml/ml.hpp", "../imgproc/include/opencv2/imgproc/imgproc.hpp", -"../imgproc/include/opencv2/imgproc/imgproc_c.h", +#"../imgproc/include/opencv2/imgproc/imgproc_c.h", "../calib3d/include/opencv2/calib3d/calib3d.hpp", "../features2d/include/opencv2/features2d/features2d.hpp", "../video/include/opencv2/video/tracking.hpp", "../video/include/opencv2/video/background_segm.hpp", "../objdetect/include/opencv2/objdetect/objdetect.hpp", "../highgui/include/opencv2/highgui/highgui.hpp", -"../highgui/include/opencv2/highgui/highgui_c.h", +#"../highgui/include/opencv2/highgui/highgui_c.h", +"opencv_api_extra.hpp", ] """ -Each declaration is [funcname, return_value_type /* in C, not in Python */, ], +Each declaration is [funcname, return_value_type /* in C, not in Python */, , ], where each element of is 4-element list itself: [argtype, argname, default_value /* or "" if none */, ] where the list of modifiers is yet another nested list of strings @@ -38,6 +39,27 @@ class CppHeaderParser(object): s = s.replace(before, after) return s + def get_macro_arg(self, arg_str, npos): + + npos2 = npos3 = arg_str.find("(", npos) + if npos2 < 0: + print "Error: no arguments for the macro at %d" % (self.lineno,) + sys.exit(-1) + balance = 1 + while 1: + t, npos3 = self.find_next_token(arg_str, ['(', ')'], npos3+1) + if npos3 < 0: + print "Error: no matching ')' in the macro call at %d" % (self.lineno,) + sys.exit(-1) + if t == '(': + balance += 1 + if t == ')': + balance -= 1 + if balance == 0: + break + + return arg_str[npos2+1:npos3].strip(), npos3 + def parse_arg(self, arg_str, argno): """ Parses [arg_name] @@ -53,21 +75,26 @@ class CppHeaderParser(object): if "CV_OUT" in arg_str: modlist.append("/O") arg_str = arg_str.replace("CV_OUT", "") + + if "CV_IN_OUT" in arg_str: + modlist.append("/IO") + arg_str = arg_str.replace("CV_IN_OUT", "") isarray = False npos = arg_str.find("CV_CARRAY") if npos >= 0: isarray = True - npos2 = arg_str.find("(", npos) - npos3 = arg_str.find(")", npos) - if (npos2 < 0) or (npos3 <= npos2): - print "Error: no arguments for CV_CARRAY macro at %d" % (self.lineno,) - sys.exit(-1) - counter_str = arg_str[npos2+1:npos3] - if "(" in counter_str: - npos3 = arg_str.find(")", npos3+1) - counter_str = arg_str[npos2+1:npos3] - modlist.append("/A " + counter_str.strip() + ";") + macro_arg, npos3 = self.get_macro_arg(arg_str, npos) + + modlist.append("/A " + macro_arg) + arg_str = arg_str[:npos] + arg_str[npos3+1:] + + npos = arg_str.find("CV_CUSTOM_CARRAY") + if npos >= 0: + isarray = True + macro_arg, npos3 = self.get_macro_arg(arg_str, npos) + + modlist.append("/CA " + macro_arg) arg_str = arg_str[:npos] + arg_str[npos3+1:] arg_str = arg_str.strip() @@ -139,7 +166,8 @@ class CppHeaderParser(object): counter_str = "" add_star = False - if "[" in arg_name: + if ("[" in arg_name) and not ("operator" in arg_str): + #print arg_str p1 = arg_name.find("[") p2 = arg_name.find("]",p1+1) if p2 < 0: @@ -170,6 +198,25 @@ class CppHeaderParser(object): return arg_type, arg_name, modlist, argno + def parse_enum(self, decl_str): + l = decl_str + ll = l.split(",") + prev_val = "" + prev_val_delta = -1 + decl = [] + for pair in ll: + pv = pair.split("=") + if len(pv) == 1: + prev_val_delta += 1 + val = "" + if prev_val: + val = prev_val + "+" + val += str(prev_val_delta) + else: + prev_val_delta = 0 + prev_val = val = pv[1].strip() + decl.append(["const " + self.get_dotted_name(pv[0].strip()), val, [], []]) + return decl def parse_class_decl(self, decl_str): """ @@ -177,12 +224,23 @@ class CppHeaderParser(object): {class|struct} [CV_EXPORTS] [: public [, ...]] Returns class_name1, """ - l = self.batch_replace(decl_str, [("CV_EXPORTS", ""), ("public ", " "), ("::", ".")]).strip() + l = decl_str + modlist = [] + if "CV_EXPORTS_AS_MAP" in l: + l = l.replace("CV_EXPORTS_AS_MAP", "") + modlist.append("/Map") + npos = l.find("CV_EXPORTS_AS") + if npos >= 0: + macro_arg, npos3 = self.get_macro_arg(l, npos) + modlist.append("=" + macro_arg) + l = l[:npos] + l[npos3+1:] + + l = self.batch_replace(l, [("CV_EXPORTS_W", ""), ("CV_EXPORTS", ""), ("public ", " "), ("::", ".")]).strip() ll = re.split(r'\s*[,:]?\s*', l) ll = [le for le in ll if le] classname = ll[1] bases = ll[2:] - return classname, bases + return classname, bases, modlist def parse_func_decl(self, decl_str): """ @@ -196,12 +254,27 @@ class CppHeaderParser(object): [, , ] (see above) """ + if not (("CV_EXPORTS_AS" in decl_str) or ("CV_EXPORTS_W" in decl_str) or \ + ("CV_WRAP" in decl_str) or ("CV_WRAP_AS" in decl_str)): + return [] + + func_modlist = [] + + npos = decl_str.find("CV_EXPORTS_AS") + if npos >= 0: + arg, npos3 = self.get_macro_arg(decl_str, npos) + func_modlist.append("="+arg) + decl_str = decl_str[:npos] + decl_str[npos3+1:] + npos = decl_str.find("CV_WRAP_AS") + if npos >= 0: + arg, npos3 = self.get_macro_arg(decl_str, npos) + func_modlist.append("="+arg) + decl_str = decl_str[:npos] + decl_str[npos3+1:] # filter off some common prefixes, which are meaningless for Python wrappers. # note that we do not strip "static" prefix, which does matter; # it means class methods, not instance methods - for prefix in ["virtual", "static inline", "inline", "CV_EXPORTS", "static CV_INLINE", "CV_INLINE"]: - if decl_str.startswith(prefix): - decl_str = decl_str[len(prefix):].lstrip() + decl_str = self.batch_replace(decl_str, [("virtual", ""), ("static inline", ""), ("inline", ""),\ + ("CV_EXPORTS_W", ""), ("CV_EXPORTS", ""), ("CV_WRAP ", " "), ("static CV_INLINE", ""), ("CV_INLINE", "")]).strip() static_method = False context = self.block_stack[-1][0] @@ -290,14 +363,13 @@ class CppHeaderParser(object): else: eqpos = a.find("CV_DEFAULT") if eqpos >= 0: - pos2 = a.find("(",eqpos) - pos3 = a.rfind(")") - if pos2 < 0 or pos3 < 0: - print "Error at %d. no arguments for CV_DEFAULT macro" - sys.exit(-1) - defval = a[pos2+1:pos3].strip() - if defval == "NULL": - defval = "0" + defval, pos3 = self.get_macro_arg(a, eqpos) + else: + eqpos = a.find("CV_WRAP_DEFAULT") + if eqpos >= 0: + defval, pos3 = self.get_macro_arg(a, eqpos) + if defval == "NULL": + defval = "0" if eqpos >= 0: a = a[:eqpos].strip() arg_type, arg_name, modlist, argno = self.parse_arg(a, argno) @@ -312,7 +384,7 @@ class CppHeaderParser(object): if static_method: rettype = " ".join([rettype, "/S"]) - return [funcname, rettype, args] + return [funcname, rettype, func_modlist, args] def get_dotted_name(self, name): """ @@ -332,7 +404,7 @@ class CppHeaderParser(object): n = "" for b in self.block_stack: block_type, block_name = b[self.BLOCK_TYPE], b[self.BLOCK_NAME] - if block_type == "file": + if block_type in ["file", "enum"]: continue if block_type not in ["struct", "class", "namespace"]: print "Error at %d: there are non-valid entries in the current block stack " % (self.lineno, self.block_stack) @@ -377,21 +449,30 @@ class CppHeaderParser(object): # do not process hidden class members and template classes/functions if not stack_top[self.PUBLIC_SECTION] or stmt.startswith("template"): return stmt_type, "", False, None - - if end_token == "{" and (stmt.startswith("class") or stmt.startswith("struct")): - stmt_type = stmt.split()[0] - classname, bases = self.parse_class_decl(stmt) - decl = [stmt_type + " " + self.get_dotted_name(classname), "", []] - if bases: - decl[1] = ": " + " ".join(bases) - return [stmt_type, classname, True, decl] - + if end_token == "{": + if stmt.startswith("class") or stmt.startswith("struct"): + stmt_type = stmt.split()[0] + classname, bases, modlist = self.parse_class_decl(stmt) + decl = [] + if ("CV_EXPORTS_W" in stmt) or ("CV_EXPORTS_AS" in stmt): + decl = [stmt_type + " " + self.get_dotted_name(classname), "", modlist, []] + if bases: + decl[1] = ": " + " ".join(bases) + return stmt_type, classname, True, decl + + if stmt.startswith("enum"): + return "enum", "", True, None + if stmt.startswith("namespace"): stmt_list = stmt.split() return stmt_list[0], stmt_list[1], True, None if stmt.startswith("extern") and "\"C\"" in stmt: return "namespace", "", True, None + + if end_token == "}" and context == "enum": + decl = self.parse_enum(stmt) + return "enum", "", False, decl if end_token == ";" and stmt.startswith("typedef"): # TODO: handle typedef's more intelligently @@ -410,12 +491,18 @@ class CppHeaderParser(object): if (context == "struct" or context == "class") and end_token == ";" and stmt: # looks like it's member declaration; append the members to the class declaration - var_list = stmt.split(",") - var_type, var_name1, modlist, argno = self.parse_arg(var_list[0], -1) - var_list = [var_name1] + [i.strip() for i in var_list[1:]] class_decl = stack_top[self.CLASS_DECL] - for v in var_list: - class_decl[2].append([var_type, v, "", []]) + if ("CV_PROP" in stmt) or (class_decl and ("/Map" in class_decl[2])): + var_modlist = [] + if "CV_PROP_RW" in stmt: + var_modlist.append("/RW") + stmt = self.batch_replace(stmt, [("CV_PROP_RW", ""), ("CV_PROP", "")]).strip() + var_list = stmt.split(",") + var_type, var_name1, modlist, argno = self.parse_arg(var_list[0], -1) + var_list = [var_name1] + [i.strip() for i in var_list[1:]] + + for v in var_list: + class_decl[3].append([var_type, v, "", var_modlist]) return stmt_type, "", False, None # something unknown @@ -529,7 +616,11 @@ class CppHeaderParser(object): # since it can start with "public:" stmt_type, name, parse_flag, decl = self.parse_stmt(stmt, token) if decl: - decls.append(decl) + if stmt_type == "enum": + for d in decl: + decls.append(d) + else: + decls.append(decl) else: stmt_type, name, parse_flag = "block", "", False @@ -557,17 +648,36 @@ class CppHeaderParser(object): Prints the list of declarations, retrieived by the parse() method """ for d in decls: - print d[0], d[1] - for a in d[2]: + print d[0], d[1], ";".join(d[2]) + for a in d[3]: print " ", a[0], a[1], a[2], if a[3]: print "; ".join(a[3]) else: print -parser = CppHeaderParser() +def parse_all(): + parser = CppHeaderParser() + decls = [] + for hname in opencv_hdr_list: + decls += parser.parse(hname) + return decls -decls = [] -for hname in hdr_list: - decls += parser.parse(hname) -parser.print_decls(decls) +if __name__ == '__main__': + parser = CppHeaderParser() + decls = parse_all() + if 0: + pass + elif 1: + CppHeaderParser().print_decls(decls) + print len(decls) + else: + fcounts = {} + for f in decls: + fname = f[0] + fcounts[fname] = fcounts.get(fname, []) + [f] + items = fcounts.items() + items.sort() + for fname, flist in items: + if len(flist) > 1: + parser.print_decls(flist) diff --git a/modules/python/opencv2x.h b/modules/python/opencv2x.h new file mode 100644 index 0000000..31148ab --- /dev/null +++ b/modules/python/opencv2x.h @@ -0,0 +1,356 @@ +#ifndef OPENCV2X_PYTHON_WRAPPERS +#define OPENCV2X_PYTHON_WRAPPERS + +#include "opencv2/core/core.hpp" + +namespace cv +{ + +#define ERRWRAP2(expr) \ +try \ +{ \ + expr; \ +} \ +catch (const cv::Exception &e) \ +{ \ + PyErr_SetString(opencv_error, e.what()); \ + return 0; \ +} + +static size_t REFCOUNT_OFFSET = (size_t)&(((PyObject*)0)->ob_refcnt) + + (0x12345678 != *(const size_t*)"\x78\x56\x34\x12\0\0\0\0\0")*sizeof(int); + +static inline PyObject* pyObjectFromRefcount(const int* refcount) +{ + return (PyObject*)((size_t)refcount - REFCOUNT_OFFSET); +} + +static inline int* refcountFromPyObject(const PyObject* obj) +{ + return (int*)((size_t)obj + REFCOUNT_OFFSET); +} + +class NumpyAllocator : public MatAllocator +{ +public: + NumpyAllocator() {} + ~NumpyAllocator() {} + + void allocate(int dims, const int* sizes, int type, int*& refcount, + uchar*& datastart, uchar*& data, size_t* step) + { + static int ncalls = 0; + printf("NumpyAllocator::allocate: %d\n", ncalls++); + + int depth = CV_MAT_DEPTH(type); + int cn = CV_MAT_CN(type); + const int f = (int)(sizeof(size_t)/8); + int typenum = depth == CV_8U ? NPY_UBYTE : depth == CV_8S ? NPY_BYTE : + depth == CV_16U ? NPY_USHORT : depth == CV_16S ? NPY_SHORT : + depth == CV_32S ? NPY_INT : depth == CV_32F ? NPY_FLOAT : + depth == CV_64F ? NPY_DOUBLE : f*NPY_ULONGLONG + (f^1)*NPY_UINT; + int i; + npy_intp _sizes[CV_MAX_DIM+1]; + for( i = 0; i < dims; i++ ) + _sizes[i] = sizes[i]; + if( cn > 1 ) + { + if( _sizes[dims-1] == 1 ) + _sizes[dims-1] = cn; + else + _sizes[dims++] = cn; + } + PyObject* o = PyArray_SimpleNew(dims, _sizes, typenum); + if(!o) + CV_Error_(CV_StsError, ("The numpy array of typenum=%d, ndims=%d can not be created", typenum, dims)); + refcount = refcountFromPyObject(o); + npy_intp* _strides = PyArray_STRIDES(o); + for( i = 0; i < dims-1; i++ ) + step[i] = (size_t)_strides[i]; + datastart = data = (uchar*)PyArray_DATA(o); + } + + void deallocate(int* refcount, uchar* datastart, uchar* data) + { + static int ncalls = 0; + printf("NumpyAllocator::deallocate: %d\n", ncalls++); + + if( !refcount ) + return; + PyObject* o = pyObjectFromRefcount(refcount); + Py_DECREF(o); + } +}; + +NumpyAllocator g_numpyAllocator; + +enum { ARG_NONE = 0, ARG_MAT = 1, ARG_SCALAR = 2 }; + +static int pyobjToMat(const PyObject* o, Mat& m, const char* name = "", bool allowND=true) +{ + static int call_idx = 0; + printf("pyobjToMatND: %d\n", call_idx++); + + if( !PyArray_Check(o) ) { + if( o == Py_None ) + return ARG_NONE; + failmsg("%s is not a numpy array", name); + return -1; + } + + int typenum = PyArray_TYPE(o); + int type = typenum == NPY_UBYTE ? CV_8U : typenum == NPY_BYTE ? CV_8S : + typenum == NPY_USHORT ? CV_16U : typenum == NPY_SHORT ? CV_16S : + typenum == NPY_INT || typenum == NPY_LONG ? CV_32S : + typenum == NPY_FLOAT ? CV_32F : + typenum == NPY_DOUBLE ? CV_64F : -1; + + if( type < 0 ) + { + failmsg("%s data type = %d is not supported", name, typenum); + return -1; + } + + int ndims = PyArray_NDIM(o); + if(ndims >= CV_MAX_DIM) + { + failmsg("%s dimensionality (=%d) is too high", name, ndims); + return -1; + } + + int size[CV_MAX_DIM+1]; + size_t step[CV_MAX_DIM+1], elemsize = CV_ELEM_SIZE(type); + const npy_intp* _sizes = PyArray_DIMS(o); + const npy_intp* _strides = PyArray_STRIDES(o); + + for(int i = 0; i < ndims; i++) + { + size[i] = (int)_sizes[i]; + step[i] = (size_t)_strides[i]; + } + + if( ndims == 0 || step[ndims-1] > elemsize ) { + size[ndims] = 1; + step[ndims] = elemsize; + ndims++; + } + + m = Mat(ndims, size, type, PyArray_DATA(o), step); + + if (!allowND) + { + if( ndims <= 2 ) + ; + else if( ndims == 3 ) + { + if( size[2] > CV_CN_MAX || step[1] != elemsize*size[2] ) + { + failmsg("%s is not contiguous, thus it can not be interpreted as image", name); + return -1; + } + m.dims--; + m.flags = (m.flags & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(type, size[2]); + } + else + { + failmsg("%s is not contiguous or has more than 3 dimensions, thus it can not be interpreted as image", name); + return -1; + } + } + + if( m.data ) + { + m.refcount = refcountFromPyObject(o); + ++*m.refcount; // protect the original numpy array from deallocation + // (since Mat destructor will decrement the reference counter) + }; + m.allocator = &g_numpyAllocator; + return ARG_MAT; +} + +static void makeEmptyMat(Mat& m) +{ + m = Mat(); + m.allocator = &g_numpyAllocator; +} + +static int pyobjToMat(const PyObject* o, Mat& m, const char* name = "") +{ + Mat temp; + int code = pyobjToMat(o, temp, name, false); + if(code > 0) + m = Mat(temp); + return code; +} + +static int pyobjToScalar(PyObject *o, Scalar& s, const char *name = "") +{ + if (PySequence_Check(o)) { + PyObject *fi = PySequence_Fast(o, name); + if (fi == NULL) + return -1; + if (4 < PySequence_Fast_GET_SIZE(fi)) + { + failmsg("Scalar value for argument '%s' is longer than 4", name); + return -1; + } + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + if (PyFloat_Check(item) || PyInt_Check(item)) { + s[i] = PyFloat_AsDouble(item); + } else { + failmsg("Scalar value for argument '%s' is not numeric", name); + return -1; + } + } + Py_DECREF(fi); + } else { + if (PyFloat_Check(o) || PyInt_Check(o)) { + s[0] = PyFloat_AsDouble(o); + } else { + failmsg("Scalar value for argument '%s' is not numeric", name); + return -1; + } + } + return ARG_SCALAR; +} + + +static int pyobjToMatOrScalar(PyObject* obj, Mat& m, Scalar& s, const char* name, bool allowND) +{ + if( PyArray_Check(obj) || (obj == Py_None)) + return pyobjToMat(obj, m, name, allowND); + + return pyobjToScalar(obj, s, name); +} + +static void pyc_add_mm(const Mat& a, const Mat& b, Mat& c, const Mat& mask) { add(a, b, c, mask); } +static void pyc_add_ms(const Mat& a, const Scalar& s, Mat& c, const Mat& mask, bool) { add(a, s, c, mask); } +static void pyc_subtract_mm(const Mat& a, const Mat& b, Mat& c, const Mat& mask) { subtract(a, b, c, mask); } +static void pyc_subtract_ms(const Mat& a, const Scalar& s, Mat& c, const Mat& mask, bool rev) +{ + if( !rev ) + subtract(a, s, c, mask); + else + subtract(s, a, c, mask); +} + +static void pyc_and_mm(const Mat& a, const Mat& b, Mat& c, const Mat& mask) { bitwise_and(a, b, c, mask); } +static void pyc_and_ms(const Mat& a, const Scalar& s, Mat& c, const Mat& mask, bool) { bitwise_and(a, s, c, mask); } +static void pyc_or_mm(const Mat& a, const Mat& b, Mat& c, const Mat& mask) { bitwise_or(a, b, c, mask); } +static void pyc_or_ms(const Mat& a, const Scalar& s, Mat& c, const Mat& mask, bool) { bitwise_or(a, s, c, mask); } +static void pyc_xor_mm(const Mat& a, const Mat& b, Mat& c, const Mat& mask) { bitwise_xor(a, b, c, mask); } +static void pyc_xor_ms(const Mat& a, const Scalar& s, Mat& c, const Mat& mask, bool) { bitwise_xor(a, s, c, mask); } +static void pyc_absdiff_mm(const Mat& a, const Mat& b, Mat& c, const Mat&) { absdiff(a, b, c); } +static void pyc_absdiff_ms(const Mat& a, const Scalar& s, Mat& c, const Mat&, bool) { absdiff(a, s, c); } +static void pyc_min_mm(const Mat& a, const Mat& b, Mat& c, const Mat&) { min(a, b, c); } +static void pyc_min_ms(const Mat& a, const Scalar& s, Mat& c, const Mat&, bool) +{ + CV_Assert( s.isReal() ); + min(a, s[0], c); +} +static void pyc_max_mm(const Mat& a, const Mat& b, Mat& c, const Mat&) { max(a, b, c); } +static void pyc_max_ms(const Mat& a, const Scalar& s, Mat& c, const Mat&, bool) +{ + CV_Assert( s.isReal() ); + max(a, s[0], c); +} + +typedef void (*BinaryOp)(const Mat& a, const Mat& b, Mat& c, const Mat& mask); +typedef void (*BinaryOpS)(const Mat& a, const Scalar& s, Mat& c, const Mat& mask, bool rev); + +static PyObject *pyopencv_binary_op(PyObject* args, PyObject* kw, BinaryOp binOp, BinaryOpS binOpS, bool supportMask) +{ + PyObject *pysrc1 = 0, *pysrc2 = 0, *pydst = 0, *pymask = 0; + Mat src1, src2, dst, mask; + Scalar alpha, beta; + + if( supportMask ) + { + const char *keywords[] = { "src1", "src2", "dst", "mask", 0 }; + if( !PyArg_ParseTupleAndKeywords(args, kw, "OO|OO", (char**)keywords, + &pysrc1, &pysrc2, &pydst, &pymask)) + return 0; + } + else + { + const char *keywords[] = { "src1", "src2", "dst", 0 }; + if( !PyArg_ParseTupleAndKeywords(args, kw, "OO|O", (char**)keywords, + &pysrc1, &pysrc2, &pydst)) + return 0; + } + + int code_src1 = pysrc1 ? pyobjToMatOrScalar(pysrc1, src1, alpha, "src1", true) : -1; + int code_src2 = pysrc2 ? pyobjToMatOrScalar(pysrc2, src2, beta, "src2", true) : -1; + int code_dst = pydst ? pyobjToMat(pydst, dst, "dst", true) : 0; + int code_mask = pymask ? pyobjToMat(pymask, mask, "mask", true) : 0; + + if( code_src1 < 0 || code_src2 < 0 || code_dst < 0 || code_mask < 0 ) + return 0; + + if( code_src1 == ARG_SCALAR && code_src2 == ARG_SCALAR ) + { + failmsg("Both %s and %s are scalars", "src1", "src2"); + return 0; + } + + if( code_dst == 0 ) + makeEmptyMat(dst); + + ERRWRAP2(code_src1 != ARG_SCALAR && code_src2 != ARG_SCALAR ? binOp(src1, src2, dst, mask) : + code_src1 != ARG_SCALAR ? binOpS(src2, alpha, dst, mask, true) : binOpS(src1, beta, dst, mask, false)); + + PyObject* result = pyObjectFromRefcount(dst.refcount); + int D = PyArray_NDIM(result); + const npy_intp* sz = PyArray_DIMS(result); + + printf("Result: check = %d, ndims = %d, size = (%d x %d), typenum=%d\n", PyArray_Check(result), + D, (int)sz[0], D >= 2 ? (int)sz[1] : 1, PyArray_TYPE(result)); + + //Py_INCREF(result); + return result; +} + +static PyObject* pyopencv_add(PyObject* self, PyObject* args, PyObject* kw) +{ + return pyopencv_binary_op(args, kw, pyc_add_mm, pyc_add_ms, true); +} + +static PyObject* pyopencv_subtract(PyObject* self, PyObject* args, PyObject* kw) +{ + return pyopencv_binary_op(args, kw, pyc_subtract_mm, pyc_subtract_ms, true); +} + +static PyObject* pyopencv_and(PyObject* self, PyObject* args, PyObject* kw) +{ + return pyopencv_binary_op(args, kw, pyc_and_mm, pyc_and_ms, true); +} + +static PyObject* pyopencv_or(PyObject* self, PyObject* args, PyObject* kw) +{ + return pyopencv_binary_op(args, kw, pyc_or_mm, pyc_or_ms, true); +} + +static PyObject* pyopencv_xor(PyObject* self, PyObject* args, PyObject* kw) +{ + return pyopencv_binary_op(args, kw, pyc_xor_mm, pyc_xor_ms, true); +} + +static PyObject* pyopencv_absdiff(PyObject* self, PyObject* args, PyObject* kw) +{ + return pyopencv_binary_op(args, kw, pyc_absdiff_mm, pyc_absdiff_ms, true); +} + +static PyObject* pyopencv_min(PyObject* self, PyObject* args, PyObject* kw) +{ + return pyopencv_binary_op(args, kw, pyc_min_mm, pyc_min_ms, true); +} + +static PyObject* pyopencv_max(PyObject* self, PyObject* args, PyObject* kw) +{ + return pyopencv_binary_op(args, kw, pyc_max_mm, pyc_max_ms, true); +} + +} + +#endif diff --git a/modules/video/include/opencv2/video/tracking.hpp b/modules/video/include/opencv2/video/tracking.hpp index 017c861..abd7f27 100644 --- a/modules/video/include/opencv2/video/tracking.hpp +++ b/modules/video/include/opencv2/video/tracking.hpp @@ -260,11 +260,11 @@ CV_EXPORTS_W double calcGlobalOrientation( const Mat& orientation, const Mat& ma // TODO: need good API for cvSegmentMotion //! updates the object tracking window using CAMSHIFT algorithm -CV_EXPORTS_W RotatedRect CamShift( const Mat& probImage, CV_OUT Rect& window, +CV_EXPORTS_W RotatedRect CamShift( const Mat& probImage, CV_IN_OUT Rect& window, TermCriteria criteria ); //! updates the object tracking window using meanshift algorithm -CV_EXPORTS_W int meanShift( const Mat& probImage, CV_OUT Rect& window, +CV_EXPORTS_W int meanShift( const Mat& probImage, CV_IN_OUT Rect& window, TermCriteria criteria ); /*! -- 2.7.4