问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

图像处理-高斯金字塔、拉普拉斯金字塔

创作时间:
作者:
@小白创作中心

图像处理-高斯金字塔、拉普拉斯金字塔

引用
CSDN
1.
https://blog.csdn.net/Javadayuge/article/details/136372237

本文主要介绍了图像处理中的高斯金字塔和拉普拉斯金字塔。文章内容较为详细,涵盖了高斯噪声、图像平滑(包括均值滤波、高斯滤波和中值滤波)、下采样、Sobel滤波、拉普拉斯滤波以及拉普拉斯金字塔的原理和实现。文章还提供了相应的Python代码示例,帮助读者更好地理解和应用这些概念。

一、高斯金字塔

高斯金字塔主要有两部分组成:高斯滤波下采样操作

1.1 高斯噪声

高斯噪声是指噪声密度函数服从高斯分布的一类噪声。由于高斯噪声在空间和频域中数学上的易处理性,这种噪声(也称为正态噪声)模型经常被用于实践中。高斯随机变量z的概率密度函数由下式给出:

$$
P(z) = \frac{1}{\sqrt{2π}\sigma}e^{ \frac{-(z-\mu)^2}{2\sigma ^2}}
$$

其中z表示灰度值,μ表示z的平均值或期望值,σ表示z的标准差。标准差的平方σ 2 称为z的方差。高斯函数的曲线如图所示:

1.2 图像平滑

图像平滑从信号处理的角度看就是去除其中的高频信息,保留低频信息。因此我们可以对图像实施低通滤波。低通滤波可以去除图像中的噪声,对图像进行平滑。根据滤波器的不同可分为均值滤波,高斯滤波,中值滤波, 双边滤波。

1.2.1 均值滤波

采用均值滤波模板对图像噪声进行滤除。令S x y 表示中心在(x, y)点,尺寸为m×n 的矩形子图像窗口的坐标组。 均值滤波器可表示为:

$$
f^2(x,y) = \frac{1}{mn}\sum_{(s,t)\subset S_{xy}} g(s,t)
$$

由一个归一化卷积框完成的。它只是用卷积框覆盖区域所有像素的平均值来代替中心元素。例如,3x3标准化的平均过滤器如下所示:

均值滤波的优点是算法简单,计算速度较快,缺点是在去噪的同时去除了很多细节部分,将图像变得模糊。

API:

cv.blur(src, ksize, anchor, borderType)

参数:

src:输入图像
ksize:卷积核的大小
anchor:默认值 (-1,-1) ,表示核中心
borderType:边界类型

代码如下(示例):

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# 1 图像读取
img = cv.imread('./image/dogsp.jpeg')

# 2 均值滤波
blur = cv.blur(img,(5,5))

# 3 图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img[:,:,::-1]),plt.title('原图')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur[:,:,::-1]),plt.title('均值滤波后结果')
plt.xticks([]), plt.yticks([])
plt.show()

1.2.2高斯滤波

高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到

二维高斯是构建高斯滤波器的基础,其概率分布函数如下所示:

$$
G(x,y) = \frac {1}{2π\sigma^2}e^{-\frac {x^2+y^2}{2\sigma^2}}
$$

G(x,y)的分布是一个突起的帽子的形状。这里的σ可以看作两个值,一个是x方向的标准差σ x ,另一个是y方向的标准差σ y

当σ x 和σ y 取值越大,关注区域越分散,也就是往两边,整个形状趋近于扁平;当σ x 和σ y 越小,整个形状越突起,关注区域越集中。

正态分布是一种钟形曲线,越接近中心,取值越大,越远离中心,取值越小。计算平滑结果时,只需要将"中心点"作为原点,其他点按照其在正态曲线上的位置,分配权重,就可以得到一个加权平均值。

高斯平滑在从图像中去除高斯噪声方面非常有效。

高斯平滑的流程:

  • 首先确定权重矩阵

假定中心点的坐标是(0,0),那么距离它最近的8个点的坐标如下:

