简体   繁体   English

如何从 output 分类器创建分割掩码?

[英]How to create segmentation mask from output classifier?

I am a newer in ML and I am trying to apply image segmentation on my gray scale tif images.我是 ML 的新手,我正在尝试在我的灰度 tif 图像上应用图像分割。 The images has areas with the value NaN which represents the sea, and areas with value from 0 to 2 which represents land.这些图像具有代表海洋的值为 NaN 的区域,以及代表陆地的值为 0 到 2 的区域。 I create some true masks for training.我为训练创建了一些真正的面具。 The masks have area with NaN representing the sea, 0 representing the land, and 1 representing the clouds.蒙版的区域中,NaN 代表海洋,0 代表陆地,1 代表云。 I would like to create a segmentation mask which has 3 classes representing the sea, the land, and the clouds.我想创建一个分割蒙版,它有 3 个类,分别代表海洋、陆地和云。

I refer to TensorFlow tutorial and Google Colab tutorial and have the code below.我参考TensorFlow 教程Google Colab 教程,并有以下代码。 The output classifier do show somethings but the segmentation mask became 0 overall. output 分类器确实显示了一些东西,但分割掩码整体变为 0。 Please help and thank you.请帮忙,谢谢。

from glob import glob
from PIL import Image
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from tensorflow.python.keras import layers
from tensorflow.python.keras import losses
from tensorflow.python.keras import models

#load images
img = sorted(glob('/content/drive/My Drive/train_sub_5/*.tif'))
mask = sorted(glob('/content/drive/My Drive/train_mask_sub_5/*.tif'))

#split into train and test dataset
img, img_val, mask, mask_val = train_test_split(img, mask, test_size=0.2, random_state=42)

#read images as array and make their shape (512, 512, 1)
train_image = []
for m in img[:]:
    image= Image.open(m)
    img_arr= np.nan_to_num(np.array(image), nan=0)
    stacked_img= np.stack((img_arr,)*1, axis=-1)
    train_image.append(stacked_img)

train_mask = []
for n in mask[:]:
    image_mask= Image.open(n)
    mask_arr= np.nan_to_num(np.array(image_mask), nan=2)
    stacked_mask = np.stack((mask_arr,)*1, axis=-1)
    train_mask.append(stacked_mask)

test_img = []
for o in img_val[:]:
    image= Image.open(o)
    img_arr = np.nan_to_num(np.array(image), nan=0)
    stacked_img = np.stack((img_arr,)*1, axis=-1)
    test_img.append(stacked_img)

test_mask = []
for p in mask_val[:]:
    image_mask= Image.open(p)
    mask_arr= np.nan_to_num(np.array(image_mask), nan=2)
    stacked_mask = np.stack((mask_arr,)*1, axis=-1)
    test_mask.append(stacked_mask)

#create tensorflow dataset 
train= tf.data.Dataset.from_tensor_slices((train_image, train_mask))
test = tf.data.Dataset.from_tensor_slices((test_img, test_mask))

#set parameters
train_length = len(train_image)
img_shape = (512,512,1)
batch_size = 16
epochs = 20

#shuffle, batch, and repeat
train_dataset = train.cache().shuffle(train_length).batch(batch_size).repeat()
train_dataset = train_dataset.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)
test_dataset = test.batch(batch_size).repeat()

#build the model
def conv_block(input_tensor, num_filters):
    encoder = layers.Conv2D(num_filters, (3, 3), padding='same')(input_tensor)
    encoder = layers.BatchNormalization()(encoder)
    encoder = layers.Activation('relu')(encoder)
    encoder = layers.Conv2D(num_filters, (3, 3), padding='same')(encoder)
    encoder = layers.BatchNormalization()(encoder)
    encoder = layers.Activation('relu')(encoder)
    return encoder

def encoder_block(input_tensor, num_filters):
    encoder = conv_block(input_tensor, num_filters)
    encoder_pool = layers.MaxPooling2D((2, 2), strides=(2, 2))(encoder)
    return encoder_pool, encoder

