非线性滤波

来源:互联网 发布:gta5手机网络中的网站 编辑:程序博客网 时间:2024/05/20 23:56

非线性滤波:中值滤波,双边滤波

线性滤波:两个信号之和的响应和它们各自响应之和相等(即每个像素的输出值是一些输入像素的加权和)。

非线性滤波:


中值滤波:用像素点领域灰度值的中值来代替该像素点的灰度值,该方法在去除脉冲噪声,椒盐噪声的同时又能保留图像的边缘细节。

优点:由于噪声很难选上,所以几乎不会影响到输出,克服线性滤波器所带来的图像细节模糊,对滤波脉冲干扰即图像扫描噪声最为有效。

缺点:中值滤波花费的时间是均值滤波的5倍以上,对细节(细,尖顶)的图形不合适。


双边滤波:结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。

优点:做边缘保存

缺点:保存过多的高频信息,对于彩色图像里的高频噪声,不能干净的滤掉。



相关核心API函数

中值滤波:

声明:

CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize );

定义:

void cv::medianBlur( InputArray _src0, OutputArray _dst, int ksize ){    CV_Assert( (ksize % 2 == 1) && (_src0.dims() <= 2 ));    if( ksize <= 1 )    {        _src0.copyTo(_dst);        return;    }    CV_OCL_RUN(_dst.isUMat(),               ocl_medianFilter(_src0,_dst, ksize))    Mat src0 = _src0.getMat();    _dst.create( src0.size(), src0.type() );    Mat dst = _dst.getMat();#if IPP_VERSION_X100 >= 801    CV_IPP_CHECK()    {#define IPP_FILTER_MEDIAN_BORDER(ippType, ippDataType, flavor) \        do \        { \            if (ippiFilterMedianBorderGetBufferSize(dstRoiSize, maskSize, \                ippDataType, CV_MAT_CN(type), &bufSize) >= 0) \            { \                Ipp8u * buffer = ippsMalloc_8u(bufSize); \                IppStatus status = ippiFilterMedianBorder_##flavor(src.ptr<ippType>(), (int)src.step, \                    dst.ptr<ippType>(), (int)dst.step, dstRoiSize, maskSize, \                    ippBorderRepl, (ippType)0, buffer); \                ippsFree(buffer); \                if (status >= 0) \                { \                    CV_IMPL_ADD(CV_IMPL_IPP); \                    return; \                } \            } \            setIppErrorStatus(); \        } \        while ((void)0, 0)        if( ksize <= 5 )        {            Ipp32s bufSize;            IppiSize dstRoiSize = ippiSize(dst.cols, dst.rows), maskSize = ippiSize(ksize, ksize);            Mat src;            if( dst.data != src0.data )                src = src0;            else                src0.copyTo(src);            int type = src0.type();            if (type == CV_8UC1)                IPP_FILTER_MEDIAN_BORDER(Ipp8u, ipp8u, 8u_C1R);            else if (type == CV_16UC1)                IPP_FILTER_MEDIAN_BORDER(Ipp16u, ipp16u, 16u_C1R);            else if (type == CV_16SC1)                IPP_FILTER_MEDIAN_BORDER(Ipp16s, ipp16s, 16s_C1R);            else if (type == CV_32FC1)                IPP_FILTER_MEDIAN_BORDER(Ipp32f, ipp32f, 32f_C1R);        }#undef IPP_FILTER_MEDIAN_BORDER    }#endif#ifdef HAVE_TEGRA_OPTIMIZATION    if (tegra::useTegra() && tegra::medianBlur(src0, dst, ksize))        return;#endif    bool useSortNet = ksize == 3 || (ksize == 5#if !(CV_SSE2 || CV_NEON)            && 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) || checkHardwareSupport(CV_CPU_NEON)) ? 1 : 3))            medianBlur_8u_Om( src, dst, ksize );        else            medianBlur_8u_O1( src, dst, ksize );    }}

双边滤波;

声明:

void cv::bilateralFilter( InputArray _src, OutputArray _dst, int d,
Line 3416:                ocl_bilateralFilter_8u(_src, _dst, d, sigmaColor, sigmaSpace, borderType))


定义:
void cv::bilateralFilter( InputArray _src, OutputArray _dst, int d,                      double sigmaColor, double sigmaSpace,                      int borderType ){    _dst.create( _src.size(), _src.type() );    CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),               ocl_bilateralFilter_8u(_src, _dst, d, sigmaColor, sigmaSpace, borderType))    Mat src = _src.getMat(), dst = _dst.getMat();    if( src.depth() == CV_8U )        bilateralFilter_8u( src, dst, d, sigmaColor, sigmaSpace, borderType );    else if( src.depth() == CV_32F )        bilateralFilter_32f( src, dst, d, sigmaColor, sigmaSpace, borderType );    else        CV_Error( CV_StsUnsupportedFormat,        "Bilateral filtering is only implemented for 8u and 32f images" );}


0 0
原创粉丝点击