Keras:Unet网络实现多类语义分割方式

作者:Robin Long 2018 时间:2022-02-26 16:36:49 

1 介绍

U-Net最初是用来对医学图像的语义分割,后来也有人将其应用于其他领域。但大多还是用来进行二分类,即将原始图像分成两个灰度级或者色度,依次找到图像中感兴趣的目标部分。

本文主要利用U-Net网络结构实现了多类的语义分割,并展示了部分测试效果,希望对你有用!

2 源代码

(1)训练模型


from __future__ import print_function
import os
import datetime
import numpy as np
from keras.models import Model
from keras.layers import Input, concatenate, Conv2D, MaxPooling2D, Conv2DTranspose, AveragePooling2D, Dropout, \
BatchNormalization
from keras.optimizers import Adam
from keras.layers.convolutional import UpSampling2D, Conv2D
from keras.callbacks import ModelCheckpoint
from keras import backend as K
from keras.layers.advanced_activations import LeakyReLU, ReLU
import cv2

PIXEL = 512 #set your image size
BATCH_SIZE = 5
lr = 0.001
EPOCH = 100
X_CHANNEL = 3 # training images channel
Y_CHANNEL = 1 # label iamges channel
X_NUM = 422 # your traning data number

pathX = 'I:\\Pascal VOC Dataset\\train1\\images\\' #change your file path
pathY = 'I:\\Pascal VOC Dataset\\train1\\SegmentationObject\\' #change your file path

#data processing
def generator(pathX, pathY,BATCH_SIZE):
while 1:
 X_train_files = os.listdir(pathX)
 Y_train_files = os.listdir(pathY)
 a = (np.arange(1, X_NUM))
 X = []
 Y = []
 for i in range(BATCH_SIZE):
  index = np.random.choice(a)
  # print(index)
  img = cv2.imread(pathX + X_train_files[index], 1)
  img = np.array(img).reshape(PIXEL, PIXEL, X_CHANNEL)
  X.append(img)
  img1 = cv2.imread(pathY + Y_train_files[index], 1)
  img1 = np.array(img1).reshape(PIXEL, PIXEL, Y_CHANNEL)
  Y.append(img1)

X = np.array(X)
 Y = np.array(Y)
 yield X, Y

#creat unet network
inputs = Input((PIXEL, PIXEL, 3))
conv1 = Conv2D(8, 3, activation='relu', padding='same', kernel_initializer='he_normal')(inputs)
pool1 = AveragePooling2D(pool_size=(2, 2))(conv1) # 16

conv2 = BatchNormalization(momentum=0.99)(pool1)
conv2 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv2)
conv2 = BatchNormalization(momentum=0.99)(conv2)
conv2 = Conv2D(64, 1, activation='relu', padding='same', kernel_initializer='he_normal')(conv2)
conv2 = Dropout(0.02)(conv2)
pool2 = AveragePooling2D(pool_size=(2, 2))(conv2) # 8

conv3 = BatchNormalization(momentum=0.99)(pool2)
conv3 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv3)
conv3 = BatchNormalization(momentum=0.99)(conv3)
conv3 = Conv2D(128, 1, activation='relu', padding='same', kernel_initializer='he_normal')(conv3)
conv3 = Dropout(0.02)(conv3)
pool3 = AveragePooling2D(pool_size=(2, 2))(conv3) # 4

conv4 = BatchNormalization(momentum=0.99)(pool3)
conv4 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv4)
conv4 = BatchNormalization(momentum=0.99)(conv4)
conv4 = Conv2D(256, 1, activation='relu', padding='same', kernel_initializer='he_normal')(conv4)
conv4 = Dropout(0.02)(conv4)
pool4 = AveragePooling2D(pool_size=(2, 2))(conv4)

conv5 = BatchNormalization(momentum=0.99)(pool4)
conv5 = Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv5)
conv5 = BatchNormalization(momentum=0.99)(conv5)
conv5 = Conv2D(512, 1, activation='relu', padding='same', kernel_initializer='he_normal')(conv5)
conv5 = Dropout(0.02)(conv5)
pool4 = AveragePooling2D(pool_size=(2, 2))(conv4)
# conv5 = Conv2D(35, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv4)
# drop4 = Dropout(0.02)(conv5)
pool4 = AveragePooling2D(pool_size=(2, 2))(pool3) # 2
pool5 = AveragePooling2D(pool_size=(2, 2))(pool4) # 1

conv6 = BatchNormalization(momentum=0.99)(pool5)
conv6 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv6)

conv7 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv6)
up7 = (UpSampling2D(size=(2, 2))(conv7)) # 2
conv7 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(up7)
merge7 = concatenate([pool4, conv7], axis=3)

conv8 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge7)
up8 = (UpSampling2D(size=(2, 2))(conv8)) # 4
conv8 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(up8)
merge8 = concatenate([pool3, conv8], axis=3)

