opencv reduce函数

二,reduce() 的使用陷阱。

       函数原型:void cv::reduce(InputArray _src, OutputArray _dst, int dim, int op, int dtype=-1)

       对dtype采用默认值方式使用函数reduce(),出现了点异常问题,然后追加try-catch,发现输入输出的数据类型不匹配,于是就结合着reduce() 原代码做进一步分析,先是尝试着将输出创建为各种指定的格式,不行!
原因在于对下面这条语句没有理解好:

    if( dtype < 0 )
            dtype = _dst.fixedType() ? _dst.type() : stype;

      上网、上Q,折腾许久,终于想到了要把
dtype指定一个初值! 由于输入的数据类型是8U,对于求和操作CV_REDUCE_SUM,那么输出是32S就可以,对应的
dtype=CV_32S 就行,此时输出的矩阵也就只需要定义一下就行,不必再进行其它操作。
例如:

Mat matIn=imread(''lena.jpg",0);

Mat matOut;

reduce(matIn, matOut, 1, CV_REDUCE_SUM, CV_32S);

 

以下为函数reduce()
源码,方便对照学习。

 

 

void cv::reduce(InputArray _src, OutputArray _dst, int dim, int op, int dtype)
{
    Mat src = _src.getMat();
    CV_Assert( src.dims <= 2 );
    int op0 = op;
    int stype = src.type(), sdepth = src.depth(), cn = src.channels();
    if( dtype < 0 )
        dtype = _dst.fixedType() ? _dst.type() : stype;
    int ddepth = CV_MAT_DEPTH(dtype);

    _dst.create(dim == 0 ? 1 : src.rows, dim == 0 ? src.cols : 1,
                CV_MAKETYPE(dtype >= 0 ? dtype : stype, cn));
    Mat dst = _dst.getMat(), temp = dst;
    
    CV_Assert( op == CV_REDUCE_SUM || op == CV_REDUCE_MAX ||
        op == CV_REDUCE_MIN || op == CV_REDUCE_AVG );
    CV_Assert( src.channels() == dst.channels() );

    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 = reduceR_<uchar,int,OpAdd<int> >;
            else if(sdepth == CV_8U && ddepth == CV_32F)
                func = reduceR_<uchar,float,OpAdd<int> >;
            else if(sdepth == CV_8U && ddepth == CV_64F)
                func = reduceR_<uchar,double,OpAdd<int> >;
            else if(sdepth == CV_16U && ddepth == CV_32F)
                func = reduceR_<ushort,float,OpAdd<float> >;
            else if(sdepth == CV_16U && ddepth == CV_64F)
                func = reduceR_<ushort,double,OpAdd<double> >;
            else if(sdepth == CV_16S && ddepth == CV_32F)
                func = reduceR_<short,float,OpAdd<float> >;
            else if(sdepth == CV_16S && ddepth == CV_64F)
                func = reduceR_<short,double,OpAdd<double> >;
            else if(sdepth == CV_32F && ddepth == CV_32F)
                func = reduceR_<float,float,OpAdd<float> >;
            else if(sdepth == CV_32F && ddepth == CV_64F)
                func = reduceR_<float,double,OpAdd<double> >;
            else if(sdepth == CV_64F && ddepth == CV_64F)
                func = reduceR_<double,double,OpAdd<double> >;
        }
        else if(op == CV_REDUCE_MAX)
        {
            if(sdepth == CV_8U && ddepth == CV_8U)
                func = reduceR_<uchar, uchar, OpMax<uchar> >;
            else if(sdepth == CV_16U && ddepth == CV_16U)
                func = reduceR_<ushort, ushort, OpMax<ushort> >;
            else if(sdepth == CV_16S && ddepth == CV_16S)
                func = reduceR_<short, short, OpMax<short> >;
            else if(sdepth == CV_32F && ddepth == CV_32F)
                func = reduceR_<float, float, OpMax<float> >;
            else if(sdepth == CV_64F && ddepth == CV_64F)
                func = reduceR_<double, double, OpMax<double> >;
        }
        else if(op == CV_REDUCE_MIN)
        {
            if(sdepth == CV_8U && ddepth == CV_8U)
                func = reduceR_<uchar, uchar, OpMin<uchar> >;
            else if(sdepth == CV_16U && ddepth == CV_16U)
                func = reduceR_<ushort, ushort, OpMin<ushort> >;
            else if(sdepth == CV_16S && ddepth == CV_16S)
                func = reduceR_<short, short, OpMin<short> >;
            else if(sdepth == CV_32F && ddepth == CV_32F)
                func = reduceR_<float, float, OpMin<float> >;
            else if(sdepth == CV_64F && ddepth == CV_64F)
                func = reduceR_<double, double, OpMin<double> >;
        }
    }
    else
    {
        if(op == CV_REDUCE_SUM)
        {
            if(sdepth == CV_8U && ddepth == CV_32S)
                func = reduceC_<uchar,int,OpAdd<int> >;
            else if(sdepth == CV_8U && ddepth == CV_32F)
                func = reduceC_<uchar,float,OpAdd<int> >;
            else if(sdepth == CV_8U && ddepth == CV_64F)
                func = reduceC_<uchar,double,OpAdd<int> >;
            else if(sdepth == CV_16U && ddepth == CV_32F)
                func = reduceC_<ushort,float,OpAdd<float> >;
            else if(sdepth == CV_16U && ddepth == CV_64F)
                func = reduceC_<ushort,double,OpAdd<double> >;
            else if(sdepth == CV_16S && ddepth == CV_32F)
                func = reduceC_<short,float,OpAdd<float> >;
            else if(sdepth == CV_16S && ddepth == CV_64F)
                func = reduceC_<short,double,OpAdd<double> >;
            else if(sdepth == CV_32F && ddepth == CV_32F)
                func = reduceC_<float,float,OpAdd<float> >;
            else if(sdepth == CV_32F && ddepth == CV_64F)
                func = reduceC_<float,double,OpAdd<double> >;
            else if(sdepth == CV_64F && ddepth == CV_64F)
                func = reduceC_<double,double,OpAdd<double> >;
        }
        else if(op == CV_REDUCE_MAX)
        {
            if(sdepth == CV_8U && ddepth == CV_8U)
                func = reduceC_<uchar, uchar, OpMax<uchar> >;
            else if(sdepth == CV_16U && ddepth == CV_16U)
                func = reduceC_<ushort, ushort, OpMax<ushort> >;
            else if(sdepth == CV_16S && ddepth == CV_16S)
                func = reduceC_<short, short, OpMax<short> >;
            else if(sdepth == CV_32F && ddepth == CV_32F)
                func = reduceC_<float, float, OpMax<float> >;
            else if(sdepth == CV_64F && ddepth == CV_64F)
                func = reduceC_<double, double, OpMax<double> >;
        }
        else if(op == CV_REDUCE_MIN)
        {
            if(sdepth == CV_8U && ddepth == CV_8U)
                func = reduceC_<uchar, uchar, OpMin<uchar> >;
            else if(sdepth == CV_16U && ddepth == CV_16U)
                func = reduceC_<ushort, ushort, OpMin<ushort> >;
            else if(sdepth == CV_16S && ddepth == CV_16S)
                func = reduceC_<short, short, OpMin<short> >;
            else if(sdepth == CV_32F && ddepth == CV_32F)
                func = reduceC_<float, float, OpMin<float> >;
            else if(sdepth == CV_64F && ddepth == CV_64F)
                func = reduceC_<double, double, OpMin<double> >;
        }
    }

    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));
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI算法网奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值