511e4c8a08d101cb00d5315b11ddd4d4
Learning OpenCV with iOS: 图像模糊--线性滤波

一、前言

上一篇我们讲解了OpenCV的图像亮度和对比度调整。本篇主要向大家介绍下图像模糊。按惯例,先来一张效果图。

铠玩模糊

铠玩模糊

二、模糊

所谓模糊,可以先简单理解为每一个像素都取周边像素的平均值。

模糊

模糊

上图中,2是中间点像素值,周边像素都是1。

模糊

模糊

中间点取周围点的平均值,就会变成1。在数值上叫平滑。在图形上,就产生了模糊效果,也就是中间点失去了细节。

模糊

模糊

三、图像模糊

图像模糊是opencv常见的操作,使用模糊操作的原因是为了给图像预处理时降低噪声影响。
Smooth和Blur是opencv图像模糊的API,其背后的原理其实是数学的卷积操作

卷积

卷积

其中权重核h(k,l) 为“滤波系数”。上面的式子可以简记为:

卷积

卷积

通常这些卷积算子计算都是线性操作,所以又叫线性滤波

四、线性滤波

1、均值滤波

均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素,再用模板中的全体像素的平均值来代替原来像素值。

还记得第二篇里所讲掩膜操作吧,均值滤波的过程跟掩膜操作极其相似。

均值滤波

均值滤波

滤波操作:在9x9上面有3x3的窗口,从左到右,从上到下移动,白色的每个像素点值之和取平均值赋给中心红色像素作为它处理之后的像素值。其中,模板就是3x3的窗口,红色格子为目标像素,白色格子为周围的临近像素

此类操作被称为卷积计算,而模板和kernel就是卷积计算中的卷积算子

opencv提供了均值滤波(模糊)的API

/** 
@param src 输入图像
@param dst 输出图像
@param ksize 模糊kernel大小
@param anchor 锚点; 默认值为Point(-1,-1) ,表示在锚点在kernel的中心
@param borderType 查看#BorderTypes
 */
blur( InputArray src, OutputArray dst,
                        Size ksize, Point anchor = Point(-1,-1),
                        int borderType = BORDER_DEFAULT );

铠玩模糊

铠玩模糊

铠玩模糊

+ (UIImage *)blur:(UIImage *)image sizeX:(int)sizeX sizeY:(int)sizeY {
    Mat src;
    UIImageToMat(image, src);

    Mat dst;
    blur(src, dst, cv::Size(sizeX, sizeY));

    UIImage* result = MatToUIImage(dst);

    return result;
}

class BlurViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var resultImageView: UIImageView!

    private var sizeX: Int32 = 3
    private var sizeY: Int32 = 3

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func onSliderValueChanged(_ sender: UISlider) {
        sizeX = Int32(sender.value)
        transform()
    }

    @IBAction func onSlider2ValueChanged(_ sender: UISlider) {
        sizeY = Int32(sender.value)
        transform()
    }

    private func transform() {
        let image = OpenCV.blur(imageView.image, sizeX: sizeX, sizeY: sizeY)
        resultImageView.image = image
    }
}

一些思考

top Created with Sketch.