def decoder_block(input_tensor, concat_tensor, num_filters):
    decoder = layers.Conv2DTranspose(num_filters, (2, 2), strides=(2, 2), padding='same')(input_tensor)
    decoder = layers.concatenate([concat_tensor, decoder], axis=-1)
    decoder = layers.BatchNormalization()(decoder)
    decoder = layers.Activation('relu')(decoder)
    decoder = layers.Conv2D(num_filters, (3, 3), padding='same')(decoder)
    decoder = layers.BatchNormalization()(decoder)
    decoder = layers.Activation('relu')(decoder)
    decoder = layers.Conv2D(num_filters, (3, 3), padding='same')(decoder)
    decoder = layers.BatchNormalization()(decoder)
    decoder = layers.Activation('relu')(decoder)
    return decoder

inputs = layers.Input(shape=img_shape)
encoder0_pool, encoder0 = encoder_block(inputs, 32)
encoder1_pool, encoder1 = encoder_block(encoder0_pool, 64)
encoder2_pool, encoder2 = encoder_block(encoder1_pool, 128)
encoder3_pool, encoder3 = encoder_block(encoder2_pool, 256)
encoder4_pool, encoder4 = encoder_block(encoder3_pool, 512)
center = conv_block(encoder4_pool, 1024)
decoder4 = decoder_block(center, encoder4, 512)
decoder3 = decoder_block(decoder4, encoder3, 256)
decoder2 = decoder_block(decoder3, encoder2, 128)
decoder1 = decoder_block(decoder2, encoder1, 64)
decoder0 = decoder_block(decoder1, encoder0, 32)
outputs = layers.Conv2D(1, (1, 1), activation='sigmoid')(decoder0)

#defined the model
model = models.Model(inputs=[inputs], outputs=[outputs])

#defined loss function
def dice_coeff(y_true, y_pred):
    smooth = 1.
    y_true_f = tf.reshape(y_true, [-1])
    y_pred_f = tf.reshape(y_pred, [-1])
    intersection = tf.reduce_sum(y_true_f * y_pred_f)
    score = (2.*intersection+smooth)/(tf.reduce_sum(y_true_f)+tf.reduce_sum(y_pred_f)+smooth)
    return score

def dice_loss(y_true, y_pred):
    loss = 1 - dice_coeff(y_true, y_pred)
    return loss

def bce_dice_loss(y_true, y_pred):
    loss = losses.binary_crossentropy(y_true, y_pred) + dice_loss(y_true, y_pred)
    return loss

#compiled the model
model.compile(optimizer='adam', loss=bce_dice_loss, metrics=[dice_loss])
model.summary()

save_model_path = '/content/drive/My Drive/tmp/weights.hdf5'
cp = tf.keras.callbacks.ModelCheckpoint(filepath=save_model_path, monitor='val_dice_loss', mode='max', save_best_only=True)

#trained the model
history = model.fit(train_dataset, steps_per_epoch=int(np.ceil(train_length / float(batch_size))), epochs=epochs, validation_data=test_dataset, validation_steps=int(np.ceil(len(test_img) / float(batch_size))), callbacks=[cp])

#visualize training process
dice = history.history['dice_loss']
val_dice = history.history['val_dice_loss']

loss = history.history['loss']
val_loss = history.history['val_loss']

epochs_range = range(epochs)

plt.figure(figsize=(16, 8))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, dice, label='Training Dice Loss')
plt.plot(epochs_range, val_dice, label='Validation Dice Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Dice Loss')

plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')

plt.show()

#visualize the output
def display(display_list):
    plt.figure(figsize=(15, 15))
    title = ['Input Image', 'True Mask', 'Predicted Mask']
    for i in range(len(display_list)):
        plt.subplot(1, len(display_list), i+1)
        plt.title(title[i])
        plt.imshow(tf.keras.preprocessing.image.array_to_img(display_list[i]))
        plt.axis('off')
    plt.show()

