@@ -1175,6 +1175,48 @@ calcHist_8u( std::vector<uchar*>& _ptrs, const std::vector<int>& _deltas,
1175
1175
}
1176
1176
}
1177
1177
1178
+ #if defined HAVE_IPP && !defined HAVE_IPP_ICV_ONLY
1179
+
1180
+ class IPPCalcHistInvoker :
1181
+ public ParallelLoopBody
1182
+ {
1183
+ public:
1184
+ IPPCalcHistInvoker (const Mat & _src, Mat & _hist, AutoBuffer<Ipp32s> & _levels, Ipp32s _histSize, Ipp32s _low, Ipp32s _high, bool * _ok) :
1185
+ ParallelLoopBody (), src(&_src), hist(&_hist), levels(&_levels), histSize(_histSize), low(_low), high(_high), ok(_ok)
1186
+ {
1187
+ *ok = true ;
1188
+ }
1189
+
1190
+ virtual void operator () (const Range & range) const
1191
+ {
1192
+ Mat phist (hist->size (), hist->type (), Scalar::all (0 ));
1193
+
1194
+ IppStatus status = ippiHistogramEven_8u_C1R (
1195
+ src->data + src->step * range.start , (int )src->step , ippiSize (src->cols , range.end - range.start ),
1196
+ (Ipp32s *)phist.data , (Ipp32s *)*levels, histSize, low, high);
1197
+
1198
+ if (status < 0 )
1199
+ {
1200
+ *ok = false ;
1201
+ return ;
1202
+ }
1203
+
1204
+ for (int i = 0 ; i < histSize; ++i)
1205
+ CV_XADD ((int *)(hist->data + i * hist->step ), *(int *)(phist.data + i * phist.step ));
1206
+ }
1207
+
1208
+ private:
1209
+ const Mat * src;
1210
+ Mat * hist;
1211
+ AutoBuffer<Ipp32s> * levels;
1212
+ Ipp32s histSize, low, high;
1213
+ bool * ok;
1214
+
1215
+ const IPPCalcHistInvoker & operator = (const IPPCalcHistInvoker & );
1216
+ };
1217
+
1218
+ #endif
1219
+
1178
1220
}
1179
1221
1180
1222
void cv::calcHist ( const Mat* images, int nimages, const int * channels,
@@ -1190,6 +1232,32 @@ void cv::calcHist( const Mat* images, int nimages, const int* channels,
1190
1232
Mat hist = _hist.getMat (), ihist = hist;
1191
1233
ihist.flags = (ihist.flags & ~CV_MAT_TYPE_MASK)|CV_32S;
1192
1234
1235
+ #if defined HAVE_IPP && !defined HAVE_IPP_ICV_ONLY
1236
+ if (nimages == 1 && images[0 ].type () == CV_8UC1 && dims == 1 && channels &&
1237
+ channels[0 ] == 0 && mask.empty () && images[0 ].dims <= 2 &&
1238
+ !accumulate && uniform)
1239
+ {
1240
+ ihist.setTo (Scalar::all (0 ));
1241
+ AutoBuffer<Ipp32s> levels (histSize[0 ] + 1 );
1242
+
1243
+ bool ok = true ;
1244
+ const Mat & src = images[0 ];
1245
+ int nstripes = std::min<int >(8 , src.total () / (1 << 16 ));
1246
+ #ifdef HAVE_CONCURRENCY
1247
+ nstripes = 1 ;
1248
+ #endif
1249
+ IPPCalcHistInvoker invoker (src, ihist, levels, histSize[0 ] + 1 , (Ipp32s)ranges[0 ][0 ], (Ipp32s)ranges[0 ][1 ], &ok);
1250
+ Range range (0 , src.rows );
1251
+ parallel_for_ (range, invoker, nstripes);
1252
+
1253
+ if (ok)
1254
+ {
1255
+ ihist.convertTo (hist, CV_32F);
1256
+ return ;
1257
+ }
1258
+ }
1259
+ #endif
1260
+
1193
1261
if ( !accumulate || histdata != hist.data )
1194
1262
hist = Scalar (0 .);
1195
1263
else
@@ -1477,7 +1545,7 @@ void cv::calcHist( InputArrayOfArrays images, const std::vector<int>& channels,
1477
1545
CV_OCL_RUN (images.total () == 1 && channels.size () == 1 && images.channels (0 ) == 1 &&
1478
1546
channels[0 ] == 0 && images.isUMatVector () && mask.empty () && !accumulate &&
1479
1547
histSize.size () == 1 && histSize[0 ] == BINS && ranges.size () == 2 &&
1480
- ranges[0 ] == 0 && ranges[1 ] == 256 ,
1548
+ ranges[0 ] == 0 && ranges[1 ] == BINS ,
1481
1549
ocl_calcHist (images, hist))
1482
1550
1483
1551
int i, dims = (int )histSize.size (), rsz = (int )ranges.size (), csz = (int )channels.size ();
0 commit comments