opencv calcHist1D_Invoker
template<typename T> class calcHist1D_Invoker { public: calcHist1D_Invoker( const std::vector<uchar*>& _ptrs, const std::vector<int>& _deltas, Mat& hist, const double* _uniranges, int sz, int dims, Size& imageSize ) : mask_(_ptrs[dims]), mstep_(_deltas[dims*2 + 1]), imageWidth_(imageSize.width), histogramSize_(hist.size()), histogramType_(hist.type()), globalHistogram_((tbb::atomic<int>*)hist.data) { p_[0] = ((T**)&_ptrs[0])[0]; step_[0] = (&_deltas[0])[1]; d_[0] = (&_deltas[0])[0]; a_[0] = (&_uniranges[0])[0]; b_[0] = (&_uniranges[0])[1]; size_[0] = sz; } void operator()( const BlockedRange& range ) const { T* p0 = p_[0] + range.begin() * (step_[0] + imageWidth_*d_[0]); uchar* mask = mask_ + range.begin()*mstep_; for( int row = range.begin(); row < range.end(); row++, p0 += step_[0] ) { if( !mask_ ) { for( int x = 0; x < imageWidth_; x++, p0 += d_[0] ) { int idx = cvFloor(*p0*a_[0] + b_[0]); if( (unsigned)idx < (unsigned)size_[0] ) { globalHistogram_[idx].fetch_and_add(1); } } } else { for( int x = 0; x < imageWidth_; x++, p0 += d_[0] ) { if( mask[x] ) { int idx = cvFloor(*p0*a_[0] + b_[0]); if( (unsigned)idx < (unsigned)size_[0] ) { globalHistogram_[idx].fetch_and_add(1); } } } mask += mstep_; } } } private: calcHist1D_Invoker operator=(const calcHist1D_Invoker&); T* p_[one]; uchar* mask_; int step_[one]; int d_[one]; int mstep_; double a_[one]; double b_[one]; int size_[one]; int imageWidth_; Size histogramSize_; int histogramType_; tbb::atomic<int>* globalHistogram_; };
代码参考:opencv-3.4.1modulesimgprocsrchistogram.cpp
######################################