diff --git a/modules/ml/include/opencv2/ml/ml.hpp b/modules/ml/include/opencv2/ml/ml.hpp index aa4dcc93b..3bd8afb9c 100644 --- a/modules/ml/include/opencv2/ml/ml.hpp +++ b/modules/ml/include/opencv2/ml/ml.hpp @@ -324,9 +324,7 @@ public: int get_var_count() const; int get_sample_count() const; bool is_regression() const; - -protected: - + virtual float write_results( int k, int k1, int start, int end, const float* neighbor_responses, const float* dist, CvMat* _results, CvMat* _neighbor_responses, CvMat* _dist, Cv32suf* sort_buf ) const; @@ -334,6 +332,7 @@ protected: virtual void find_neighbors_direct( const CvMat* _samples, int k, int start, int end, float* neighbor_responses, const float** neighbors, float* dist ) const; +protected: int max_k, var_count; int total; @@ -2001,6 +2000,7 @@ public: return layer_sizes && weights && (unsigned)layer <= (unsigned)layer_sizes->cols ? weights[layer] : 0; } + virtual void calc_activ_func_deriv( CvMat* xf, CvMat* deriv, const double* bias ) const; protected: diff --git a/modules/ml/src/knearest.cpp b/modules/ml/src/knearest.cpp index 769c92eea..46189325a 100644 --- a/modules/ml/src/knearest.cpp +++ b/modules/ml/src/knearest.cpp @@ -300,7 +300,54 @@ float CvKNearest::write_results( int k, int k1, int start, int end, return result; } +struct P1 { + P1(const CvKNearest* _pointer, int _buf_sz, int _k, const CvMat* __samples, const float** __neighbors, + int _k1, CvMat* __results, CvMat* __neighbor_responses, CvMat* __dist, float* _result) + { + pointer = _pointer; + k = _k; + _samples = __samples; + _neighbors = __neighbors; + k1 = _k1; + _results = __results; + _neighbor_responses = __neighbor_responses; + _dist = __dist; + result = _result; + buf_sz = _buf_sz; + } + + const CvKNearest* pointer; + int k; + const CvMat* _samples; + const float** _neighbors; + int k1; + CvMat* _results; + CvMat* _neighbor_responses; + CvMat* _dist; + float* result; + int buf_sz; + + void operator()( const cv::BlockedRange& range ) const + { + cv::AutoBuffer buf(buf_sz); + for(int i = range.begin(); i < range.end(); i += 1 ) + { + float* neighbor_responses = &buf[0]; + float* dist = neighbor_responses + 1*k; + Cv32suf* sort_buf = (Cv32suf*)(dist + 1*k); + pointer->find_neighbors_direct( _samples, k, i, i + 1, + neighbor_responses, _neighbors, dist ); + + float r = pointer->write_results( k, k1, i, i + 1, neighbor_responses, dist, + _results, _neighbor_responses, _dist, sort_buf ); + + if( i == 0 ) + *result = r; + } + } + +}; float CvKNearest::find_nearest( const CvMat* _samples, int k, CvMat* _results, const float** _neighbors, CvMat* _neighbor_responses, CvMat* _dist ) const @@ -359,23 +406,9 @@ float CvKNearest::find_nearest( const CvMat* _samples, int k, CvMat* _results, k1 = get_sample_count(); k1 = MIN( k1, k ); - cv::AutoBuffer buf(buf_sz); - - for( i = 0; i < count; i += blk_count ) - { - blk_count = MIN( count - i, blk_count0 ); - float* neighbor_responses = &buf[0]; - float* dist = neighbor_responses + blk_count*k; - Cv32suf* sort_buf = (Cv32suf*)(dist + blk_count*k); - - find_neighbors_direct( _samples, k, i, i + blk_count, - neighbor_responses, _neighbors, dist ); - - float r = write_results( k, k1, i, i + blk_count, neighbor_responses, dist, - _results, _neighbor_responses, _dist, sort_buf ); - if( i == 0 ) - result = r; - } + cv::parallel_for(cv::BlockedRange(0, count), P1(this, buf_sz, k, _samples, _neighbors, k1, + _results, _neighbor_responses, _dist, &result) + ); return result; }