in modules/core/src/matrix.cpp [3625:3770]
void cv::reduce(InputArray _src, OutputArray _dst, int dim, int op, int dtype)
{
CV_Assert( _src.dims() <= 2 );
int op0 = op;
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
if( dtype < 0 )
dtype = _dst.fixedType() ? _dst.type() : stype;
dtype = CV_MAKETYPE(dtype >= 0 ? dtype : stype, cn);
int ddepth = CV_MAT_DEPTH(dtype);
CV_Assert( cn == CV_MAT_CN(dtype) );
CV_Assert( op == CV_REDUCE_SUM || op == CV_REDUCE_MAX ||
op == CV_REDUCE_MIN || op == CV_REDUCE_AVG );
CV_OCL_RUN(_dst.isUMat(),
ocl_reduce(_src, _dst, dim, op, op0, stype, dtype))
Mat src = _src.getMat();
_dst.create(dim == 0 ? 1 : src.rows, dim == 0 ? src.cols : 1, dtype);
Mat dst = _dst.getMat(), temp = dst;
if( op == CV_REDUCE_AVG )
{
op = CV_REDUCE_SUM;
if( sdepth < CV_32S && ddepth < CV_32S )
{
temp.create(dst.rows, dst.cols, CV_32SC(cn));
ddepth = CV_32S;
}
}
ReduceFunc func = 0;
if( dim == 0 )
{
if( op == CV_REDUCE_SUM )
{
if(sdepth == CV_8U && ddepth == CV_32S)
func = GET_OPTIMIZED(reduceSumR8u32s);
else if(sdepth == CV_8U && ddepth == CV_32F)
func = reduceSumR8u32f;
else if(sdepth == CV_8U && ddepth == CV_64F)
func = reduceSumR8u64f;
else if(sdepth == CV_16U && ddepth == CV_32F)
func = reduceSumR16u32f;
else if(sdepth == CV_16U && ddepth == CV_64F)
func = reduceSumR16u64f;
else if(sdepth == CV_16S && ddepth == CV_32F)
func = reduceSumR16s32f;
else if(sdepth == CV_16S && ddepth == CV_64F)
func = reduceSumR16s64f;
else if(sdepth == CV_32F && ddepth == CV_32F)
func = GET_OPTIMIZED(reduceSumR32f32f);
else if(sdepth == CV_32F && ddepth == CV_64F)
func = reduceSumR32f64f;
else if(sdepth == CV_64F && ddepth == CV_64F)
func = reduceSumR64f64f;
}
else if(op == CV_REDUCE_MAX)
{
if(sdepth == CV_8U && ddepth == CV_8U)
func = GET_OPTIMIZED(reduceMaxR8u);
else if(sdepth == CV_16U && ddepth == CV_16U)
func = reduceMaxR16u;
else if(sdepth == CV_16S && ddepth == CV_16S)
func = reduceMaxR16s;
else if(sdepth == CV_32F && ddepth == CV_32F)
func = GET_OPTIMIZED(reduceMaxR32f);
else if(sdepth == CV_64F && ddepth == CV_64F)
func = reduceMaxR64f;
}
else if(op == CV_REDUCE_MIN)
{
if(sdepth == CV_8U && ddepth == CV_8U)
func = GET_OPTIMIZED(reduceMinR8u);
else if(sdepth == CV_16U && ddepth == CV_16U)
func = reduceMinR16u;
else if(sdepth == CV_16S && ddepth == CV_16S)
func = reduceMinR16s;
else if(sdepth == CV_32F && ddepth == CV_32F)
func = GET_OPTIMIZED(reduceMinR32f);
else if(sdepth == CV_64F && ddepth == CV_64F)
func = reduceMinR64f;
}
}
else
{
if(op == CV_REDUCE_SUM)
{
if(sdepth == CV_8U && ddepth == CV_32S)
func = GET_OPTIMIZED(reduceSumC8u32s);
else if(sdepth == CV_8U && ddepth == CV_32F)
func = reduceSumC8u32f;
else if(sdepth == CV_8U && ddepth == CV_64F)
func = reduceSumC8u64f;
else if(sdepth == CV_16U && ddepth == CV_32F)
func = reduceSumC16u32f;
else if(sdepth == CV_16U && ddepth == CV_64F)
func = reduceSumC16u64f;
else if(sdepth == CV_16S && ddepth == CV_32F)
func = reduceSumC16s32f;
else if(sdepth == CV_16S && ddepth == CV_64F)
func = reduceSumC16s64f;
else if(sdepth == CV_32F && ddepth == CV_32F)
func = GET_OPTIMIZED(reduceSumC32f32f);
else if(sdepth == CV_32F && ddepth == CV_64F)
func = reduceSumC32f64f;
else if(sdepth == CV_64F && ddepth == CV_64F)
func = reduceSumC64f64f;
}
else if(op == CV_REDUCE_MAX)
{
if(sdepth == CV_8U && ddepth == CV_8U)
func = GET_OPTIMIZED(reduceMaxC8u);
else if(sdepth == CV_16U && ddepth == CV_16U)
func = reduceMaxC16u;
else if(sdepth == CV_16S && ddepth == CV_16S)
func = reduceMaxC16s;
else if(sdepth == CV_32F && ddepth == CV_32F)
func = GET_OPTIMIZED(reduceMaxC32f);
else if(sdepth == CV_64F && ddepth == CV_64F)
func = reduceMaxC64f;
}
else if(op == CV_REDUCE_MIN)
{
if(sdepth == CV_8U && ddepth == CV_8U)
func = GET_OPTIMIZED(reduceMinC8u);
else if(sdepth == CV_16U && ddepth == CV_16U)
func = reduceMinC16u;
else if(sdepth == CV_16S && ddepth == CV_16S)
func = reduceMinC16s;
else if(sdepth == CV_32F && ddepth == CV_32F)
func = GET_OPTIMIZED(reduceMinC32f);
else if(sdepth == CV_64F && ddepth == CV_64F)
func = reduceMinC64f;
}
}
if( !func )
CV_Error( CV_StsUnsupportedFormat,
"Unsupported combination of input and output array formats" );
func( src, temp );
if( op0 == CV_REDUCE_AVG )
temp.convertTo(dst, dst.type(), 1./(dim == 0 ? src.rows : src.cols));
}