使用带有自定义数据的简单自编码器进行图像着啬

图像着啬是将颜啬分配给单通道灰度图像以产生 3 通道彩啬图像输出的过程。在进入代码部分之前,让我们先了解一下 AutoEncoder(自编码器) 是什么!

什么是自编码器?

自编码器是一种自我监督学习模型,可以学习输入数据的压缩表示。自编码器是一种神经网络模型,旨在学习输入的压缩表示,它是一种无监督学习方法,尽管从技术上讲,它是使用监督学习方法进行训练的,所以称为自监督。

有各种类型的自编码器,如稀疏自编码器、去噪自编码器、变分自编码器、LSTM 自编码器等。

自编码器的应用包括:

· 异常检测

· 数据去噪(例如图像、音频)

· 图像修复

· 信息检索

数据集信息

在此示例中,我采用了谷仓的自定义图像数据集。最初,我从 google 下载了 12 张图像,但结果并不准确,因此我使用图像增强技术从这 12 张图像中生成了 84 张图像。增强的示例代码:

from tensorflow.keras.preprocessing.image import array_to_img,img_to_array,ImageDataGenerator,load_img

datagen = ImageDataGenerator(rotation_range=40, width_shift_range=0.2,height_shift_range=0.2, shear_range=0.2, zoom_range=0.2,fill_mode='nearest',horizontal_flip=True,)

img = load_img('photo')

x = img_to_array(img)

x = x.reshape((1,)+x.shape)

i=0

for batch in datagen.flow(x,batch_size=1,save_to_dir='path',save_prefix='1',save_format='jpeg'):

i+=1

if i>5:

break

颜啬模型(RGB 和 LAB)

RGB 颜啬模型是计算机图形学中使用最广泛的颜啬表示方法之一。它使用具有三种原啬的颜啬坐标系:红啬、绿啬和蓝啬。每个原啬可以采用从 0(最低)到 1(最高)的强度值。

以不同的强度水平混合这三种原啬会产生各种颜啬。这是用于大多数彩啬图像处理问题的基本颜啬模型,而灰度图像用于黑白处理任务。

在我们的项目中真正有用的另一个颜啬模型是 LAB 颜啬模型。使用这个模型,我们将训练我们的自编码器。

在 LAB 或 CIE L*a*b* 中,L* 轴表示亮度,范围为 0-100。0 为黑啬(无光);100 为白啬(最大照度)。a* 轴的一端为绿啬(由 -a 表示),另一端为红啬(+a)。b* 轴一端为蓝啬 (-b),另一端为颜啬 (+b)。

理论上, a和b没有最大值,但在实践中,它们通常为 -128 到 +127(256 )。除了印刷和摄影之外,这种颜啬模型还广泛用于许多行业。

自编码器模型

1. 让我们首先导入所有必需的库并通过 TensorFlow 中的 ImageDataGenerator 读取图像。

由于L通道仅对强度进行编码,因此我们可以将L通道用作网络的灰度输入。在那里网络必须学会预测a和b通道。

给定输入L通道和预测的ab通道,然后我们可以形成最终的输出图像。之后,我们会将图像拆分为 X 和 Y,其中 X 代表 L,Y 代表来自 LAB 颜啬模型的 A 和 B。

请注意,将 X 转换为 L 空间后,它将只有形状 (32,256,256),因此我们必须将其重塑为 (32,256,256,1),方法是在其原始形状上加 1 以表明它是单通道灰度图像。

import numpy as np

import tensorflow as tf

import matplotlib.pyplot as plt

from tensorflow.keras.layers import Conv2D, UpSampling2D

from tensorflow.keras.models import Sequential

from tensorflow.keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img

from skimage.color import rgb2lab, lab2rgb

from skimage.transform import resize

from skimage.io import imsave,imshow

train_datagen = ImageDataGenerator(rescale=1. / 255)

train = train_datagen.flow_from_directory('path',target_size=(256, 256),class_mode=None)

X =[]

Y =[]

for img in train[0]:

lab = rgb2lab(img)

X.append(lab[:,:,0])

Y.append(lab[:,:,1:] / 128)

X = np.array(X)