conv9 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge8)
up9 = (UpSampling2D(size=(2, 2))(conv9)) # 8
conv9 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(up9)
merge9 = concatenate([pool2, conv9], axis=3)

conv10 = Conv2D(32, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge9)
up10 = (UpSampling2D(size=(2, 2))(conv10)) # 16
conv10 = Conv2D(32, 3, activation='relu', padding='same', kernel_initializer='he_normal')(up10)

conv11 = Conv2D(16, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv10)
up11 = (UpSampling2D(size=(2, 2))(conv11)) # 32
conv11 = Conv2D(8, 3, activation='relu', padding='same', kernel_initializer='he_normal')(up11)

# conv12 = Conv2D(3, 1, activation='relu', padding='same', kernel_initializer='he_normal')(conv11)
conv12 = Conv2D(3, 1, activation='relu', padding='same', kernel_initializer='he_normal')(conv11)

model = Model(input=inputs, output=conv12)
print(model.summary())
model.compile(optimizer=Adam(lr=1e-3), loss='mse', metrics=['accuracy'])

history = model.fit_generator(generator(pathX, pathY,BATCH_SIZE),
       steps_per_epoch=600, nb_epoch=EPOCH)
end_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

#save your training model
model.save(r'V1_828.h5')

#save your loss data
mse = np.array((history.history['loss']))
np.save(r'V1_828.npy', mse)

(2)测试模型


from keras.models import load_model
import numpy as np
import matplotlib.pyplot as plt
import os
import cv2

model = load_model('V1_828.h5')
test_images_path = 'I:\\Pascal VOC Dataset\\test\\test_images\\'
test_gt_path = 'I:\\Pascal VOC Dataset\\test\\SegmentationObject\\'
pre_path = 'I:\\Pascal VOC Dataset\\test\\pre\\'

X = []
for info in os.listdir(test_images_path):
A = cv2.imread(test_images_path + info)
X.append(A)
# i += 1
X = np.array(X)
print(X.shape)
Y = model.predict(X)

groudtruth = []
for info in os.listdir(test_gt_path):
A = cv2.imread(test_gt_path + info)
groudtruth.append(A)
groudtruth = np.array(groudtruth)

i = 0
for info in os.listdir(test_images_path):
cv2.imwrite(pre_path + info,Y[i])
i += 1

a = range(10)
n = np.random.choice(a)
cv2.imwrite('prediction.png',Y[n])
cv2.imwrite('groudtruth.png',groudtruth[n])
fig, axs = plt.subplots(1, 3)
# cnt = 1
# for j in range(1):
axs[0].imshow(np.abs(X[n]))
axs[0].axis('off')
axs[1].imshow(np.abs(Y[n]))
axs[1].axis('off')
axs[2].imshow(np.abs(groudtruth[n]))
axs[2].axis('off')
# cnt += 1
fig.savefig("imagestest.png")
plt.close()

3 效果展示

说明:从左到右依次是预测图像,真实图像,标注图像。可以看出,对于部分数据的分割效果还有待改进,主要原因还是数据集相对复杂,模型难于找到其中的规律。

Keras:Unet网络实现多类语义分割方式

来源:https://blog.csdn.net/u013419318/article/details/102721288

标签:Keras,Unet,多类,语义分割
0
投稿

猜你喜欢

  • 使用python实现微信小程序自动签到功能

    2021-05-30 10:04:11
  • Python使用 TCP协议实现智能聊天机器人功能

    2022-08-19 03:49:48
  • python 通过SSHTunnelForwarder隧道连接redis的方法

    2021-03-08 12:58:41
  • python3.5 tkinter实现页面跳转

    2022-08-03 22:23:46
  • python简单实现插入排序实例代码

    2021-11-27 14:33:04
  • django模型查询操作的实现

    2023-03-31 04:01:04
  • python文件读取和导包的绝对路径、相对路径详解

    2021-04-12 03:27:05
  • Python虚拟机字节码教程之控制流实现详解

    2023-01-09 09:56:53
  • Django发送html邮件的方法

    2021-04-06 13:22:52
  • Python数学建模学习模拟退火算法旅行商问题示例解析

    2023-07-28 08:33:24
  • 用python生成1000个txt文件的方法

    2023-03-24 07:51:11
  • Python可视化工具如何实现动态图表

    2023-05-22 19:21:27
  • pytorch中tensor的合并与截取方法

    2022-02-11 14:16:58
  • 基于display:table的CSS布局

    2008-10-30 10:38:00
  • python中异常的传播详解

    2021-12-20 11:31:05
  • Python内置函数property()如何使用

    2022-12-07 07:04:28
  • 详解LyScript 内存扫描与查壳实现

    2022-04-18 07:07:31
  • Python OpenCV 直方图的计算与显示的方法示例

    2022-10-15 07:36:24
  • python随机模块random使用方法详解

    2022-07-02 04:31:10
  • Django restful framework生成API文档过程详解

    2021-08-10 16:37:16
  • asp之家 网络编程 m.aspxhome.com