更远的点以此类推。

为了计算权重矩阵,需要设定σ的值。假定σ=1.5,则模糊半径为1的权重矩阵如下(将上图中的坐标点带入到高斯分布中得到的权重矩阵):

这9个点的权重总和等于0.4787147,如果只计算这9个点的加权平均,还必须让它们的权重之和等于1,因此上面9个值还要分别除以0.4787147,得到最终的权重矩阵。

  • 计算高斯模糊

有了权重矩阵,就可以计算高斯模糊的值了。

假设现有9个像素点,灰度值(0-255)如下:

每个点乘以对应的权重值:

得到

将这9个值加起来,就是中心点的高斯模糊的值。

对所有点重复这个过程,就得到了高斯模糊后的图像。如果原图是彩色图片,可以对RGB三个通道分别做高斯平滑。

API:

cv2.GaussianBlur(src,ksize,sigmaX,sigmay,borderType)

参数:

  • src: 输入图像
  • ksize:高斯卷积核的大小,注意 : 卷积核的宽度和高度都应为奇数,且可以不同
  • sigmaX: 水平方向的标准差
  • sigmaY: 垂直方向的标准差,默认值为0,表示与sigmaX相同
  • borderType:填充边界类型

代码如下(示例)

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# 1 图像读取
img = cv.imread('./image/dogGasuss.jpeg')

# 2 高斯滤波
blur = cv.GaussianBlur(img,(3,3),1)

# 3 图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img[:,:,::-1]),plt.title('原图')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur[:,:,::-1]),plt.title('高斯滤波后结果')
plt.xticks([]), plt.yticks([])
plt.show()

1.2.3中值滤波

中值滤波是一种典型的非线性滤波技术,基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值。

中值滤波对椒盐噪声(salt-and-pepper noise)来说尤其有用,因为它不依赖于邻域内那些与典型值差别很大的值。

API:

cv.medianBlur(src, ksize )

参数:

  • src:输入图像
  • ksize:卷积核的大小
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# 1 图像读取
img = cv.imread('./image/dogsp.jpeg')

# 2 中值滤波
blur = cv.medianBlur(img,5)

# 3 图像展示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img[:,:,::-1]),plt.title('原图')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur[:,:,::-1]),plt.title('中值滤波后结果')
plt.xticks([]), plt.yticks([])
plt.show()

1.3 小总结

1.图像噪声

  • 椒盐噪声:图像中随机出现的白点或者黑点
  • 高斯噪声:噪声的概率密度分布是正态分布

2.图像平滑

  • 均值滤波:算法简单,计算速度快,在去噪的同时去除了很多细节部分,将图像变得模糊
    cv.blur()
  • 高斯滤波: 去除高斯噪声
    cv.GaussianBlur()
  • 中值滤波: 去除椒盐噪声
    cv.medianBlur()

2.下采样

高斯金字塔主要有两部分组成:高斯滤波下采样操作,高斯滤波上面已经介绍,降采样其实就是提取特征的过程,简单的,如下图我们都是将每四个像素选取左上角的一个,构成下面的新的像素图。

如下图,如果我们只进行降采样而不进行高斯模糊,会导致一些特征的丢失,使图像看起来很粗糙,而利用了高斯模糊的图像就看起来柔和、连贯了很多。高斯金字塔本质上为信号的多尺度表达方式

二、拉普拉斯金字塔

1.1 Sobel滤波

Sobel是最常见的一种检验垂直或者水平边缘的滤波器。梯度就是不同方向的一阶导数拼到一起。它是一个二维向量,向量的元素是横竖两个方向的函数一阶导数:

$$
grad(I) = [\frac {\partial I}{\partial x},\frac {\partial I}{\partial y}]^T
$$

1.2拉普拉斯滤波

如果不是一阶导数,我们取二阶导数呢?

二阶导数其实就是拉普拉斯算子:

$$
\Delta f= \frac {\partial^2 f}{\partial x^2}+\frac {\partial^2 f}{\partial y^2}
$$