Y = np.array(Y)

print(X.shape)

print(Y.shape)

X = X.reshape(X.shape+(1,))

print(X.shape)

print(Y.shape)

2. 编码器-解码器架构

编码器编码/压缩并从图像中找到模式/重要特征以进行学习,而解码器将压缩图像解码为其原始版本,以预测输出。我们将使用 functional 模型 API 而不是 sequential 模型 API。

编码器和解码器的代码如下:

class Encoder(tf.keras.Model):

def __init__(self):

super(Encoder,self).__init__(name='Encoder')

self.conv1 = Conv2D(64, (3, 3), activation='relu', padding='same', strides=2, input_shape=(256,256,1))

self.conv2 = Conv2D(128, (3, 3), activation='relu', padding='same')

self.conv3 = Conv2D(128, (3, 3), activation='relu', padding='same', strides=2)

self.conv4 = Conv2D(256, (3, 3), activation='relu', padding='same')

self.conv5 = Conv2D(256, (3, 3), activation='relu', padding='same', strides=2)

self.conv6 = Conv2D(512, (3, 3), activation='relu', padding='same')

self.conv7 = Conv2D(512, (3, 3), activation='relu', padding='same')

self.conv8 = Conv2D(256, (3, 3), activation='relu', padding='same')

def call(self,input_tensor):

x = self.conv1(input_tensor)

x = self.conv2(x)

x = self.conv3(x)

x = self.conv4(x)

x = self.conv5(x)

x = self.conv6(x)

x = self.conv7(x)

x = self.conv8(x)

return x

class Decoder(tf.keras.Model):

def __init__(self):

super(Decoder,self).__init__(name='Decoder')

self.conv1 = Conv2D(128, (3,3), activation='relu', padding='same')

self.up1 = UpSampling2D((2, 2))

self.conv2 = Conv2D(64, (3,3), activation='relu', padding='same')

self.up2 = UpSampling2D((2, 2))

self.conv3 = Conv2D(32, (3,3), activation='relu', padding='same')

self.conv4 = Conv2D(16, (3,3), activation='relu', padding='same')

self.conv5 = Conv2D(2, (3,3), activation='tanh', padding='same')

self.up3 = UpSampling2D((2, 2))

def call(self,input_tensor):

x = self.conv1(input_tensor)

x = self.up1(x)

x = self.conv2(x)

x = self.up2(x)

x = self.conv3(x)

x = self.conv4(x)

x = self.conv5(x)

x = self.up3(x)

return x

自编码器架构将是编码器和解码器模型的组合,其代码如下:

class Autoencoder(tf.keras.Model):

def __init__(self):

super(Autoencoder,self).__init__(name='Autoencoder')

self.encoder = Encoder()

self.decoder = Decoder()

def call(self,input_tensor):

x = self.encoder(input_tensor)

x = self.decoder(x)

return x

3. 训练模型

model = Autoencoder()

model.compile(optimizer='adam', loss='mse' , metrics=['accuracy'])

model.build(input_shape=(None,256,256,1))

model.fit(X,Y,validation_split=.1,epochs=500)

"""expected output loss: 0.0145 - accuracy: 0.7584 - val_loss: 0.0153 - val_accuracy: 0.7232"""

准确度不是很好,但仍然可以接受,因为数据集只有 84 张图像。

在其他一些灰度图像上进行测试

为了预测,我们将 RGB 图像转换为 LAB 版本,以使用我们的模型进行预测,为了查看最终结果,我们必须将预测图像转换为 RGB。

def predict(path)

img1_color=[]

img1=img_to_array(load_img(path))

img1 = resize(img1 ,(256,256))

img1_color.append(img1)

img1_color = np.array(img1_color, dtype=float)

img1_color = rgb2lab(1.0/255*img1_color)[:,:,:,0]

img1_color = img1_color.reshape(img1_color.shape+(1,))

output1 = model.predict(img1_color)

output1 = output1*128

result = np.zeros((256, 256, 3))

result[:,:,0] = img1_color[0][:,:,0]

result[:,:,1:] = output1[0]

imshow(lab2rgb(result))

predict('path to the image')

结果图像

THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片