From 6de422701aa6da643a4abe58e91d901408b0b93c Mon Sep 17 00:00:00 2001 From: LeonidBeynenson Date: Tue, 29 Jan 2013 21:11:52 +0400 Subject: [PATCH 01/17] Made changes to allow ml module to work with big data. --- apps/traincascade/boost.cpp | 73 +++++++++++++++-------- modules/ml/include/opencv2/ml/ml.hpp | 8 ++- modules/ml/src/boost.cpp | 14 +++-- modules/ml/src/ertrees.cpp | 56 +++++++++++------ modules/ml/src/tree.cpp | 89 +++++++++++++++++----------- 5 files changed, 156 insertions(+), 84 deletions(-) diff --git a/apps/traincascade/boost.cpp b/apps/traincascade/boost.cpp index 3e17b5d42f..0ba11a936a 100644 --- a/apps/traincascade/boost.cpp +++ b/apps/traincascade/boost.cpp @@ -360,7 +360,7 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id if (is_buf_16u) { - unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols + + unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + vi*sample_count + data_root->offset); for( int i = 0; i < num_valid; i++ ) { @@ -373,7 +373,7 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id } else { - int* idst_idx = buf->data.i + root->buf_idx*buf->cols + + int* idst_idx = buf->data.i + root->buf_idx*get_length_subbuf() + vi*sample_count + root->offset; for( int i = 0; i < num_valid; i++ ) { @@ -390,14 +390,14 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id const int* src_lbls = get_cv_labels(data_root, (int*)(uchar*)inn_buf); if (is_buf_16u) { - unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols + + unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + (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*buf->cols + + int* idst = buf->data.i + root->buf_idx*get_length_subbuf() + (workVarCount-1)*sample_count + root->offset; for( int i = 0; i < count; i++ ) idst[i] = src_lbls[sidx[i]]; @@ -407,14 +407,14 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id const int* sample_idx_src = get_sample_indices(data_root, (int*)(uchar*)inn_buf); if (is_buf_16u) { - unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols + + unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + 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*buf->cols + + int* sample_idx_dst = buf->data.i + root->buf_idx*get_length_subbuf() + workVarCount*sample_count + root->offset; for( int i = 0; i < count; i++ ) sample_idx_dst[i] = sample_idx_src[sidx[i]]; @@ -489,6 +489,10 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat int* idst = 0; unsigned short* udst = 0; + uint64 effective_buf_size = -1; + int effective_buf_height = -1, effective_buf_width = -1; + + clear(); shared = true; have_labels = true; @@ -548,13 +552,28 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat 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_size = (work_var_count + 1) * sample_count/*sample_indices*/; buf_count = 2; - if ( is_buf_16u ) - buf = cvCreateMat( buf_count, buf_size, CV_16UC1 ); + 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 - buf = cvCreateMat( buf_count, buf_size, CV_32SC1 ); + 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 ); @@ -609,7 +628,7 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat 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 ); + split_buf = cvCreateMat( 1, sample_count, CV_32SC1 );//TODO: make a pointer } void CvCascadeBoostTrainData::free_train_data() @@ -652,10 +671,10 @@ void CvCascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* o if ( vi < numPrecalcIdx ) { if( !is_buf_16u ) - *sortedIndices = buf->data.i + n->buf_idx*buf->cols + vi*sample_count + n->offset; + *sortedIndices = buf->data.i + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset; else { - const unsigned short* shortIndices = (const unsigned short*)(buf->data.s + n->buf_idx*buf->cols + + const unsigned short* shortIndices = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset ); for( int i = 0; i < nodeSampleCount; i++ ) sortedIndicesBuf[i] = shortIndices[i]; @@ -1027,6 +1046,7 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) 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*)(uchar*)inn_buf; bool splitInputData; @@ -1070,7 +1090,7 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) if (data->is_buf_16u) { ushort *ldst, *rdst; - ldst = (ushort*)(buf->data.s + left->buf_idx*buf->cols + + ldst = (ushort*)(buf->data.s + left->buf_idx*length_buf_row + vi*scount + left->offset); rdst = (ushort*)(ldst + nl); @@ -1096,9 +1116,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) else { int *ldst, *rdst; - ldst = buf->data.i + left->buf_idx*buf->cols + + ldst = buf->data.i + left->buf_idx*length_buf_row + vi*scount + left->offset; - rdst = buf->data.i + right->buf_idx*buf->cols + + rdst = buf->data.i + right->buf_idx*length_buf_row + vi*scount + right->offset; // split sorted @@ -1131,9 +1151,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) if (data->is_buf_16u) { - unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*buf->cols + + unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*length_buf_row + (workVarCount-1)*scount + left->offset); - unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*buf->cols + + unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*length_buf_row + (workVarCount-1)*scount + right->offset); for( int i = 0; i < n; i++ ) @@ -1154,9 +1174,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) } else { - int *ldst = buf->data.i + left->buf_idx*buf->cols + + int *ldst = buf->data.i + left->buf_idx*length_buf_row + (workVarCount-1)*scount + left->offset; - int *rdst = buf->data.i + right->buf_idx*buf->cols + + int *rdst = buf->data.i + right->buf_idx*length_buf_row + (workVarCount-1)*scount + right->offset; for( int i = 0; i < n; i++ ) @@ -1184,9 +1204,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) if (data->is_buf_16u) { - unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*buf->cols + + unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*length_buf_row + workVarCount*scount + left->offset); - unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*buf->cols + + unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*length_buf_row + workVarCount*scount + right->offset); for (int i = 0; i < n; i++) { @@ -1205,9 +1225,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) } else { - int* ldst = buf->data.i + left->buf_idx*buf->cols + + int* ldst = buf->data.i + left->buf_idx*length_buf_row + workVarCount*scount + left->offset; - int* rdst = buf->data.i + right->buf_idx*buf->cols + + int* rdst = buf->data.i + right->buf_idx*length_buf_row + workVarCount*scount + right->offset; for (int i = 0; i < n; i++) { @@ -1352,6 +1372,7 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree ) 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); @@ -1375,7 +1396,7 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree ) if (data->is_buf_16u) { - unsigned short* labels = (unsigned short*)(buf->data.s + data->data_root->buf_idx*buf->cols + + unsigned short* labels = (unsigned short*)(buf->data.s + data->data_root->buf_idx*length_buf_row + data->data_root->offset + (data->work_var_count-1)*data->sample_count); for( int i = 0; i < n; i++ ) { @@ -1393,7 +1414,7 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree ) } else { - int* labels = buf->data.i + data->data_root->buf_idx*buf->cols + + int* labels = buf->data.i + data->data_root->buf_idx*length_buf_row + data->data_root->offset + (data->work_var_count-1)*data->sample_count; for( int i = 0; i < n; i++ ) diff --git a/modules/ml/include/opencv2/ml/ml.hpp b/modules/ml/include/opencv2/ml/ml.hpp index 32047608e0..dc7a4048a5 100644 --- a/modules/ml/include/opencv2/ml/ml.hpp +++ b/modules/ml/include/opencv2/ml/ml.hpp @@ -796,7 +796,7 @@ struct CV_EXPORTS CvDTreeTrainData const CvMat* responses; CvMat* responses_copy; // used in Boosting - int buf_count, buf_size; + 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; @@ -806,6 +806,12 @@ struct CV_EXPORTS CvDTreeTrainData 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; diff --git a/modules/ml/src/boost.cpp b/modules/ml/src/boost.cpp index 3525a1173a..8db94bd713 100644 --- a/modules/ml/src/boost.cpp +++ b/modules/ml/src/boost.cpp @@ -1130,13 +1130,13 @@ CvBoost::update_weights( CvBoostTree* tree ) 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) ? data->sample_count*sizeof(int) : 0; + 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->buf->cols*(sizeof(float)+sizeof(uchar)); + _buf_size += data->get_length_subbuf()*(sizeof(float)+sizeof(uchar)); } inn_buf.allocate(_buf_size); uchar* cur_buf_pos = (uchar*)inn_buf; @@ -1151,6 +1151,7 @@ CvBoost::update_weights( CvBoostTree* tree ) 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; @@ -1189,7 +1190,7 @@ CvBoost::update_weights( CvBoostTree* tree ) if (data->is_buf_16u) { - unsigned short* labels = (unsigned short*)(dtree_data_buf->data.s + data->data_root->buf_idx*dtree_data_buf->cols + + unsigned short* labels = (unsigned short*)(dtree_data_buf->data.s + data->data_root->buf_idx*length_buf_row + data->data_root->offset + (data->work_var_count-1)*data->sample_count); for( i = 0; i < n; i++ ) { @@ -1207,7 +1208,7 @@ CvBoost::update_weights( CvBoostTree* tree ) } else { - int* labels = dtree_data_buf->data.i + data->data_root->buf_idx*dtree_data_buf->cols + + int* labels = dtree_data_buf->data.i + data->data_root->buf_idx*length_buf_row + data->data_root->offset + (data->work_var_count-1)*data->sample_count; for( i = 0; i < n; i++ ) @@ -1254,9 +1255,10 @@ CvBoost::update_weights( CvBoostTree* tree ) if( have_subsample ) { float* values = (float*)cur_buf_pos; - cur_buf_pos = (uchar*)(values + data->buf->cols); + cur_buf_pos = (uchar*)(values + data->get_length_subbuf()); uchar* missing = cur_buf_pos; - cur_buf_pos = missing + data->buf->step; + cur_buf_pos = missing + data->get_length_subbuf() * (size_t)CV_ELEM_SIZE(data->buf->type); + CvMat _sample, _mask; // invert the subsample mask diff --git a/modules/ml/src/ertrees.cpp b/modules/ml/src/ertrees.cpp index 8a3828d993..380d87a795 100644 --- a/modules/ml/src/ertrees.cpp +++ b/modules/ml/src/ertrees.cpp @@ -75,11 +75,14 @@ void CvERTreeTrainData::set_data( const CvMat* _train_data, int _tflag, 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; + int64 ds_step, dv_step, ms_step = 0, mv_step = 0; // {data|mask}{sample|var}_step + int64 vi, i, size; char err[100]; const int *sidx = 0, *vidx = 0; + uint64 effective_buf_size = -1; + int effective_buf_height = -1, effective_buf_width = -1; + if ( _params.use_surrogates ) CV_ERROR(CV_StsBadArg, "CvERTrees do not support surrogate splits"); @@ -179,18 +182,34 @@ void CvERTreeTrainData::set_data( const CvMat* _train_data, int _tflag, have_labels = cv_n > 0 || (ord_var_count == 1 && cat_var_count == 0) || _add_labels; work_var_count = cat_var_count + (is_classifier ? 1 : 0) + (have_labels ? 1 : 0); - buf_size = (work_var_count + 1)*sample_count; + 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( buf_count, buf_size, CV_16UC1 )); + 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( buf_count, buf_size, CV_32SC1 )); + CV_CALL( buf = cvCreateMat( effective_buf_height, effective_buf_width, CV_32SC1 )); CV_CALL( int_ptr = (int**)cvAlloc( sample_count*sizeof(int_ptr[0]) )); } @@ -303,7 +322,7 @@ void CvERTreeTrainData::set_data( const CvMat* _train_data, int _tflag, val = cvRound(t); if( val != t ) { - sprintf( err, "%d-th value of %d-th (categorical) " + sprintf( err, "%ld-th value of %ld-th (categorical) " "variable is not an integer", i, vi ); CV_ERROR( CV_StsBadArg, err ); } @@ -311,7 +330,7 @@ void CvERTreeTrainData::set_data( const CvMat* _train_data, int _tflag, if( val == INT_MAX ) { - sprintf( err, "%d-th value of %d-th (categorical) " + sprintf( err, "%ld-th value of %ld-th (categorical) " "variable is too large", i, vi ); CV_ERROR( CV_StsBadArg, err ); } @@ -414,7 +433,7 @@ void CvERTreeTrainData::set_data( const CvMat* _train_data, int _tflag, if( fabs(val) >= ord_nan ) { - sprintf( err, "%d-th value of %d-th (ordered) " + sprintf( err, "%ld-th value of %ld-th (ordered) " "variable (=%g) is too large", i, vi, val ); CV_ERROR( CV_StsBadArg, err ); } @@ -578,9 +597,9 @@ const int* CvERTreeTrainData::get_cat_var_data( CvDTreeNode* n, int vi, int* cat int ci = get_var_type( vi); const int* cat_values = 0; if( !is_buf_16u ) - cat_values = buf->data.i + n->buf_idx*buf->cols + ci*sample_count + n->offset; + cat_values = buf->data.i + n->buf_idx*get_length_subbuf() + ci*sample_count + n->offset; else { - const unsigned short* short_values = (const unsigned short*)(buf->data.s + n->buf_idx*buf->cols + + const unsigned short* short_values = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + ci*sample_count + n->offset); for( int i = 0; i < n->sample_count; i++ ) cat_values_buf[i] = short_values[i]; @@ -1333,6 +1352,7 @@ void CvForestERTree::split_node_data( CvDTreeNode* node ) CvDTreeNode *left = 0, *right = 0; int new_buf_idx = data->get_child_buf_idx( node ); CvMat* buf = data->buf; + size_t length_buf_row = data->get_length_subbuf(); cv::AutoBuffer temp_buf(n); complete_node_dir(node); @@ -1385,9 +1405,9 @@ void CvForestERTree::split_node_data( CvDTreeNode* node ) if (data->is_buf_16u) { - unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*buf->cols + + unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*length_buf_row + ci*scount + left->offset); - unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*buf->cols + + unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*length_buf_row + ci*scount + right->offset); for( i = 0; i < n; i++ ) @@ -1415,9 +1435,9 @@ void CvForestERTree::split_node_data( CvDTreeNode* node ) } else { - int *ldst = buf->data.i + left->buf_idx*buf->cols + + int *ldst = buf->data.i + left->buf_idx*length_buf_row + ci*scount + left->offset; - int *rdst = buf->data.i + right->buf_idx*buf->cols + + int *rdst = buf->data.i + right->buf_idx*length_buf_row + ci*scount + right->offset; for( i = 0; i < n; i++ ) @@ -1460,9 +1480,9 @@ void CvForestERTree::split_node_data( CvDTreeNode* node ) if (data->is_buf_16u) { - unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*buf->cols + + 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*buf->cols + + unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*length_buf_row + pos*scount + right->offset); for (i = 0; i < n; i++) @@ -1483,9 +1503,9 @@ void CvForestERTree::split_node_data( CvDTreeNode* node ) } else { - int* ldst = buf->data.i + left->buf_idx*buf->cols + + int* ldst = buf->data.i + left->buf_idx*length_buf_row + pos*scount + left->offset; - int* rdst = buf->data.i + right->buf_idx*buf->cols + + int* rdst = buf->data.i + right->buf_idx*length_buf_row + pos*scount + right->offset; for (i = 0; i < n; i++) { diff --git a/modules/ml/src/tree.cpp b/modules/ml/src/tree.cpp index 0da24d66a2..aef4a3523b 100644 --- a/modules/ml/src/tree.cpp +++ b/modules/ml/src/tree.cpp @@ -50,7 +50,8 @@ static const int block_size_delta = 1 << 10; CvDTreeTrainData::CvDTreeTrainData() { var_idx = var_type = cat_count = cat_ofs = cat_map = - priors = priors_mult = counts = buf = direction = split_buf = responses_copy = 0; + priors = priors_mult = counts = direction = split_buf = responses_copy = 0; + buf = 0; tree_storage = temp_storage = 0; clear(); @@ -64,7 +65,8 @@ CvDTreeTrainData::CvDTreeTrainData( const CvMat* _train_data, int _tflag, bool _shared, bool _add_labels ) { var_idx = var_type = cat_count = cat_ofs = cat_map = - priors = priors_mult = counts = buf = direction = split_buf = responses_copy = 0; + priors = priors_mult = counts = direction = split_buf = responses_copy = 0; + buf = 0; tree_storage = temp_storage = 0; @@ -152,11 +154,14 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, 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; + int64 ds_step, dv_step, ms_step = 0, mv_step = 0; // {data|mask}{sample|var}_step + int64 vi, i, size; char err[100]; const int *sidx = 0, *vidx = 0; + uint64 effective_buf_size = -1; + int effective_buf_height = -1, effective_buf_width = -1; + if( _update_data && data_root ) { data = new CvDTreeTrainData( _train_data, _tflag, _responses, _var_idx, @@ -285,18 +290,35 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, work_var_count = var_count + (is_classifier ? 1 : 0) // for responses class_labels + (have_labels ? 1 : 0); // for cv_labels - buf_size = (work_var_count + 1 /*for sample_indices*/) * sample_count; 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( buf_count, buf_size, CV_16UC1 )); + 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( buf_count, buf_size, CV_32SC1 )); + CV_CALL( buf = cvCreateMat( effective_buf_height, effective_buf_width, CV_32SC1 )); CV_CALL( int_ptr = (int**)cvAlloc( sample_count*sizeof(int_ptr[0]) )); } @@ -356,7 +378,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, { int ci; const uchar* mask = 0; - int m_step = 0, step; + int64 m_step = 0, step; const int* idata = 0; const float* fdata = 0; int num_valid = 0; @@ -409,7 +431,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, val = cvRound(t); if( fabs(t - val) > FLT_EPSILON ) { - sprintf( err, "%d-th value of %d-th (categorical) " + sprintf( err, "%ld-th value of %ld-th (categorical) " "variable is not an integer", i, vi ); CV_ERROR( CV_StsBadArg, err ); } @@ -417,7 +439,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, if( val == INT_MAX ) { - sprintf( err, "%d-th value of %d-th (categorical) " + sprintf( err, "%ld-th value of %ld-th (categorical) " "variable is too large", i, vi ); CV_ERROR( CV_StsBadArg, err ); } @@ -524,7 +546,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, if( fabs(val) >= ord_nan ) { - sprintf( err, "%d-th value of %d-th (ordered) " + sprintf( err, "%ld-th value of %ld-th (ordered) " "variable (=%g) is too large", i, vi, val ); CV_ERROR( CV_StsBadArg, err ); } @@ -532,7 +554,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, } if (is_buf_16u) - udst[i] = (unsigned short)i; + udst[i] = (unsigned short)i; // TODO: memory corruption may be here else idst[i] = i; _fdst[i] = val; @@ -751,7 +773,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) if (is_buf_16u) { - unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols + + unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + vi*sample_count + root->offset); for( i = 0; i < count; i++ ) { @@ -762,7 +784,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) } else { - int* idst = buf->data.i + root->buf_idx*buf->cols + + int* idst = buf->data.i + root->buf_idx*get_length_subbuf() + vi*sample_count + root->offset; for( i = 0; i < count; i++ ) { @@ -788,7 +810,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) if (is_buf_16u) { - unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols + + unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + vi*sample_count + data_root->offset); for( i = 0; i < num_valid; i++ ) { @@ -812,7 +834,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) } else { - int* idst_idx = buf->data.i + root->buf_idx*buf->cols + + int* idst_idx = buf->data.i + root->buf_idx*get_length_subbuf() + vi*sample_count + root->offset; for( i = 0; i < num_valid; i++ ) { @@ -840,14 +862,14 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) const int* sample_idx_src = get_sample_indices(data_root, (int*)(uchar*)inn_buf); if (is_buf_16u) { - unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols + + unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + 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*buf->cols + + int* sample_idx_dst = buf->data.i + root->buf_idx*get_length_subbuf() + workVarCount*sample_count + root->offset; for (i = 0; i < count; i++) sample_idx_dst[i] = sample_idx_src[sidx[i]]; @@ -1158,10 +1180,10 @@ void CvDTreeTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ord_valu const int* sample_indices = get_sample_indices(n, sample_indices_buf); if( !is_buf_16u ) - *sorted_indices = buf->data.i + n->buf_idx*buf->cols + + *sorted_indices = buf->data.i + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset; else { - const unsigned short* short_indices = (const unsigned short*)(buf->data.s + n->buf_idx*buf->cols + + const unsigned short* short_indices = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset ); for( int i = 0; i < node_sample_count; i++ ) sorted_indices_buf[i] = short_indices[i]; @@ -1232,10 +1254,10 @@ const int* CvDTreeTrainData::get_cat_var_data( CvDTreeNode* n, int vi, int* cat_ { const int* cat_values = 0; if( !is_buf_16u ) - cat_values = buf->data.i + n->buf_idx*buf->cols + + cat_values = buf->data.i + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset; else { - const unsigned short* short_values = (const unsigned short*)(buf->data.s + n->buf_idx*buf->cols + + const unsigned short* short_values = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset); for( int i = 0; i < n->sample_count; i++ ) cat_values_buf[i] = short_values[i]; @@ -3004,6 +3026,7 @@ void CvDTree::split_node_data( CvDTreeNode* node ) 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*)(uchar*)inn_buf; @@ -3049,7 +3072,7 @@ void CvDTree::split_node_data( CvDTreeNode* node ) { unsigned short *ldst, *rdst, *ldst0, *rdst0; //unsigned short tl, tr; - ldst0 = ldst = (unsigned short*)(buf->data.s + left->buf_idx*buf->cols + + ldst0 = ldst = (unsigned short*)(buf->data.s + left->buf_idx*length_buf_row + vi*scount + left->offset); rdst0 = rdst = (unsigned short*)(ldst + nl); @@ -3095,9 +3118,9 @@ void CvDTree::split_node_data( CvDTreeNode* node ) else { int *ldst0, *ldst, *rdst0, *rdst; - ldst0 = ldst = buf->data.i + left->buf_idx*buf->cols + + ldst0 = ldst = buf->data.i + left->buf_idx*length_buf_row + vi*scount + left->offset; - rdst0 = rdst = buf->data.i + right->buf_idx*buf->cols + + rdst0 = rdst = buf->data.i + right->buf_idx*length_buf_row + vi*scount + right->offset; // split sorted @@ -3158,9 +3181,9 @@ void CvDTree::split_node_data( CvDTreeNode* node ) if (data->is_buf_16u) { - unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*buf->cols + + 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*buf->cols + + unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*length_buf_row + vi*scount + right->offset); for( i = 0; i < n; i++ ) @@ -3188,9 +3211,9 @@ void CvDTree::split_node_data( CvDTreeNode* node ) } else { - int *ldst = buf->data.i + left->buf_idx*buf->cols + + int *ldst = buf->data.i + left->buf_idx*length_buf_row + vi*scount + left->offset; - int *rdst = buf->data.i + right->buf_idx*buf->cols + + int *rdst = buf->data.i + right->buf_idx*length_buf_row + vi*scount + right->offset; for( i = 0; i < n; i++ ) @@ -3230,9 +3253,9 @@ void CvDTree::split_node_data( CvDTreeNode* node ) int pos = data->get_work_var_count(); if (data->is_buf_16u) { - unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*buf->cols + + 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*buf->cols + + unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*length_buf_row + pos*scount + right->offset); for (i = 0; i < n; i++) { @@ -3252,9 +3275,9 @@ void CvDTree::split_node_data( CvDTreeNode* node ) } else { - int* ldst = buf->data.i + left->buf_idx*buf->cols + + int* ldst = buf->data.i + left->buf_idx*length_buf_row + pos*scount + left->offset; - int* rdst = buf->data.i + right->buf_idx*buf->cols + + int* rdst = buf->data.i + right->buf_idx*length_buf_row + pos*scount + right->offset; for (i = 0; i < n; i++) { From 51eba617a8a99951ebe7ac6836a8056976f8cd4b Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Fri, 1 Feb 2013 14:01:44 +0400 Subject: [PATCH 02/17] a part of PR269 (parallelization of several functions) by Alexander Mordvintsev --- modules/core/src/matrix.cpp | 20 ++++++++++---------- modules/core/src/stat.cpp | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 54adb5db23..f21e6ac4f2 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -2459,7 +2459,7 @@ static void generateRandomCenter(const vector& box, float* center, RNG& r center[j] = ((float)rng*(1.f+margin*2.f)-margin)*(box[j][1] - box[j][0]) + box[j][0]; } -class KMeansPPDistanceComputer +class KMeansPPDistanceComputer : public ParallelLoopBody { public: KMeansPPDistanceComputer( float *_tdist2, @@ -2475,10 +2475,10 @@ public: step(_step), stepci(_stepci) { } - void operator()( const cv::BlockedRange& range ) const + void operator()( const cv::Range& range ) const { - const int begin = range.begin(); - const int end = range.end(); + const int begin = range.start; + const int end = range.end; for ( int i = begin; i(0); - parallel_for(BlockedRange(0, N), + parallel_for_(Range(0, N), KMeansDistanceComputer(dist, labels, data, centers)); compactness = 0; for( i = 0; i < N; i++ ) diff --git a/modules/core/src/stat.cpp b/modules/core/src/stat.cpp index fe98cf7ef8..b62f10a2a8 100644 --- a/modules/core/src/stat.cpp +++ b/modules/core/src/stat.cpp @@ -1726,7 +1726,7 @@ typedef void (*BatchDistFunc)(const uchar* src1, const uchar* src2, size_t step2 int nvecs, int len, uchar* dist, const uchar* mask); -struct BatchDistInvoker +struct BatchDistInvoker : public ParallelLoopBody { BatchDistInvoker( const Mat& _src1, const Mat& _src2, Mat& _dist, Mat& _nidx, int _K, @@ -1743,12 +1743,12 @@ struct BatchDistInvoker func = _func; } - void operator()(const BlockedRange& range) const + void operator()(const Range& range) const { AutoBuffer buf(src2->rows); int* bufptr = buf; - for( int i = range.begin(); i < range.end(); i++ ) + for( int i = range.start; i < range.end; i++ ) { func(src1->ptr(i), src2->ptr(), src2->step, src2->rows, src2->cols, K > 0 ? (uchar*)bufptr : dist->ptr(i), mask->data ? mask->ptr(i) : 0); @@ -1899,8 +1899,8 @@ void cv::batchDistance( InputArray _src1, InputArray _src2, ("The combination of type=%d, dtype=%d and normType=%d is not supported", type, dtype, normType)); - parallel_for(BlockedRange(0, src1.rows), - BatchDistInvoker(src1, src2, dist, nidx, K, mask, update, func)); + parallel_for_(Range(0, src1.rows), + BatchDistInvoker(src1, src2, dist, nidx, K, mask, update, func)); } From 013d54c230a738c6f3d275f6877e8122fc6ed92b Mon Sep 17 00:00:00 2001 From: LeonidBeynenson Date: Fri, 1 Feb 2013 14:26:02 +0400 Subject: [PATCH 03/17] Changed types of some variables from int64 back to int. Also corrected some indexes to be size_t. --- modules/ml/src/ertrees.cpp | 26 +++++++++++++------------- modules/ml/src/tree.cpp | 30 +++++++++++++++--------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/modules/ml/src/ertrees.cpp b/modules/ml/src/ertrees.cpp index 380d87a795..31d20398a9 100644 --- a/modules/ml/src/ertrees.cpp +++ b/modules/ml/src/ertrees.cpp @@ -75,13 +75,13 @@ void CvERTreeTrainData::set_data( const CvMat* _train_data, int _tflag, 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; - int64 ds_step, dv_step, ms_step = 0, mv_step = 0; // {data|mask}{sample|var}_step - int64 vi, i, size; + 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 = -1; - int effective_buf_height = -1, effective_buf_width = -1; + uint64 effective_buf_size = 0; + int effective_buf_height = 0, effective_buf_width = 0; if ( _params.use_surrogates ) CV_ERROR(CV_StsBadArg, "CvERTrees do not support surrogate splits"); @@ -312,17 +312,17 @@ void CvERTreeTrainData::set_data( const CvMat* _train_data, int _tflag, for( i = 0; i < sample_count; i++ ) { int val = INT_MAX, si = sidx ? sidx[i] : i; - if( !mask || !mask[si*m_step] ) + if( !mask || !mask[(size_t)si*m_step] ) { if( idata ) - val = idata[si*step]; + val = idata[(size_t)si*step]; else { - float t = fdata[si*step]; + float t = fdata[(size_t)si*step]; val = cvRound(t); if( val != t ) { - sprintf( err, "%ld-th value of %ld-th (categorical) " + sprintf( err, "%d-th value of %d-th (categorical) " "variable is not an integer", i, vi ); CV_ERROR( CV_StsBadArg, err ); } @@ -330,7 +330,7 @@ void CvERTreeTrainData::set_data( const CvMat* _train_data, int _tflag, if( val == INT_MAX ) { - sprintf( err, "%ld-th value of %ld-th (categorical) " + sprintf( err, "%d-th value of %d-th (categorical) " "variable is too large", i, vi ); CV_ERROR( CV_StsBadArg, err ); } @@ -424,16 +424,16 @@ void CvERTreeTrainData::set_data( const CvMat* _train_data, int _tflag, { float val = ord_nan; int si = sidx ? sidx[i] : i; - if( !mask || !mask[si*m_step] ) + if( !mask || !mask[(size_t)si*m_step] ) { if( idata ) - val = (float)idata[si*step]; + val = (float)idata[(size_t)si*step]; else - val = fdata[si*step]; + val = fdata[(size_t)si*step]; if( fabs(val) >= ord_nan ) { - sprintf( err, "%ld-th value of %ld-th (ordered) " + sprintf( err, "%d-th value of %d-th (ordered) " "variable (=%g) is too large", i, vi, val ); CV_ERROR( CV_StsBadArg, err ); } diff --git a/modules/ml/src/tree.cpp b/modules/ml/src/tree.cpp index aef4a3523b..583cd33ba8 100644 --- a/modules/ml/src/tree.cpp +++ b/modules/ml/src/tree.cpp @@ -154,8 +154,8 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, 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; - int64 ds_step, dv_step, ms_step = 0, mv_step = 0; // {data|mask}{sample|var}_step - int64 vi, i, size; + 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; @@ -421,17 +421,17 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, for( i = 0; i < sample_count; i++ ) { int val = INT_MAX, si = sidx ? sidx[i] : i; - if( !mask || !mask[si*m_step] ) + if( !mask || !mask[(size_t)si*m_step] ) { if( idata ) - val = idata[si*step]; + val = idata[(size_t)si*step]; else { - float t = fdata[si*step]; + float t = fdata[(size_t)si*step]; val = cvRound(t); if( fabs(t - val) > FLT_EPSILON ) { - sprintf( err, "%ld-th value of %ld-th (categorical) " + sprintf( err, "%d-th value of %d-th (categorical) " "variable is not an integer", i, vi ); CV_ERROR( CV_StsBadArg, err ); } @@ -439,7 +439,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, if( val == INT_MAX ) { - sprintf( err, "%ld-th value of %ld-th (categorical) " + sprintf( err, "%d-th value of %d-th (categorical) " "variable is too large", i, vi ); CV_ERROR( CV_StsBadArg, err ); } @@ -537,16 +537,16 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, { float val = ord_nan; int si = sidx ? sidx[i] : i; - if( !mask || !mask[si*m_step] ) + if( !mask || !mask[(size_t)si*m_step] ) { if( idata ) - val = (float)idata[si*step]; + val = (float)idata[(size_t)si*step]; else - val = fdata[si*step]; + val = fdata[(size_t)si*step]; if( fabs(val) >= ord_nan ) { - sprintf( err, "%ld-th value of %ld-th (ordered) " + sprintf( err, "%d-th value of %d-th (ordered) " "variable (=%g) is too large", i, vi, val ); CV_ERROR( CV_StsBadArg, err ); } @@ -3333,7 +3333,7 @@ float CvDTree::calc_error( CvMLData* _data, int type, vector *resp ) float r = (float)predict( &sample, missing ? &miss : 0 )->value; if( pred_resp ) pred_resp[i] = r; - int d = fabs((double)r - response->data.fl[si*r_step]) <= FLT_EPSILON ? 0 : 1; + 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; @@ -3350,7 +3350,7 @@ float CvDTree::calc_error( CvMLData* _data, int type, vector *resp ) float r = (float)predict( &sample, missing ? &miss : 0 )->value; if( pred_resp ) pred_resp[i] = r; - float d = r - response->data.fl[si*r_step]; + float d = r - response->data.fl[(size_t)si*r_step]; err += d*d; } err = sample_count ? err / (float)sample_count : -FLT_MAX; @@ -3656,8 +3656,8 @@ CvDTreeNode* CvDTree::predict( const CvMat* _sample, int vi = split->var_idx; int ci = vtype[vi]; i = vidx ? vidx[vi] : vi; - float val = sample[i*step]; - if( m && m[i*mstep] ) + 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; From 25086ed2579759e4d409a19cf7b81a00bc2d830c Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Fri, 1 Feb 2013 16:07:32 +0400 Subject: [PATCH 04/17] Smartek Giganetix Cameras support (Patch #2192) integrated. --- modules/highgui/src/cap_giganetix.cpp | 763 ++++++++++++++++++++++++++ 1 file changed, 763 insertions(+) create mode 100644 modules/highgui/src/cap_giganetix.cpp diff --git a/modules/highgui/src/cap_giganetix.cpp b/modules/highgui/src/cap_giganetix.cpp new file mode 100644 index 0000000000..ccbe7020fa --- /dev/null +++ b/modules/highgui/src/cap_giganetix.cpp @@ -0,0 +1,763 @@ +//////////////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +// + +// +// The code has been contributed by Vladimir N. Litvinenko on 2012 Jul +// mailto:vladimir.litvinenko@codepaint.ru +// + +#include "precomp.hpp" +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#ifdef NDEBUG +#define CV_WARN(message) +#else +#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__) +#endif + +#define QTGIG_HEARTBEAT_TIME (12000.0) +#define QTGIG_MAX_WAIT_TIME (2.0) +#define QTGIG_IMG_WAIT_TIME (3.0) + +/*----------------------------------------------------------------------------*/ +/** + \internal + \fn bool wrprInitGigEVisionAPI(); + \brief Wrapper to GigEVisionAPI function gige::InitGigEVisionAPI () + \return true -- success + See \a wrprExitGigEVisionAPI + +*/ +bool +wrprInitGigEVisionAPI() +{ + CV_FUNCNAME("wrprInitGigEVisionAPI"); + __BEGIN__; + + try { + gige::InitGigEVisionAPI (); + } catch(...) { + CV_ERROR(CV_StsError, "GigEVisionAPI: initialization (InitGigEVisionAPI()) failed.\n"); + } + __END__; + return true; +} + +/*----------------------------------------------------------------------------*/ +/** + \internal + \fn void wrprExitGigEVisionAPI() + \brief Wrapper to GigEVisionAPI function gige::ExitGigEVisionAPI () + \return true -- success + See \a wrprInitGigEVisionAPI + +*/ +bool +wrprExitGigEVisionAPI() +{ + CV_FUNCNAME("wrprExitGigEVisionAPI"); + __BEGIN__; + + try { + gige::ExitGigEVisionAPI (); + } catch(...) { + CV_ERROR(CV_StsError, "GigEVisionAPI: finalization (ExitGigEVisionAPI()) failed.\n"); + return false; + } + __END__; + return true; +} + + +/*----------------------------------------------------------------------------*/ +/** + \internal + \fn gige::IGigEVisionAPI wrprGetGigEVisionAPI() + \brief Wrapper to GigEVisionAPI function gige::GetGigEVisionAPI () + \return item of gige::IGigEVisionAPI type + See \a wrprInitGigEVisionAPI, \a gige::IGigEVisionAPI +*/ +gige::IGigEVisionAPI +wrprGetGigEVisionAPI() +{ + + gige::IGigEVisionAPI b_ret = 0; + + CV_FUNCNAME("wrprGetGigEVisionAPI"); + __BEGIN__; + + try { + b_ret = gige::GetGigEVisionAPI (); + } catch(...) { + CV_ERROR(CV_StsError, "GigEVisionAPI: API instance (from GetGigEVisionAPI()) failed.\n"); + } + + __END__; + + return b_ret; +} + + +/*----------------------------------------------------------------------------*/ +/** + \internal + \fn bool wrprUnregisterCallback( const gige::IGigEVisionAPI* api, gige::ICallbackEvent* eventHandler) + \brief Wrapper to GigEVisionAPI function + \param api + \param eventHandler + \return true - succsess, else - false + See \a wrprInitGigEVisionAPI, \a gige::IGigEVisionAPI + +*/ +bool +wrprUnregisterCallback( const gige::IGigEVisionAPI* api, gige::ICallbackEvent* eventHandler) +{ + bool b_ret = api != NULL; + + if(b_ret) b_ret = api->IsValid (); + + CV_FUNCNAME("wrprUnregisterCallback"); + __BEGIN__; + + if(b_ret) + { + if(eventHandler != NULL) + { + try { + b_ret = ((gige::IGigEVisionAPIInterface*)api)->UnregisterCallback (eventHandler); + } catch(...) { + CV_ERROR(CV_StsError, "GigEVisionAPI: API unregister callback function (from UnregisterCallback()) failed.\n"); + b_ret = false; + } + } + } + __END__; + + return (b_ret); +} + + +/*----------------------------------------------------------------------------*/ +/** + \internal + \fn bool wrprDeviceIsConnect( gige::IDevice& device ) + \brief Wrapper to GigEVisionAPI function IDevice::IsConnected() + \param device - selected device + \return true - device connected +*/ +bool +wrprDeviceIsConnect( gige::IDevice& device ) +{ + bool b_ret = device != NULL; + + CV_FUNCNAME("wrprDeviceIsConnect"); + __BEGIN__; + + if(b_ret) + { + try { + b_ret = device->IsConnected (); + } catch (...) { + CV_ERROR(CV_StsError, "GigEVisionAPI: API device connection state (from IsConnected()) failed.\n"); + b_ret = false; + } + } + __END__; + + return (b_ret); +} + + +/*----------------------------------------------------------------------------*/ +/** + \internal + \fn bool wrprDeviceIsValid( gige::IDevice& device ) + \brief Wrapper to GigEVisionAPI function IDevice::Connect() + \param device - selected device + \return true - device valid + +*/ +bool +wrprDeviceIsValid( gige::IDevice& device ) +{ + bool b_ret = device != NULL; + + CV_FUNCNAME("wrprDeviceIsConnect"); + __BEGIN__; + + if(b_ret) + { + try { + b_ret = device.IsValid (); + } catch (...) { + CV_ERROR(CV_StsError, "GigEVisionAPI: API device validation state (from IsValid()) failed.\n"); + b_ret = false; + } + } + __END__; + + return (b_ret); +} + + +/*----------------------------------------------------------------------------*/ +/** + \internal + \fn bool wrprDeviceDisconnect ( gige::IDevice& device ) + \brief Wrapper to GigEVisionAPI function IDevice::Disconnect() + \param device - selected device + \return true - device valid + +*/ +bool +wrprDeviceDisconnect ( gige::IDevice& device ) +{ + bool b_ret = device != NULL; + + CV_FUNCNAME("wrprDeviceDisconnect"); + __BEGIN__; + + if(b_ret) + { + try { + device->Disconnect (); + } catch (...) { + CV_ERROR(CV_StsError, "GigEVisionAPI: API device disconnect (from Disconnect()) failed.\n"); + b_ret = false; + } + } + + __END__; + + return (b_ret); +} + + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/** + \internal + \class CvCaptureCAM_Giganetix + \brief Capturing video from camera via Smartec Giganetix (use GigEVisualSDK library). +*/ + +class CvCaptureCAM_Giganetix : public CvCapture +{ + public: + CvCaptureCAM_Giganetix(); + virtual ~CvCaptureCAM_Giganetix(); + + virtual bool open( int index ); + virtual void close(); + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() + { + return CV_CAP_GIGANETIX; + } + + bool start (); + bool stop (); + + protected: + + void init (); + void grabImage (); + + gige::IGigEVisionAPI m_api; + bool m_api_on; + gige::IDevice m_device; + bool m_active; + + IplImage* m_raw_image; + UINT32 m_rawImagePixelType; + bool m_monocrome; + +}; +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +void +CvCaptureCAM_Giganetix::init () +{ + m_monocrome = m_active = m_api_on = false; + m_api = 0; + m_device = 0; + m_raw_image = 0; + m_rawImagePixelType = 0; +} + +/*----------------------------------------------------------------------------*/ +CvCaptureCAM_Giganetix::CvCaptureCAM_Giganetix() +{ + init (); + + m_api_on = wrprInitGigEVisionAPI (); + + if(m_api_on) + { + if((m_api = wrprGetGigEVisionAPI ()) != NULL) + { + m_api->SetHeartbeatTime (QTGIG_HEARTBEAT_TIME); + } + } +} + +/*----------------------------------------------------------------------------*/ +CvCaptureCAM_Giganetix::~CvCaptureCAM_Giganetix() +{ + close(); +} +/*----------------------------------------------------------------------------*/ +void +CvCaptureCAM_Giganetix::close() +{ + stop (); + + (void)wrprDeviceDisconnect(m_device); + + (void)wrprExitGigEVisionAPI (); + + if(m_raw_image) cvReleaseImageHeader(&m_raw_image); + + init (); +} + +/*----------------------------------------------------------------------------*/ +bool +CvCaptureCAM_Giganetix::open( int index ) +{ + bool b_ret = m_api_on; + + CV_FUNCNAME("CvCaptureCAM_Giganetix::open"); + __BEGIN__; + + if(b_ret) + b_ret = m_api.IsValid (); + + if(b_ret ) + { + m_api->FindAllDevices (QTGIG_MAX_WAIT_TIME); + + //TODO - serch device as DevicesList member + gige::DevicesList DevicesList = m_api->GetAllDevices (); + + m_device = 0; + b_ret = false; + + for (int i = 0; i < (int) DevicesList.size() && !b_ret; i++) + { + if((b_ret = i == index)) + { + m_device = DevicesList[i]; + b_ret = m_device->Connect (); + + if(b_ret) + { + b_ret = + m_device->SetStringNodeValue("AcquisitionStatusSelector", "AcquisitionActive") + && + m_device->SetStringNodeValue ("TriggerMode", "Off") + && + m_device->SetStringNodeValue ("AcquisitionMode", "Continuous") + && + m_device->SetIntegerNodeValue ("AcquisitionFrameCount", 20) + ; + } + } + } // for + } + + if(!b_ret) + { + CV_ERROR(CV_StsError, "Giganetix: Error cannot find camera\n"); + close (); + } else { + start (); + } + + __END__; + + return b_ret; +} + +/*----------------------------------------------------------------------------*/ +void +CvCaptureCAM_Giganetix::grabImage () +{ + CV_FUNCNAME("CvCaptureCAM_Giganetix::grabImage"); + __BEGIN__; + + if(wrprDeviceIsValid(m_device) && wrprDeviceIsConnect(m_device)) + { + if(!m_device->IsBufferEmpty ()) + { + gige::IImageInfo imageInfo; + m_device->GetImageInfo (&imageInfo); + assert(imageInfo.IsValid()); + + if (m_device->GetPendingImagesCount() == 1) + { + UINT32 newPixelType; + UINT32 newWidth, newHeight; + + imageInfo->GetPixelType(newPixelType); + imageInfo->GetSize(newWidth, newHeight); + + //TODO - validation of image exists + bool b_validation = m_raw_image != NULL; + if(b_validation) + { + b_validation = + m_raw_image->imageSize == (int)(imageInfo->GetRawDataSize ()) + && + m_rawImagePixelType == newPixelType; + } else { + if(m_raw_image) cvReleaseImageHeader(&m_raw_image); + } + + m_rawImagePixelType = newPixelType; + m_monocrome = GvspGetBitsPerPixel((GVSP_PIXEL_TYPES)newPixelType) == IPL_DEPTH_8U; + + try { + if (m_monocrome) + { + //TODO - For Mono & Color BayerRGB raw pixel types + if (!b_validation) + { + m_raw_image = cvCreateImageHeader (cvSize((int)newWidth, (int)newHeight),IPL_DEPTH_8U,1); + m_raw_image->origin = IPL_ORIGIN_TL; + m_raw_image->dataOrder = IPL_DATA_ORDER_PIXEL; + m_raw_image->widthStep = newWidth; + } + // Copy image. + // ::memcpy(m_raw_image->imageData, imageInfo->GetRawData (), imageInfo->GetRawDataSize ()); + + //TODO - Set pointer to image ! + m_raw_image->imageData = (char*)(imageInfo->GetRawData ()); + } + + if (!m_monocrome && newPixelType == GVSP_PIX_RGB8_PACKED) + { + //TODO - 24 bit RGB color image. + if (!b_validation) + { + m_raw_image = cvCreateImageHeader (cvSize((int)newWidth, (int)newHeight), IPL_DEPTH_32F, 3); + m_raw_image->origin = IPL_ORIGIN_TL; + m_raw_image->dataOrder = IPL_DATA_ORDER_PIXEL; + m_raw_image->widthStep = newWidth * 3; + } + m_raw_image->imageData = (char*)(imageInfo->GetRawData ()); + } + } catch (...) { + CV_ERROR(CV_StsError, "Giganetix: failed to queue a buffer on device\n"); + close (); + } + } else { + //TODO - all other pixel types + m_raw_image = 0; + CV_WARN("Giganetix: Undefined image pixel type\n"); + } + m_device->PopImage (imageInfo); + m_device->ClearImageBuffer (); + } + } + + __END__; +} + +/*----------------------------------------------------------------------------*/ +bool +CvCaptureCAM_Giganetix::start () +{ + CV_FUNCNAME("CvCaptureCAM_Giganetix::start"); + __BEGIN__; + + m_active = wrprDeviceIsValid(m_device) && wrprDeviceIsConnect(m_device); + + if(m_active) + { + (void)m_device->SetIntegerNodeValue("TLParamsLocked", 1); + (void)m_device->CommandNodeExecute("AcquisitionStart"); + m_active = m_device->GetBooleanNodeValue("AcquisitionStatus", m_active); + } + + if(!m_active) + { + CV_ERROR(CV_StsError, "Giganetix: Cannot open camera\n"); + close (); + } + + __END__; + + return m_active; +} + +/*----------------------------------------------------------------------------*/ +bool +CvCaptureCAM_Giganetix::stop () +{ + if (!m_active) return true; + + CV_FUNCNAME("CvCaptureCAM_Giganetix::stop"); + __BEGIN__; + + if(wrprDeviceIsValid(m_device) && wrprDeviceIsConnect(m_device)) + { + (void)m_device->GetBooleanNodeValue("AcquisitionStatus", m_active); + + if(m_active) + { + (void)m_device->CommandNodeExecute("AcquisitionStop"); + (void)m_device->SetIntegerNodeValue("TLParamsLocked", 0); + m_device->ClearImageBuffer (); + (void)m_device->GetBooleanNodeValue("AcquisitionStatus", m_active); + } + } + + if(m_active) + { + CV_ERROR(CV_StsError, "Giganetix: Improper closure of the camera\n"); + close (); + } + __END__; + + return !m_active; +} + +/*----------------------------------------------------------------------------*/ +bool +CvCaptureCAM_Giganetix::grabFrame() +{ + bool b_ret = + wrprDeviceIsValid(m_device) + && + wrprDeviceIsConnect(m_device); + + if(b_ret) grabImage (); + + return b_ret; +} + + +/*----------------------------------------------------------------------------*/ +IplImage* +CvCaptureCAM_Giganetix::retrieveFrame(int) +{ + return ( + wrprDeviceIsValid(m_device) && wrprDeviceIsConnect(m_device) ? + m_raw_image : + NULL + ); +} + +/*----------------------------------------------------------------------------*/ +double +CvCaptureCAM_Giganetix::getProperty( int property_id ) +{ + double d_ret = -1.0; + INT64 i; + + if(wrprDeviceIsConnect(m_device)) + { + switch ( property_id ) + { + case CV_CAP_PROP_FRAME_WIDTH: + m_device->GetIntegerNodeValue ("Width", i); + d_ret = i; + break; + case CV_CAP_PROP_FRAME_HEIGHT: + m_device->GetIntegerNodeValue ("Height", i); + d_ret = i; + break; + case CV_CAP_PROP_GIGA_FRAME_OFFSET_X: + m_device->GetIntegerNodeValue ("OffsetX", i); + d_ret = i; + break; + case CV_CAP_PROP_GIGA_FRAME_OFFSET_Y: + m_device->GetIntegerNodeValue ("OffsetY", i); + d_ret = i; + break; + case CV_CAP_PROP_GIGA_FRAME_WIDTH_MAX: + m_device->GetIntegerNodeValue ("WidthMax", i); + d_ret = i; + break; + case CV_CAP_PROP_GIGA_FRAME_HEIGH_MAX: + m_device->GetIntegerNodeValue ("HeightMax", i); + d_ret = i; + break; + case CV_CAP_PROP_GIGA_FRAME_SENS_WIDTH: + m_device->GetIntegerNodeValue ("SensorWidth", i); + d_ret = i; + break; + case CV_CAP_PROP_GIGA_FRAME_SENS_HEIGH: + m_device->GetIntegerNodeValue ("SensorHeight", i); + d_ret = i; + break; + case CV_CAP_PROP_FRAME_COUNT: + m_device->GetIntegerNodeValue ("AcquisitionFrameCount", i); + d_ret = i; + break; + case CV_CAP_PROP_EXPOSURE: + m_device->GetFloatNodeValue ("ExposureTime",d_ret); + break; + case CV_CAP_PROP_GAIN : + m_device->GetFloatNodeValue ("Gain",d_ret); + break; + case CV_CAP_PROP_TRIGGER : + bool b; + m_device->GetBooleanNodeValue ("TriggerMode",b); + d_ret = (double)b; + break; + case CV_CAP_PROP_TRIGGER_DELAY : + m_device->GetFloatNodeValue ("TriggerDelay",d_ret); + break; + default : ; + } + } + + return d_ret; +} + +/*----------------------------------------------------------------------------*/ +bool +CvCaptureCAM_Giganetix::setProperty( int property_id, double value ) +{ + bool b_ret = wrprDeviceIsConnect(m_device); + + if(b_ret) + { + bool b_val = m_active; + + switch ( property_id ) + { + case CV_CAP_PROP_FRAME_WIDTH: + stop (); + b_ret = m_device->SetIntegerNodeValue ("Width", (INT64)value); + if(b_val) start (); + break; + case CV_CAP_PROP_GIGA_FRAME_WIDTH_MAX: + stop (); + b_ret = m_device->SetIntegerNodeValue ("WidthMax", (INT64)value); + if(b_val) start (); + break; + case CV_CAP_PROP_GIGA_FRAME_SENS_WIDTH: + stop (); + b_ret = m_device->SetIntegerNodeValue ("SensorWidth", (INT64)value); + if(b_val) start (); + break; + case CV_CAP_PROP_FRAME_HEIGHT: + stop (); + b_ret = m_device->SetIntegerNodeValue ("Height", (INT64)value); + if(b_val) start (); + break; + case CV_CAP_PROP_GIGA_FRAME_HEIGH_MAX: + stop (); + b_ret = m_device->SetIntegerNodeValue ("HeightMax", (INT64)value); + if(b_val) start (); + break; + case CV_CAP_PROP_GIGA_FRAME_SENS_HEIGH: + stop (); + b_ret = m_device->SetIntegerNodeValue ("SensorHeight", (INT64)value); + if(b_val) start (); + break; + case CV_CAP_PROP_GIGA_FRAME_OFFSET_X: { + INT64 w, wmax, val = (INT64)value; + if((b_ret = m_device->GetIntegerNodeValue ("Width", w))) + if((b_ret = m_device->GetIntegerNodeValue ("WidthMax", wmax))) + b_ret = m_device->SetIntegerNodeValue ("OffsetX", val w > wmax ? wmax - w : val); + } break; + case CV_CAP_PROP_GIGA_FRAME_OFFSET_Y: { + INT64 h, hmax, val = (INT64)value; + if((b_ret = m_device->GetIntegerNodeValue ("Height", h))) + if((b_ret = m_device->GetIntegerNodeValue ("HeightMax", hmax))) + b_ret = m_device->SetIntegerNodeValue ("OffsetY", val h > hmax ? hmax - h : val); + b_ret = m_device->SetIntegerNodeValue ("OffsetY", (INT64)value); + } + break; + case CV_CAP_PROP_EXPOSURE: + b_ret = m_device->SetFloatNodeValue ("ExposureTime",value); + break; + case CV_CAP_PROP_GAIN : + b_ret = m_device->SetFloatNodeValue ("Gain",value); + break; + case CV_CAP_PROP_TRIGGER : + b_ret = m_device->SetBooleanNodeValue ("TriggerMode",(bool)value); + break; + case CV_CAP_PROP_TRIGGER_DELAY : + stop (); + b_ret = m_device->SetFloatNodeValue ("TriggerDelay",value); + if(b_val) start (); + break; + default: + b_ret = false; + } + } + + return b_ret; +} + + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +CvCapture* +cvCreateCameraCapture_Giganetix( int index ) +{ + CvCaptureCAM_Giganetix* capture = new CvCaptureCAM_Giganetix; + + if (!(capture->open( index ))) + { + delete capture; + capture = NULL; + } + + return ((CvCapture*)capture); +} + +/*----------------------------------------------------------------------------*/ From 87b0126e0d78144af7bd43e274971a0b6cfd845c Mon Sep 17 00:00:00 2001 From: LeonidBeynenson Date: Fri, 1 Feb 2013 16:16:43 +0400 Subject: [PATCH 05/17] Fixed dummy warning. --- apps/traincascade/boost.cpp | 4 ++-- modules/ml/src/tree.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/traincascade/boost.cpp b/apps/traincascade/boost.cpp index 0ba11a936a..2d29f338b0 100644 --- a/apps/traincascade/boost.cpp +++ b/apps/traincascade/boost.cpp @@ -489,8 +489,8 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat int* idst = 0; unsigned short* udst = 0; - uint64 effective_buf_size = -1; - int effective_buf_height = -1, effective_buf_width = -1; + uint64 effective_buf_size = 0; + int effective_buf_height = 0, effective_buf_width = 0; clear(); diff --git a/modules/ml/src/tree.cpp b/modules/ml/src/tree.cpp index 583cd33ba8..1ba94fcaf0 100644 --- a/modules/ml/src/tree.cpp +++ b/modules/ml/src/tree.cpp @@ -159,8 +159,8 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, char err[100]; const int *sidx = 0, *vidx = 0; - uint64 effective_buf_size = -1; - int effective_buf_height = -1, effective_buf_width = -1; + uint64 effective_buf_size = 0; + int effective_buf_height = 0, effective_buf_width = 0; if( _update_data && data_root ) { From 6f1961031c17ea8cd91e3d076eb26a428f52d51f Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Fri, 1 Feb 2013 14:37:24 +0400 Subject: [PATCH 06/17] Update regression checks in Java test This follows SURF changes in 1f261c2 --- .../BruteForceDescriptorMatcherTest.java | 10 +++--- .../BruteForceL1DescriptorMatcherTest.java | 10 +++--- .../BruteForceSL2DescriptorMatcherTest.java | 10 +++--- .../FlannBasedDescriptorMatcherTest.java | 10 +++--- .../SURFDescriptorExtractorTest.java | 31 +++++++++++-------- .../features2d/SURFFeatureDetectorTest.java | 4 +-- 6 files changed, 40 insertions(+), 35 deletions(-) diff --git a/modules/java/android_test/src/org/opencv/test/features2d/BruteForceDescriptorMatcherTest.java b/modules/java/android_test/src/org/opencv/test/features2d/BruteForceDescriptorMatcherTest.java index 28e07b1b29..2d43307352 100644 --- a/modules/java/android_test/src/org/opencv/test/features2d/BruteForceDescriptorMatcherTest.java +++ b/modules/java/android_test/src/org/opencv/test/features2d/BruteForceDescriptorMatcherTest.java @@ -85,11 +85,11 @@ public class BruteForceDescriptorMatcherTest extends OpenCVTestCase { matSize = 100; truth = new DMatch[] { - new DMatch(0, 0, 0, 1.0496940f), - new DMatch(1, 0, 0, 1.0984558f), - new DMatch(2, 1, 0, 0.4945875f), - new DMatch(3, 1, 0, 0.48435235f), - new DMatch(4, 0, 0, 1.0836693f) + new DMatch(0, 0, 0, 0.6211397f), + new DMatch(1, 1, 0, 0.9177120f), + new DMatch(2, 1, 0, 0.3112163f), + new DMatch(3, 1, 0, 0.2925074f), + new DMatch(4, 1, 0, 0.9309178f) }; } diff --git a/modules/java/android_test/src/org/opencv/test/features2d/BruteForceL1DescriptorMatcherTest.java b/modules/java/android_test/src/org/opencv/test/features2d/BruteForceL1DescriptorMatcherTest.java index d5370f32b4..5d0ab51e4b 100644 --- a/modules/java/android_test/src/org/opencv/test/features2d/BruteForceL1DescriptorMatcherTest.java +++ b/modules/java/android_test/src/org/opencv/test/features2d/BruteForceL1DescriptorMatcherTest.java @@ -85,11 +85,11 @@ public class BruteForceL1DescriptorMatcherTest extends OpenCVTestCase { matSize = 100; truth = new DMatch[] { - new DMatch(0, 1, 0, 6.9202340f), - new DMatch(1, 1, 0, 6.1675916f), - new DMatch(2, 1, 0, 2.6798590f), - new DMatch(3, 1, 0, 2.6545324f), - new DMatch(4, 0, 0, 6.1294870f) + new DMatch(0, 0, 0, 3.0975165f), + new DMatch(1, 1, 0, 3.5680308f), + new DMatch(2, 1, 0, 1.3722466f), + new DMatch(3, 1, 0, 1.3041023f), + new DMatch(4, 1, 0, 3.5970376f) }; } diff --git a/modules/java/android_test/src/org/opencv/test/features2d/BruteForceSL2DescriptorMatcherTest.java b/modules/java/android_test/src/org/opencv/test/features2d/BruteForceSL2DescriptorMatcherTest.java index 39253f0441..6a097b4fa5 100644 --- a/modules/java/android_test/src/org/opencv/test/features2d/BruteForceSL2DescriptorMatcherTest.java +++ b/modules/java/android_test/src/org/opencv/test/features2d/BruteForceSL2DescriptorMatcherTest.java @@ -90,11 +90,11 @@ public class BruteForceSL2DescriptorMatcherTest extends OpenCVTestCase { matSize = 100; truth = new DMatch[] { - new DMatch(0, 0, 0, 1.1018573f), - new DMatch(1, 0, 0, 1.2066052f), - new DMatch(2, 1, 0, 0.2446168f), - new DMatch(3, 1, 0, 0.23459719f), - new DMatch(4, 0, 0, 1.174339f) + new DMatch(0, 0, 0, 0.3858146f), + new DMatch(1, 1, 0, 0.8421953f), + new DMatch(2, 1, 0, 0.0968556f), + new DMatch(3, 1, 0, 0.0855606f), + new DMatch(4, 1, 0, 0.8666080f) }; } diff --git a/modules/java/android_test/src/org/opencv/test/features2d/FlannBasedDescriptorMatcherTest.java b/modules/java/android_test/src/org/opencv/test/features2d/FlannBasedDescriptorMatcherTest.java index 96e4986399..70c994b288 100644 --- a/modules/java/android_test/src/org/opencv/test/features2d/FlannBasedDescriptorMatcherTest.java +++ b/modules/java/android_test/src/org/opencv/test/features2d/FlannBasedDescriptorMatcherTest.java @@ -158,11 +158,11 @@ public class FlannBasedDescriptorMatcherTest extends OpenCVTestCase { matcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED); matSize = 100; truth = new DMatch[] { - new DMatch(0, 0, 0, 1.049694f), - new DMatch(1, 0, 0, 1.0984558f), - new DMatch(2, 1, 0, 0.4945875f), - new DMatch(3, 1, 0, 0.48435235f), - new DMatch(4, 0, 0, 1.0836693f) + new DMatch(0, 0, 0, 0.6211397f), + new DMatch(1, 1, 0, 0.9177120f), + new DMatch(2, 1, 0, 0.3112163f), + new DMatch(3, 1, 0, 0.2925075f), + new DMatch(4, 1, 0, 0.9309179f) }; } diff --git a/modules/java/android_test/src/org/opencv/test/features2d/SURFDescriptorExtractorTest.java b/modules/java/android_test/src/org/opencv/test/features2d/SURFDescriptorExtractorTest.java index 8b063ee4f6..af2e26efbe 100644 --- a/modules/java/android_test/src/org/opencv/test/features2d/SURFDescriptorExtractorTest.java +++ b/modules/java/android_test/src/org/opencv/test/features2d/SURFDescriptorExtractorTest.java @@ -27,7 +27,12 @@ public class SURFDescriptorExtractorTest extends OpenCVTestCase { @Override protected void setUp() throws Exception { super.setUp(); + extractor = DescriptorExtractor.create(DescriptorExtractor.SURF); + String filename = OpenCVTestRunner.getTempFileName("yml"); + writeFile(filename, "%YAML:1.0\nextended: 1\nhessianThreshold: 100.\nnOctaveLayers: 2\nnOctaves: 4\nupright: 0"); + extractor.read(filename); + matSize = 100; } @@ -46,19 +51,19 @@ public class SURFDescriptorExtractorTest extends OpenCVTestCase { Mat truth = new Mat(1, 128, CvType.CV_32FC1) { { put(0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0.045382127, 0.075976953, -0.031969212, 0.035002094, 0.012224297, - 0.012286193, -0.0088025155, 0.0088025155, 0.00017225844, 0.00017225844, 0, 0, 8.2743405e-05, - 8.2743405e-05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8.2743405e-05, 8.2743405e-05, -0.00017225844, - 0.00017225844, 0, 0, 0.31723264, 0.42715758, -0.19872268, 0.23621935, 0.033304065, 0.033918764, - -0.021780485, 0.021780485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.0088025145, - 0.0088025145, 0.012224296, 0.012286192, -0.045382123, 0.075976953, 0.031969212, 0.035002094, - 0.10047197, 0.21463872, -0.0012294546, 0.18176091, -0.075555265, 0.35627601, 0.01270232, - 0.20058797, -0.037658721, 0.037658721, 0.064850949, 0.064850949, -0.27688536, 0.44229308, - 0.14888979, 0.14888979, -0.0031531656, 0.0031531656, 0.0068481555, 0.0072466261, -0.034193151, - 0.040314503, 0.01108359, 0.023398584, -0.00071876607, 0.00071876607, -0.0031819802, - 0.0031819802, 0, 0, -0.0013680183, 0.0013680183, 0.034193147, 0.040314503, -0.01108359, - 0.023398584, 0.006848156, 0.0072466265, -0.0031531656, 0.0031531656, 0, 0, 0, 0, 0, 0, 0, 0, - -0.0013680183, 0.0013680183, 0, 0, 0.00071876607, 0.00071876607, 0.0031819802, 0.0031819802 + 0, 0, 0, 0, 0, 0, 0, 0, 0.058821894, 0.058821894, -0.045962855, 0.046261817, 0.0085156476, + 0.0085754395, -0.0064509804, 0.0064509804, 0.00044069235, 0.00044069235, 0, 0, 0.00025723741, + 0.00025723741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00025723741, 0.00025723741, -0.00044069235, + 0.00044069235, 0, 0, 0.36278215, 0.36278215, -0.24688604, 0.26173124, 0.052068226, 0.052662034, + -0.032815345, 0.032815345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.0064523756, + 0.0064523756, 0.0082002236, 0.0088908644, -0.059001274, 0.059001274, 0.045789491, 0.04648013, + 0.11961588, 0.22789426, -0.01322381, 0.18291828, -0.14042182, 0.23973691, 0.073782086, 0.23769434, + -0.027880307, 0.027880307, 0.049587864, 0.049587864, -0.33991757, 0.33991757, 0.21437603, 0.21437603, + -0.0020763327, 0.0020763327, 0.006245892, 0.006245892, -0.04067041, 0.04067041, 0.019361559, + 0.019361559, 0, 0, -0.0035977389, 0.0035977389, 0, 0, -0.00099993451, 0.00099993451, 0.040670406, + 0.040670406, -0.019361559, 0.019361559, 0.006245892, 0.006245892, -0.0020763327, 0.0020763327, + -0.00034532088, 0.00034532088, 0, 0, 0, 0, 0.00034532088, 0.00034532088, -0.00099993451, + 0.00099993451, 0, 0, 0, 0, 0.0035977389, 0.0035977389 ); } }; diff --git a/modules/java/android_test/src/org/opencv/test/features2d/SURFFeatureDetectorTest.java b/modules/java/android_test/src/org/opencv/test/features2d/SURFFeatureDetectorTest.java index 29da6ffcbb..778d6f3735 100644 --- a/modules/java/android_test/src/org/opencv/test/features2d/SURFFeatureDetectorTest.java +++ b/modules/java/android_test/src/org/opencv/test/features2d/SURFFeatureDetectorTest.java @@ -150,7 +150,7 @@ public class SURFFeatureDetectorTest extends OpenCVTestCase { detector.write(filename); - String truth = "\n\nFeature2D.SURF\n1\n100.\n2\n4\n0\n\n"; + String truth = "\n\nFeature2D.SURF\n0\n100.\n3\n4\n0\n\n"; assertEquals(truth, readFile(filename)); } @@ -159,7 +159,7 @@ public class SURFFeatureDetectorTest extends OpenCVTestCase { detector.write(filename); - String truth = "%YAML:1.0\nname: \"Feature2D.SURF\"\nextended: 1\nhessianThreshold: 100.\nnOctaveLayers: 2\nnOctaves: 4\nupright: 0\n"; + String truth = "%YAML:1.0\nname: \"Feature2D.SURF\"\nextended: 0\nhessianThreshold: 100.\nnOctaveLayers: 3\nnOctaves: 4\nupright: 0\n"; assertEquals(truth, readFile(filename)); } From 0cd8684ade920bc81d34330d032e4e911ec358e0 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Fri, 1 Feb 2013 18:01:13 +0400 Subject: [PATCH 07/17] Fix setting of FPS after frame width and height with DShow cameras Issue #2114 --- modules/highgui/src/cap_dshow.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/modules/highgui/src/cap_dshow.cpp b/modules/highgui/src/cap_dshow.cpp index b1b142c79b..c2513d788d 100644 --- a/modules/highgui/src/cap_dshow.cpp +++ b/modules/highgui/src/cap_dshow.cpp @@ -3120,6 +3120,7 @@ protected: void init(); int index, width, height,fourcc; + int widthSet, heightSet; IplImage* frame; static videoInput VI; }; @@ -3138,6 +3139,7 @@ CvCaptureCAM_DShow::CvCaptureCAM_DShow() index = -1; frame = 0; width = height = fourcc = -1; + widthSet = heightSet = -1; CoInitialize(0); } @@ -3155,7 +3157,7 @@ void CvCaptureCAM_DShow::close() index = -1; cvReleaseImage(&frame); } - width = height = -1; + widthSet = heightSet = width = height = -1; } // Initialize camera input @@ -3282,9 +3284,12 @@ bool CvCaptureCAM_DShow::setProperty( int property_id, double value ) { VI.stopDevice(index); VI.setIdealFramerate(index,fps); - VI.setupDevice(index); + if (widthSet > 0 && heightSet > 0) + VI.setupDevice(index, widthSet, heightSet); + else + VI.setupDevice(index); } - break; + return VI.isDeviceSetup(index); } @@ -3299,8 +3304,15 @@ bool CvCaptureCAM_DShow::setProperty( int property_id, double value ) VI.setIdealFramerate(index, fps); VI.setupDeviceFourcc(index, width, height, fourcc); } - width = height = fourcc = -1; - return VI.isDeviceSetup(index); + + bool success = VI.isDeviceSetup(index); + if (success) + { + widthSet = width; + heightSet = height; + width = height = fourcc = -1; + } + return success; } return true; } From bc68dfb4e8a89f291945fa886be168872d99081f Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Fri, 1 Feb 2013 18:09:58 -0500 Subject: [PATCH 08/17] Remove unused vars --- modules/contrib/src/chamfermatching.cpp | 1 - modules/gpu/src/cascadeclassifier.cpp | 2 -- modules/imgproc/src/pyramids.cpp | 3 +-- modules/objdetect/src/matching.cpp | 5 +---- modules/ocl/src/arithm.cpp | 1 - 5 files changed, 2 insertions(+), 10 deletions(-) diff --git a/modules/contrib/src/chamfermatching.cpp b/modules/contrib/src/chamfermatching.cpp index d33b243a59..881606afea 100644 --- a/modules/contrib/src/chamfermatching.cpp +++ b/modules/contrib/src/chamfermatching.cpp @@ -622,7 +622,6 @@ void ChamferMatcher::Matching::followContour(Mat& templ_img, template_coords_t& { const int dir[][2] = { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} }; coordinate_t next; - coordinate_t next_temp; unsigned char ptr; assert (direction==-1 || !coords.empty()); diff --git a/modules/gpu/src/cascadeclassifier.cpp b/modules/gpu/src/cascadeclassifier.cpp index ac839ce96e..cfaa753114 100644 --- a/modules/gpu/src/cascadeclassifier.cpp +++ b/modules/gpu/src/cascadeclassifier.cpp @@ -771,8 +771,6 @@ NCVStatus loadFromXML(const std::string &filename, haar.bNeedsTiltedII = false; Ncv32u curMaxTreeDepth; - std::vector xmlFileCont; - std::vector h_TmpClassifierNotRootNodes; haarStages.resize(0); haarClassifierNodes.resize(0); diff --git a/modules/imgproc/src/pyramids.cpp b/modules/imgproc/src/pyramids.cpp index a337df7bbb..e7d315cb52 100644 --- a/modules/imgproc/src/pyramids.cpp +++ b/modules/imgproc/src/pyramids.cpp @@ -327,11 +327,10 @@ pyrUp_( const Mat& _src, Mat& _dst, int) CV_Assert( std::abs(dsize.width - ssize.width*2) == dsize.width % 2 && std::abs(dsize.height - ssize.height*2) == dsize.height % 2); - int k, x, sy0 = -PU_SZ/2, sy = sy0, width0 = ssize.width - 1; + int k, x, sy0 = -PU_SZ/2, sy = sy0; ssize.width *= cn; dsize.width *= cn; - width0 *= cn; for( x = 0; x < ssize.width; x++ ) dtab[x] = (x/cn)*2*cn + x % cn; diff --git a/modules/objdetect/src/matching.cpp b/modules/objdetect/src/matching.cpp index 11873b1c28..382f6312a9 100644 --- a/modules/objdetect/src/matching.cpp +++ b/modules/objdetect/src/matching.cpp @@ -1396,7 +1396,7 @@ static int createSchedule(const CvLSVMFeaturePyramid *H, const CvLSVMFilterObjec const int n, const int bx, const int by, const int threadsNum, int *kLevels, int **processingLevels) { - int rootFilterDim, sumPartFiltersDim, i, numLevels, dbx, dby, numDotProducts; + int rootFilterDim, sumPartFiltersDim, i, numLevels, dbx, dby; int j, minValue, argMin, lambda, maxValue, k; int *dotProd, *weights, *disp; if (H == NULL || all_F == NULL) @@ -1420,8 +1420,6 @@ static int createSchedule(const CvLSVMFeaturePyramid *H, const CvLSVMFilterObjec // of feature map with part filter dbx = 2 * bx; dby = 2 * by; - // Total number of dot products for all levels - numDotProducts = 0; lambda = LAMBDA; for (i = 0; i < numLevels; i++) { @@ -1429,7 +1427,6 @@ static int createSchedule(const CvLSVMFeaturePyramid *H, const CvLSVMFilterObjec H->pyramid[i + lambda]->sizeY * rootFilterDim + (H->pyramid[i]->sizeX + dbx) * (H->pyramid[i]->sizeY + dby) * sumPartFiltersDim; - numDotProducts += dotProd[i]; } // Allocation memory for saving dot product number performed by each thread weights = (int *)malloc(sizeof(int) * threadsNum); diff --git a/modules/ocl/src/arithm.cpp b/modules/ocl/src/arithm.cpp index de8f4343b4..e9e82b94c4 100644 --- a/modules/ocl/src/arithm.cpp +++ b/modules/ocl/src/arithm.cpp @@ -2205,7 +2205,6 @@ void cv::ocl::transpose(const oclMat &src, oclMat &dst) CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC3 || src.type() == CV_8UC4 || src.type() == CV_8SC3 || src.type() == CV_8SC4 || src.type() == CV_16UC2 || src.type() == CV_16SC2 || src.type() == CV_32SC1 || src.type() == CV_32FC1); - stringstream idxstr; oclMat emptyMat; if( src.data == dst.data && dst.cols == dst.rows ) From 3154cdf8ac5c224e0b6e3941ab66ffb886e1da74 Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Fri, 1 Feb 2013 22:57:22 -0500 Subject: [PATCH 09/17] Fix subtle bug when src & dst agree on sparsity but have different dimensions Remove unused var "total" Declare vars as locally as possible --- modules/imgproc/src/histogram.cpp | 42 +++++++++++++++++-------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/modules/imgproc/src/histogram.cpp b/modules/imgproc/src/histogram.cpp index 864b49b314..61509d3445 100644 --- a/modules/imgproc/src/histogram.cpp +++ b/modules/imgproc/src/histogram.cpp @@ -2592,39 +2592,36 @@ cvCompareHist( const CvHistogram* hist1, CV_IMPL void cvCopyHist( const CvHistogram* src, CvHistogram** _dst ) { - int eq = 0; - int is_sparse; - int i, dims1, dims2; - int size1[CV_MAX_DIM], size2[CV_MAX_DIM], total = 1; - float* ranges[CV_MAX_DIM]; - float** thresh = 0; - CvHistogram* dst; - if( !_dst ) CV_Error( CV_StsNullPtr, "Destination double pointer is NULL" ); - dst = *_dst; + CvHistogram* dst = *_dst; if( !CV_IS_HIST(src) || (dst && !CV_IS_HIST(dst)) ) CV_Error( CV_StsBadArg, "Invalid histogram header[s]" ); - is_sparse = CV_IS_SPARSE_MAT(src->bins); - dims1 = cvGetDims( src->bins, size1 ); - for( i = 0; i < dims1; i++ ) - total *= size1[i]; - - if( dst && is_sparse == CV_IS_SPARSE_MAT(dst->bins)) + bool eq = false; + int size1[CV_MAX_DIM]; + bool is_sparse = CV_IS_SPARSE_MAT(src->bins); + int dims1 = cvGetDims( src->bins, size1 ); + + if( dst && (is_sparse == CV_IS_SPARSE_MAT(dst->bins))) { - dims2 = cvGetDims( dst->bins, size2 ); + int size2[CV_MAX_DIM]; + int dims2 = cvGetDims( dst->bins, size2 ); if( dims1 == dims2 ) { + int i; + for( i = 0; i < dims1; i++ ) + { if( size1[i] != size2[i] ) break; + } + + eq = (i == dims1); } - - eq = i == dims1; } if( !eq ) @@ -2636,14 +2633,21 @@ cvCopyHist( const CvHistogram* src, CvHistogram** _dst ) if( CV_HIST_HAS_RANGES( src )) { + float* ranges[CV_MAX_DIM]; + float** thresh = 0; + if( CV_IS_UNIFORM_HIST( src )) { - for( i = 0; i < dims1; i++ ) + for( int i = 0; i < dims1; i++ ) ranges[i] = (float*)src->thresh[i]; + thresh = ranges; } else + { thresh = src->thresh2; + } + cvSetHistBinRanges( dst, thresh, CV_IS_UNIFORM_HIST(src)); } From b497380a686cc9812a086ce246d7a0430943c697 Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Sat, 2 Feb 2013 08:33:40 -0500 Subject: [PATCH 10/17] Check memory allocation Initialize local variables --- modules/ml/src/knearest.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/ml/src/knearest.cpp b/modules/ml/src/knearest.cpp index fa6b15e1b3..3c2f9ebada 100644 --- a/modules/ml/src/knearest.cpp +++ b/modules/ml/src/knearest.cpp @@ -100,9 +100,9 @@ bool CvKNearest::train( const CvMat* _train_data, const CvMat* _responses, __BEGIN__; - CvVectors* _samples; - float** _data; - int _count, _dims, _dims_all, _rsize; + CvVectors* _samples = 0; + float** _data = 0; + int _count = 0, _dims = 0, _dims_all = 0, _rsize = 0; if( !_update_base ) clear(); @@ -114,6 +114,9 @@ bool CvKNearest::train( const CvMat* _train_data, const CvMat* _responses, _responses, CV_VAR_ORDERED, 0, _sample_idx, true, (const float***)&_data, &_count, &_dims, &_dims_all, &responses, 0, 0 )); + if( !responses ) + CV_ERROR( CV_StsNoMem, "Could not allocate memory for responses" ); + if( _update_base && _dims != var_count ) CV_ERROR( CV_StsBadArg, "The newly added data have different dimensionality" ); From b79e8053c1a44733f9c3e98f8e9a659c546931c6 Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Sat, 2 Feb 2013 08:44:25 -0500 Subject: [PATCH 11/17] Check memory allocation Declare vars as locally as possible --- modules/objdetect/src/haar.cpp | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/modules/objdetect/src/haar.cpp b/modules/objdetect/src/haar.cpp index aa062c38e0..0a5f8873a8 100644 --- a/modules/objdetect/src/haar.cpp +++ b/modules/objdetect/src/haar.cpp @@ -1935,20 +1935,14 @@ icvLoadCascadeCART( const char** input_cascade, int n, CvSize orig_window_size ) CV_IMPL CvHaarClassifierCascade* cvLoadHaarClassifierCascade( const char* directory, CvSize orig_window_size ) { - const char** input_cascade = 0; - CvHaarClassifierCascade *cascade = 0; - - int i, n; - const char* slash; - char name[_MAX_PATH]; - int size = 0; - char* ptr = 0; - if( !directory ) CV_Error( CV_StsNullPtr, "Null path is passed" ); - n = (int)strlen(directory)-1; - slash = directory[n] == '\\' || directory[n] == '/' ? "" : "/"; + char name[_MAX_PATH]; + + int n = (int)strlen(directory)-1; + const char* slash = directory[n] == '\\' || directory[n] == '/' ? "" : "/"; + int size = 0; /* try to read the classifier from directory */ for( n = 0; ; n++ ) @@ -1969,10 +1963,14 @@ cvLoadHaarClassifierCascade( const char* directory, CvSize orig_window_size ) CV_Error( CV_StsBadArg, "Invalid path" ); size += (n+1)*sizeof(char*); - input_cascade = (const char**)cvAlloc( size ); - ptr = (char*)(input_cascade + n + 1); + const char** input_cascade = (const char**)cvAlloc( size ); + + if( !input_cascade ) + CV_Error( CV_StsNoMem, "Could not allocate memory for input_cascade" ); + + char* ptr = (char*)(input_cascade + n + 1); - for( i = 0; i < n; i++ ) + for( int i = 0; i < n; i++ ) { sprintf( name, "%s/%d/AdaBoostCARTHaarClassifier.txt", directory, i ); FILE* f = fopen( name, "rb" ); @@ -1990,7 +1988,8 @@ cvLoadHaarClassifierCascade( const char* directory, CvSize orig_window_size ) } input_cascade[n] = 0; - cascade = icvLoadCascadeCART( input_cascade, n, orig_window_size ); + + CvHaarClassifierCascade* cascade = icvLoadCascadeCART( input_cascade, n, orig_window_size ); if( input_cascade ) cvFree( &input_cascade ); From c8cad0857e04d457686e16960b0e2f84e0eac4de Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Sat, 2 Feb 2013 16:09:10 -0500 Subject: [PATCH 12/17] Remove unused constructor Add checks for valid values Fix wording on some errors --- modules/features2d/src/evaluation.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/features2d/src/evaluation.cpp b/modules/features2d/src/evaluation.cpp index ca5fe26cf7..1724b0176a 100644 --- a/modules/features2d/src/evaluation.cpp +++ b/modules/features2d/src/evaluation.cpp @@ -241,7 +241,6 @@ static void filterEllipticKeyPointsByImageSize( vector& keypoi struct IntersectAreaCounter { - IntersectAreaCounter() : bua(0), bna(0) {} IntersectAreaCounter( float _dr, int _minx, int _miny, int _maxy, const Point2f& _diff, @@ -257,6 +256,9 @@ struct IntersectAreaCounter void operator()( const BlockedRange& range ) { + CV_Assert( miny < maxy ); + CV_Assert( dr > FLT_EPSILON ); + int temp_bua = bua, temp_bna = bna; for( int i = range.begin(); i != range.end(); i++ ) { @@ -461,7 +463,7 @@ void cv::evaluateFeatureDetector( const Mat& img1, const Mat& img2, const Mat& H keypoints2 = _keypoints2 != 0 ? _keypoints2 : &buf2; if( (keypoints1->empty() || keypoints2->empty()) && fdetector.empty() ) - CV_Error( CV_StsBadArg, "fdetector must be no empty when keypoints1 or keypoints2 is empty" ); + CV_Error( CV_StsBadArg, "fdetector must not be empty when keypoints1 or keypoints2 is empty" ); if( keypoints1->empty() ) fdetector->detect( img1, *keypoints1 ); @@ -572,10 +574,10 @@ void cv::evaluateGenericDescriptorMatcher( const Mat& img1, const Mat& img2, con correctMatches1to2Mask = _correctMatches1to2Mask != 0 ? _correctMatches1to2Mask : &buf2; if( keypoints1.empty() ) - CV_Error( CV_StsBadArg, "keypoints1 must be no empty" ); + CV_Error( CV_StsBadArg, "keypoints1 must not be empty" ); if( matches1to2->empty() && dmatcher.empty() ) - CV_Error( CV_StsBadArg, "dmatch must be no empty when matches1to2 is empty" ); + CV_Error( CV_StsBadArg, "dmatch must not be empty when matches1to2 is empty" ); bool computeKeypoints2ByPrj = keypoints2.empty(); if( computeKeypoints2ByPrj ) From ac8744af6ab76a65451780bab735ab84e3bf5caa Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Sat, 2 Feb 2013 19:00:41 -0500 Subject: [PATCH 13/17] No need to check vector size before clear() --- modules/contrib/src/chamfermatching.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/contrib/src/chamfermatching.cpp b/modules/contrib/src/chamfermatching.cpp index 881606afea..17d06b3b75 100644 --- a/modules/contrib/src/chamfermatching.cpp +++ b/modules/contrib/src/chamfermatching.cpp @@ -930,15 +930,13 @@ void ChamferMatcher::Template::show() const void ChamferMatcher::Matching::addTemplateFromImage(Mat& templ, float scale) { Template* cmt = new Template(templ, scale); - if(templates.size() > 0) - templates.clear(); + templates.clear(); templates.push_back(cmt); cmt->show(); } void ChamferMatcher::Matching::addTemplate(Template& template_){ - if(templates.size() > 0) - templates.clear(); + templates.clear(); templates.push_back(&template_); } /** From a639a1ae5c2e4a77c73f488b24bd733a359238e5 Mon Sep 17 00:00:00 2001 From: yao Date: Mon, 4 Feb 2013 15:06:36 +0800 Subject: [PATCH 14/17] add setDeviceEx interface simplify the logic of save binary --- modules/ocl/include/opencv2/ocl/ocl.hpp | 16 ++- modules/ocl/src/initialization.cpp | 170 ++++++++++-------------- modules/ocl/src/precomp.hpp | 8 +- modules/ocl/src/pyrlk.cpp | 2 +- 4 files changed, 90 insertions(+), 106 deletions(-) diff --git a/modules/ocl/include/opencv2/ocl/ocl.hpp b/modules/ocl/include/opencv2/ocl/ocl.hpp index 5e4b143f85..ed672fe0e3 100644 --- a/modules/ocl/include/opencv2/ocl/ocl.hpp +++ b/modules/ocl/include/opencv2/ocl/ocl.hpp @@ -84,20 +84,26 @@ namespace cv //this function may be obsoleted //CV_EXPORTS cl_device_id getDevice(); //the function must be called before any other cv::ocl::functions, it initialize ocl runtime + //each Info relates to an OpenCL platform + //there is one or more devices in each platform, each one has a separate name CV_EXPORTS int getDevice(std::vector &oclinfo, int devicetype = CVCL_DEVICE_TYPE_GPU); + //set device you want to use, optional function after getDevice be called + //the devnum is the index of the selected device in DeviceName vector of INfo CV_EXPORTS void setDevice(Info &oclinfo, int devnum = 0); - //this function is not ready yet - //CV_EXPORTS void getComputeCapability(cl_device_id device, int &major, int &minor); + //optional function, if you want save opencl binary kernel to the file, set its path CV_EXPORTS void setBinpath(const char *path); - //The two functions below are used to get opencl runtime so that opencv can interactive with - - //other opencl program + //The two functions below enable other opencl program to use ocl module's cl_context and cl_command_queue CV_EXPORTS void* getoclContext(); CV_EXPORTS void* getoclCommandQueue(); + + //this function enable ocl module to use customized cl_context and cl_command_queue + //getDevice also need to be called before this function + CV_EXPORTS void setDeviceEx(Info &oclinfo, void *ctx, void *qu, int devnum = 0); + //////////////////////////////// Error handling //////////////////////// CV_EXPORTS void error(const char *error_string, const char *file, const int line, const char *func); diff --git a/modules/ocl/src/initialization.cpp b/modules/ocl/src/initialization.cpp index a23900419c..d2dad4a846 100644 --- a/modules/ocl/src/initialization.cpp +++ b/modules/ocl/src/initialization.cpp @@ -12,11 +12,13 @@ // // Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved. // Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved. +// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved. // Third party copyrights are property of their respective owners. // // @Authors // Guoping Long, longguoping@gmail.com -// Niko Li, newlife20080214@gmail.com +// Niko Li, newlife20080214@gmail.com +// Yao Wang, bitwangyaoyao@gmail.com // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // @@ -292,23 +294,12 @@ namespace cv } return devcienums; } - void setDevice(Info &oclinfo, int devnum) - { - CV_Assert(devnum >= 0); - cl_int status = 0; - cl_context_properties cps[3] = - { - CL_CONTEXT_PLATFORM, (cl_context_properties)(oclinfo.impl->oclplatform), 0 - }; - oclinfo.impl->devnum = devnum; - oclinfo.impl->oclcontext = clCreateContext(cps, 1, &oclinfo.impl->devices[devnum], NULL, NULL, &status); - openCLVerifyCall(status); - //create the command queue using the first device of the list - oclinfo.impl->clCmdQueue = clCreateCommandQueue(oclinfo.impl->oclcontext, oclinfo.impl->devices[devnum], - CL_QUEUE_PROFILING_ENABLE, &status); - openCLVerifyCall(status); + static void fillClcontext(Info &oclinfo) + { //get device information + size_t devnum = oclinfo.impl->devnum; + openCLSafeCall(clGetDeviceInfo(oclinfo.impl->devices[devnum], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), (void *)&oclinfo.impl->maxWorkGroupSize, NULL)); openCLSafeCall(clGetDeviceInfo(oclinfo.impl->devices[devnum], CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, @@ -338,7 +329,41 @@ namespace cv oclinfo.impl -> double_support = 1; } Context::setContext(oclinfo); + } + + void setDevice(Info &oclinfo, int devnum) + { + CV_Assert(devnum >= 0); + cl_int status = 0; + cl_context_properties cps[3] = + { + CL_CONTEXT_PLATFORM, (cl_context_properties)(oclinfo.impl->oclplatform), 0 + }; + oclinfo.impl->devnum = devnum; + oclinfo.impl->oclcontext = clCreateContext(cps, 1, &oclinfo.impl->devices[devnum], NULL, NULL, &status); + openCLVerifyCall(status); + //create the command queue using the first device of the list + oclinfo.impl->clCmdQueue = clCreateCommandQueue(oclinfo.impl->oclcontext, oclinfo.impl->devices[devnum], + CL_QUEUE_PROFILING_ENABLE, &status); + openCLVerifyCall(status); + fillClcontext(oclinfo); + } + + void setDeviceEx(Info &oclinfo, void *ctx, void *q, int devnum) + { + CV_Assert(devnum >= 0); + oclinfo.impl->devnum = devnum; + if(ctx && q) + { + oclinfo.impl->oclcontext = (cl_context)ctx; + oclinfo.impl->clCmdQueue = (cl_command_queue)q; + clRetainContext((cl_context)ctx); + clRetainCommandQueue((cl_command_queue)q); + fillClcontext(oclinfo); + } + } + void *getoclContext() { @@ -440,87 +465,35 @@ namespace cv Context *clcxt = Context::getContext(); clcxt->impl->Binpath = path; } - int savetofile(const Context *clcxt, cl_program &program, const char *fileName) + + int savetofile(const Context*, cl_program &program, const char *fileName) { - //cl_int status; - size_t numDevices = 1; - cl_device_id *devices = clcxt->impl->devices; - //figure out the sizes of each of the binaries. - size_t *binarySizes = (size_t *)malloc( sizeof(size_t) * numDevices ); - + size_t binarySize; openCLSafeCall(clGetProgramInfo(program, - CL_PROGRAM_BINARY_SIZES, - sizeof(size_t) * numDevices, - binarySizes, NULL)); - - size_t i = 0; - //copy over all of the generated binaries. - char **binaries = (char **)malloc( sizeof(char *) * numDevices ); - if(binaries == NULL) + CL_PROGRAM_BINARY_SIZES, + sizeof(size_t), + &binarySize, NULL)); + char* binary = (char*)malloc(binarySize); + if(binary == NULL) { - CV_Error(CV_StsNoMem, "Failed to allocate host memory.(binaries)\r\n"); - } - - for(i = 0; i < numDevices; i++) - { - if(binarySizes[i] != 0) - { - binaries[i] = (char *)malloc( sizeof(char) * binarySizes[i]); - if(binaries[i] == NULL) - { - CV_Error(CV_StsNoMem, "Failed to allocate host memory.(binaries[i])\r\n"); - } - } - else - { - binaries[i] = NULL; - } + CV_Error(CV_StsNoMem, "Failed to allocate host memory."); } openCLSafeCall(clGetProgramInfo(program, - CL_PROGRAM_BINARIES, - sizeof(char *) * numDevices, - binaries, - NULL)); + CL_PROGRAM_BINARIES, + sizeof(char *), + &binary, + NULL)); - //dump out each binary into its own separate file. - for(i = 0; i < numDevices; i++) + FILE *fp = fopen(fileName, "wb+"); + if(fp != NULL) { - if(binarySizes[i] != 0) - { - char deviceName[1024]; - openCLSafeCall(clGetDeviceInfo(devices[i], - CL_DEVICE_NAME, - sizeof(deviceName), - deviceName, - NULL)); - - printf( "%s binary kernel: %s\n", deviceName, fileName); - FILE *fp = fopen(fileName, "wb+"); - if(fp == NULL) - { - char *temp = NULL; - sprintf(temp, "Failed to load kernel file : %s\r\n", fileName); - CV_Error(CV_GpuApiCallError, temp); - } - else - { - fwrite(binaries[i], binarySizes[i], 1, fp); - free(binaries[i]); - fclose(fp); - } - } - else - { - printf("Skipping %s since there is no binary data to write!\n", - fileName); - } + fwrite(binary, binarySize, 1, fp); + free(binary); + fclose(fp); } - free(binarySizes); - free(binaries); return 1; } - cl_kernel openCLGetKernelFromSource(const Context *clCxt, const char **source, string kernelName, const char *build_options) { @@ -572,7 +545,7 @@ namespace cv program = clCreateProgramWithSource( clCxt->impl->clContext, 1, source, NULL, &status); openCLVerifyCall(status); - status = clBuildProgram(program, 1, &(clCxt->impl->devices[0]), all_build_options, NULL, NULL); + status = clBuildProgram(program, 1, &(clCxt->impl->devices), all_build_options, NULL, NULL); if(status == CL_SUCCESS && clCxt->impl->Binpath.size()) savetofile(clCxt, program, filename.c_str()); } @@ -587,13 +560,14 @@ namespace cv cl_int status = 0; program = clCreateProgramWithBinary(clCxt->impl->clContext, 1, - &(clCxt->impl->devices[0]), + &(clCxt->impl->devices), (const size_t *)&binarySize, (const unsigned char **)&binary, NULL, &status); openCLVerifyCall(status); - status = clBuildProgram(program, 1, &(clCxt->impl->devices[0]), all_build_options, NULL, NULL); + status = clBuildProgram(program, 1, &(clCxt->impl->devices), all_build_options, NULL, NULL); + delete[] binary; } if(status != CL_SUCCESS) @@ -604,14 +578,14 @@ namespace cv char *buildLog = NULL; size_t buildLogSize = 0; logStatus = clGetProgramBuildInfo(program, - clCxt->impl->devices[0], CL_PROGRAM_BUILD_LOG, buildLogSize, + clCxt->impl->devices, CL_PROGRAM_BUILD_LOG, buildLogSize, buildLog, &buildLogSize); if(logStatus != CL_SUCCESS) cout << "Failed to build the program and get the build info." << endl; buildLog = new char[buildLogSize]; CV_DbgAssert(!!buildLog); memset(buildLog, 0, buildLogSize); - openCLSafeCall(clGetProgramBuildInfo(program, clCxt->impl->devices[0], + openCLSafeCall(clGetProgramBuildInfo(program, clCxt->impl->devices, CL_PROGRAM_BUILD_LOG, buildLogSize, buildLog, NULL)); cout << "\n\t\t\tBUILD LOG\n"; cout << buildLog << endl; @@ -633,7 +607,7 @@ namespace cv void openCLVerifyKernel(const Context *clCxt, cl_kernel kernel, size_t *localThreads) { size_t kernelWorkGroupSize; - openCLSafeCall(clGetKernelWorkGroupInfo(kernel, clCxt->impl->devices[0], + openCLSafeCall(clGetKernelWorkGroupInfo(kernel, clCxt->impl->devices, CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), &kernelWorkGroupSize, 0)); CV_Assert( (localThreads[0] <= clCxt->impl->maxWorkItemSizes[0]) && (localThreads[1] <= clCxt->impl->maxWorkItemSizes[1]) && @@ -795,15 +769,16 @@ namespace cv Context *clcxt = getContext(); clcxt->impl->clContext = oclinfo.impl->oclcontext; clcxt->impl->clCmdQueue = oclinfo.impl->clCmdQueue; - clcxt->impl->devices = &oclinfo.impl->devices[oclinfo.impl->devnum]; + clcxt->impl->devices = oclinfo.impl->devices[oclinfo.impl->devnum]; clcxt->impl->devName = oclinfo.impl->devName[oclinfo.impl->devnum]; clcxt->impl->maxDimensions = oclinfo.impl->maxDimensions; clcxt->impl->maxWorkGroupSize = oclinfo.impl->maxWorkGroupSize; - clcxt->impl->maxWorkItemSizes = oclinfo.impl->maxWorkItemSizes; + for(size_t i=0; iimpl->maxDimensions && i<4; i++) + clcxt->impl->maxWorkItemSizes[i] = oclinfo.impl->maxWorkItemSizes[i]; clcxt->impl->maxComputeUnits = oclinfo.impl->maxComputeUnits; clcxt->impl->double_support = oclinfo.impl->double_support; //extra options to recognize compiler options - clcxt->impl->extra_options = oclinfo.impl->extra_options; + memcpy(clcxt->impl->extra_options, oclinfo.impl->extra_options, 512); } Context::Context() { @@ -814,11 +789,12 @@ namespace cv impl->devices = NULL; impl->maxDimensions = 0; impl->maxWorkGroupSize = 0; - impl->maxWorkItemSizes = NULL; + for(int i=0; i<4; i++) + impl->maxWorkItemSizes[i] = 0; impl->maxComputeUnits = 0; impl->double_support = 0; //extra options to recognize vendor specific fp64 extensions - impl->extra_options = NULL; + memset(impl->extra_options, 0, 512); programCache = ProgramCache::getProgramCache(); } diff --git a/modules/ocl/src/precomp.hpp b/modules/ocl/src/precomp.hpp index 317da59919..f65621f41d 100644 --- a/modules/ocl/src/precomp.hpp +++ b/modules/ocl/src/precomp.hpp @@ -12,10 +12,12 @@ // // Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved. // Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved. +// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved. // Third party copyrights are property of their respective owners. // // @Authors // Guoping Long, longguoping@gmail.com +// Yao Wang, bitwangyaoyao@gmail.com // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -131,15 +133,15 @@ namespace cv //Information of the OpenCL context cl_context clContext; cl_command_queue clCmdQueue; - cl_device_id *devices; + cl_device_id devices; string devName; cl_uint maxDimensions; size_t maxWorkGroupSize; - size_t *maxWorkItemSizes; + size_t maxWorkItemSizes[4]; cl_uint maxComputeUnits; int double_support; //extra options to recognize vendor specific fp64 extensions - char *extra_options; + char extra_options[512]; string Binpath; }; } diff --git a/modules/ocl/src/pyrlk.cpp b/modules/ocl/src/pyrlk.cpp index 0e871068a7..8048fafba9 100644 --- a/modules/ocl/src/pyrlk.cpp +++ b/modules/ocl/src/pyrlk.cpp @@ -742,7 +742,7 @@ static void lkSparse_run(oclMat &I, oclMat &J, Context *clCxt = I.clCxt; char platform[256] = {0}; cl_platform_id pid; - clGetDeviceInfo(*clCxt->impl->devices, CL_DEVICE_PLATFORM, sizeof(pid), &pid, NULL); + clGetDeviceInfo(clCxt->impl->devices, CL_DEVICE_PLATFORM, sizeof(pid), &pid, NULL); clGetPlatformInfo(pid, CL_PLATFORM_NAME, 256, platform, NULL); std::string namestr = platform; bool isImageSupported = true; From e58f4e44c8b72a864ae61fd459e940da40bcbfb6 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Fri, 1 Feb 2013 13:15:39 +0400 Subject: [PATCH 15/17] Modules redifinition in case of multiple includes of OpenCV.mk in single Android.mk fixed. --- cmake/templates/OpenCV.mk.in | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/cmake/templates/OpenCV.mk.in b/cmake/templates/OpenCV.mk.in index d52f75b915..943d7cb672 100644 --- a/cmake/templates/OpenCV.mk.in +++ b/cmake/templates/OpenCV.mk.in @@ -89,14 +89,20 @@ define add_opencv_camera_module include $(PREBUILT_SHARED_LIBRARY) endef -ifeq ($(OPENCV_INSTALL_MODULES),on) -$(foreach module,$(OPENCV_LIBS),$(eval $(call add_opencv_module,$(module)))) -endif -$(foreach module,$(OPENCV_3RDPARTY_COMPONENTS),$(eval $(call add_opencv_3rdparty_component,$(module)))) -$(foreach module,$(OPENCV_CAMERA_MODULES),$(eval $(call add_opencv_camera_module,$(module)))) +ifeq ($(OPENCV_MK_ALREADY_INCLUDED),) + ifeq ($(OPENCV_INSTALL_MODULES),on) + $(foreach module,$(OPENCV_LIBS),$(eval $(call add_opencv_module,$(module)))) + endif -ifneq ($(OPENCV_BASEDIR),) - OPENCV_LOCAL_C_INCLUDES += $(foreach mod, $(OPENCV_MODULES), $(OPENCV_BASEDIR)/modules/$(mod)/include) + $(foreach module,$(OPENCV_3RDPARTY_COMPONENTS),$(eval $(call add_opencv_3rdparty_component,$(module)))) + $(foreach module,$(OPENCV_CAMERA_MODULES),$(eval $(call add_opencv_camera_module,$(module)))) + + ifneq ($(OPENCV_BASEDIR),) + OPENCV_LOCAL_C_INCLUDES += $(foreach mod, $(OPENCV_MODULES), $(OPENCV_BASEDIR)/modules/$(mod)/include) + endif + + #turn off module installation to prevent their redefinition + OPENCV_MK_ALREADY_INCLUDED:=on endif ifeq ($(OPENCV_LOCAL_CFLAGS),) From 0b1599d88a9b748256db01ac8fabc59c88229d7a Mon Sep 17 00:00:00 2001 From: Vincent Rabaud Date: Sun, 3 Feb 2013 14:31:15 +0100 Subject: [PATCH 16/17] write documentation for BRISK --- ...on_interfaces_of_descriptor_extractors.rst | 1 + ...mmon_interfaces_of_descriptor_matchers.rst | 2 +- ...common_interfaces_of_feature_detectors.rst | 1 + .../doc/feature_detection_and_description.rst | 52 +++++++++++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/modules/features2d/doc/common_interfaces_of_descriptor_extractors.rst b/modules/features2d/doc/common_interfaces_of_descriptor_extractors.rst index d785bafafa..63e56f6786 100644 --- a/modules/features2d/doc/common_interfaces_of_descriptor_extractors.rst +++ b/modules/features2d/doc/common_interfaces_of_descriptor_extractors.rst @@ -79,6 +79,7 @@ The current implementation supports the following types of a descriptor extracto * ``"SIFT"`` -- :ocv:class:`SIFT` * ``"SURF"`` -- :ocv:class:`SURF` * ``"ORB"`` -- :ocv:class:`ORB` + * ``"BRISK"`` -- :ocv:class:`BRISK` * ``"BRIEF"`` -- :ocv:class:`BriefDescriptorExtractor` A combined format is also supported: descriptor extractor adapter name ( ``"Opponent"`` -- diff --git a/modules/features2d/doc/common_interfaces_of_descriptor_matchers.rst b/modules/features2d/doc/common_interfaces_of_descriptor_matchers.rst index 533d2e9cae..8596ae43db 100644 --- a/modules/features2d/doc/common_interfaces_of_descriptor_matchers.rst +++ b/modules/features2d/doc/common_interfaces_of_descriptor_matchers.rst @@ -269,7 +269,7 @@ Brute-force matcher constructor. .. ocv:function:: BFMatcher::BFMatcher( int normType=NORM_L2, bool crossCheck=false ) - :param normType: One of ``NORM_L1``, ``NORM_L2``, ``NORM_HAMMING``, ``NORM_HAMMING2``. ``L1`` and ``L2`` norms are preferable choices for SIFT and SURF descriptors, ``NORM_HAMMING`` should be used with ORB and BRIEF, ``NORM_HAMMING2`` should be used with ORB when ``WTA_K==3`` or ``4`` (see ORB::ORB constructor description). + :param normType: One of ``NORM_L1``, ``NORM_L2``, ``NORM_HAMMING``, ``NORM_HAMMING2``. ``L1`` and ``L2`` norms are preferable choices for SIFT and SURF descriptors, ``NORM_HAMMING`` should be used with ORB, BRISK and BRIEF, ``NORM_HAMMING2`` should be used with ORB when ``WTA_K==3`` or ``4`` (see ORB::ORB constructor description). :param crossCheck: If it is false, this is will be default BFMatcher behaviour when it finds the k nearest neighbors for each query descriptor. If ``crossCheck==true``, then the ``knnMatch()`` method with ``k=1`` will only return pairs ``(i,j)`` such that for ``i-th`` query descriptor the ``j-th`` descriptor in the matcher's collection is the nearest and vice versa, i.e. the ``BFMathcher`` will only return consistent pairs. Such technique usually produces best results with minimal number of outliers when there are enough matches. This is alternative to the ratio test, used by D. Lowe in SIFT paper. diff --git a/modules/features2d/doc/common_interfaces_of_feature_detectors.rst b/modules/features2d/doc/common_interfaces_of_feature_detectors.rst index 8a1fa8c001..8804bdeba7 100644 --- a/modules/features2d/doc/common_interfaces_of_feature_detectors.rst +++ b/modules/features2d/doc/common_interfaces_of_feature_detectors.rst @@ -127,6 +127,7 @@ The following detector types are supported: * ``"SIFT"`` -- :ocv:class:`SIFT` (nonfree module) * ``"SURF"`` -- :ocv:class:`SURF` (nonfree module) * ``"ORB"`` -- :ocv:class:`ORB` +* ``"BRISK"`` -- :ocv:class:`BRISK` * ``"MSER"`` -- :ocv:class:`MSER` * ``"GFTT"`` -- :ocv:class:`GoodFeaturesToTrackDetector` * ``"HARRIS"`` -- :ocv:class:`GoodFeaturesToTrackDetector` with Harris detector enabled diff --git a/modules/features2d/doc/feature_detection_and_description.rst b/modules/features2d/doc/feature_detection_and_description.rst index a6cf5a620a..a39dc68bf4 100644 --- a/modules/features2d/doc/feature_detection_and_description.rst +++ b/modules/features2d/doc/feature_detection_and_description.rst @@ -98,6 +98,58 @@ Finds keypoints in an image and computes their descriptors :param useProvidedKeypoints: If it is true, then the method will use the provided vector of keypoints instead of detecting them. +BRISK +----- +.. ocv:class:: BRISK : public Feature2D + +Class implementing the BRISK keypoint detector and descriptor extractor, described in [LCS11]_. + +.. [LCS11] Stefan Leutenegger, Margarita Chli and Roland Siegwart: BRISK: Binary Robust Invariant Scalable Keypoints. ICCV 2011: 2548-2555. + +BRISK::BRISK +------------ +The BRISK constructor + +.. ocv:function:: BRISK::BRISK(int thresh=30, int octaves=3, float patternScale=1.0f) + + :param thresh: FAST/AGAST detection threshold score. + + :param octaves: detection octaves. Use 0 to do single scale. + + :param patternScale: apply this scale to the pattern used for sampling the neighbourhood of a keypoint. + +BRISK::BRISK +------------ +The BRISK constructor for a custom pattern + +.. ocv:function:: BRISK::BRISK(std::vector &radiusList, std::vector &numberList, float dMax=5.85f, float dMin=8.2f, std::vector indexChange=std::vector()) + + :param radiusList: defines the radii (in pixels) where the samples around a keypoint are taken (for keypoint scale 1). + + :param numberList: defines the number of sampling points on the sampling circle. Must be the same size as radiusList.. + + :param dMax: threshold for the short pairings used for descriptor formation (in pixels for keypoint scale 1). + + :param dMin: threshold for the long pairings used for orientation determination (in pixels for keypoint scale 1). + + :param indexChanges: index remapping of the bits. + +BRISK::operator() +----------------- +Finds keypoints in an image and computes their descriptors + +.. ocv:function:: void BRISK::operator()(InputArray image, InputArray mask, vector& keypoints, OutputArray descriptors, bool useProvidedKeypoints=false ) const + + :param image: The input 8-bit grayscale image. + + :param mask: The operation mask. + + :param keypoints: The output vector of keypoints. + + :param descriptors: The output descriptors. Pass ``cv::noArray()`` if you do not need it. + + :param useProvidedKeypoints: If it is true, then the method will use the provided vector of keypoints instead of detecting them. + FREAK ----- .. ocv:class:: FREAK : public DescriptorExtractor From d235c3a6780d1cab25dd07847ff9eb6938dd6ae6 Mon Sep 17 00:00:00 2001 From: Vincent Rabaud Date: Sun, 3 Feb 2013 14:31:59 +0100 Subject: [PATCH 17/17] define the default remapping in the right scope --- modules/features2d/src/brisk.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/features2d/src/brisk.cpp b/modules/features2d/src/brisk.cpp index ad8c698c57..d1fa0c9c8b 100644 --- a/modules/features2d/src/brisk.cpp +++ b/modules/features2d/src/brisk.cpp @@ -309,10 +309,9 @@ BRISK::generateKernel(std::vector &radiusList, std::vector &numberLi { indexChange.resize(points_ * (points_ - 1) / 2); indSize = (unsigned int)indexChange.size(); - } - for (unsigned int i = 0; i < indSize; i++) - { - indexChange[i] = i; + + for (unsigned int i = 0; i < indSize; i++) + indexChange[i] = i; } const float dMin_sq = dMin_ * dMin_; const float dMax_sq = dMax_ * dMax_;