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

本文介绍使用U-Net网络实现多类语义分割的方法。通过详细代码示例,展示了如何构建U-Net模型并训练它来处理多类别的图像分割任务。实验结果显示该方法在某些场景下仍有待改进。

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网络实现多类语义分割方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值