opencv calcHist3D_Invoker
template<typename T> class calcHist3D_Invoker { public: calcHist3D_Invoker( const std::vector<uchar*>& _ptrs, const std::vector<int>& _deltas, Size imsize, Mat& hist, const double* uniranges, int _dims, size_t* hstep, int* size ) : mask_(_ptrs[_dims]), mstep_(_deltas[_dims*2 + 1]), imageWidth_(imsize.width), globalHistogram_(hist.data) { p_[0] = ((T**)&_ptrs[0])[0]; p_[1] = ((T**)&_ptrs[0])[1]; p_[2] = ((T**)&_ptrs[0])[2]; step_[0] = (&_deltas[0])[1]; step_[1] = (&_deltas[0])[3]; step_[2] = (&_deltas[0])[5]; d_[0] = (&_deltas[0])[0]; d_[1] = (&_deltas[0])[2]; d_[2] = (&_deltas[0])[4]; a_[0] = uniranges[0]; a_[1] = uniranges[2]; a_[2] = uniranges[4]; b_[0] = uniranges[1]; b_[1] = uniranges[3]; b_[2] = uniranges[5]; size_[0] = size[0]; size_[1] = size[1]; size_[2] = size[2]; hstep_[0] = hstep[0]; hstep_[1] = hstep[1]; } void operator()( const BlockedRange& range ) const { T* p0 = p_[0] + range.begin()*(imageWidth_*d_[0] + step_[0]); T* p1 = p_[1] + range.begin()*(imageWidth_*d_[1] + step_[1]); T* p2 = p_[2] + range.begin()*(imageWidth_*d_[2] + step_[2]); uchar* mask = mask_ + range.begin()*mstep_; for( int i = range.begin(); i < range.end(); i++, p0 += step_[0], p1 += step_[1], p2 += step_[2] ) { if( !mask_ ) { for( int x = 0; x < imageWidth_; x++, p0 += d_[0], p1 += d_[1], p2 += d_[2] ) { int idx0 = cvFloor(*p0*a_[0] + b_[0]); int idx1 = cvFloor(*p1*a_[1] + b_[1]); int idx2 = cvFloor(*p2*a_[2] + b_[2]); if( (unsigned)idx0 < (unsigned)size_[0] && (unsigned)idx1 < (unsigned)size_[1] && (unsigned)idx2 < (unsigned)size_[2] ) { ( (tbb::atomic<int>*)(globalHistogram_ + hstep_[0]*idx0 + hstep_[1]*idx1) )[idx2].fetch_and_add(1); } } } else { for( int x = 0; x < imageWidth_; x++, p0 += d_[0], p1 += d_[1], p2 += d_[2] ) { if( mask[x] ) { int idx0 = cvFloor(*p0*a_[0] + b_[0]); int idx1 = cvFloor(*p1*a_[1] + b_[1]); int idx2 = cvFloor(*p2*a_[2] + b_[2]); if( (unsigned)idx0 < (unsigned)size_[0] && (unsigned)idx1 < (unsigned)size_[1] && (unsigned)idx2 < (unsigned)size_[2] ) { ( (tbb::atomic<int>*)(globalHistogram_ + hstep_[0]*idx0 + hstep_[1]*idx1) )[idx2].fetch_and_add(1); } } } mask += mstep_; } } } static bool isFit( const Mat& histogram, const Size imageSize ) { return ( imageSize.width * imageSize.height >= 320*240 && histogram.total() >= 8*8*8 ); } private: calcHist3D_Invoker operator=(const calcHist3D_Invoker&); T* p_[three]; uchar* mask_; int step_[three]; int d_[three]; const int mstep_; double a_[three]; double b_[three]; int size_[three]; int imageWidth_; size_t hstep_[two]; uchar* globalHistogram_; };
代码参考:opencv-3.4.1modulesimgprocsrchistogram.cpp
####################################