iOS使用OpenCV之滤波处理(三)

1,669 阅读4分钟

前言

  • 这篇文章我们来介绍滤波处理,

理论

平滑/模糊(Smooth/Blur)是图像处理中最简单和常用的操作,可以给图像预处理时候降低噪声。
图像平滑处理往往使图像中的边界、轮廓变得模糊,原因是因为图像受到了平均或积分运算,从频率域来考虑,图像模糊的实质是因为其高频分量被衰减

image.png
f(i,j)表示一幅图像,第i行j列的像素,h(k,l)是卷积核/卷积算子,k l大小又叫窗口大小,在k l范围内f(i,j)与h(k,l)乘积,各值相加得到一新像素值,输出图像g(i,j)

WeChata7bb18facd4f5d48864f773fe7a9ff34.png 卷积过程:6x6上面是个3x3的窗口,从左向右,从上向下移动,黄色的每个像个像素点值之和取平均值赋给中心红色像素作为它卷积处理之后新的像素值。每次移动一个像素格。

滤波处理分为两大类:线性滤波和非线性滤波

  • 线性滤波:方框滤波、均值滤波、高斯滤波
  • 非线性滤波:中值滤波、双边滤波

均值模糊

均值滤波的缺点就是不能很好地保护细节,在图像去燥的同时也破坏了图像的而细节部分,从而使图像变得模糊,不能很好的去除噪点。

/* 模糊处理 */
- (UIImage*)kj_opencvBlurX:(int)x y:(int)y{
    cv::Mat src,dst;
    UIImageToMat(self,src,true);
    //均值滤波处理
    blur(src, dst, cv::Size(x,y));
    return kMatToUIImage(dst);
}

高斯模糊

高斯滤波,可以消除高斯噪声,广泛应用于图像处理的减噪过程。
高斯滤波处理,Size高斯内核大小必须为正奇数

/* 高斯模糊,xy需要正数且为奇数 */
- (UIImage*)kj_opencvGaussianBlurX:(int)x y:(int)y{
    cv::Mat src,dst;
    UIImageToMat(self,src,true);
    //高斯滤波处理,Size高斯内核大小必须为正奇数
    GaussianBlur(src, dst, cv::Size(x,y), 0);
    return kMatToUIImage(dst);
}

中值模糊

基本思想就是用像素点的领域灰度的中值来代替该像素点的灰度值,该方法在去除脉冲噪声、椒盐噪声的同时又能保留图像的细节(不会出现边缘模糊的情况)
中值滤波跟均值滤波的思想看起来很相似,只是一个取平均值,一个取中位数而已

/* 中值模糊,可以去掉白色小颗粒,ksize必须为正数且奇数 */
- (UIImage*)kj_opencvMedianBlurksize:(int)ksize{
    cv::Mat src,dst;
    UIImageToMat(self,src,true);
    //中值滤波主要处理椒盐小颗粒
    medianBlur(src, dst, ksize);
    return kMatToUIImage(dst);
}

高斯双边模糊

双边滤波的最大特点就是做边缘保存,可以做磨皮美白效果
双边滤波器可以很好的保存图像边缘细节而滤除掉低频分量的噪音,sigma<10则对滤波器影响很小,如果sigma>150则会对滤波器产生较大的影响,会使图片看起来像卡通

/* 高斯双边模糊,可以做磨皮美白效果 */
- (UIImage*)kj_opencvBilateralFilterBlurRadio:(int)radio sigma:(int)sigma{
    cv::Mat src,dst;
    UIImageToMat(self,src,true);
    src = kFourChannelsBecomeThree(src);
    //双边滤波器可以很好的保存图像边缘细节而滤除掉低频分量的噪音,
    //sigma<10,则对滤波器影响很小,如果sigma>150则会对滤波器产生较大的影响,会使图片看起来像卡通
    //图像必须是8位或浮点型单通道、三通道的图像
    bilateralFilter(src, dst, radio, sigma, 5);
    
    dst = kPromoteImageContrast(dst);
    return kMatToUIImage(dst);
}

综合对比,双边滤波是所有滤波中最清晰的

自定义线性模糊

filter2D自定义卷积核,然后达到模糊效果

/* 自定义线性模糊 */
- (UIImage*)kj_opencvCustomBlurksize:(int)ksize{
    cv::Mat src,dst;
    UIImageToMat(self,src,true);
    if (!(ksize%2)) ksize++;//保证为奇数
    Mat kernel = Mat::ones(cv::Size(ksize,ksize), CV_32F/(float)(ksize*ksize));
    filter2D(src, dst, -1, kernel);
    return kMatToUIImage(dst);
}

效果图

高斯双边模糊效果:

系列文章关联

1、如何在 iOS 工程中使用 OpenCV
2、iOS使用OpenCV之调整图片亮度和对比度(一)
3、iOS使用OpenCV之图像融合(二)
4、iOS使用OpenCV之滤波处理(三)

接下来我会慢慢补充Opencv的相关文章,暂时已将常见的图片处理和图片算法封装出来,有需要的朋友可以去pod 'OpencvQueen'

如何在 iOS 工程中使用 OpenCV介绍就到此完毕,后面有相关再补充,写文章不容易,还请点个**小星星**传送门