用于图像降噪的卷积自编码器

用于图像降噪的卷积自编码器

在神经网络中,有一些重要的方法来对图像数据进行建模。其中卷积神经网络(CNN 或者 ConvNet)和卷积自编码器。

  • 图像的基本知识
  • 图像降噪的总结
  • 卷积编码器的基本原理
  • Keras的内置函数
  • 如何实现卷积编码器

图像的基本知识

基本知识

图像是有像素组成,如下图所示。

在这里插入图片描述

  • 在黑白图像中,每个像素是用0到255直接的数字来表示。
  • 在RGB彩色图像中,每一个像素由红色,绿色和蓝色组成,这三个颜色各自的像素值从0到255。比如,一个像素由含三个值的RGB(102、255、102)构成,其色号为#66ff66

举例说明,一张宽800像素,高600像素的图像具有800 x 600 = 480,000像素,即0.48兆像素(“兆像素”等于100万像素)。分辨率为1024×768的图像是一个由1,024列和768行构成的网格,共有1,024 × 768 = 0.78兆像素。

MNIST

MNIST数据库是一个大型的手写数字数据库,通常用于训练各种图像处理系统。Keras的训练数据集具备60,000条记录,而测试数据集则包含了10,000条记录。每条记录共有28 x 28个像素。

先来看以下前10的记录

from tensorflow.keras.models import Model
from tensorflow.keras.datasets import mnist
import matplotlib.pyplot as plt
import numpy as np

(x_train, _), (x_test, _) = mnist.load_data()

