parallel version
This commit is contained in:
parent
18ef25ec30
commit
b970ec7dae
@ -1175,6 +1175,48 @@ calcHist_8u( std::vector<uchar*>& _ptrs, const std::vector<int>& _deltas,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined HAVE_IPP && !defined HAVE_IPP_ICV_ONLY
|
||||||
|
|
||||||
|
class IPPCalcHistInvoker :
|
||||||
|
public ParallelLoopBody
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IPPCalcHistInvoker(const Mat & _src, Mat & _hist, AutoBuffer<Ipp32s> & _levels, Ipp32s _histSize, Ipp32s _low, Ipp32s _high, bool * _ok) :
|
||||||
|
ParallelLoopBody(), src(&_src), hist(&_hist), levels(&_levels), histSize(_histSize), low(_low), high(_high), ok(_ok)
|
||||||
|
{
|
||||||
|
*ok = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator() (const Range & range) const
|
||||||
|
{
|
||||||
|
Mat phist(hist->size(), hist->type(), Scalar::all(0));
|
||||||
|
|
||||||
|
IppStatus status = ippiHistogramEven_8u_C1R(
|
||||||
|
src->data + src->step * range.start, (int)src->step, ippiSize(src->cols, range.end - range.start),
|
||||||
|
(Ipp32s *)phist.data, (Ipp32s *)*levels, histSize, low, high);
|
||||||
|
|
||||||
|
if (status < 0)
|
||||||
|
{
|
||||||
|
*ok = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < histSize; ++i)
|
||||||
|
CV_XADD((int *)(hist->data + i * hist->step), *(int *)(phist.data + i * phist.step));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Mat * src;
|
||||||
|
Mat * hist;
|
||||||
|
AutoBuffer<Ipp32s> * levels;
|
||||||
|
Ipp32s histSize, low, high;
|
||||||
|
bool * ok;
|
||||||
|
|
||||||
|
const IPPCalcHistInvoker & operator = (const IPPCalcHistInvoker & );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cv::calcHist( const Mat* images, int nimages, const int* channels,
|
void cv::calcHist( const Mat* images, int nimages, const int* channels,
|
||||||
@ -1190,19 +1232,25 @@ void cv::calcHist( const Mat* images, int nimages, const int* channels,
|
|||||||
Mat hist = _hist.getMat(), ihist = hist;
|
Mat hist = _hist.getMat(), ihist = hist;
|
||||||
ihist.flags = (ihist.flags & ~CV_MAT_TYPE_MASK)|CV_32S;
|
ihist.flags = (ihist.flags & ~CV_MAT_TYPE_MASK)|CV_32S;
|
||||||
|
|
||||||
#ifdef HAVE_IPP
|
#if defined HAVE_IPP && !defined HAVE_IPP_ICV_ONLY
|
||||||
if (nimages == 1 && images[0].type() == CV_8UC1 && dims == 1 && channels &&
|
if (nimages == 1 && images[0].type() == CV_8UC1 && dims == 1 && channels &&
|
||||||
channels[0] == 0 && mask.empty() && images[0].dims <= 2 &&
|
channels[0] == 0 && mask.empty() && images[0].dims <= 2 &&
|
||||||
!accumulate && uniform)
|
!accumulate && uniform)
|
||||||
{
|
{
|
||||||
hist.setTo(Scalar::all(0));
|
ihist.setTo(Scalar::all(0));
|
||||||
AutoBuffer<Ipp32s> levels(histSize[0] + 1);
|
AutoBuffer<Ipp32s> levels(histSize[0] + 1);
|
||||||
IppStatus status =
|
|
||||||
ippiHistogramEven_8u_C1R(
|
|
||||||
(const Ipp8u *)images[0].data, (int)images[0].step, ippiSize(images[0].size()),
|
|
||||||
(Ipp32s *)ihist.data, (Ipp32s *)levels, histSize[0] + 1, (Ipp32s)ranges[0][0], (Ipp32s)ranges[0][1]);
|
|
||||||
|
|
||||||
if (status >= 0)
|
bool ok = true;
|
||||||
|
const Mat & src = images[0];
|
||||||
|
int nstripes = std::min<int>(8, src.total() / (1 << 16));
|
||||||
|
#ifdef HAVE_CONCURRENCY
|
||||||
|
nstripes = 1;
|
||||||
|
#endif
|
||||||
|
IPPCalcHistInvoker invoker(src, ihist, levels, histSize[0] + 1, (Ipp32s)ranges[0][0], (Ipp32s)ranges[0][1], &ok);
|
||||||
|
Range range(0, src.rows);
|
||||||
|
parallel_for_(range, invoker, nstripes);
|
||||||
|
|
||||||
|
if (ok)
|
||||||
{
|
{
|
||||||
ihist.convertTo(hist, CV_32F);
|
ihist.convertTo(hist, CV_32F);
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user