def show_predictions(dataset=None, num=1):
    for image, mask in dataset.take(num):
        pred_mask = model.predict(image)
        display([image[0,:,:,0], mask[0,:,:,0], create_mask(pred_mask)[:,:,0]]) #1
        display([image[0,:,:,0], mask[0,:,:,0], pred_mask[0,:,:,0]]) #2

def create_mask(pred_mask):
    pred_mask = tf.argmax(pred_mask, axis=-1)
    pred_mask = pred_mask[..., tf.newaxis]
    return pred_mask[0]

show_predictions(test_dataset, 3)

The output classifier pred_mask do show some meaningful structures, below are some examples of the output from code #1. output 分类器 pred_mask 确实显示了一些有意义的结构,下面是代码 #1 中 output 的一些示例。 Example 1 .示例 1 Example 2 .示例 2 Example 3 .例 3

When I tried to create a segmentation mask like TensorFlow tutorial with code #2, it returned 0 all over for the segmentation mask.当我尝试使用代码 #2 创建像 TensorFlow 教程这样的分段掩码时,它为分段掩码返回了 0。 Example 1 .示例 1

I find out how to produce the mask.我知道如何生产面具。 Below is what required to be modified.以下是需要修改的内容。

#read images as array and make their shape
train_image = []
for m in img[:]:
    image= Image.open(m)
    img_arr= np.nan_to_num(np.array(image), nan=0)
    stacked_img= np.stack((img_arr,)*3, axis=-1)
    train_image.append(stacked_img)

test_img = []
for o in img_val[:]:
    image= Image.open(o)
    img_arr = np.nan_to_num(np.array(image), nan=0)
    stacked_img = np.stack((img_arr,)*3, axis=-1)
    test_img.append(stacked_img)
#set parameters
img_shape = (512,512,3) #if I want to produce a 3-class mask, then set the third channel as 3
#build the model
outputs = layers.Conv2D(3, (1, 1), activation='softmax')(decoder0) #if I want to produce 3-class mask, then set layers.Conv2D(3,(1,1)) and use softmax; if 2-class mask is required, then set (2,(1,1)) and use sigmoid.

Though it works now, I am confused about the image channel and the parameter layers.Conv2D.虽然它现在可以工作,但我对图像通道和参数 layers.Conv2D 感到困惑。 If I have a RGB image and I want to produce a 5-class mask, how should I set for the parameter img_shape as input and layers.Conv2D (?,(1,1)) as output?如果我有一个 RGB 图像并且我想生成一个 5 类蒙版,我应该如何将参数 img_shape 设置为输入,并将 layers.Conv2D (?,(1,1)) 设置为 output?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从 Python 中的蒙版分割图像创建轮廓(厚度可控)? - How to create an outline (with controllable thickness) from a mask segmentation image in Python? 创建一个目录来存储输出掩码,用于图像分割任务 - Create a directory to store output mask, for image segmentation task 从Python中的两条分割线创建二进制掩码 - Create binary mask from two segmentation lines in Python 从Keras的输出层创建一个“解开”掩码 - Create an “unpooling” mask from output layers in Keras 如何从python输出RandomForest分类器? - How to output RandomForest Classifier from python? 如何堆叠多个二进制掩码以创建用于多类分割的单个掩码? - How to stack multiple binary masks to create a single mask for multiclass segmentation? 使用深度 CNN 和全连接分类器将分割掩码 numpy arrays 用于图像分割 - converting segmentation mask numpy arrays for image segmentation using a deep CNN and a fully connected classifier 如何 plot 来自具有 2 个 output 神经元的 softmax 二元分类器的 ROC 曲线? - How to plot a ROC curve from a softmax binary classifier with 2 output neurons? 如何从 numpy 数组创建背景蒙版? - How to create a background mask from numpy array? 如何从 COCO 数据集创建掩码图像? - How to create mask images from COCO dataset?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM