opencv---cvSmooth部分源码

来源:互联网 发布:java web 书 编辑:程序博客网 时间:2024/06/05 14:30



//////////////////////////////////////////////////////////////////////////////////////////CV_IMPL voidcvSmooth( const void* srcarr, void* dstarr, int smooth_type,          int param1, int param2, double param3, double param4 ){    cv::Mat src = cv::cvarrToMat(srcarr), dst0 = cv::cvarrToMat(dstarr), dst = dst0;    CV_Assert( dst.size() == src.size() &&        (smooth_type == CV_BLUR_NO_SCALE || dst.type() == src.type()) );    if( param2 <= 0 )        param2 = param1;    if( smooth_type == CV_BLUR || smooth_type == CV_BLUR_NO_SCALE )        cv::boxFilter( src, dst, dst.depth(), cv::Size(param1, param2), cv::Point(-1,-1),            smooth_type == CV_BLUR, cv::BORDER_REPLICATE );    else if( smooth_type == CV_GAUSSIAN )        cv::GaussianBlur( src, dst, cv::Size(param1, param2), param3, param4, cv::BORDER_REPLICATE );    else if( smooth_type == CV_MEDIAN )        cv::medianBlur( src, dst, param1 );    else        cv::bilateralFilter( src, dst, param1, param3, param4, cv::BORDER_REPLICATE );    if( dst.data != dst0.data )        CV_Error( CV_StsUnmatchedFormats, "The destination image does not have the proper type" );}




void cv::medianBlur( InputArray _src0, OutputArray _dst, int ksize ){    Mat src0 = _src0.getMat();    _dst.create( src0.size(), src0.type() );    Mat dst = _dst.getMat();    if( ksize <= 1 )    {        src0.copyTo(dst);        return;    }    CV_Assert( ksize % 2 == 1 );#ifdef HAVE_TEGRA_OPTIMIZATION    if (tegra::medianBlur(src0, dst, ksize))        return;#endif    bool useSortNet = ksize == 3 || (ksize == 5#if !CV_SSE2            && src0.depth() > CV_8U#endif        );    Mat src;    if( useSortNet )    {        if( dst.data != src0.data )            src = src0;        else            src0.copyTo(src);        if( src.depth() == CV_8U )            medianBlur_SortNet<MinMax8u, MinMaxVec8u>( src, dst, ksize );        else if( src.depth() == CV_16U )            medianBlur_SortNet<MinMax16u, MinMaxVec16u>( src, dst, ksize );        else if( src.depth() == CV_16S )            medianBlur_SortNet<MinMax16s, MinMaxVec16s>( src, dst, ksize );        else if( src.depth() == CV_32F )            medianBlur_SortNet<MinMax32f, MinMaxVec32f>( src, dst, ksize );        else            CV_Error(CV_StsUnsupportedFormat, "");        return;    }    else    {        cv::copyMakeBorder( src0, src, 0, 0, ksize/2, ksize/2, BORDER_REPLICATE );        int cn = src0.channels();        CV_Assert( src.depth() == CV_8U && (cn == 1 || cn == 3 || cn == 4) );        double img_size_mp = (double)(src0.total())/(1 << 20);        if( ksize <= 3 + (img_size_mp < 1 ? 12 : img_size_mp < 4 ? 6 : 2)*(MEDIAN_HAVE_SIMD && checkHardwareSupport(CV_CPU_SSE2) ? 1 : 3))            medianBlur_8u_Om( src, dst, ksize );        else            medianBlur_8u_O1( src, dst, ksize );    }}


template<class Op, class VecOp>static voidmedianBlur_SortNet( const Mat& _src, Mat& _dst, int m ){    typedef typename Op::value_type T;    typedef typename Op::arg_type WT;    typedef typename VecOp::arg_type VT;    const T* src = (const T*)_src.data;    T* dst = (T*)_dst.data;    int sstep = (int)(_src.step/sizeof(T));    int dstep = (int)(_dst.step/sizeof(T));    Size size = _dst.size();    int i, j, k, cn = _src.channels();    Op op;    VecOp vop;    volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE2);    if( m == 3 )    {        if( size.width == 1 || size.height == 1 )        {            int len = size.width + size.height - 1;            int sdelta = size.height == 1 ? cn : sstep;            int sdelta0 = size.height == 1 ? 0 : sstep - cn;            int ddelta = size.height == 1 ? cn : dstep;            for( i = 0; i < len; i++, src += sdelta0, dst += ddelta )                for( j = 0; j < cn; j++, src++ )                {                    WT p0 = src[i > 0 ? -sdelta : 0];                    WT p1 = src[0];                    WT p2 = src[i < len - 1 ? sdelta : 0];                    op(p0, p1); op(p1, p2); op(p0, p1);                    dst[j] = (T)p1;                }            return;        }        size.width *= cn;        for( i = 0; i < size.height; i++, dst += dstep )        {            const T* row0 = src + std::max(i - 1, 0)*sstep;            const T* row1 = src + i*sstep;            const T* row2 = src + std::min(i + 1, size.height-1)*sstep;            int limit = useSIMD ? cn : size.width;            for(j = 0;; )            {                for( ; j < limit; j++ )                {                    int j0 = j >= cn ? j - cn : j;                    int j2 = j < size.width - cn ? j + cn : j;                    WT p0 = row0[j0], p1 = row0[j], p2 = row0[j2];                    WT p3 = row1[j0], p4 = row1[j], p5 = row1[j2];                    WT p6 = row2[j0], p7 = row2[j], p8 = row2[j2];                    op(p1, p2); op(p4, p5); op(p7, p8); op(p0, p1);                    op(p3, p4); op(p6, p7); op(p1, p2); op(p4, p5);                    op(p7, p8); op(p0, p3); op(p5, p8); op(p4, p7);                    op(p3, p6); op(p1, p4); op(p2, p5); op(p4, p7);                    op(p4, p2); op(p6, p4); op(p4, p2);                    dst[j] = (T)p4;                }                if( limit == size.width )                    break;                for( ; j <= size.width - VecOp::SIZE - cn; j += VecOp::SIZE )                {                    VT p0 = vop.load(row0+j-cn), p1 = vop.load(row0+j), p2 = vop.load(row0+j+cn);                    VT p3 = vop.load(row1+j-cn), p4 = vop.load(row1+j), p5 = vop.load(row1+j+cn);                    VT p6 = vop.load(row2+j-cn), p7 = vop.load(row2+j), p8 = vop.load(row2+j+cn);                    vop(p1, p2); vop(p4, p5); vop(p7, p8); vop(p0, p1);                    vop(p3, p4); vop(p6, p7); vop(p1, p2); vop(p4, p5);                    vop(p7, p8); vop(p0, p3); vop(p5, p8); vop(p4, p7);                    vop(p3, p6); vop(p1, p4); vop(p2, p5); vop(p4, p7);                    vop(p4, p2); vop(p6, p4); vop(p4, p2);                    vop.store(dst+j, p4);                }                limit = size.width;            }        }    }    else if( m == 5 )    {        if( size.width == 1 || size.height == 1 )        {            int len = size.width + size.height - 1;            int sdelta = size.height == 1 ? cn : sstep;            int sdelta0 = size.height == 1 ? 0 : sstep - cn;            int ddelta = size.height == 1 ? cn : dstep;            for( i = 0; i < len; i++, src += sdelta0, dst += ddelta )                for( j = 0; j < cn; j++, src++ )                {                    int i1 = i > 0 ? -sdelta : 0;                    int i0 = i > 1 ? -sdelta*2 : i1;                    int i3 = i < len-1 ? sdelta : 0;                    int i4 = i < len-2 ? sdelta*2 : i3;                    WT p0 = src[i0], p1 = src[i1], p2 = src[0], p3 = src[i3], p4 = src[i4];                    op(p0, p1); op(p3, p4); op(p2, p3); op(p3, p4); op(p0, p2);                    op(p2, p4); op(p1, p3); op(p1, p2);                    dst[j] = (T)p2;                }            return;        }        size.width *= cn;        for( i = 0; i < size.height; i++, dst += dstep )        {            const T* row[5];            row[0] = src + std::max(i - 2, 0)*sstep;            row[1] = src + std::max(i - 1, 0)*sstep;            row[2] = src + i*sstep;            row[3] = src + std::min(i + 1, size.height-1)*sstep;            row[4] = src + std::min(i + 2, size.height-1)*sstep;            int limit = useSIMD ? cn*2 : size.width;            for(j = 0;; )            {                for( ; j < limit; j++ )                {                    WT p[25];                    int j1 = j >= cn ? j - cn : j;                    int j0 = j >= cn*2 ? j - cn*2 : j1;                    int j3 = j < size.width - cn ? j + cn : j;                    int j4 = j < size.width - cn*2 ? j + cn*2 : j3;                    for( k = 0; k < 5; k++ )                    {                        const T* rowk = row[k];                        p[k*5] = rowk[j0]; p[k*5+1] = rowk[j1];                        p[k*5+2] = rowk[j]; p[k*5+3] = rowk[j3];                        p[k*5+4] = rowk[j4];                    }                    op(p[1], p[2]); op(p[0], p[1]); op(p[1], p[2]); op(p[4], p[5]); op(p[3], p[4]);                    op(p[4], p[5]); op(p[0], p[3]); op(p[2], p[5]); op(p[2], p[3]); op(p[1], p[4]);                    op(p[1], p[2]); op(p[3], p[4]); op(p[7], p[8]); op(p[6], p[7]); op(p[7], p[8]);                    op(p[10], p[11]); op(p[9], p[10]); op(p[10], p[11]); op(p[6], p[9]); op(p[8], p[11]);                    op(p[8], p[9]); op(p[7], p[10]); op(p[7], p[8]); op(p[9], p[10]); op(p[0], p[6]);                    op(p[4], p[10]); op(p[4], p[6]); op(p[2], p[8]); op(p[2], p[4]); op(p[6], p[8]);                    op(p[1], p[7]); op(p[5], p[11]); op(p[5], p[7]); op(p[3], p[9]); op(p[3], p[5]);                    op(p[7], p[9]); op(p[1], p[2]); op(p[3], p[4]); op(p[5], p[6]); op(p[7], p[8]);                    op(p[9], p[10]); op(p[13], p[14]); op(p[12], p[13]); op(p[13], p[14]); op(p[16], p[17]);                    op(p[15], p[16]); op(p[16], p[17]); op(p[12], p[15]); op(p[14], p[17]); op(p[14], p[15]);                    op(p[13], p[16]); op(p[13], p[14]); op(p[15], p[16]); op(p[19], p[20]); op(p[18], p[19]);                    op(p[19], p[20]); op(p[21], p[22]); op(p[23], p[24]); op(p[21], p[23]); op(p[22], p[24]);                    op(p[22], p[23]); op(p[18], p[21]); op(p[20], p[23]); op(p[20], p[21]); op(p[19], p[22]);                    op(p[22], p[24]); op(p[19], p[20]); op(p[21], p[22]); op(p[23], p[24]); op(p[12], p[18]);                    op(p[16], p[22]); op(p[16], p[18]); op(p[14], p[20]); op(p[20], p[24]); op(p[14], p[16]);                    op(p[18], p[20]); op(p[22], p[24]); op(p[13], p[19]); op(p[17], p[23]); op(p[17], p[19]);                    op(p[15], p[21]); op(p[15], p[17]); op(p[19], p[21]); op(p[13], p[14]); op(p[15], p[16]);                    op(p[17], p[18]); op(p[19], p[20]); op(p[21], p[22]); op(p[23], p[24]); op(p[0], p[12]);                    op(p[8], p[20]); op(p[8], p[12]); op(p[4], p[16]); op(p[16], p[24]); op(p[12], p[16]);                    op(p[2], p[14]); op(p[10], p[22]); op(p[10], p[14]); op(p[6], p[18]); op(p[6], p[10]);                    op(p[10], p[12]); op(p[1], p[13]); op(p[9], p[21]); op(p[9], p[13]); op(p[5], p[17]);                    op(p[13], p[17]); op(p[3], p[15]); op(p[11], p[23]); op(p[11], p[15]); op(p[7], p[19]);                    op(p[7], p[11]); op(p[11], p[13]); op(p[11], p[12]);                    dst[j] = (T)p[12];                }                if( limit == size.width )                    break;                for( ; j <= size.width - VecOp::SIZE - cn*2; j += VecOp::SIZE )                {                    VT p[25];                    for( k = 0; k < 5; k++ )                    {                        const T* rowk = row[k];                        p[k*5] = vop.load(rowk+j-cn*2); p[k*5+1] = vop.load(rowk+j-cn);                        p[k*5+2] = vop.load(rowk+j); p[k*5+3] = vop.load(rowk+j+cn);                        p[k*5+4] = vop.load(rowk+j+cn*2);                    }                    vop(p[1], p[2]); vop(p[0], p[1]); vop(p[1], p[2]); vop(p[4], p[5]); vop(p[3], p[4]);                    vop(p[4], p[5]); vop(p[0], p[3]); vop(p[2], p[5]); vop(p[2], p[3]); vop(p[1], p[4]);                    vop(p[1], p[2]); vop(p[3], p[4]); vop(p[7], p[8]); vop(p[6], p[7]); vop(p[7], p[8]);                    vop(p[10], p[11]); vop(p[9], p[10]); vop(p[10], p[11]); vop(p[6], p[9]); vop(p[8], p[11]);                    vop(p[8], p[9]); vop(p[7], p[10]); vop(p[7], p[8]); vop(p[9], p[10]); vop(p[0], p[6]);                    vop(p[4], p[10]); vop(p[4], p[6]); vop(p[2], p[8]); vop(p[2], p[4]); vop(p[6], p[8]);                    vop(p[1], p[7]); vop(p[5], p[11]); vop(p[5], p[7]); vop(p[3], p[9]); vop(p[3], p[5]);                    vop(p[7], p[9]); vop(p[1], p[2]); vop(p[3], p[4]); vop(p[5], p[6]); vop(p[7], p[8]);                    vop(p[9], p[10]); vop(p[13], p[14]); vop(p[12], p[13]); vop(p[13], p[14]); vop(p[16], p[17]);                    vop(p[15], p[16]); vop(p[16], p[17]); vop(p[12], p[15]); vop(p[14], p[17]); vop(p[14], p[15]);                    vop(p[13], p[16]); vop(p[13], p[14]); vop(p[15], p[16]); vop(p[19], p[20]); vop(p[18], p[19]);                    vop(p[19], p[20]); vop(p[21], p[22]); vop(p[23], p[24]); vop(p[21], p[23]); vop(p[22], p[24]);                    vop(p[22], p[23]); vop(p[18], p[21]); vop(p[20], p[23]); vop(p[20], p[21]); vop(p[19], p[22]);                    vop(p[22], p[24]); vop(p[19], p[20]); vop(p[21], p[22]); vop(p[23], p[24]); vop(p[12], p[18]);                    vop(p[16], p[22]); vop(p[16], p[18]); vop(p[14], p[20]); vop(p[20], p[24]); vop(p[14], p[16]);                    vop(p[18], p[20]); vop(p[22], p[24]); vop(p[13], p[19]); vop(p[17], p[23]); vop(p[17], p[19]);                    vop(p[15], p[21]); vop(p[15], p[17]); vop(p[19], p[21]); vop(p[13], p[14]); vop(p[15], p[16]);                    vop(p[17], p[18]); vop(p[19], p[20]); vop(p[21], p[22]); vop(p[23], p[24]); vop(p[0], p[12]);                    vop(p[8], p[20]); vop(p[8], p[12]); vop(p[4], p[16]); vop(p[16], p[24]); vop(p[12], p[16]);                    vop(p[2], p[14]); vop(p[10], p[22]); vop(p[10], p[14]); vop(p[6], p[18]); vop(p[6], p[10]);                    vop(p[10], p[12]); vop(p[1], p[13]); vop(p[9], p[21]); vop(p[9], p[13]); vop(p[5], p[17]);                    vop(p[13], p[17]); vop(p[3], p[15]); vop(p[11], p[23]); vop(p[11], p[15]); vop(p[7], p[19]);                    vop(p[7], p[11]); vop(p[11], p[13]); vop(p[11], p[12]);                    vop.store(dst+j, p[12]);                }                limit = size.width;            }        }    }}}





原创粉丝点击