这篇论文在实现上有三个问题:
1.下采样和上采样上使用了没有边界补充的卷积,这导致了需要进行分割卷积层才能够在前层和后面的层进行拼接操作时需要裁剪前面的层。
2.当输入图像不能够被16整除时会出现左边是单数而上采样后是双数的图像大小。
3.由于每次卷积导致了大小的变化,输入的图片大小和输出的图片大小不一致。
所以实现时进行如下操作:
1.使用边界补充的卷积
2.对图像进行预处理,将图像裁剪为16整除的大小
import keras
from keras.layers.normalization import BatchNormalization
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import *
from keras.optimizers import Adam
from keras.utils import np_utils
from keras.datasets import mnist
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
import numpy as np
import os
import glob
from keras import backend as K
import os
#os.environ["CUDA_VISIBLE_DEVICES"] = "0"
import numpy as np
from keras.models import *
from keras.layers import Input, merge, Conv2D, MaxPooling2D, UpSampling2D, Dropout, Cropping2D
from keras.optimizers import *
from keras.callbacks import ModelCheckpoint, LearningRateScheduler
from keras import backend as keras
from data import *
npy_path="/media/chenli/F1/medical/SegCaps/data/train"
img_type="tif"
data_path="/media/chenli/F1/medical/SegCaps/data/train/img/"
label_path="/media/chenli/F1/medical/SegCaps/data/train/masks/"
out_rows=512
out_cols=512
def create_train_data():
i = 0
print('-' * 30)
print('Creating training images...')
print('-' * 30)
imgdatas = np.ndarray(
(133, 1,out_rows, out_cols), dtype=np.uint8)
imglabels = np.ndarray(
(133, 1,out_rows, out_cols), dtype=np.uint8)
for k in range(1,133):
label = load_img(label_path + "%d.png" % (k), grayscale=True)
label = img_to_array(label)
imglabels[i] = label[:,:,:]
img = load_img(data_path + "%d.png" % (k), grayscale=True)
img = img_to_array(img)
imgdatas[i] = img[:,:,:]
i +=1
# if('mask' in midname):
# label[:] = map(list,zip(*label[::-1]))
# imglabels[i] = label
# else:
# img[:] = map(list,zip(*img[::-1]))
# imgdatas[i] = img
# i +=1
#img = cv2.imread(self.data_path + "/" + midname,cv2.IMREAD_GRAYSCALE)
#label = cv2.imread(self.label_path + "/" + midname,cv2.IMREAD_GRAYSCALE)
#img = np.array([img])
#label = np.array([label])
print('loading done')
np.save(npy_path + '/imgs_train.npy', imgdatas)
np.save(npy_path + '/imgs_mask_train.npy', imglabels)
print('Saving to .npy files done.')
return imgdatas,imglabels
imgs_train,imgs_mask_train = create_train_data()
imgs_train = np.load(npy_path + "/imgs_train.npy")
imgs_mask_train = np.load(npy_path + "/imgs_mask_train.npy")
imgs_train = imgs_train.astype('float32')
# imgs_mask_train = imgs_mask_train.astype('float32')
imgs_train /= 255
#mean = imgs_train.mean(axis = 0)
#imgs_train -= mean
imgs_mask_train /= 255
#损失函数
smooth = 1.
def dice_coef(y_true, y_pred):
y_true_f = K.flatten(y_true)
y_pred_f = K.flatten(y_pred)
intersection = K.sum(y_true_f * y_pred_f)
return (2. * intersection + smooth) / (K.sum(y_true_f * y_true_f) + K.sum(y_pred_f * y_pred_f) + smooth)
def dice_coef_loss(y_true, y_pred):
return 1. - dice_coef(y_true, y_pred)
def models():
inputs=Input((1,512,512))
x1 = Conv2D(16, (3, 3), activation='relu', padding='same', strides=(1, 1))(inputs)
x2 = Conv2D(16, (3, 3), activation='relu', padding='same', strides=(1, 1))(x1)
pool1 = MaxPooling2D(pool_size=(2, 2),padding='same')(x2)
print('x2 =',x2.shape)
print('pool1=',pool1.shape)
x3 = Conv2D(32, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(pool1)
x4 = Conv2D(32, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(x3)
pool2 = MaxPooling2D(pool_size=(2, 2),padding='same')(x4)
print('x4 =',x4.shape)
print('pool2=',pool2.shape)
x5 = Conv2D(64, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(pool2)
x6 = Conv2D(64, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(x5)
pool3 = MaxPooling2D(pool_size=(2, 2),padding='same')(x6)
print('x6 =',x6.shape)
print('pool3=',pool3.shape)
x7 = Conv2D(128, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(pool3)
x8 = Conv2D(128, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(x7)
pool4 = MaxPooling2D(pool_size=(2, 2),padding='same')(x8)
print('x8 =',x8.shape)
print('pool4=',pool4.shape)
x9 = Conv2D(256, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(pool4)
x10 = Conv2D(128, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(x9)
up1 = UpSampling2D()(x10)
# up1 = Cropping2D(cropping=((1, 0), (1, 0)), data_format=None)(up1)
# print('x10=',x10.shape)
print('up1 =',up1.shape)
x11 = concatenate([x8, up1] , axis=1)
print('x11 =',x11.shape)
x12 = Conv2D(128, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(x11)
x13 = Conv2D(64, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(x12)
up2 = UpSampling2D()(x13)
# up2 = Cropping2D(cropping=((1, 0), (1, 0)), data_format=None)(up2)
# print('x2=',x2.shape)
print('up2 =',up2.shape)
x14 = concatenate([x6, up2] , axis=1)
x15 = Conv2D(64, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(x14)
x16 = Conv2D(64, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(x15)
up3 = UpSampling2D()(x16)
# print('x2=',x2.shape)
print('up3 =',up3.shape)
x17 = concatenate([x4, up3] , axis=1)
x18 = Conv2D(32, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(x17)
x19 = Conv2D(16, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(x18)
up4 = UpSampling2D()(x19)
# print('x2=',x2.shape)
print('up4 =',up4.shape)
x20 = concatenate([x2, up4] , axis=1)
x21 = Conv2D(16, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(x20)
x22 = Conv2D(16, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(x21)
x23 = Conv2D(2, (3, 3), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(x22)
x24 = Conv2D(1, (1, 1), activation='relu', padding='same', strides=(1, 1), kernel_initializer = 'RandomNormal')(x23)
# print('x23=',up4.shape)
print('x24=',x24.shape)
model = Model(input=inputs, output=x24)
model.summary()
model.compile(optimizer=Adam(lr=1e-4),
loss=dice_coef_loss, metrics=[dice_coef])
# merge([Convolution2D(256, 2, 2,activation='relu', border_mode='same')
return model
model=models()
model_checkpoint = ModelCheckpoint(
'unet.hdf5', monitor='loss', verbose=1, save_best_only=False)
model.fit(imgs_train, imgs_mask_train, batch_size=1, nb_epoch=100, verbose=1,
validation_split=0.05, shuffle=True,callbacks=[model_checkpoint])
test_path= '/media/chenli/F1/medical/SegCaps/data/test/img/'
def create_test_data():
print('-' * 30)
print('Creating test images...')
print('-' * 30)
imgs = glob.glob(test_path + "/*.png")
print(len(imgs))
imgdatas = np.ndarray(
(len(imgs),1,out_rows, out_cols), dtype=np.uint8)
for i in range(0,240):
img = load_img(test_path + "%d.png" % (i), grayscale=True)
img = img_to_array(img)
#img = cv2.imread(self.test_path + "/" + midname,cv2.IMREAD_GRAYSCALE)
#img = np.array([img])
imgdatas[i] = img[:,:,:]
i += 1
print('loading done')
np.save(npy_path + '/imgs_test.npy', imgdatas)
print('Saving to imgs_test.npy files done.')
return imgdatas
create_test_data()
imgs_test = np.load(npy_path + "/imgs_test.npy")
imgs_test = imgs_test.astype('float32')
imgs_test /= 255
imgs=imgs_test[0:240]
imgs_mask_test = model.predict(imgs, verbose=1)
np.save('imgs_mask_test.npy', imgs_mask_test)
for i in range(0,240):
img = imgs_mask_test[i]
img = array_to_img(img)
img.save("/media/chenli/F1/medical/SegCaps/data/test/masks/%d.png" % (i))
实验结果