非线性滤波

25 篇文章 2 订阅

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

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

非线性滤波:


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

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

缺点:中值滤波花费的时间是均值滤波的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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

HySmiley

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

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

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

打赏作者

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

抵扣说明:

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

余额充值