Advertisement

模糊 (Blurring)

阅读量:

作者:禅与计算机程序设计艺术

1.简介

在计算机视觉领域中,图像模糊(Blurring)是指在某种程度上使图像失真或者模糊的过程。由于摄像机、照相机等传感器的特性,光线或光束往往在图像传感器上会发生反射、散射,而由于各类物体的复杂三维形状、灰度分布、色彩饱和度等多种原因,造成图像中存在噪声,因此需要对图像进行模糊处理从而提高图像的质量。

在图片处理中,模糊处理(Blurring)主要应用于图像的降噪、去雾、锐化、平滑、模糊、边缘检测、纹理分析、轮廓提取、对象识别等领域。对模糊效果进行精确控制可以提升图像质量,优化图像处理结果。例如,对于图像进行缩放、旋转、翻转、锐化、锯齿化、浮雕化、低通滤波、高通滤波、泛洪填充等方式都属于图像模糊的一种。

2.模糊处理的基本概念与术语

2.1 图像模糊的定义

图像模糊,也叫做图像虚化(Image Degradation),是指通过某些手段将原始的图像信号从无噪音到有噪音、从清晰到模糊、从逼真到简单等形式的变化过程。图像模糊的基本方法是依靠图形学中的滤波技术,对图像信号进行加权平均或求平均值的过程。所得到的新图像称为模糊后的图像或噪声图。

对图像进行模糊处理之后,其重要性不言而喻,首先,图像模糊能够提高图像的质量,更好的显示图像中的信息。其次,图像模糊还能够增强图像的辨识能力、识别能力以及对比度,能够减少图像数据量和传输流量,并提升图像检索速度。

模糊处理属于图像处理的一项重要功能。在实际应用过程中,根据图像的类型和要求,可以选择不同的模糊技术,如均值模糊、方框模糊、基于卷积的模糊、基于傅里叶变换的频率域滤波、基于空间域滤波的空间域模糊、基于模型的图像模糊等。

2.2 模糊处理的分类与分级

2.2.1 基准测试法

基准测试法是模糊处理领域的一种常用技术。它建立了一个模糊处理的标准化体系,然后对不同模糊算法或参数设置下的模糊效果进行比较。这样就可以找出最适合目标图像模糊应用的算法,而且具有一定的客观性。然而,基准测试法的缺点也是很明显的,只能找出一些经验上、直观上的效果,而不能真正地测量算法的性能。

2.2.2 比较法

比较法则是模糊处理领域另一个常用的技术。它通过实验或模拟的方式对各种模糊算法的参数组合及其他条件的影响,评估不同模糊算法的表现效果。这种方法能够评估算法的多方面性,但却受限于试验环境、测试样本数量、计算资源等条件的限制,同时也可能会受到实验方法和设备的影响。

2.2.3 统计法

统计法是模糊处理领域第三种常用技术。它基于已有的模糊处理数据集,通过分析这些数据集中参数与模糊效果之间的关系,构建非线性回归模型,推导出数据的抽象模式。这种方法的优点是能够准确描述模糊效果随着模糊参数或条件变化的曲线。但是,统计法又受到参数数量、模糊算法和场景的限制,并且无法对模型过拟合和效率问题给出有效的解决方案。

2.2.4 启发式方法

启发式方法是模糊处理领域最后一种常用技术。它不需要建模,只需要对不同因素作出一定的权衡取舍,直接对输入图像施加合理的模糊效果。这种方法具有很高的普遍性和适应性,但是可能会产生“胡乱”的结果。

通过对上述三个分类方法的总结,可以得知,基准测试法、比较法、统计法和启发式方法都可以用于模糊处理,其中比较法和统计法又可进一步分为基于数值方法和基于数据驱动方法两类。

2.3 模糊算法

2.3.1 均值模糊 (Average Blur)

概念:在图像的每一个像素位置处,该位置对应的颜色值为周围一定范围内的颜色值的平均值。常见的实现方法是对图像中邻近的像素点的值求平均,该平均值再代替中心像素点的颜色值。