n = 10
plt.figure(figsize=(20,4))
for i in range(n):
    ax =plt.subplot(2,n,i+1)
    plt.imshow(x_train[i].reshape(28,28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

plt.show()

在这里插入图片描述

注意: keras 源码中下载MNIST的方式是 path = get_file(path, origin=‘https://s3.amazonaws.com/img-datasets/mnist.npz’ ), 数据源是通过 url = https://s3.amazonaws.com/img-datasets/mnist.npz 进行下载的。访问该 url 地址被墙了,导致 MNIST 相关的案例都卡在数据下载的环节。

文件mnist.npz 用下面的方式来读取,其他的代码做相应的更改即可。

import numpy as np

f = np.load('mnist.npz')
x_train, y_train = f['x_train'], f['y_train']
x_test, y_test = f['x_test'], f['y_test']
f.close()

图像降噪的简要分析与总结

图像降噪,是最基础的图像处理逆问题(inverse problem)。大多数情况下,图像降噪都是不适应问题(ill-posed problem)。因为通过有噪音的观察,总是无法逆向求得唯一正确的干净图片。按噪声和信号之间的关系,图像噪声可分为加性噪声和乘性噪声。为了分析处理方便,往往将乘性噪声近似认为是加性噪声,而且总是假定信号和噪声是互相独立的。加性噪声可以用数学表达式为
y = x + e y=x+e y=x+e
y是你观察到的带噪音的图像,e是噪音, x是干净无噪音的图像。

图像的噪声模型

实际获得的图像含有的噪声,根据不同分类可将噪声进行不同的分类。从噪声的概率分布情况来看,可分为高斯噪声、瑞利噪声、伽马噪声、指数噪声和均匀噪声。

  • 高斯噪音
    由于高斯噪声在空间和频域中数学上的易处理性,这种噪声(也称为正态噪声)模型经常被用于实践中。事实上,这种易处理性非常方便,使高斯模型经常用于临界情况下。其概率密度函数如下所示:
    p ( z ) = 1 2 π σ 2 exp ⁡ ( − ( z − μ ) 2 2 σ 2 ) p(z)=\frac{1}{\sqrt{2 \pi \sigma^2}} \exp\left(\frac{-(z-\mu)^2}{2 \sigma^2}\right) p(z)=2πσ2 1exp(2σ2(zμ)2)

高斯函数具有五个重要的性质,这些性质使得它在早期图像处理中特别有用.这些性质表明,高斯平滑滤波器无论在空间域还是在频率域都是十分有效的低通滤波器,且在实际图像处理中得到了工程人员的有效使用.高斯函数具有五个十分重要的性质,它们是:

  1. 二维高斯函数具有旋转对称性,即滤波器在各个方向上的平滑程度是相同的.一般来说,一幅图像的边缘方向是事先不知道的,因此,在滤波前是无法确定一个方向上比另一方向上需要更多的平滑.旋转对称性意味着高斯平滑滤波器在后续边缘检测中不会偏向任一方向.
  2. 高斯函数是单值函数.这表明,高斯滤波器用像素邻域的加权均值来代替该点的像素值,而每一邻域像素点权值是随该点与中心点的距离单调增减的.这一性 质是很重要的,因为边缘是一种图像局部特征,如果平滑运算对离算子中心很远的像素点仍然有很大作用,则平滑运算会使图像失真.
  3. 高斯函数的付立叶变换频谱是单瓣的.正如下面所示,这一性质是高斯函数付立叶变换等于高斯函数本身这一事实的直接推论.图像常被不希望的高频信号所 污染(噪声和细纹理).而所希望的图像特征(如边缘),既含有低频分量,又含有高频分量.高斯函数付立叶变换的单瓣意味着平滑图像不会被不需要的高频信号 所污染,同时保留了大部分所需信号.
  4. 高斯滤波器宽度(决定着平滑程度)是由参数σ表征的,而且σ和平滑程度的关系是非常简单的.σ越大,高斯滤波器的频带就越宽,平滑程度就越好.通过 调节平滑程度参数σ,可在图像特征过分模糊(过平滑)与平滑图像中由于噪声和细纹理所引起的过多的不希望突变量(欠平滑)之间取得折衷.
  5. 由于高斯函数的可分离性,大高斯滤波器可以得以有效地实现.二维高斯函数卷积可以分两步来进行,首先将图像与一维高斯函数进行卷积,然后将卷积结果与方向垂直的相同一维高斯函数卷积.因此,二维高斯滤波的计算量随滤波模板宽度成线性增长而不是成平方增长.
  • 瑞利噪声的概率密度函数由下式给出:
    p ( z ) = { 2 b

  • 31
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的一维卷积降噪自编码器的代码示例: ```python import tensorflow as tf # 定义模型 class Conv1DAutoencoder(tf.keras.Model): def __init__(self, filters, kernel_size, pool_size): super(Conv1DAutoencoder, self).__init__() self.encoder = tf.keras.Sequential([ tf.keras.layers.Conv1D(filters, kernel_size, activation='relu', padding='same'), tf.keras.layers.MaxPooling1D(pool_size, padding='same') ]) self.decoder = tf.keras.Sequential([ tf.keras.layers.Conv1D(filters, kernel_size, activation='relu', padding='same'), tf.keras.layers.UpSampling1D(pool_size) ]) def call(self, x): encoded = self.encoder(x) decoded = self.decoder(encoded) return decoded # 定义损失函数 def loss(model, x): reconstructed = model(x) mse = tf.keras.losses.MeanSquaredError() return mse(x, reconstructed) # 定义优化器 def train(model, train_dataset, epochs): optimizer = tf.keras.optimizers.Adam() for epoch in range(epochs): for step, x in enumerate(train_dataset): with tf.GradientTape() as tape: cost = loss(model, x) grads = tape.gradient(cost, model.trainable_variables) optimizer.apply_gradients(zip(grads, model.trainable_variables)) if (step + 1) % 10 == 0: print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch + 1, epochs, step + 1, len(train_dataset), cost.numpy())) # 测试模型 def test(model, test_dataset): for x in test_dataset: reconstructed = model(x) print('Original:', x.numpy()) print('Reconstructed:', reconstructed.numpy()) break # 加载数据集 (x_train, _), (x_test, _) = tf.keras.datasets.mnist.load_data() x_train = x_train.astype('float32') / 255. x_test = x_test.astype('float32') / 255. x_train = tf.expand_dims(x_train, axis=-1) x_test = tf.expand_dims(x_test, axis=-1) # 构建和训练模型 model = Conv1DAutoencoder(filters=32, kernel_size=3, pool_size=2) train_dataset = tf.data.Dataset.from_tensor_slices(x_train).batch(32) train(model, train_dataset, epochs=10) # 测试模型 test_dataset = tf.data.Dataset.from_tensor_slices(x_test).batch(1) test(model, test_dataset) ``` 这个模型使用了一个卷积层和一个最大池化层来编码输入数据,然后使用一个卷积层和一个上采样层来解码编码后的数据。损失函数使用均方误差,优化器使用Adam。在训练过程中,模型会在每个epoch结束时打印出损失值。在测试过程中,模型会将测试集中的第一个样本重构并显示原始图像和重构图像。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值