作用:

  • 团块检测:周边高于(低于)中心点
  • 边缘检测:像素值快速变化的区域

拉普拉斯滤波器的基本条件,相加必须为零,并且拉普拉斯滤波器能够使原始图像变得锐化,细节凸显明显。

1.3拉普拉斯金字塔

  • 高频细节信息在卷积和下采样中丢失
  • 保留所有层所丢失的高频信息,用于图像恢复

$$
L_i = G_i-UP(G_{i+1}\bigotimes g_{n*n})
$$

$G_{i+1}$表示进行高斯模糊之后的小图。$UP(G_{i+1})$表示将这个小图上采样放大。$g_{n*n}$代表高斯模糊。所以$L_i$就是将高斯模糊以后的小图再次上采样放大与原图的差,就是拉普拉斯金字塔。过程如下:

$*$代表高斯模糊

$\downarrow$代表下采样

$\uparrow$代表下采样

上采样后再进行高斯模糊化可保留高频细节,叠加拉普拉斯金字塔可精确恢复原图。

代码如下:

import cv2 # 我只用它来做图像读写和绘图,没调用它的其它函数哦
import numpy as np # 进行数值计算

# padding 函数
def padding(img, K_size=3):
    # img 为需要处理图像
    # K_size 为滤波器也就是卷积核的尺寸,这里我默认设为3*3,基本上都是奇数
    # 获取图片尺寸
    H, W, C = img.shape
    pad = K_size // 2 # 需要在图像边缘填充的0行列数,
    # 之所以我要这样设置,是为了处理图像边缘时,滤波器中心与边缘对齐
    # 先填充行
    rows = np.zeros((pad, W, C), dtype=np.uint8)
    # 再填充列
    cols = np.zeros((H+2*pad, pad, C), dtype=np.uint8)
    # 进行拼接
    img = np.vstack((rows, img, rows)) # 上下拼接
    img = np.hstack((cols, img, cols)) # 左右拼接
    return img

# Prewitt 滤波函数
def laplacian(img, K_size=3):
    # 获取图像尺寸
    H, W, C = img.shape
    # 进行padding
    pad = K_size // 2
    out = padding(img, K_size=3)
    # 滤波器系数
    K = np.array([[0., 1., 0.],[1., -4., 1.], [0., 1., 0.]])
    
    # 进行滤波
    tem = out.copy()
    for h in range(H):
        for w in range(W):
            for c in range(C):
                out[pad+h, pad+w, c] = np.sum(K * tem[h:h+K_size, w:w+K_size, c], dtype=np.float)
    out = np.clip(out, 0, 255)
    out = out[pad:pad+H, pad:pad+W].astype(np.uint8)
    return out

# 这里需要把图像先灰度化
# 直接用之前的灰度化代码
# 灰度化函数
def BGR2GRAY(img):
    # 获取图片尺寸
    H, W, C = img.shape
    # 灰度化
    out = np.ones((H,W,3))
    for i in range(H):
        for j in range(W):
            out[i,j,:] = 0.299*img[i,j,0] + 0.578*img[i,j,1] + 0.114*img[i,j,2]
    out = out.astype(np.uint8)
    return out

# 读取图片
path = 'C:/Users/86187/Desktop/image/'
file_in = path + 'cake.jpg' 
file_out = path + 'laplacian_filter.jpg' 
img = cv2.imread(file_in)

# 调用函数进行灰度化
img = BGR2GRAY(img)

# 调用函数进行sobel滤波
out = laplacian(img)

# 保存图片
cv2.imwrite(file_out, out)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()
)

结果如下:

代码来源:https://blog.csdn.net/qq_42662568/article/details/105494853?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-105494853-blog-91167438.235%5Ev43%5Epc_blog_bottom_relevance_base4&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-105494853-blog-91167438.235%5Ev43%5Epc_blog_bottom_relevance_base4&utm_relevant_index=2

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号