操作步骤: 1. 设置滤波半径(即对原图像进行模糊时,邻近像素点的数目);
2. 以中心像素为起点,向外移动邻近像素点,对每个像素点求平均值并替换原值;
3. 重复步骤2,直至所有像素点都完成模糊处理。

2.3.2 方框模糊 (Box Filter)

概念:在图像的每一个像素点处,该点对应的颜色值由邻域内的颜色值加权平均得到。其中权重由滤波函数确定。常见的实现方法是对图像中邻近的像素点的值求平均,该平均值再代替中心像素点的颜色值。

操作步骤: 1. 设置滤波半径(即对原图像进行模糊时,邻近像素点的数目);
2. 使用一个大小为n \times n的方框,邻域内的点都由该方框内的点决定,方框中颜色值的权值除以该点个数;
3. 将方框滤波后得到的图像赋值给原图像对应位置的点。

2.3.3 高斯模糊 (Gaussian Blur)

概念:高斯模糊是一种非线性模糊滤波器,它结合了平滑滤波和噪声抑制两个特点。它的工作原理是对原始图像的每个像素点赋予一个系数,用来调节邻近像素的权重。通常情况下,高斯滤波器有着越大的“标准差”,所应用的权重就越大。

操作步骤: 1. 设置高斯函数标准差,标准差越大,应用的权重就越大;
2. 对图像进行加权平均。

复制代码
     
$$G_{ij}=\frac{1}{2\pi\sigma^2}\exp{\left(-\frac{(x_i-x_j)^2+(y_i-y_j)^2}{2\sigma^2}\right)}$$
      
      $\sigma$ 为标准差,$(x_i, y_i)$为第 $i$ 个像素点坐标,$G_{ij}$ 为在 $(x_i, y_i)$ 和 $(x_j, y_j)$ 之间传递信息的可能性,$\sigma$ 越大,$G_{ij}$ 越小。
      
     
$$\begin{pmatrix}I_1 \  I_2 \ ... \  I_N\end{pmatrix}_{M\times N}=g\left(\begin{pmatrix}G & G^{'} &... & G^{(n-1)} \  G^{*} & G &... & G^{(n-2)} \ .\ .\ .\  \  G^{*(n-1)} & G^{(n-2)} &... & G\end{pmatrix}^{T}\begin{pmatrix}I_1 \  I_2 \ ... \  I_N\end{pmatrix}\right)$$
      
      这里 $g(\cdot)$ 是应用的非线性函数,如指数函数等。
    
    
      
      
      
      
      
      
      
    
    代码解读

2.3.4 中值模糊 (Median filter)

概念:中值模糊是一种滤波算法,它利用像素排序中的中间值作为最终的颜色值。它可以消除椒盐噪声、边界噪声、伪影和孤立点等。

操作步骤: 1. 对图像中每个像素的邻域进行排序;
2. 根据排序顺序,取出中间值作为新像素的值;
3. 将新像素的值赋值给原图像对应位置的点。

2.3.5 双边滤波 (Bilateral Filtering)

概念:双边滤波是一种非线性的空间滤波器。它在保持图像的边界、细节的同时过滤掉无关的噪声。与其他滤波器相比,双边滤波能够捕捉到边缘的方向和形状信息。

操作步骤: 1. 使用高斯滤波器对图像进行模糊处理,以达到平滑图像的目的;
2. 使用一个带权重的窗口对图像中的每个像素进行双线性插值,以达到保留边缘的作用;
3. 在双边滤波的过程中,除了考虑像素值之外,还考虑它们与其临近像素的距离和方向关系。

3.核心算法原理与操作步骤及数学公式解析

上面的模糊算法都是基于图像处理中的基本概念,图像模糊是一个重要的图像处理任务,其相关数学理论知识在此处不会展开,因为篇幅过长,这里只简单地对三种常见的模糊算法进行一个简单的概括。

3.1 均值模糊 (Average Blur)

3.1.1 操作步骤

设置滤波半径(k)。

创建一个大小为 (w+2k+1) × (h+2k+1) 的图像模板,并初始化为零矩阵。

遍历图像的每个像素点,并对邻域内的 k+1 个像素点求平均值。

把第 i 行 j 列的邻域内的平均值存入第 i+k+1 行第 j+k+1 列的模板矩阵的相应位置。

提取模板矩阵的第 k+1 到 w+k 行,第 k+1 到 h+k 列,生成模糊后的图像。

复制代码
    import cv2
    
    def average_blur(image, kernel_size=5):
    if len(image.shape)<3:
        image = cv2.cvtColor(image,cv2.COLOR_GRAY2RGB)
    
    height, width, channels = image.shape
    
    temp = np.zeros((height + kernel_size * 2,
                     width + kernel_size * 2,
                     channels))
    
    for channel in range(channels):
        for row in range(kernel_size*2, height + kernel_size*2):
            for col in range(kernel_size*2, width + kernel_size*2):
                pixel = []
                
                for r in range(row - kernel_size, row + kernel_size + 1):
                    for c in range(col - kernel_size, col + kernel_size + 1):
                        pixel += [image[r][c][channel]]
    
                avg = sum(pixel)/len(pixel)
                temp[row][col][channel] = int(avg)
                
    return temp[:height,:width,:]
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

3.1.2 数学公式

设原始图像为 f(x, y), x=0,...,W−1, y=0,...,H−1, 我们要生成模糊后的图像为 f^\prime(x', y'), x'=0,..., W'+K − 1, y'=0,..., H'+K − 1. 对第 (x', y') 个像素,可以表示如下:

f^\prime(x', y') = \frac{1}{K^2}\sum_{s=-K/2}^{K/2} \sum_{t=-K/2}^{K/2} f(s+x', t+y')

f(s+x', t+y') 表示的是滤波器的尺寸是 K×K 的矩形框, 因此 -\frac{K}{2}<= s . -\frac{K}{2}<= x', 因此有:

x'=\lfloor x+\frac{K}{2}\rfloor,\ y'=\lfloor y+\frac{K}{2}\rfloor, 有:

f^\prime(x', y') = \frac{1}{K^2} \sum_{\substack{-K/2 \leq s \leq K/2 \\ -K/2 \leq t \leq K/2}} f(s+x', t+y')

因此, 可以将原图像按原来的大小划分为多个子块, 每个子块都使用均值滤波器对其模糊一次, 得到模糊后的子块, 拼接起来就是得到模糊后的图像.

3.2 方框模糊 (Box Filter)

3.2.1 操作步骤

设置滤波半径(k)。

对原始图像取周围 k+1 个像素为邻域,并求平均值。

把第 i 行 j 列的像素值复制到第 i+k+1 行第 j+k+1 列的位置。

生成模糊后的图像。

复制代码
    import cv2
    
    def box_filter(image, kernel_size=5):
    if len(image.shape)<3:
        image = cv2.cvtColor(image,cv2.COLOR_GRAY2RGB)
        
    height, width, channels = image.shape
    
    result = np.zeros((height + kernel_size * 2,
                       width + kernel_size * 2,
                       channels))
    
    for channel in range(channels):
        for row in range(kernel_size*2, height + kernel_size*2):
            for col in range(kernel_size*2, width + kernel_size*2):
                temp = [image[(row - kernel_size):(row + kernel_size+1),
                              (col - kernel_size):(col + kernel_size+1)][:, :, channel].flatten()]
                mean = np.mean(temp)[0]
                result[row][col][channel] = int(mean)
    
    return result[:height,:width,:]
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

3.2.2 数学公式

设原始图像为 f(x, y), x=0,...,W−1, y=0,...,H−1, 我们要生成模糊后的图像为 f^\prime(x', y'), x'=0,..., W'+K − 1, y'=0,..., H'+K − 1. 对第 (x', y') 个像素,可以表示如下:

f^\prime(x', y') = \frac{1}{K^2} \sum_{s=-K/2}^{K/2} \sum_{t=-K/2}^{K/2} f(s+x', t+y')

3.3 高斯模糊 (Gaussian Blur)

3.3.1 操作步骤

设置高斯函数标准差 \sigma.

对原始图像进行加权平均。

生成模糊后的图像。

复制代码
    import cv2
    
    def gaussian_blur(image, sigma=3):
    if len(image.shape)<3:
        image = cv2.cvtColor(image,cv2.COLOR_GRAY2RGB)
    
    height, width, channels = image.shape
    
    temp = np.zeros((height + 2*int(sigma)+1,
                     width + 2*int(sigma)+1,
                     channels))
    
    for channel in range(channels):
        for row in range(int(sigma)*2+1):
            for col in range(int(sigma)*2+1):
                arg = -(np.square(row-sigma) + np.square(col-sigma))/(2*np.square(sigma))
                exp_arg = np.exp(arg)
                weight = exp_arg/(2*np.pi*np.square(sigma))
                temp[row][col][channel] = int(weight*255)
        
        for row in range(int(sigma), height + int(sigma)):
            for col in range(int(sigma), width + int(sigma)):
                pixel = [(image[(row-int(sigma)-1)]
                            [col-int(sigma)])[:, channel],
                         (image[(row-int(sigma)-1)]
                           [col])[:, channel],
                         (image[(row-int(sigma)-1)]
                           [col+int(sigma)])[:, channel],
                         (image[(row)]
                           [col-int(sigma)])[:, channel],
                         (image[(row)]
                           [col])[:, channel],
                         (image[(row)]
                           [col+int(sigma)])[:, channel],
                         (image[(row+int(sigma))]
                           [col-int(sigma)])[:, channel],
                         (image[(row+int(sigma))]
                           [col])[:, channel],
                         (image[(row+int(sigma))]
                           [col+int(sigma)])[:, channel]][::-1]
            
                total = sum([p[0]*p[1]/(2*sigma**2) for p in zip(pixel[:-1], pixel[1:])])
                temp[row+int(sigma)][col+int(sigma)][channel] = int(total)
    
    return temp[:height,:width,:]
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

3.3.2 数学公式

设原始图像为 f(x, y), x=0,...,W−1, y=0,...,H−1, 我们要生成模糊后的图像为 f^\prime(x', y'), x'=0,..., W'+K − 1, y'=0,..., H'+K − 1. 对第 (x', y') 个像素,可以表示如下:

f^\prime(x', y') = g\left(\sum_{s=-K/2}^{K/2} \sum_{t=-K/2}^{K/2} f(s+x', t+y')\right)

其中 \sum_{s=-K/2}^{K/2} \sum_{t=-K/2}^{K/2} f(s+x', t+y') 是滤波器的尺寸是 K×K 的矩形框, 因此 -\frac{K}{2}<= s . -\frac{K}{2}<= x', 因此有:

x'=\lfloor x+\frac{K}{2}\rfloor,\ y'=\lfloor y+\frac{K}{2}\rfloor. 有:

f^\prime(x', y') = g\left(\sum_{\substack{-K/2 \leq s \leq K/2 \\ -K/2 \leq t \leq K/2}} f(s+x', t+y')\right)

其中 g(x)=e^{-x^2/2\sigma^2} 是归一化常数, \sigma 是高斯函数的标准差.

4. 具体代码实例与解释说明

下面用 Python 中的 OpenCV 库来实现模糊处理。

复制代码
    import cv2
    from matplotlib import pyplot as plt
    
    
    blur1 = cv2.blur(img,(5,5))   # apply a 5x5 averaging filter
    blur2 = cv2.medianBlur(img,7) # apply a 7x7 median filter
    gauss_blur = cv2.GaussianBlur(img,(5,5),0)    # apply a 5x5 Gaussian filter with standard deviation of 0
    
    titles = ['Original Image','Averaging Filter', 'Median Filter', 'Gaussian Filter']
    images = [img, blur1, blur2, gauss_blur]
    
    for i in range(4):
      plt.subplot(2,2,i+1),plt.imshow(images[i]),plt.title(titles[i])
      plt.xticks([]),plt.yticks([])
    
    plt.show() 
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

输出的结果展示了对原图进行 5x5 平均模糊、7x7 中值模糊、5x5 高斯模糊后的结果。

全部评论 (0)

还没有任何评论哟~