LITS挑战肝分割

本文详细介绍了参与LITS挑战的肝分割过程,包括配置设置、使用CRF进行后处理优化,以及多个阶段的实验数据和验证步骤,探讨了numpy_data_layer在数据处理中的应用。
摘要由CSDN通过智能技术生成

LITS挑战肝分割

config

import logging

# Logging level#日志记录级别
log_level = logging.INFO

logfile = 'output.txt'

# Number of CPUs used for parallel processing#用于并行处理的CPU数量
N_PROC = 14

#Maximum number of iterations before optimisation is stopped#优化停止前的最大迭代次数
MAX_N_IT = -1


# Image/Seg shape#图片/ SEG形状
slice_shape = (388,388)

#Initial Parameters#初始参数
params_initial_liver = [\
3,  # pos_x_std
0.75,  # pos_y_std
3,  # pos_z_std
60,  # bilateral_x_std
15,  # bilateral_y_std
15,  # bilateral_z_std
20.0, # bilateral_intensity_std
0.75,  # pos_w
1.0   # bilateral_w  #we fix this one during optimization#WE解决优化过程中这一个
]

params_initial_lesion = [\
3.0,  # pos_x_std
3.0,  # pos_y_std
3.0,  # pos_z_std
60.0,  # bilateral_x_std
60.0,  # bilateral_y_std
60.0,  # bilateral_z_std
20.0, # bilateral_intensity_std
3.0,  # pos_w
10.0   # bilateral_w  #we fix this one during optimization#WE解决优化过程中这一个
]


### CHOOSE LIVER OR LESION# ## CHOOSE肝或病变
params_initial = params_initial_liver
target_label = 1


#Fixed CRF Parameters#固定CRF参数
max_iterations = 20
dynamic_z = False
ignore_memory = True




###########################
##### 3DIRCA DATASET ######
###########################


test_set=[
(82, '/home/guest/training/volume-82.npy', '/home/guest/training/segmentation-82.npy') ,
(74, '/home/guest/training/volume-74.npy', '/home/guest/training/segmentation-74.npy') ,
(125, '/home/guest/training/volume-125.npy', '/home/guest/training/segmentation-125.npy') ,
(11, '/home/guest/training/volume-11.npy', '/home/guest/training/segmentation-11.npy') ,
(89, '/home/guest/training/volume-89.npy', '/home/guest/training/segmentation-89.npy') ,
(78, '/home/guest/training/volume-78.npy', '/home/guest/training/segmentation-78.npy') ,
(64, '/home/guest/training/volume-64.npy', '/home/guest/training/segmentation-64.npy') ,
(126, '/home/guest/training/volume-126.npy', '/home/guest/training/segmentation-126.npy') ,
(129, '/home/guest/training/volume-129.npy', '/home/guest/training/segmentation-129.npy') ,
(114, '/home/guest/training/volume-114.npy', '/home/guest/training/segmentation-114.npy') ,
(37, '/home/guest/training/volume-37.npy', '/home/guest/training/segmentation-37.npy') ,
(25, '/home/guest/training/volume-25.npy', '/home/guest/training/segmentation-25.npy') ,
(85, '/home/guest/training/volume-85.npy', '/home/guest/training/segmentation-85.npy') ,
(80, '/home/guest/training/volume-80.npy', '/home/guest/training/segmentation-80.npy') ,
(27, '/home/guest/training/volume-27.npy', '/home/guest/training/segmentation-27.npy') ,
(18, '/home/guest/training/volume-18.npy', '/home/guest/training/segmentation-18.npy') ,
(69, '/home/guest/training/volume-69.npy', '/home/guest/training/segmentation-69.npy') ,
(40, '/home/guest/training/volume-40.npy', '/home/guest/training/segmentation-40.npy') ,
(61, '/home/guest/training/volume-61.npy', '/home/guest/training/segmentation-61.npy') ,
(117, '/home/guest/training/volume-117.npy', '/home/guest/training/segmentation-117.npy') ,
(44, '/home/guest/training/volume-44.npy', '/home/guest/training/segmentation-44.npy') ,
(26, '/home/guest/training/volume-26.npy', '/home/guest/training/segmentation-26.npy') ,
(91, '/home/guest/training/volume-91.npy', '/home/guest/training/segmentation-91.npy') ,
(65, '/home/guest/training/volume-65.npy', '/home/guest/training/segmentation-65.npy') ,
(55, '/home/guest/training/volume-55.npy', '/home/guest/training/segmentation-55.npy') ,
(5, '/home/guest/training/volume-5.npy', '/home/guest/training/segmentation-5.npy') ,
(77, '/home/guest/training/volume-77.npy', '/home/guest/training/segmentation-77.npy') ,
(12, '/home/guest/training/volume-12.npy', '/home/guest/training/segmentation-12.npy') ,
(28, '/home/guest/training/volume-28.npy', '/home/guest/training/segmentation-28.npy') ,
(6, '/home/guest/training/volume-6.npy', '/home/guest/training/segmentation-6.npy') ,
(79, '/home/guest/training/volume-79.npy', '/home/guest/training/segmentation-79.npy') ,
(84, '/home/guest/training/volume-84.npy', '/home/guest/training/segmentation-84.npy') ,
(103, '/home/guest/training/volume-103.npy', '/home/guest/training/segmentation-103.npy') ,
(101, '/home/guest/training/volume-101.npy', '/home/guest/training/segmentation-101.npy') ,
(106, '/home/guest/training/volume-106.npy', '/home/guest/training/segmentation-106.npy') ,
(59, '/home/guest/training/volume-59.npy', '/home/guest/training/segmentation-59.npy') ,
(45, '/home/guest/training/volume-45.npy', '/home/guest/training/segmentation-45.npy') ,
(53, '/home/guest/training/volume-53.npy', '/home/guest/training/segmentation-53.npy') ,
(41, '/home/guest/training/volume-41.npy', '/home/guest/training/segmentation-41.npy') ,
(121, '/home/guest/training/volume-121.npy', '/home/guest/training/segmentation-121.npy')]


# Select dataset#选择数据集
#dataset数据集 = [irca_train_fold1, irca_test_fold1,\
#		irca_train_fold2, irca_test_fold2,\
#		irca_train_fold3, irca_test_fold3,\
#		irca_train_fold4, irca_test_fold4]
#
# Datset测试
dataset = test_set

CRF优化

#! /usr/bin/env python


import numpy as np

import logging
import config

from denseinference import CRFProcessor

from multiprocessing import Pool, Manager

import nibabel as nib

import scipy.misc
import os

import medpy.metric

# global list for volumes#voluum全局列表
volumes = []

# best results so far#目前为止效果最好
best_dice = -1
best_params = None

n_iterations = 0

IMG_DTYPE = np.float
SEG_DTYPE = np.uint8


def to_scale(img, shape=None):
    if shape is None:
        shape = config.slice_shape

    height, width = shape
    if img.dtype == SEG_DTYPE:
        return scipy.misc.imresize(img, (height, width), interp="nearest").astype(SEG_DTYPE)
    elif img.dtype == IMG_DTYPE:
        factor = 256.0 / np.max(img)
        return (scipy.misc.imresize(img, (height, width), interp="nearest") / factor).astype(IMG_DTYPE)
    else:
        raise TypeError(
            'Error. To scale the image array, its type must be np.uint8 or np.float64. (' + str(img.dtype) + ')')


def norm_hounsfield_dyn(arr, c_min=0.1, c_max=0.3):
    """ Converts from hounsfield units to float64 image with range 0.0 to 1.0 """
    # calc min and max#,计算的最小和最大
    min, max = np.amin(arr), np.amax(arr)
    if min <= 0:
        arr = np.clip(arr, min * c_min, max * c_max)
        # right shift to zero#右移到零
        arr = np.abs(min * c_min) + arr
    else:
        arr = np.clip(arr, min, max * c_max)
        # left shift to zero #左移到零
        arr = arr - min
    # normalization#正常化
    norm_fac = np.amax(arr)
    if norm_fac != 0:
        norm = np.divide(
            np.multiply(arr, 255),
            np.amax(arr))
    else:  # don't divide through 0#不要除以0
        norm = np.multiply(arr, 255)

    norm = np.clip(np.multiply(norm, 0.00390625), 0, 1)
    return norm


def histeq_processor(img):
    """Histogram equalization"""“”“直方图均衡”“”
    nbr_bins = 256
    # get image histogram#获取图像的直方图
    imhist, bins = np.histogram(img.flatten(), nbr_bins, normed=True)
    cdf = imhist.cumsum()  # cumulative distribution function#累积分布函数
    cdf = 255 * cdf / cdf[-1]  # normalize#正常化
    # use linear interpolation of cdf to find new pixel values#使用cdf的线性插值来查找新的像素值
    original_shape = img.shape
    img = np.interp(img.flatten(), bins[:-1], cdf)
    img = img / 256.0
    return img.reshape(original_shape)


def process_img_label(imgvol, segvol):
    """
    Process a given image volume and its label and return arrays as a new copy处理给定的图像卷及其标签,并将数组作为新副本返回
    :param imgvol:
    :param label_vol:
    :return:
    """
    imgvol_downscaled = np.zeros((config.slice_shape[0], config.slice_shape[1], imgvol.shape[2]))
    segvol_downscaled = np.zeros((config.slice_shape[0], config.slice_shape[1], imgvol.shape[2]))
    imgvol[imgvol > 1200] = 0

    for i in range(imgvol.shape[2]):
        # Get the current slice, normalize and downscale#获取当前切片,规范化和缩减
        slice = np.copy(imgvol[:, :, i])
        slice = norm_hounsfield_dyn(slice)
        slice = to_scale(slice, config.slice_shape)
        slice = histeq_processor(slice)
        imgvol_downscaled[:, :, i] = slice
        # downscale the label slice for the crf#缩减标签片用于慢性肾功能衰竭
        segvol_downscaled[:, :, i] = to_scale(segvol[:, :, i], config.slice_shape)

    return [imgvol_downscaled, segvol_downscaled]


def crf_worker(img, label, probvol, crfsettings):
    """
    Worker function for Parallel CRF Processing of multiple Volumes并行CRF处理多个卷的工作器函数
    :param img:
    :param label:
    :param prob:
    :param crfsettings:
    :return:  dice
    """
    pro = CRFProcessor.CRF3DProcessor(**crfsettings)
    # print "started crf"#打印“开始CRF”
    # print np.min(img), np.max(img)  #打印np.min(IMG),np.max(IMG)
    result = pro.set_data_and_run(img, probvol)
    # print np.unique(result)  #打印np.unique(结果)
    # print "done with crf"#打印“慢性肾功能衰竭做”
    _dice = medpy.metric.dc(result == 1, label == config.target_label)
    print "Dice of single volume: " + str(_dice)

    # not sure if that's necessary#不确定是否有必要
    del pro

    return _dice


def run_crf(params, grad):
    """
    :param pos_x_std:
    :param bilateral_x_std:
    :param bilateral_intensity_std:
    :param pos_w:
    :param bilateral_w:
    :return:
    """
    global best_dice, best_params, volumes, n_iterations

    n_iterations += 1
    # Stupid NLopt it always wants a grad even for algorithms that don't use gradient. If grad is not empty, something is wrong.
    # print grad#愚蠢NLopt它总是想即使不使用梯度算法的毕业生。如果毕业不是空的,那就错了。
    #打印毕业生

    pos_x_std, pos_y_std, pos_z_std, bilateral_x_std, bilateral_y_std, bilateral_z_std, bilateral_intensity_std, pos_w, bilateral_w = params

    # 	logging.info("=======================")
    # 	logging.info("Running CRF with the following parameters使用以下参数运行CRF:")
    # 	logging.info("pos x std: " + str(pos_x_std))
    # 	logging.info("pos y std: " + str(pos_y_std))
    # 	logging.info("pos z std: " + str(pos_z_std))
    # 	logging.info("pos w: " + str(pos_w))
    # 	logging.info("bilateral x std: " + str(bilateral_x_std))
    # 	logging.info("bilateral y std: " + str(bilateral_y_std))
    # 	logging.info("bilateral z std: " + str(bilateral_z_std))
    # 	logging.info("bilateral intensity std双边强度标准: " + str(bilateral_intensity_std))
    # 	logging.info("bilateral w: " + str(bilateral_w))

    # Here's something to come#这是未来的事情
    crfsettings = dict(max_iterations=config.max_iterations,
                       pos_x_std=pos_x_std,
                       pos_y_std=pos_y_std,
                       pos_z_std=pos_z_std,
                       pos_w=pos_w,
                       bilateral_x_std=bilateral_x_std,
                       bilateral_y_std=bilateral_y_std,
                       bilateral_z_std=bilateral_z_std,
                       bilateral_intensity_std=bilateral_intensity_std,
                       bilateral_w=bilateral_w,

                       dynamic_z=config.dynamic_z,
                       ignore_memory=config.ignore_memory)

    # list of dice scores#骰子得分列表
    dices = []
    # list of pipes#管道列表
    results = []

    pool = Pool(processes=config.N_PROC)

    # start results  #开始结果
    for img, label, voxelsize, prob in volumes:
        # Normalize z std according to volume's voxel slice spacing
        copy_crfsettings = dict(crfsettings)
        copy_crfsettings['pos_z_std'] *= voxelsize[2]  # z std grows with larger spacing between slices
        results.append(pool.apply_async(crf_worker, (img, label, prob, crfsettings)))
    # dices.append(crf_worker(img,label,prob,crfsettings))

    # get results#得到结果
    for p in results:
        dices.append(p.get())

    pool.close()

    dice_average = np.average(dices)

    logging.info("-----------------------")
    logging.info("Iteration迭代 : " + str(n_iterations))
    logging.info("Best avg dice was最好的平均值是: " + str(best_dice))
    logging.info("   with best params : " + str(best_params))
    logging.info("Current avg dice is当前平均骰子是: " + str(dice_average))
    logging.info("   with current params :" + str(params))
    logging.info("=======================")

    if dice_average >= best_dice:
        best_params = params
        best_dice = dice_average
        print 'FOUND BETTER PARAMS'打印 '找到更好的参数'

    return dice_average

实验数据

import logging

# Logging level#日志记录级别
log_level = logging.WARNING

# Takes only the first n volumes. Useful to create small datasets fast#仅占前n个卷。用于快速创建小型数据集
max_volumes = -1


# Pre-write processing#预写处理
# Processors applied to images/segmentations right before persisting them to database (after augmentation...etc)#处理器在将它们持久化到数据库之前应用于图像/分段(在增强之后......等)
# A processor takes 2 images img and seg, and returns a tuple (img,seg)#一个处理器需要2个图像img和seg,并返回一个元组(img,seg)
# Available processors:#可用处理器:
#  - processors.zoomliver_UNET_processor
#  - processors.plain_UNET_processor
#  - processors.histeq_processor
#  - processors.liveronly_label_processor
from numpy_data_layer import processors
processors_list = [processors.plain_UNET_processor]
# Step 1#第1步
#processors_list = [processors.histeq_processor, processors.plain_UNET_processor, processors.liveronly_label_processor]
#processors_list = [processors.histeq_processor, processors.plain_UNET_processor][1:]
# Step 2#第2步
#processors_list = [processors.remove_non_liver, processors.zoomliver_UNET_processor]
#processors_list = [processors.histeq_processor]

# Shuffle slices and their augmentations globally across the database#在整个数据库中全局切换切片及其扩充
# You might want to set to False if dataset = test_set#如果dataset = test_set,您可能希望设置为False
shuffle_slices = True

# Augmentation factor#增强因子
augmentation_factor = 10

# ** Labels order : tissue=0, liver=1, lesion=2# **标签顺序:组织= 0,肝脏= 1,病变= 2
# ** We call a slice "lesion slice" if the MAX label it has is 2# **如果它的MAX标签是2,我们称之为切片“病变切片”
# slice options: liver-lesion, stat-batch, dyn-batch#切片选项:肝脏病变,STAT-批,达因批
#
# liver-only:   Include only slices which are labeld with liver or lower (1 or 0)切片选项:肝脏病变,STAT-批,达因批
# lesion-only:  Include only slices which are labeled with lesion or lower (2, 1 or 0)仅包含标有病变或更低(2,1或0)的切片
# liver-lesion: Include only slices which are labeled with liver or lesion (slices with max=2 or with max=1)仅包括标有肝脏或病变的切片(max = 2或max = 1的切片)
select_slices = "all"
#select_slices = 'liver-lesion肝脏病变'

more_small_livers = False
# Percentage of the image, such that any liver small than that is considered small#图像的百分比,使得任何小于此的肝脏被认为是小的
small_liver_percent = 2

decrease_empty_slices = 0.9
# data=[
# (49, '/home/guest/training/volume-49.nii', '/home/guest/training/segmentation-49.nii') ,
# (42, '/home/guest/training/volume-42.nii', '/home/guest/training/segmentation-42.nii') ,
# (23, '/home/guest/training/volume-23.nii', '/home/guest/training/segmentation-23.nii') ,
# (26, '/home/guest/training/volume-26.nii', '/home/guest/training/segmentation-26.nii') ,
# (37, '/home/guest/training/volume-37.nii', '/home/guest/training/segmentation-37.nii') ,
# (46, '/home/guest/training/volume-46.nii', '/home/guest/training/segmentation-46.nii') ,
# (2, '/home/guest/training/volume-2.nii', '/home/guest/training/segmentation-2.nii') ,
# (24, '/home/guest/training/volume-24.nii', '/home/guest/training/segmentation-24.nii') ,
# (44, '/home/guest/training/volume-44.nii', '/home/guest/training/segmentation-44.nii') ,
# (6, '/home/guest/training/volume-6.nii', '/home/guest/training/segmentation-6.nii') ,
# (25, '/home/guest/training/volume-25.nii', '/home/guest/training/segmentation-25.nii') ,
# (18, '/home/guest/training/volume-18.nii', '/home/guest/training/segmentation-18.nii') ,
# (16, '/home/guest/training/volume-16.nii', '/home/guest/training/segmentation-16.nii') ,
# (60, '/home/guest/training/volume-60.nii', '/home/guest/training/segmentation-60.nii') ,
# (59, '/home/guest/training/volume-59.nii', '/home/guest/training/segmentation-59.nii') ,
# (33, '/home/guest/training/volume-33.nii', '/home/guest/training/segmentation-33.nii') ,
# (58, '/home/guest/training/volume-58.nii', '/home/guest/training/segmentation-58.nii') ,
# (31, '/home/guest/training/volume-31.nii', '/home/guest/training/segmentation-31.nii') ,
# (54, '/home/guest/training/volume-54.nii', '/home/guest/training/segmentation-54.nii') ,
# (52, '/home/guest/training/volume-52.nii', '/home/guest/training/segmentation-52.nii') ,
# (12, '/home/guest/training/volume-12.nii', '/home/guest/training/segmentation-12.nii') ,
# (41, '/home/guest/training/volume-41.nii', '/home/guest/training/segmentation-41.nii') ,
# (56, '/home/guest/training/volume-56.nii', '/home/guest/training/segmentation-56.nii') ,
# (14, '/home/guest/training/volume-14.nii', '/home/guest/training/segmentation-14.nii') ,
# (4, '/home/guest/training/volume-4.nii', '/home/guest/training/segmentation-4.nii') ,
# (51, '/home/guest/training/volume-51.nii', '/home/guest/training/segmentation-51.nii') ,
# (47, '/home/guest/training/volume-47.nii', '/home/guest/training/segmentation-47.nii') ,
# (38, '/home/guest/training/volume-38.nii', '/home/guest/training/segmentation-38.nii') ,
# (34, '/home/guest/training/volume-34.nii', '/home/guest/training/segmentation-34.nii') ,
# (19, '/home/guest/training/volume-19.nii', '/home/guest/training/segmentation-19.nii') ,
# (43, '/home/guest/training/volume-43.nii', '/home/guest/training/segmentation-43.nii') ,
# (9, '/home/guest/training/volume-9.nii', '/home/guest/training/segmentation-9.nii') ,
# (15, '/home/guest/training/volume-15.nii', '/home/guest/training/segmentation-15.nii') ,
# (39, '/home/guest/training/volume-39.nii', '/home/guest/training/segmentation-39.nii') ,
# (20, '/home/guest/training/volume-20.nii', '/home/guest/training/segmentation-20.nii') ,
# (17, '/home/guest/training/volume-17.nii', '/home/guest/training/segmentation-17.nii') ,
# (55, '/home/guest/training/volume-55.nii', '/home/guest/training/segmentation-55.nii') ,
# (30, '/home/guest/training/volume-30.nii', '/home/guest/training/segmentation-30.nii') ,
# (29, '/home/guest/training/volume-29.nii', '/home/guest/training/segmentation-29.nii') ,
# (7, '/home/guest/training/volume-7.nii', '/home/guest/training/segmentation-7.nii') ,
# (22, '/home/guest/training/volume-22.nii', '/home/guest/training/segmentation-22.nii') ,
# (8, '/home/guest/training/volume-8.nii', '/home/guest/training/segmentation-8.nii') ,
# (13, '/home/guest/training/volume-13.nii', '/home/guest/training/segmentation-13.nii') ,
# (40, '/home/guest/training/volume-40.nii', '/home/guest/training/segmentation-40.nii') ,
# (0, '/home/guest/training/volume-0.nii', '/home/guest/training/segmentation-0.nii') ,
# (53, '/home/guest/training/volume-53.nii', '/home/guest/training/segmentation-53.nii') ,
# (5, '/home/guest/training/volume-5.nii', '/home/guest/training/segmentation-5.nii') ,
# (1, '/home/guest/training/volume-1.nii', '/home/guest/training/segmentation-1.nii') ,
# (36, '/home/guest/training/volume-36.nii', '/home/guest/training/segmentation-36.nii') ,
# (10, '/home/guest/training/volume-10.nii', '/home/guest/training/segmentation-10.nii') ,
# (48, '/home/guest/training/volume-48.nii', '/home/guest/training/segmentation-48.nii') ,
# (28, '/home/guest/training/volume-28.nii', '/home/guest/training/segmentation-28.nii') ,
# (11, '/home/guest/training/volume-11.nii', '/home/guest/training/segmentation-11.nii') ,
# (50, '/home/guest/training/volume-50.nii', '/home/guest/training/segmentation-50.nii') ,
# (45, '/home/guest/training/volume-45.nii', '/home/guest/training/segmentation-45.nii') ,
# (3, '/home/guest/training/volume-3.nii', '/home/guest/training/segmentation-3.nii') ,
# (57, '/home/guest/training/volume-57.nii', '/home/guest/training/segmentation-57.nii') ,
# (35, '/home/guest/training/volume-35.nii', '/home/guest/training/segmentation-35.nii') ,
# (32, '/home/guest/training/volume-32.nii', '/home/guest/training/segmentation-32.nii') ,
# (21, '/home/guest/training/volume-21.nii', '/home/guest/training/segmentation-21.nii') ,
# (27, '/home/guest/training/volume-27.nii', '/home/guest/training/segmentation-27.nii')]
data=[
(35, '/home/guest/training/volume-35.npy', '/home/guest/training/segmentation-35.npy') ,
(127, '/home/guest/training/volume-127.npy', '/home/guest/training/segmentation-127.npy') ,
(122, '/home/guest/training/volume-122.npy', '/home/guest/training/segmentation-122.npy') ,
(83, '/home/guest/training/volume-83.npy', '/home/guest/training/segmentation-83.npy') ,
(123, '/home/guest/training/volume-123.npy', '/home/guest/training/segmentation-123.npy') ,
(93, '/home/guest/training/volume-93.npy', '/home/guest/training/segmentation-93.npy') ,
(108, '/home/guest/training/volume-108.npy', '/home/guest/training/segmentation-108.npy') ,
(98, '/home/guest/training/volume-98.npy', '/home/guest/training/segmentation-98.npy') ,
(46, '/home/guest/training/volume-46.npy', '/home/guest/training/segmentation-46.npy') ,
(51, '/home/guest/training/volume-51.npy', '/home/guest/training/segmentation-51.npy') ,
(19, '/home/guest/training/volume-19.npy', '/home/guest/training/segmentation-19.npy') ,
(62, '/home/guest/training/volume-62.npy', '/home/guest/training/segmentation-62.npy') ,
(120, '/home/guest/training/volume-120.npy', '/home/guest/training/segmentation-120.npy') ,
(87, '/home/guest/training/volume-87.npy', '/home/guest/training/segmentation-87.npy') ,
(7, '/home/guest/training/volume-7.npy', '/home/guest/training/segmentation-7.npy') ,
(54, '/home/guest/training/volume-54.npy', '/home/guest/training/segmentation-54.npy') ,
(102, '/home/guest/training/volume-102.npy', '/home/guest/training/segmentation-102.npy') ,
(105, '/home/guest/training/volume-105.npy', '/home/guest/training/segmentation-105.npy') ,
(81, '/home/guest/training/volume-81.npy', '/home/guest/training/segmentation-81.npy') ,
(97, '/home/guest/training/volume-97.npy', '/home/guest/training/segmentation-97.npy') ,
(88, '/home/guest/training/volume-88.npy', '/home/guest/training/segmentation-88.npy') ,
(39, '/home/guest/training/volume-39.npy', '/home/guest/training/segmentation-39.npy') ,
(1, '/home/guest/training/volume-1.npy', '/home/guest/training/segmentation-1.npy') ,
(124, '/home/guest/training/volume-124.npy', '/home/guest/training/segmentation-124.npy') ,
(34, '/home/guest/training/volume-34.npy', '/home/guest/training/segmentation-34.npy') ,
(31, '/home/guest/training/volume-31.npy', '/home/guest/training/segmentation-31.npy') ,
(42, '/home/guest/training/volume-42.npy', '/home/guest/training/segmentation-42.npy') ,
(13, '/home/guest/training/volume-13.npy', '/home/guest/training/segmentation-13.npy') ,
(107, '/home/guest/training/volume-107.npy', '/home/guest/training/segmentation-107.npy') ,
(112, '/home/guest/training/volume-112.npy', '/home/guest/training/segmentation-112.npy') ,
(92, '/home/guest/training/volume-92.npy', '/home/guest/training/segmentation-92.npy') ,
(110, '/home/guest/training/volume-110.npy', '/home/guest/training/segmentation-110.npy') ,
(8, '/home/guest/training/volume-8.npy', '/home/guest/training/segmentation-8.npy') ,
(72, '/home/guest/training/volume-72.npy', '/home/guest/training/segmentation-72.npy') ,
(56, '/home/guest/training/volume-56.npy', '/home/guest/training/segmentation-56.npy') ,
(115, '/home/guest/training/volume-115.npy', '/home/guest/training/segmentation-115.npy') ,
(57, '/home/guest/training/volume-57.npy', '/home/guest/training/segmentation-57.npy') ,
(109, '/home/guest/training/volume-109.npy', '/home/guest/training/segmentation-109.npy') ,
(118, '/home/guest/training/volume-118.npy', '/home/guest/training/segmentation-118.npy') ,
(90, '/home/guest/training/volume-90.npy', '/home/guest/training/segmentation-90.npy') ,
(76, '/home/guest/training/volume-76.npy', '/home/guest/training/segmentation-76.npy') ,
(68, '/home/guest/training/volume-68.npy', '/home/guest/training/segmentation-68.npy') ,
(119, '/home/guest/training/volume-119.npy', '/home/guest/training/segmentation-119.npy') ,
(58, '/home/guest/training/volume-58.npy', '/home/guest/training/segmentation-58.npy') ,
(73, '/home/guest/training/volume-73.npy', '/home/guest/training/segmentation-73.npy') ,
(116, '/home/guest/training/volume-116.npy', '/home/guest/training/segmentation-116.npy') ,
(47, '/home/guest/training/volume-47.npy', '/home/guest/training/segmentation-47.npy') ,
(66, '/home/guest/training/volume-66.npy', '/home/guest/training/segmentation-66.npy') ,
(94, '/home/guest/training/volume-94.npy', '/home/guest/training/segmentation-94.npy') ,
(38, '/home/guest/training/volume-38.npy', '/home/guest/training/segmentation-38.npy') ,
(130, '/home/guest/training/volume-130.npy', '/home/guest/training/segmentation-130.npy') ,
(71, '/home/guest/training/volume-71.npy', '/home/guest/training/segmentation-71.npy') ,
(20, '/home/guest/training/volume-20.npy', '/home/guest/training/segmentation-20.npy') ,
(48, '/home/guest/training/volume-48.npy', '/home/guest/training/segmentation-48.npy') ,
(21, '/home/guest/training/volume-21.npy', '/home/guest/training/segmentation-21.npy') ,
(63, '/home/guest/training/volume-63.npy', '/home/guest/training/segmentation-63.npy') ,
(3, '/home/guest/training/volume-3.npy', '/home/guest/training/segmentation-3.npy') ,
(22, '/home/guest/training/volume-22.npy', '/home/guest/training/segmentation-22.npy') ,
(96, '/home/guest/training/volume-96.npy', '/home/guest/training/segmentation-96.npy') ,
(4, '/home/guest/training/volume-4.npy', '/home/guest/training/segmentation-4.npy') ,
(111, '/home/guest/training/volume-111.npy', '/home/guest/training/segmentation-111.npy') ,
(32, '/home/guest/training/volume-32.npy', '/home/guest/training/segmentation-32.npy') ,
(104, '/home/guest/training/volume-104.npy', '/home/guest/training/segmentation-104.npy') ,
(9, '/home/guest/training/volume-9.npy', '/home/guest/training/segmentation-9.npy') ,
(29, '/home/guest/training/volume-29.npy', '/home/guest/training/segmentation-29.npy') ,
(100, '/home/guest/training/volume-100.npy', '/home/guest/training/segmentation-100.npy') ,
(70, '/home/guest/training/volume-70.npy', '/home/guest/training/segmentation-70.npy') ,
(36, '/home/guest/training/volume-36.npy', '/home/guest/training/segmentation-36.npy') ,
(43, '/home/guest/training/volume-43.npy', '/home/guest/training/segmentation-43.npy') ,
(99, '/home/guest/training/volume-99.npy', '/home/guest/training/segmentation-99.npy') ,
(24, '/home/guest/training/volume-24.npy', '/home/guest/training/segmentation-24.npy') ,
(15, '/home/guest/training/volume-15.npy', '/home/guest/training/segmentation-15.npy') ,
(95, '/home/guest/training/volume-95.npy', '/home/guest/training/segmentation-95.npy') ,
(128, '/home/guest/training/volume-128.npy', '/home/guest/training/segmentation-128.npy') ,
(60, '/home/guest/training/volume-60.npy', '/home/guest/training/segmentation-60.npy') ,
(33, '/home/guest/training/volume-33.npy', '/home/guest/training/segmentation-33.npy') ,
(86, '/home/guest/training/volume-86.npy', '/home/guest/training/segmentation-86.npy') ,
(0, '/home/guest/training/volume-0.npy', '/home/guest/training/segmentation-0.npy') ,
(50, '/home/guest/training/volume-50.npy', '/home/guest/training/segmentation-50.npy') ,
(17, '/home/guest/training/volume-17.npy', '/home/guest/training/segmentation-17.npy') ,
(49, '/home/guest/training/volume-49.npy', '/home/guest/training/segmentation-49.npy') ,
(16, '/home/guest/training/volume-16.npy', '/home/guest/training/segmentation-16.npy') ,
(10, '/home/guest/training/volume-10.npy', '/home/guest/training/segmentation-10.npy') ,
(52, '/home/guest/training/volume-52.npy', '/home/guest/training/segmentation-52.npy') ,
(75, '/home/guest/training/volume-75.npy', '/home/guest/training/segmentation-75.npy') ,
(23, '/home/guest/training/volume-23.npy', '/home/guest/training/segmentation-23.npy') ,
(67, '/home/guest/training/volume-67.npy', '/home/guest/training/segmentation-67.npy') ,
(113, '/home/guest/training/volume-113.npy', '/home/guest/training/segmentation-113.npy') ,
(14, '/home/guest/training/volume-14.npy', '/home/guest/training/segmentation-14.npy') ,
(30, '/home/guest/training/volume-30.npy', '/home/guest/training/segmentation-30.npy') ,
(2, '/home/guest/training/volume-2.npy', '/home/guest/training/segmentation-2.npy') ,
(82, '/home/guest/training/volume-82.npy', '/home/guest/training/segmentation-82.npy') ,
(74, '/home/guest/training/volume-74.npy', '/home/guest/training/segmentation-74.npy') ,
(125, '/home/guest/training/volume-125.npy', '/home/guest/training/segmentation-125.npy') ,
(11, '/home/guest/training/volume-11.npy', '/home/guest/training/segmentation-11.npy') ,
(89, '/home/guest/training/volume-89.npy', '/home/guest/training/segmentation-89.npy') ,
(78, '/home/guest/training/volume-78.npy', '/home/guest/training/segmentation-78.npy') ,
(64, '/home/guest/training/volume-64.npy', '/home/guest/training/segmentation-64.npy') ,
(126, '/home/guest/training/volume-126.npy', '/home/guest/training/segmentation-126.npy') ,
(129, '/home/guest/training/volume-129.npy', '/home/guest/training/segmentation-129.npy') ,
(114, '/home/guest/training/volume-114.npy', '/home/guest/training/segmentation-114.npy') ,
(37, '/home/guest/training/volume-37.npy', '/home/guest/training/segmentation-37.npy') ,
(25, '/home/guest/training/volume-25.npy', '/home/guest/training/segmentation-25.npy') ,
(85, '/home/guest/training/volume-85.npy', '/home/guest/training/segmentation-85.npy') ,
(80, '/home/guest/training/volume-80.npy', '/home/guest/training/segmentation-80.npy') ,
(27, '/home/guest/training/volume-27.npy', '/home/guest/training/segmentation-27.npy') ,
(18, '/home/guest/training/volume-18.npy', '/home/guest/training/segmentation-18.npy') ,
(69, '/home/guest/training/volume-69.npy', '/home/guest/training/segmentation-69.npy') ,
(40, '/home/guest/training/volume-40.npy', '/home/guest/training/segmentation-40.npy') ,
(61, '/home/guest/training/volume-61.npy', '/home/guest/training/segmentation-61.npy') ,
(117, '/home/guest/training/volume-117.npy', '/home/guest/training/segmentation-117.npy') ,
(44, '/home/guest/training/volume-44.npy', '/home/guest/training/segmentation-44.npy') ,
(26, '/home/guest/training/volume-26.npy', '/home/guest/training/segmentation-26.npy') ,
(91, '/home/guest/training/volume-91.npy', '/home/guest/training/segmentation-91.npy') ,
(65, '/home/guest/training/volume-65.npy', '/home/guest/training/segmentation-65.npy') ,
(55, '/home/guest/training/volume-55.npy', '/home/guest/training/segmentation-55.npy') ,
(5, '/home/guest/training/volume-5.npy', '/home/guest/training/segmentation-5.npy') ,
(77, '/home/guest/training/volume-77.npy', '/home/guest/training/segmentation-77.npy') ,
(12, '/home/guest/training/volume-12.npy', '/home/guest/training/segmentation-12.npy') ,
(28, '/home/guest/training/volume-28.npy', '/home/guest/training/segmentation-28.npy') ,
(6, '/home/guest/training/volume-6.npy', '/home/guest/training/segmentation-6.npy') ,
(79, '/home/guest/training/volume-79.npy', '/home/guest/training/segmentation-79.npy') ,
(84, '/home/guest/training/volume-84.npy', '/home/guest/training/segmentation-84.npy') ,
(103, '/home/guest/training/volume-103.npy', '/home/guest/training/segmentation-103.npy') ,
(101, '/home/guest/training/volume-101.npy', '/home/guest/training/segmentation-101.npy') ,
(106, '/home/guest/training/volume-106.npy', '/home/guest/training/segmentation-106.npy') ,
(59, '/home/guest/training/volume-59.npy', '/home/guest/training/segmentation-59.npy') ,
(45, '/home/guest/training/volume-45.npy', '/home/guest/training/segmentation-45.npy') ,
(53, '/home/guest/training/volume-53.npy', '/home/guest/training/segmentation-53.npy') ,
(41, '/home/guest/training/volume-41.npy', '/home/guest/training/segmentation-41.npy') ,
(121, '/home/guest/training/volume-121.npy', '/home/guest/training/segmentation-121.npy')]

train_set=[
(35, '/home/guest/training/volume-35.npy', '/home/guest/training/segmentation-35.npy') ,
(127, '/home/guest/training/volume-127.npy', '/home/guest/training/segmentation-127.npy') ,
(122, '/home/guest/training/volume-122.npy', '/home/guest/training/segmentation-122.npy') ,
(83, '/home/guest/training/volume-83.npy', '/home/guest/training/segmentation-83.npy') ,
(123, '/home/guest/training/volume-123.npy', '/home/guest/training/segmentation-123.npy') ,
(93, '/home/guest/training/volume-93.npy', '/home/guest/training/segmentation-93.npy') ,
(108, '/home/guest/training/volume-108.npy', '/home/guest/training/segmentation-108.npy') ,
(98, '/home/guest/training/volume-98.npy', '/home/guest/training/segmentation-98.npy') ,
(46, '/home/guest/training/volume-46.npy', '/home/guest/training/segmentation-46.npy') ,
(51, '/home/guest/training/volume-51.npy', '/home/guest/training/segmentation-51.npy') ,
(19, '/home/guest/training/volume-19.npy', '/home/guest/training/segmentation-19.npy') ,
(62, '/home/guest/training/volume-62.npy', '/home/guest/training/segmentation-62.npy') ,
(120, '/home/guest/training/volume-120.npy', '/home/guest/training/segmentation-120.npy') ,
(87, '/home/guest/training/volume-87.npy', '/home/guest/training/segmentation-87.npy') ,
(7, '/home/guest/training/volume-7.npy', '/home/guest/training/segmentation-7.npy') ,
(54, '/home/guest/training/volume-54.npy', '/home/guest/training/segmentation-54.npy') ,
(102, '/home/guest/training/volume-102.npy', '/home/guest/training/segmentation-102.npy') ,
(105, '/home/guest/training/volume-105.npy', '/home/guest/training/segmentation-105.npy') ,
(81, '/home/guest/training/volume-81.npy', '/home/guest/training/segmentation-81.npy') ,
(97, '/home/guest/training/volume-97.npy', '/home/guest/training/segmentation-97.npy') ,
(88, '/home/guest/training/volume-88.npy', '/home/guest/training/segmentation-88.npy') ,
(39, '/home/guest/training/volume-39.npy', '/home/guest/training/segmentation-39.npy') ,
(1, '/home/guest/training/volume-1.npy', '/home/guest/training/segmentation-1.npy') ,
(124, '/home/guest/training/volume-124.npy', '/home/guest/training/segmentation-124.npy') ,
(34, '/home/guest/training/volume-34.npy', '/home/guest/training/segmentation-34.npy') ,
(31, '/home/guest/training/volume-31.npy', '/home/guest/training/segmentation-31.npy') ,
(42, '/home/guest/training/volume-42.npy', '/home/guest/training/segmentation-42.npy') ,
(13, '/home/guest/training/volume-13.npy', '/home/guest/training/segmentation-13.npy') ,
(107, '/home/guest/training/volume-107.npy', '/home/guest/training/segmentation-107.npy') ,
(112, '/home/guest/training/volume-112.npy', '/home/guest/training/segmentation-112.npy') ,
(92, '/home/guest/training/volume-92.npy', '/home/guest/training/segmentation-92.npy') ,
(110, '/home/guest/training/volume-110.npy', '/home/guest/training/segmentation-110.npy') ,
(8, '/home/guest/training/volume-8.npy', '/home/guest/training/segmentation-8.npy') ,
(72, '/home/guest/training/volume-72.npy', '/home/guest/training/segmentation-72.npy') ,
(56, '/home/guest/training/volume-56.npy', '/home/guest/training/segmentation-56.npy') ,
(115, '/home/guest/training/volume-115.npy', '/home/guest/training/segmentation-115.npy') ,
(57, '/home/guest/training/volume-57.npy', '/home/guest/training/segmentation-57.npy') ,
(109, '/home/guest/training/volume-109.npy', '/home/guest/training/segmentation-109.npy') ,
(118, '/home/guest/training/volume-118.npy', '/home/guest/training/segmentation-118.npy') ,
(90, '/home/guest/training/volume-90.npy', '/home/guest/training/segmentation-90.npy') ,
(76, '/home/guest/training/volume-76.npy', '/home/guest/training/segmentation-76.npy') ,
(68, '/home/guest/training/volume-68.npy', '/home/guest/training/segmentation-68.npy') ,
(119, '/home/guest/training/volume-119.npy', '/home/guest/training/segmentation-119.npy') ,
(58, '/home/guest/training/volume-58.npy', '/home/guest/training/segmentation-58.npy') ,
(73, '/home/guest/training/volume-73.npy', '/home/guest/training/segmentation-73.npy') ,
(116, '/home/guest/training/volume-116.npy', '/home/guest/training/segmentation-116.npy') ,
(47, '/home/guest/training/volume-47.npy', '/home/guest/training/segmentation-47.npy') ,
(66, '/home/guest/training/volume-66.npy', '/home/guest/training/segmentation-66.npy') ,
(94, '/home/guest/training/volume-94.npy', '/home/guest/training/segmentation-94.npy') ,
(38, '/home/guest/training/volume-38.npy', '/home/guest/training/segmentation-38.npy') ,
(130, '/home/guest/training/volume-130.npy', '/home/guest/training/segmentation-130.npy') ,
(71, '/home/guest/training/volume-71.npy', '/home/guest/training/segmentation-71.npy') ,
(20, '/home/guest/training/volume-20.npy', '/home/guest/training/segmentation-20.npy') ,
(48, '/home/guest/training/volume-48.npy', '/home/guest/training/segmentation-48.npy') ,
(21, '/home/guest/training/volume-21.npy', '/home/guest/training/segmentation-21.npy') ,
(63, '/home/guest/training/volume-63.npy', '/home/guest/training/segmentation-63.npy') ,
(3, '/home/guest/training/volume-3.npy', '/home/guest/training/segmentation-3.npy') ,
(22, '/home/guest/training/volume-22.npy', '/home/guest/training/segmentation-22.npy') ,
(96, '/home/guest/training/volume-96.npy', '/home/guest/training/segmentation-96.npy') ,
(4, '/home/guest/training/volume-4.npy', '/home/guest/training/segmentation-4.npy') ,
(111, '/home/guest/training/volume-111.npy', '/home/guest/training/segmentation-111.npy') ,
(32, '/home/guest/training/volume-32.npy', '/home/guest/training/segmentation-32.npy') ,
(104, '/home/guest/training/volume-104.npy', '/home/guest/training/segmentation-104.npy') ,
(9, '/home/guest/training/volume-9.npy', '/home/guest/training/segmentation-9.npy') ,
(29, '/home/guest/training/volume-29.npy', '/home/guest/training/segmentation-29.npy') ,
(100, '/home/guest/training/volume-100.npy', '/home/guest/training/segmentation-100.npy') ,
(70, '/home/guest/training/volume-70.npy', '/home/guest/training/segmentation-70.npy') ,
(36, '/home/guest/training/volume-36.npy', '/home/guest/training/segmentation-36.npy') ,
(43, '/home/guest/training/volume-43.npy', '/home/guest/training/segmentation-43.npy') ,
(99, '/home/guest/training/volume-99.npy', '/home/guest/training/segmentation-99.npy') ,
(24, '/home/guest/training/volume-24.npy', '/home/guest/training/segmentation-24.npy') ,
(15, '/home/guest/training/volume-15.npy', '/home/guest/training/segmentation-15.npy') ,
(95, '/home/guest/training/volume-95.npy', '/home/guest/training/segmentation-95.npy') ,
(128, '/home/guest/training/volume-128.npy', '/home/guest/training/segmentation-128.npy') ,
(60, '/home/guest/training/volume-60.npy', '/home/guest/training/segmentation-60.npy') ,
(33, '/home/guest/training/volume-33.npy', '/home/guest/training/segmentation-33.npy') ,
(86, '/home/guest/training/volume-86.npy', '/home/guest/training/segmentation-86.npy') ,
(0, '/home/guest/training/volume-0.npy', '/home/guest/training/segmentation-0.npy') ,
(50, '/home/guest/training/volume-50.npy', '/home/guest/training/segmentation-50.npy') ,
(17, '/home/guest/training/volume-17.npy', '/home/guest/training/segmentation-17.npy') ,
(49, '/home/guest/training/volume-49.npy', '/home/guest/training/segmentation-49.npy') ,
(16, '/home/guest/training/volume-16.npy', '/home/guest/training/segmentation-16.npy') ,
(10, '/home/guest/training/volume-10.npy', '/home/guest/training/segmentation-10.npy') ,
(52, '/home/guest/training/volume-52.npy', '/home/guest/training/segmentation-52.npy') ,
(75, '/home/guest/training/volume-75.npy', '/home/guest/training/segmentation-75.npy') ,
(23, '/home/guest/training/volume-23.npy', '/home/guest/training/segmentation-23.npy') ,
(67, '/home/guest/training/volume-67.npy', '/home/guest/training/segmentation-67.npy') ,
(113, '/home/guest/training/volume-113.npy', '/home/guest/training/segmentation-113.npy') ,
(14, '/home/guest/training/volume-14.npy', '/home/guest/training/segmentation-14.npy') ,
(30, '/home/guest/training/volume-30.npy', '/home/guest/training/segmentation-30.npy') ,
(2, '/home/guest/training/volume-2.npy', '/home/guest/training/segmentation-2.npy') ]


test_set=[
(82, '/home/guest/training/volume-82.npy', '/home/guest/training/segmentation-82.npy') ,
(74, '/home/guest/training/volume-74.npy', '/home/guest/training/segmentation-74.npy') ,
(125, '/home/guest/training/volume-125.npy', '/home/guest/training/segmentation-125.npy') ,
(11, '/home/guest/training/volume-11.npy', '/home/guest/training/segmentation-11.npy') ,
(89, '/home/guest/training/volume-89.npy', '/home/guest/training/segmentation-89.npy') ,
(78, '/home/guest/training/volume-78.npy', '/home/guest/training/segmentation-78.npy') ,
(64, '/home/guest/training/volume-64.npy', '/home/guest/training/segmentation-64.npy') ,
(126, '/home/guest/training/volume-126.npy', '/home/guest/training/segmentation-126.npy') ,
(129, '/home/guest/training/volume-129.npy', '/home/guest/training/segmentation-129.npy') ,
(114, '/home/guest/training/volume-114.npy', '/home/guest/training/segmentation-114.npy') ,
(37, '/home/guest/training/volume-37.npy', '/home/guest/training/segmentation-37.npy') ,
(25, '/home/guest/training/volume-25.npy', '/home/guest/training/segmentation-25.npy') ,
(85, '/home/guest/training/volume-85.npy', '/home/guest/training/segmentation-85.npy') ,
(80, '/home/guest/training/volume-80.npy', '/home/guest/training/segmentation-80.npy') ,
(27, '/home/guest/training/volume-27.npy', '/home/guest/training/segmentation-27.npy') ,
(18, '/home/guest/training/volume-18.npy', '/home/guest/training/segmentation-18.npy') ,
(69, '/home/guest/training/volume-69.npy', '/home/guest/training/segmentation-69.npy') ,
(40, '/home/guest/training/volume-40.npy', '/home/guest/training/segmentation-40.npy') ,
(61, '/home/guest/training/volume-61.npy', '/home/guest/training/segmentation-61.npy') ,
(117, '/home/guest/training/volume-117.npy', '/home/guest/training/segmentation-117.npy') ,
(44, '/home/guest/training/volume-44.npy', '/home/guest/training/segmentation-44.npy') ,
(26, '/home/guest/training/volume-26.npy', '/home/guest/training/segmentation-26.npy') ,
(91, '/home/guest/training/volume-91.npy', '/home/guest/training/segmentation-91.npy') ,
(65, '/home/guest/training/volume-65.npy', '/home/guest/training/segmentation-65.npy') ,
(55, '/home/guest/training/volume-55.npy', '/home/guest/training/segmentation-55.npy') ,
(5, '/home/guest/training/volume-5.npy', '/home/guest/training/segmentation-5.npy') ,
(77, '/home/guest/training/volume-77.npy', '/home/guest/training/segmentation-77.npy') ,
(12, '/home/guest/training/volume-12.npy', '/home/guest/training/segmentation-12.npy') ,
(28, '/home/guest/training/volume-28.npy', '/home/guest/training/segmentation-28.npy') ,
(6, '/home/guest/training/volume-6.npy', '/home/guest/training/segmentation-6.npy') ,
(79, '/home/guest/training/volume-79.npy', '/home/guest/training/segmentation-79.npy') ,
(84, '/home/guest/training/volume-84.npy', '/home/guest/training/segmentation-84.npy') ,
(103, '/home/guest/training/volume-103.npy', '/home/guest/training/segmentation-103.npy') ,
(101, '/home/guest/training/volume-101.npy', '/home/guest/training/segmentation-101.npy') ,
(106, '/home/guest/training/volume-106.npy', '/home/guest/training/segmentation-106.npy') ,
(59, '/home/guest/training/volume-59.npy', '/home/guest/training/segmentation-59.npy') ,
(45, '/home/guest/training/volume-45.npy', '/home/guest/training/segmentation-45.npy') ,
(53, '/home/guest/training/volume-53.npy', '/home/guest/training/segmentation-53.npy') ,
(41, '/home/guest/training/volume-41.npy', '/home/guest/training/segmentation-41.npy') ,
(121, '/home/guest/training/volume-121.npy', '/home/guest/training/segmentation-121.npy')]




# Select network datasets#选择网络数据集
#train_dataset = irca_numpy_all[:10]
#test_dataset = irca_numpy_all[10:]

train_dataset = train_set#fire3_train_set
test_dataset = test_set

实验数据2 numpy_data_layer.py

'''
Created on Apr 6, 2016
@author: Mohamed.Ezz
This module includes Caffe python data layers to read volumes directly from Npy files (3D CT volumes).该模块包含Caffe python数据层,可直接从Npy文件(3D CT卷)读取卷。
The layer scales well with large amounts of data, and supports prefetching for minimal processing overhead.该层可以很好地扩展大量数据,并支持预取,以最小化处理开销。
'''
import sys, os, time, random, shutil
import numpy as np
import lmdb, caffe, nibabel
from multiprocessing import Pool, Process, Queue
from Queue import Empty, Full
import scipy.misc, scipy.ndimage.interpolation
from tqdm import tqdm
import plyvel
from itertools import izip
import logging
from contextlib import closing

## Deformation Augmentation#变形增强
from skimage.transform import PiecewiseAffineTransform, warp

IMG_DTYPE = np.float
SEG_DTYPE = np.uint8

# Prefetching queue#预取队列
MAX_QUEUE_SIZE = 1000
PREFETCH_BATCH_SIZE = 100


def maybe_true(probability=0.5):
    rnd = random.random()
    return rnd <= probability


def to_scale(img, shape=None):
    if shape is None:
        shape = config.slice_shape

    height, width = shape高度,宽度=形状
    if img.dtype == SEG_DTYPE:
        return scipy.misc.imresize(img, (height, width), interp="nearest").astype(SEG_DTYPE)
    elif img.dtype == IMG_DTYPE:
        factor = 256.0 / np.max(img)
        return (scipy.misc.imresize(img, (height, width), interp="nearest") / factor).astype(IMG_DTYPE)
    else:
        raise TypeError(
            'Error. To scale the image array, its type must be np.uint8 or np.float64. '错误。要缩放图像数组,其类型必须为np.uint8或np.float64。(' + str(img.dtype) + ')')


def norm_hounsfield_dyn(arr, c_min=0.1, c_max=0.3):
    """ Converts from hounsfield units to float64 image with range 0.0 to 1.0 """“”“从hounsfield单位转换为float64图像,范围为0.0到1.0 ”“”
    # calc min and max#计算的最小和最大
    min, max = np.amin(arr), np.amax(arr)
    arr = arr.astype(IMG_DTYPE)
    if min <= 0:
        arr = np.clip(arr, min * c_min, max * c_max)
        # right shift to zero  #右移到零
        arr = np.abs(min * c_min) + arr
    else:
        arr = np.clip(arr, min, max * c_max)
        # left shift to zero #左移到零
        arr = arr - min
    # normalization
    norm_fac = np.amax(arr)
    if norm_fac != 0:
        # norm = (arr*255)/ norm_fac
        norm = np.divide(
            np.multiply(arr, 255),
            np.amax(arr))
    else:  # don't divide through 0#不要除以0
        norm = np.multiply(arr, 255)

    norm = np.clip(np.multiply(norm, 0.00390625), 0, 1)
    return norm


class augmentation:
    ### Core functions# ##核心职能
    @staticmethod
    def _get_shift(img, seg, x, y):
        """Move pixel in a direction by attaching on the other side. (i.e. x=5 -> 5 pixel to the right; y=-7 seven pixel down)
        :param id: slice id in current volume
        :return: Shifted img and seg"""“”通过附加在另一侧的方向移动像素。(即x = 5  - > 5像素向右; y = -7七像素向下)
        :param id:当前卷中的slice id
        :return:移位img和seg “”“
        # slide in x direction#沿x方向滑动
        if x != 0:
            img = np.append(img[x:, :], img[:x, :], axis=0)
            seg = np.append(seg[x:, :], seg[:x, :], axis=0)
        # slide in y direction#沿y方向滑动
        if y != 0:
            img = np.append(img[:, -y:], img[:, :-y], axis=1)
            seg = np.append(seg[:, -y:], seg[:, :-y], axis=1)
        return img, seg

    @staticmethod
    def _crop(img, seg, crop_type, frac=0.95):

        height, width = img.shape

        if crop_type == 'lt':
            box = (0, 0,
                   int(round(width * frac)), int(round(height * frac)))
        elif crop_type == 'rt':
            box = (int(round((1.0 - frac) * width)), 0,
                   width, int(round(height * frac)))
        elif crop_type == 'lb':
            box = (0, int(round((1.0 - frac) * height)),
                   int(round(width * frac)), height)
        elif crop_type == 'rb':
            box = (int(round((1.0 - frac) * width)), int(round((1.0 - frac) * height)),
                   width, height)
        elif crop_type == 'c':
            box = (int(round((1.0 - frac) * (width / 2.0))), int(round((1.0 - frac) * (height / 2.0))),
                   int(round(width * (frac + (1 - frac) / 2.0))), int(round(height * (frac + (1 - frac) / 2.0))))
        else:
            raise ValueError("Wrong crop_type. Must be lt, rt, lb, rb or c.")
        # Do the cropping#做裁剪
        x1, y1, x2, y2 = box
        img, seg = img[y1:y2, x1:x2], seg[y1:y2, x1:x2]

        return img, seg

    @staticmethod
    def _rotate(img, angle):
        # Prevent augmentation with no rotation, otherwise the same image will be appended #防止无旋转的扩充,否则将附加相同的图像
        if angle == 0:
            angle = 1
        # rotate without interpolation (order=0 makes it take nearest pixel)#旋转而不插补(为了= 0时取最近的像素)
        rotated = scipy.ndimage.interpolation.rotate(img, angle, order=0)
        # rotation results in extra pixels on the borders#旋转导致在边界额外的像素
        # We fix it assuming square shape#我们把它固定成方形
        assert img.shape[0] == img.shape[1], "Given image for rotation is not of square shape给定的旋转图像不是方形 :" + str(img.shape)
        extra = rotated.shape[0] - img.shape[0]
        extra_left = extra / 2
        extra_right = extra - extra_left
        rotated = rotated[extra_left: -extra_right, extra_left: - extra_right]
        return rotated

    #####################################
    ######    PUBLIC FUNCTIONS    #######
    #####################################
      # ####################################
    # #####公共职能#######
    # ####################################

    @staticmethod
    def identity(img, seg):
        """ return original slices...."""
        return img, seg

    @staticmethod
    def noise(img, seg):
        img_noisy = (img + 0.3 * img.std() * np.random.random(img.shape)).astype(IMG_DTYPE)
        return img_noisy, seg

    @staticmethod
    def get_shift_up(img, seg):
        height = img.shape[0]
        return augmentation._get_shift(img, seg, 0, int(height / 15))

    @staticmethod
    def get_shift_down(img, seg):
        height = img.shape[0]
        return augmentation._get_shift(img, seg, 0, -int(height / 15))

    @staticmethod
    def get_shift_left(img, seg):
        width = img.shape[1]
        return augmentation._get_shift(img, seg, -int(width / 15), 0)

    @staticmethod
    def get_shift_right(img, seg):
        width = img.shape[1]
        return augmentation._get_shift(img, seg, int(width / 15), 0)

    @staticmethod
    def crop_lb(img, seg):
        return augmentation._crop(img, seg, 'lb')

    @staticmethod
    def crop_rt(img, seg):
        return augmentation._crop(img, seg, 'rt')

    @staticmethod
    def crop_c(img, seg):
        return augmentation._crop(img, seg, 'c')

    @staticmethod
    def rotate(img, seg):
        rand = random.randrange(-10, 10)
        return augmentation._rotate(img, rand), augmentation._rotate(seg, rand)


class processors:
    @staticmethod
    def histeq_processor(img, seg):
        """Histogram equalization"""“”“直方图均衡”“”
        nbr_bins = 256
        # get image histogram#获取图像的直方图
        imhist, bins = np.histogram(img.flatten(), nbr_bins, normed=True)
        cdf = imhist.cumsum()  # cumulative distribution function#累积分布函数
        cdf = 255 * cdf / cdf[-1]  # normalize#正常化
        # use linear interpolation of cdf to find new pixel values#使用cdf的线性插值来查找新的像素值
        original_shape = img.shape
        img = np.interp(img.flatten(), bins[:-1], cdf)
        img = img / 255.0
        return img.reshape(original_shape), seg

    @staticmethod
    def plain_UNET_processor(img, seg):
        img = to_scale(img, (388, 388))
        seg = to_scale(seg, (388, 388))
        # Now do padding for UNET, which takes 572x572#现在为UNET做填充,需要572x572
        # seg=np.pad(seg,((92,92),(92,92)),mode='reflect')# SEG = np.pad(SEG,((92,92),(92,92)),模式= '反映')
        img = np.pad(img, 92, mode='reflect')
        return img, seg

    @staticmethod
    def liveronly_label_processor(img, seg):
        """Converts lesion labels to liver label. The resulting classifier classifies liver vs. background."""“”将病变标签转换为肝脏标签。由此产生的分类器将肝脏与背景分类。“”
        seg[seg == 2] = 1
        return img, seg

    @staticmethod
    def remove_non_liver(img, seg):
        # Remove background !#删除背景!
        img = np.multiply(img, np.clip(seg, 0, 1))
        return img, seg

    @staticmethod
    def zoomliver_UNET_processor(img, seg):
        """ Custom preprocessing of img,seg for UNET architecture:
        Crops the background and upsamples the found patch."""“”“用于UNET架构的img,seg的自定义预处理:
        裁剪背景并对找到的补丁进行上采样。“””
        # get patch size #得到补丁大小
        col_maxes = np.max(seg, axis=0)  # a row
        row_maxes = np.max(seg, axis=1)  # a column

        nonzero_colmaxes = np.nonzero(col_maxes)[0]
        nonzero_rowmaxes = np.nonzero(row_maxes)[0]

        x1, x2 = nonzero_colmaxes[0], nonzero_colmaxes[-1]
        y1, y2 = nonzero_rowmaxes[0], nonzero_rowmaxes[-1]
        width = x2 - x1
        height = y2 - y1
        MIN_WIDTH = 60
        MIN_HEIGHT = 60
        x_pad = int((MIN_WIDTH - width) / 2.0 if width < MIN_WIDTH else 0)
        y_pad = int((MIN_HEIGHT - height) / 2.0 if height < MIN_HEIGHT else 0)

        # Additional padding to make sure boundary lesions are included#附加填充以确保包括边界病变
        # SAFETY_PAD = 15
        # x_pad += SAFETY_PAD
        # y_pad += SAFETY_PAD

        x1 = max(0, x1 - x_pad)
        x2 = min(img.shape[1], x2 + x_pad)
        y1 = max(0, y1 - y_pad)
        y2 = min(img.shape[0], y2 + y_pad)

        img = img[y1:y2 + 1, x1:x2 + 1]
        seg = seg[y1:y2 + 1, x1:x2 + 1]

        img = to_scale(img, (388, 388))
        seg = to_scale(seg, (388, 388))
        # All non-lesion is background#所有非病变都是背景
        seg[seg == 1] = 0
        # Lesion label becomes 1#病变标签变为1
        seg[seg == 2] = 1

        # Now do padding for UNET, which takes 572x572#现在为UNET做填充,需要572x572
        # seg=np.pad(seg,((92,92),(92,92)),mode='reflect')
        img = np.pad(img, 92, mode='reflect')
        return img, seg


import config


class NumpyDataLayer(caffe.Layer):
    """ Caffe Data layer that reads directly from npy files """“”“直接从npy文件读取的Caffe数据层”“”

    def setup(self, bottom, top):
        print "Setup NumpyDataLayer"
        self.top_names = ['data', 'label']

        self.batch_size = 1  # current batch_size>1 is not implemented. but very simple to implement in the forward() function# current batch_size> 1未实现。但是在forward()函数中实现非常简单
        self.img_volumes = []  # list of numpy volumes# numpy的卷列表
        self.seg_volumes = []  # list of numpy label volumes# numpy的标签卷的列表

        self.n_volumes = 0  # number of volumes in dataset#数据集中的卷数
        self.n_augmentations = config.augmentation_factor  # number of possible augmentations#可能的扩充次数
        self.queue = Queue(MAX_QUEUE_SIZE)
        self.n_total_slices = 0
        for vol_id, img_path, seg_path in self.dataset:
            # shape initially is like 512,512,129#形状最初是像512512129
            imgvol = np.load(img_path, mmap_mode='r')
            imgvol = np.rot90(imgvol)  # rotate so that spine is down, not left#转动,使脊柱下来,不剩
            imgvol = np.transpose(imgvol, (2, 0, 1))  # bring slice index to first place #带来切片索引到第一位置
            self.img_volumes.append(imgvol)

            segvol = np.load(seg_path, mmap_mode='r')
            segvol = np.rot90(segvol)
            segvol = np.transpose(segvol, (2, 0, 1))
            self.seg_volumes.append(segvol)

            assert imgvol.shape == segvol.shape, "Volume and segmentation have different shapes音量和分段有不同的形状: %s vs. %s" % (
            str(imgvol.shape), str(segvol.shape))

            self.n_volumes += 1
            self.n_total_slices += segvol.shape[0]

        print "Dataset has ", self.n_total_slices, "(before augmentation)"
        top[0].reshape(1, 1, 572, 572)
        top[1].reshape(1, 1, 388, 388)

        # Seed the random generator#播种随机生成器
        np.random.seed(123)
        # Put first input into queue#将第一个输入放入队列
        child_seed = np.random.randint(0, 9000)
        # The child_seed is a randomly generated seed and it is needed because#是一个随机生成的种子,它是所需要的,因为child_seed
        # without it, every newly created process will be identical and will generate #没有它,每个新创建的进程都将是相同的并将生成
        # the same sequence of random numbers#相同的随机数序列
        self.p = Process(target=self.prepare_next_batch, args=(child_seed,))
        self.p.start()

        import atexit
        def cleanup():
            print "Terminating dangling process终止悬空过程"
            self.p.terminate()
            self.p.join()

        atexit.register(cleanup)

        import signal
        signal.signal(signal.SIGINT, cleanup)

    def reshape(self, bottom, top):
        pass

    def forward(self, bottom, top):
        while True:
            try:
                img, seg = self.queue.get(timeout=1)
                break
            except Empty:  # If queue is empty for any reason, must get_next_slice now#如果队列因任何原因为空,则必须立即获取get_next_slice
                # Make sure that there is no self.p currently running#确保当前没有运行self.p.
                if not self.p.is_alive():
                    # be 100% sure to terminate self.p# 100%肯定会终止self.p
                    self.p.join()
                    print "forward(): Queue was empty. Spawing prefetcher and retrying队列是空的.Spawing prefetcher并重试"
                    child_seed = np.random.randint(0, 9000)
                    self.p = Process(target=self.prepare_next_batch, args=(child_seed,))
                    self.p.start()

        top[0].data[0, ...] = img
        top[1].data[0, ...] = seg

    # self.p.join()

    # child_seed = np.random.randint(0,9000)
    # self.pool_result = self.ppool.apply_async(self, args=(child_seed,))
    # self.pool_result.get()
    # self.p = Process(target = self.prepare_next_batch, args=(child_seed,))
    # self.p.start()

    def backward(self, top, propagate_down, bottom):
        pass

    def prepare_next_batch(self, seed):
        np.random.seed(seed)
        for _ in range(PREFETCH_BATCH_SIZE):
            self.get_next_slice()

    def get_next_slice(self):
        """ Randomly pick a next slice and push it to the shared queue """“”“随机选择下一个切片并将其推送到共享队列”“”
        while True:
            # Pick random slice and augmentation
            # Doing it this way, each volume has equal probability of being selected regardless of
            # how many slices it has.
            # Each slice inside the volume has equal chances to be picked.
            # But globally, not every slice has the same probablity of being selected,
            # it depends on how many other slices in its same volume is competing with it.
            #选择随机切片和扩充
            #这样做,每个卷都有相同的被选中概率,无论如何
            #它有多少片。
            #卷内的每个切片都有相同的拾取机会。
            #但在全球范围内,并非每个切片都具有相同的选择概率,
            #它取决于同一卷中有多少其他切片与之竞争。
            vol_idx = np.random.randint(0, self.n_volumes)
            slice_idx = np.random.randint(0, self.img_volumes[vol_idx].shape[0])
            aug_idx = np.random.randint(0, self.n_augmentations)

            img = self.img_volumes[vol_idx][slice_idx]
            seg = self.seg_volumes[vol_idx][slice_idx]

            # print vol_idx, slice_idx, aug_idx
            # Only break if we found a relevant slice
            #打印vol_idx,slice_idx,aug_idx
            #只有在找到相关切片时才会中断
            if self.is_relevant_slice(seg):
                break

        img, seg = self.prepare_slice(img, seg, aug_idx)

        try:
            self.queue.put((img, seg))
        except Full:
            pass

    def is_relevant_slice(self, slc):
        """ Checks whether a given segmentation slice is relevant, according to rule specified in config.select_slices (e.g., lesion-only)"""“”根据config.select_slices中指定的规则检查给定的分段切片是否相关(例如,仅损伤)“”“

        # We increase small livers by rejecting non-small liver slices more frequently#我们通过更频繁地拒绝非小肝片来增加小肝脏
        if config.more_small_livers:
            n_liver = 1.0 * np.sum(slc > 0)
            if (100 * n_liver / slc.size) > config.small_liver_percent:  # NOT small liver
                return maybe_true(0.7)

        if config.select_slices == "all":
            # Reject half of the slices that has no liver/lesion#拒绝一半没有肝脏/病变的切片
            if np.count_nonzero(slc) == 0:
                return maybe_true(0.3)
            return True

        max = np.max(slc)
        if config.select_slices == "liver-lesion肝脏病变":
            return max == 1 or max == 2
        elif config.select_slices == "lesion-only仅病变":
            return max == 2
        elif config.select_slices == "liver-only仅肝脏":
            return max == 1
        else:
            raise ValueError("Invalid value for config.select_slices :", config.select_slices)

    def prepare_slice(self, img, seg, aug_idx):
        # Make sure 0 >= label >= 2
        seg = np.clip(seg, 0, 2)
        img = norm_hounsfield_dyn(img)
        img, seg = self.augment_slice(img, seg, aug_idx)
        for processor in config.processors_list:
            img, seg = processor(img, seg)
        # img = to_scale(img, (400,400))
        # seg = to_scale(seg, (400,400))
        return img, seg

    def augment_slice(self, img, seg, aug_idx):

        aug_func = [augmentation.identity,
                    augmentation.crop_lb,
                    augmentation.crop_rt,
                    augmentation.crop_c,
                    augmentation.rotate,
                    augmentation.rotate,
                    augmentation.get_shift_up,
                    augmentation.get_shift_down,
                    augmentation.get_shift_left,
                    augmentation.get_shift_right]
        # augmentation.noise

        # Invoke the selected augmentation function#调用选定的增强功能
        img, seg = aug_func[aug_idx](img, seg)
        return img, seg


class NumpyTrainDataLayer(NumpyDataLayer):
    """ NumpyDataLayer for the Train dataset """“”“train数据集的NumpyDataLayer ”“”

    def setup(self, bottom, top):
        self.dataset = config.train_dataset
        print 'Training size:', len(self.dataset)
        super(NumpyTrainDataLayer, self).setup(bottom, top)


class NumpyTestDataLayer(NumpyDataLayer):
    """ NumpyDataLayer for the Test dataset """“”“测试数据集的NumpyDataLayer ”“”

    def setup(self, bottom, top):
        self.dataset = config.test_dataset
        print 'Training size:', len(self.dataset)
        super(NumpyTestDataLayer, self).setup(bottom, top)

验证1

import logging

# Number of CPUs used for parallel processing#用于并行处理的CPU数量
N_PROC = 14

# Image/Seg shape#图片/ SEG形状
slice_shape = (388,388)

#################
#### OUTPUT #####
#################

ct_window_type='stat'
ct_window_type_min=-100
ct_window_type_max=200

# Logging level#日志记录级别
log_level = logging.INFO
output_dir = "/home/guest/output/"
logfile = 'output.txt'
# Save liver.npy and lesion.npy volumes to output_dir/[niftiname].liver.npy, with shape h,w,slices,classes#将liver.npy和lesion.npy卷保存到output_dir / [niftiname] .liver.npy,其中包含形状h,w,切片,类
save_probability_volumes =  True
save_probability_volumes = True
# Save slices as png files. This param is the increment between plotting one slice and the next#将切片保存为png文件。该参数是绘制一个切片和下一个切片之间的增量
# Set 0 or -1 to disable plotting#设置0或-1以禁用绘图
plot_every_n_slices = -1

test_set=[
(82, '/home/guest/training/volume-82.npy', '/home/guest/training/segmentation-82.npy') ,
(74, '/home/guest/training/volume-74.npy', '/home/guest/training/segmentation-74.npy') ,
(125, '/home/guest/training/volume-125.npy', '/home/guest/training/segmentation-125.npy') ,
(11, '/home/guest/training/volume-11.npy', '/home/guest/training/segmentation-11.npy') ,
(89, '/home/guest/training/volume-89.npy', '/home/guest/training/segmentation-89.npy') ,
(78, '/home/guest/training/volume-78.npy', '/home/guest/training/segmentation-78.npy') ,
(64, '/home/guest/training/volume-64.npy', '/home/guest/training/segmentation-64.npy') ,
(126, '/home/guest/training/volume-126.npy', '/home/guest/training/segmentation-126.npy') ,
(129, '/home/guest/training/volume-129.npy', '/home/guest/training/segmentation-129.npy') ,
(114, '/home/guest/training/volume-114.npy', '/home/guest/training/segmentation-114.npy') ,
(37, '/home/guest/training/volume-37.npy', '/home/guest/training/segmentation-37.npy') ,
(25, '/home/guest/training/volume-25.npy', '/home/guest/training/segmentation-25.npy') ,
(85, '/home/guest/training/volume-85.npy', '/home/guest/training/segmentation-85.npy') ,
(80, '/home/guest/training/volume-80.npy', '/home/guest/training/segmentation-80.npy') ,
(27, '/home/guest/training/volume-27.npy', '/home/guest/training/segmentation-27.npy') ,
(18, '/home/guest/training/volume-18.npy', '/home/guest/training/segmentation-18.npy') ,
(69, '/home/guest/training/volume-69.npy', '/home/guest/training/segmentation-69.npy') ,
(40, '/home/guest/training/volume-40.npy', '/home/guest/training/segmentation-40.npy') ,
(61, '/home/guest/training/volume-61.npy', '/home/guest/training/segmentation-61.npy') ,
(117, '/home/guest/training/volume-117.npy', '/home/guest/training/segmentation-117.npy') ,
(44, '/home/guest/training/volume-44.npy', '/home/guest/training/segmentation-44.npy') ,
(26, '/home/guest/training/volume-26.npy', '/home/guest/training/segmentation-26.npy') ,
(91, '/home/guest/training/volume-91.npy', '/home/guest/training/segmentation-91.npy') ,
(65, '/home/guest/training/volume-65.npy', '/home/guest/training/segmentation-65.npy') ,
(55, '/home/guest/training/volume-55.npy', '/home/guest/training/segmentation-55.npy') ,
(5, '/home/guest/training/volume-5.npy', '/home/guest/training/segmentation-5.npy') ,
(77, '/home/guest/training/volume-77.npy', '/home/guest/training/segmentation-77.npy') ,
(12, '/home/guest/training/volume-12.npy', '/home/guest/training/segmentation-12.npy') ,
(28, '/home/guest/training/volume-28.npy', '/home/guest/training/segmentation-28.npy') ,
(6, '/home/guest/training/volume-6.npy', '/home/guest/training/segmentation-6.npy') ,
(79, '/home/guest/training/volume-79.npy', '/home/guest/training/segmentation-79.npy') ,
(84, '/home/guest/training/volume-84.npy', '/home/guest/training/segmentation-84.npy') ,
(103, '/home/guest/training/volume-103.npy', '/home/guest/training/segmentation-103.npy') ,
(101, '/home/guest/training/volume-101.npy', '/home/guest/training/segmentation-101.npy') ,
(106, '/home/guest/training/volume-106.npy', '/home/guest/training/segmentation-106.npy') ,
(59, '/home/guest/training/volume-59.npy', '/home/guest/training/segmentation-59.npy') ,
(45, '/home/guest/training/volume-45.npy', '/home/guest/training/segmentation-45.npy') ,
(53, '/home/guest/training/volume-53.npy', '/home/guest/training/segmentation-53.npy') ,
(41, '/home/guest/training/volume-41.npy', '/home/guest/training/segmentation-41.npy') ,
(121, '/home/guest/training/volume-121.npy', '/home/guest/training/segmentation-121.npy')]


dataset = [test_set]
models=['/home/guest/step1/_iter_77000.caffemodel']
models_step_two=['/home/guest/step2/_iter_60000.caffemodel']
deployprototxt=['/home/guest/deploy.prototxt']
deployprototxt_step_two=['/home/guest/deploy.prototxt']

验证2

name: "phseg_v5"
force_backward: true


input: "data"
input_dim:1
input_dim:1
input_dim:572
input_dim:572

layer {
  name: "conv_d0a-b"
  type: "Convolution"
  bottom: "data"
  top: "d0b"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 64
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}

#layer { name: "bn_d0b" type: "BatchNorm" bottom: "d0b" top: "d0b"
#  param {lr_mult: 0} param {lr_mult: 0} param {lr_mult: 0}}


layer {
  name: "relu_d0b"
  type: "ReLU"
  bottom: "d0b"
  top: "d0b"
}
layer {
  name: "conv_d0b-c"
  type: "Convolution"
  bottom: "d0b"
  top: "d0c"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 64
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}

#layer { name: "bn_d0c" type: "BatchNorm" bottom: "d0c" top: "d0c"
#  param {lr_mult: 0} param {lr_mult: 0} param {lr_mult: 0}}


layer {
  name: "relu_d0c"
  type: "ReLU"
  bottom: "d0c"
  top: "d0c"
}
layer {
  name: "pool_d0c-1a"
  type: "Pooling"
  bottom: "d0c"
  top: "d1a"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {
  name: "conv_d1a-b"
  type: "Convolution"
  bottom: "d1a"
  top: "d1b"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 128
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}

#layer { name: "bn_d1b" type: "BatchNorm" bottom: "d1b" top: "d1b"
#  param {lr_mult: 0} param {lr_mult: 0} param {lr_mult: 0}}


layer {
  name: "relu_d1b"
  type: "ReLU"
  bottom: "d1b"
  top: "d1b"
}
layer {
  name: "conv_d1b-c"
  type: "Convolution"
  bottom: "d1b"
  top: "d1c"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 128
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}

#layer { name: "bn_d1c" type: "BatchNorm" bottom: "d1c" top: "d1c"
#  param {lr_mult: 0} param {lr_mult: 0} param {lr_mult: 0}}



layer {
  name: "relu_d1c"
  type: "ReLU"
  bottom: "d1c"
  top: "d1c"
}
layer {
  name: "pool_d1c-2a"
  type: "Pooling"
  bottom: "d1c"
  top: "d2a"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {
  name: "conv_d2a-b"
  type: "Convolution"
  bottom: "d2a"
  top: "d2b"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 256
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}


#layer { name: "bn_d2b" type: "BatchNorm" bottom: "d2b" top: "d2b"
#  param {lr_mult: 0} param {lr_mult: 0} param {lr_mult: 0}}




layer {
  name: "relu_d2b"
  type: "ReLU"
  bottom: "d2b"
  top: "d2b"
}
layer {
  name: "conv_d2b-c"
  type: "Convolution"
  bottom: "d2b"
  top: "d2c"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 256
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}



#layer { name: "bn_d2c" type: "BatchNorm" bottom: "d2c" top: "d2c"
#  param {lr_mult: 0} param {lr_mult: 0} param {lr_mult: 0}}




layer {
  name: "relu_d2c"
  type: "ReLU"
  bottom: "d2c"
  top: "d2c"
}
layer {
  name: "pool_d2c-3a"
  type: "Pooling"
  bottom: "d2c"
  top: "d3a"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {
  name: "conv_d3a-b"
  type: "Convolution"
  bottom: "d3a"
  top: "d3b"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 512
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}


#layer { name: "bn_d3b" type: "BatchNorm" bottom: "d3b" top: "d3b"
#  param {lr_mult: 0} param {lr_mult: 0} param {lr_mult: 0}}



layer {
  name: "relu_d3b"
  type: "ReLU"
  bottom: "d3b"
  top: "d3b"
}
layer {
  name: "conv_d3b-c"
  type: "Convolution"
  bottom: "d3b"
  top: "d3c"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 512
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}


#layer { name: "bn_d3c" type: "BatchNorm" bottom: "d3c" top: "d3c"
#  param {lr_mult: 0} param {lr_mult: 0} param {lr_mult: 0}}



layer {
  name: "relu_d3c"
  type: "ReLU"
  bottom: "d3c"
  top: "d3c"
}


layer {
  name: "dropout_d3c"
  type: "Dropout"
  bottom: "d3c"
   top: "d3c"
  include {phase: TRAIN}
  dropout_param {dropout_ratio: 0.5}}


layer {
  name: "pool_d3c-4a"
  type: "Pooling"
  bottom: "d3c"
  top: "d4a"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {
  name: "conv_d4a-b"
  type: "Convolution"
  bottom: "d4a"
  top: "d4b"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 1024
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}


#layer { name: "bn_d4b" type: "BatchNorm" bottom: "d4b" top: "d4b"
#  param {lr_mult: 0} param {lr_mult: 0} param {lr_mult: 0}}



layer {
  name: "relu_d4b"
  type: "ReLU"
  bottom: "d4b"
  top: "d4b"
}
layer {
  name: "conv_d4b-c"
  type: "Convolution"
  bottom: "d4b"
  top: "d4c"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 1024
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}


#layer { name: "bn_d4c" type: "BatchNorm" bottom: "d4c" top: "d4c"
#  param {lr_mult: 0} param {lr_mult: 0} param {lr_mult: 0}}



layer {
  name: "relu_d4c"
  type: "ReLU"
  bottom: "d4c"
  top: "d4c"
}

layer {
  name: "dropout_d4c"
  type: "Dropout"
  bottom: "d4c"
  top: "d4c"
  include {phase: TRAIN}
  dropout_param {dropout_ratio: 0.5}}


layer {
  name: "upconv_d4c_u3a"
  type: "Deconvolution"
  bottom: "d4c"
  top: "u3a"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 512
    pad: 0
    kernel_size: 2
    stride: 2
    weight_filler {
      type: "xavier"
    }
  }
}




layer {
  name: "relu_u3a"
  type: "ReLU"
  bottom: "u3a"
  top: "u3a"
}
layer {
  name: "crop_d3c-d3cc"
  type: "Crop"
  bottom: "d3c"
  bottom: "u3a"
  top: "d3cc"

}
layer {
  name: "concat_d3cc_u3a-b"
  type: "Concat"
  bottom: "u3a"
  bottom: "d3cc"
  top: "u3b"
}
layer {
  name: "conv_u3b-c"
  type: "Convolution"
  bottom: "u3b"
  top: "u3c"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 512
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}
layer {
  name: "relu_u3c"
  type: "ReLU"
  bottom: "u3c"
  top: "u3c"
}
layer {
  name: "conv_u3c-d"
  type: "Convolution"
  bottom: "u3c"
  top: "u3d"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 512
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}
layer {
  name: "relu_u3d"
  type: "ReLU"
  bottom: "u3d"
  top: "u3d"
}
layer {
  name: "upconv_u3d_u2a"
  type: "Deconvolution"
  bottom: "u3d"
  top: "u2a"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 256
    pad: 0
    kernel_size: 2
    stride: 2
    weight_filler {
      type: "xavier"
    }
  }
}
layer {
  name: "relu_u2a"
  type: "ReLU"
  bottom: "u2a"
  top: "u2a"
}
layer {
  name: "crop_d2c-d2cc"
  type: "Crop"
  bottom: "d2c"
  bottom: "u2a"
  top: "d2cc"

}
layer {
  name: "concat_d2cc_u2a-b"
  type: "Concat"
  bottom: "u2a"
  bottom: "d2cc"
  top: "u2b"
}
layer {
  name: "conv_u2b-c"
  type: "Convolution"
  bottom: "u2b"
  top: "u2c"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 256
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}
layer {
  name: "relu_u2c"
  type: "ReLU"
  bottom: "u2c"
  top: "u2c"
}
layer {
  name: "conv_u2c-d"
  type: "Convolution"
  bottom: "u2c"
  top: "u2d"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 256
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}
layer {
  name: "relu_u2d"
  type: "ReLU"
  bottom: "u2d"
  top: "u2d"
}
layer {
  name: "upconv_u2d_u1a"
  type: "Deconvolution"
  bottom: "u2d"
  top: "u1a"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 128
    pad: 0
    kernel_size: 2
    stride: 2
    weight_filler {
      type: "xavier"
    }
  }
}
layer {
  name: "relu_u1a"
  type: "ReLU"
  bottom: "u1a"
  top: "u1a"
}
layer {
  name: "crop_d1c-d1cc"
  type: "Crop"
  bottom: "d1c"
  bottom: "u1a"
  top: "d1cc"

}
layer {
  name: "concat_d1cc_u1a-b"
  type: "Concat"
  bottom: "u1a"
  bottom: "d1cc"
  top: "u1b"
}
layer {
  name: "conv_u1b-c"
  type: "Convolution"
  bottom: "u1b"
  top: "u1c"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 128
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}
layer {
  name: "relu_u1c"
  type: "ReLU"
  bottom: "u1c"
  top: "u1c"
}
layer {
  name: "conv_u1c-d"
  type: "Convolution"
  bottom: "u1c"
  top: "u1d"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 128
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}
layer {
  name: "relu_u1d"
  type: "ReLU"
  bottom: "u1d"
  top: "u1d"
}
layer {
  name: "upconv_u1d_u0a_NEW"
  type: "Deconvolution"
  bottom: "u1d"
  top: "u0a"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 64
    pad: 0
    kernel_size: 2
    stride: 2
    weight_filler {
      type: "xavier"
    }
  }
}
layer {
  name: "relu_u0a"
  type: "ReLU"
  bottom: "u0a"
  top: "u0a"
}
layer {
  name: "crop_d0c-d0cc"
  type: "Crop"
  bottom: "d0c"
  bottom: "u0a"
  top: "d0cc"

}
layer {
  name: "concat_d0cc_u0a-b"
  type: "Concat"
  bottom: "u0a"
  bottom: "d0cc"
  top: "u0b"
}
layer {
  name: "conv_u0b-c_New"
  type: "Convolution"
  bottom: "u0b"
  top: "u0c"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 64
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}
layer {
  name: "relu_u0c"
  type: "ReLU"
  bottom: "u0c"
  top: "u0c"
}
layer {
  name: "conv_u0c-d_New"
  type: "Convolution"
  bottom: "u0c"
  top: "u0d"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 64
    pad: 0
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}
layer {
  name: "relu_u0d"
  type: "ReLU"
  bottom: "u0d"
  top: "u0d"
}
layer {
  name: "conv_u0d-score_New"
  type: "Convolution"
  bottom: "u0d"
  top: "score"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 2
    pad: 0
    kernel_size: 1
    weight_filler {
      type: "xavier"
    }
    engine: CAFFE
  }
}

layer {
    name: "prob"
    type: "Softmax"
    bottom: "score"
    top: "prob"
    include {
        phase: TEST
    }
}

验证3

"""
@package medpy.metric.surface
Holds a metrics class computing surface metrics over two 3D-images contain each a binary object.
Classes:
    - Surface: Computes different surface metrics between two 3D-images contain each an object.
@author Oskar Maier
@version r0.4.1
@since 2011-12-01
@status Release
"""

# build-in modules
import math

# third-party modules
import scipy.spatial
import scipy.ndimage.morphology

# own modules

# code
class Surface(object):
    """
    Computes different surface metrics between two 3D-images contain each an object.
    The surface of the objects is computed using a 18-neighbourhood edge detection.
    The distance metrics are computed over all points of the surfaces using the nearest
    neighbour approach.
    Beside this provides a number of statistics of the two images.
    During the initialization the edge detection is run for both images, taking up to
    5 min (on 512^3 images). The first call to one of the metric measures triggers the
    computation of the nearest neighbours, taking up to 7 minutes (based on 250.000 edge
    point for each of the objects, which corresponds to a typical liver mask). All
    subsequent calls to one of the metrics measures can be expected be in the
    sub-millisecond area.
    Metrics defined in:
    Heimann, T.; van Ginneken, B.; Styner, M.A.; Arzhaeva, Y.; Aurich, V.; Bauer, C.; Beck, A.; Becker, C.; Beichel, R.; Bekes, G.; Bello, F.; Binnig, G.; Bischof, H.; Bornik, A.; Cashman, P.; Ying Chi; Cordova, A.; Dawant, B.M.; Fidrich, M.; Furst, J.D.; Furukawa, D.; Grenacher, L.; Hornegger, J.; Kainmuller, D.; Kitney, R.I.; Kobatake, H.; Lamecker, H.; Lange, T.; Jeongjin Lee; Lennon, B.; Rui Li; Senhu Li; Meinzer, H.-P.; Nemeth, G.; Raicu, D.S.; Rau, A.-M.; van Rikxoort, E.M.; Rousson, M.; Rusko, L.; Saddi, K.A.; Schmidt, G.; Seghers, D.; Shimizu, A.; Slagmolen, P.; Sorantin, E.; Soza, G.; Susomboon, R.; Waite, J.M.; Wimmer, A.; Wolf, I.; , "Comparison and Evaluation of Methods for Liver Segmentation From CT Datasets," Medical Imaging, IEEE Transactions on , vol.28, no.8, pp.1251-1265, Aug. 2009
    doi: 10.1109/TMI.2009.2013851
    """

    # The edge points of the mask object.
    __mask_edge_points = None
    # The edge points of the reference object.
    __reference_edge_points = None
    # The nearest neighbours distances between mask and reference edge points.
    __mask_reference_nn = None
    # The nearest neighbours distances between reference and mask edge points.
    __reference_mask_nn = None
    # Distances of the two objects surface points.
    __distance_matrix = None

    def __init__(self, mask, reference, physical_voxel_spacing = [1,1,1], mask_offset = [0,0,0], reference_offset = [0,0,0]):
        """
        Initialize the class with two binary images, each containing a single object.
        Assumes the input to be a representation of a 3D image, that fits one of the
        following formats:
            - 1. all 0 values denoting background, all others the foreground/object
            - 2. all False values denoting the background, all others the foreground/object
        The first image passed is referred to as 'mask', the second as 'reference'. This
        is only important for some metrics that are not symmetric (and therefore not
        really metrics).
        @param mask binary mask as an scipy array (3D image)
        @param reference binary reference as an scipy array (3D image)
        @param physical_voxel_spacing The physical voxel spacing of the two images
            (must be the same for both)
        @param mask_offset offset of the mask array to 0,0,0-origin
        @param reference_offset offset of the reference array to 0,0,0-origin
        """
        # compute edge images
        mask_edge_image = Surface.compute_contour(mask)
        reference_edge_image = Surface.compute_contour(reference)

        # collect the object edge voxel positions
        # !TODO: When the distance matrix is already calculated here
        # these points don't have to be actually stored, only their number.
        # But there might be some later metric implementation that requires the
        # points and then it would be good to have them. What is better?
        mask_pts = mask_edge_image.nonzero()
        mask_edge_points = zip(mask_pts[0], mask_pts[1], mask_pts[2])
        reference_pts = reference_edge_image.nonzero()
        reference_edge_points = zip(reference_pts[0], reference_pts[1], reference_pts[2])

        # check if there is actually an object present
        if 0 >= len(mask_edge_points):
            raise Exception('The mask image does not seem to contain an object.')
        if 0 >= len(reference_edge_points):
            raise Exception('The reference image does not seem to contain an object.')

        # add offsets to the voxels positions and multiply with physical voxel spacing
        # to get the real positions in millimeters
        physical_voxel_spacing = scipy.array(physical_voxel_spacing)
        mask_edge_points += scipy.array(mask_offset)
        mask_edge_points *= physical_voxel_spacing
        reference_edge_points += scipy.array(reference_offset)
        reference_edge_points *= physical_voxel_spacing

        # set member vars
        self.__mask_edge_points = mask_edge_points
        self.__reference_edge_points = reference_edge_points

    def get_maximum_symmetric_surface_distance(self):
        """
        Computes the maximum symmetric surface distance, also known as Hausdorff
        distance, between the two objects surfaces.
        @return the maximum symmetric surface distance in millimeters
        For a perfect segmentation this distance is 0. This metric is sensitive to
        outliers and returns the true maximum error.
        Metric definition:
        Let \f$S(A)\f$ denote the set of surface voxels of \f$A\f$. The shortest
        distance of an arbitrary voxel \f$v\f$ to \f$S(A)\f$ is defined as:
        \f[
            d(v,S(A)) = \min_{s_A\in S(A)} ||v-s_A||
        \f]
        where \f$||.||\f$ denotes the Euclidean distance. The maximum symmetric
        surface distance is then given by:
        \f[
            MSD(A,B) = \max
                \left\{
                    \max_{s_A\in S(A)} d(s_A,S(B)),
                    \max_{s_B\in S(B)} d(s_B,S(A)),
                \right\}
        \f]
        """
        # Get the maximum of the nearest neighbour distances
        A_B_distance = self.get_mask_reference_nn().max()
        B_A_distance = self.get_reference_mask_nn().max()

        # compute result and return
        return max(A_B_distance, B_A_distance)

    def get_root_mean_square_symmetric_surface_distance(self):
        """
        Computes the root mean square symmetric surface distance between the
        two objects surfaces.
        @return root mean square symmetric surface distance in millimeters
        For a perfect segmentation this distance is 0. This metric punishes large
        deviations from the true contour stronger than the average symmetric surface
        distance.
        Metric definition:
        Let \f$S(A)\f$ denote the set of surface voxels of \f$A\f$. The shortest
        distance of an arbitrary voxel \f$v\f$ to \f$S(A)\f$ is defined as:
        \f[
            d(v,S(A)) = \min_{s_A\in S(A)} ||v-s_A||
        \f]
        where \f$||.||\f$ denotes the Euclidean distance. The root mean square
        symmetric surface distance is then given by:
        \f[
          RMSD(A,B) =
            \sqrt{\frac{1}{|S(A)|+|S(B)|}}
            \times
            \sqrt{
                \sum_{s_A\in S(A)} d^2(s_A,S(B))
                +
                \sum_{s_B\in S(B)} d^2(s_B,S(A))
            }
        \f]
        """
        # get object sizes
        mask_surface_size = len(self.get_mask_edge_points())
        reference_surface_sice = len(self.get_reference_edge_points())

        # get minimal nearest neighbours distances
        A_B_distances = self.get_mask_reference_nn()
        B_A_distances = self.get_reference_mask_nn()

        # square the distances
        A_B_distances_sqrt = A_B_distances * A_B_distances
        B_A_distances_sqrt = B_A_distances * B_A_distances

        # sum the minimal distances
        A_B_distances_sum = A_B_distances_sqrt.sum()
        B_A_distances_sum = B_A_distances_sqrt.sum()

        # compute result and return
        return math.sqrt(1. / (mask_surface_size + reference_surface_sice)) * math.sqrt(A_B_distances_sum + B_A_distances_sum)

    def get_average_symmetric_surface_distance(self):
        """
        Computes the average symmetric surface distance between the
        two objects surfaces.
        @return average symmetric surface distance in millimeters
        For a perfect segmentation this distance is 0.
        Metric definition:
        Let \f$S(A)\f$ denote the set of surface voxels of \f$A\f$. The shortest
        distance of an arbitrary voxel \f$v\f$ to \f$S(A)\f$ is defined as:
        \f[
            d(v,S(A)) = \min_{s_A\in S(A)} ||v-s_A||
        \f]
        where \f$||.||\f$ denotes the Euclidean distance. The average symmetric
        surface distance is then given by:
        \f[
            ASD(A,B) =
                \frac{1}{|S(A)|+|S(B)|}
                \left(
                    \sum_{s_A\in S(A)} d(s_A,S(B))
                    +
                    \sum_{s_B\in S(B)} d(s_B,S(A))
                \right)
        \f]
        """
        # get object sizes
        mask_surface_size = len(self.get_mask_edge_points())
        reference_surface_sice = len(self.get_reference_edge_points())

        # get minimal nearest neighbours distances
        A_B_distances = self.get_mask_reference_nn()
        B_A_distances = self.get_reference_mask_nn()

        # sum the minimal distances
        A_B_distances = A_B_distances.sum()
        B_A_distances = B_A_distances.sum()

        # compute result and return
        return 1. / (mask_surface_size + reference_surface_sice) * (A_B_distances + B_A_distances)

    def get_mask_reference_nn(self):
        """
        @return The distances of the nearest neighbours of all mask edge points to all
                reference edge points.
        """
        # Note: see note for @see get_reference_mask_nn
        if None == self.__mask_reference_nn:
            tree = scipy.spatial.cKDTree(self.get_mask_edge_points())
            self.__mask_reference_nn, _ = tree.query(self.get_reference_edge_points())
        return self.__mask_reference_nn

    def get_reference_mask_nn(self):
        """
        @return The distances of the nearest neighbours of all reference edge points
                to all mask edge points.
        The underlying algorithm used for the scipy.spatial.KDTree implementation is
        based on:
        Sunil Arya, David M. Mount, Nathan S. Netanyahu, Ruth Silverman, and
        Angela Y. Wu. 1998. An optimal algorithm for approximate nearest neighbor
        searching fixed dimensions. J. ACM 45, 6 (November 1998), 891-923
        """
        # Note: KDTree is faster than scipy.spatial.distance.cdist when the number of
        # voxels exceeds 10.000 (computationally tested). The maximum complexity is
        # O(D*N^2) vs. O(D*N*log(N), where D=3 and N=number of voxels
        if None == self.__reference_mask_nn:
            tree = scipy.spatial.cKDTree(self.get_reference_edge_points())
            self.__reference_mask_nn, _ = tree.query(self.get_mask_edge_points())
        return self.__reference_mask_nn

    def get_mask_edge_points(self):
        """
        @return The edge points of the mask object.
        """
        return self.__mask_edge_points

    def get_reference_edge_points(self):
        """
        @return The edge points of the reference object.
        """
        return self.__reference_edge_points

    @staticmethod
    def compute_contour(array):
        """
        Uses a 18-neighbourhood filter to create an edge image of the input object.
        Assumes the input to be a representation of a 3D image, that fits one of the
        following formats:
            - 1. all 0 values denoting background, all others the foreground/object
            - 2. all False values denoting the background, all others the foreground/object
        The area outside the array is assumed to contain background voxels. The method
        does not ensure that the object voxels are actually connected, this is silently
        assumed.
        @param array a numpy array with only 0/N\{0} or False/True values.
        @return a boolean numpy array with the input objects edges
        """
        # set 18-neighbourhood/conectivity (for 3D images) alias face-and-edge kernel
        # all values covered by 1/True passed to the function
        # as a 1D array in order left-right, top-down
        # Note: all in all 19 ones, as the center value
        # also has to be checked (if it is a masked pixel)
        # [[[0, 1, 0], [[1, 1, 1],  [[0, 1, 0],
        #   [1, 1, 1],  [1, 1, 1],   [1, 1, 1],
        #   [0, 1, 0]], [1, 1, 1]],  [0, 1, 0]]]
        footprint = scipy.ndimage.morphology.generate_binary_structure(3, 2)

        # create an erode version of the array
        erode_array = scipy.ndimage.morphology.binary_erosion(array, footprint)

        # xor the erode_array with the original and return
        return array ^ erode_array

验证4

'''
Contains common functions for reading data out of leveldb
@author: Mohamed.Ezz
'''
import plyvel, lmdb
import numpy as np
from caffe.proto import caffe_pb2
IMG_DTYPE = np.float
SEG_DTYPE = np.uint8


def denormalize_img_255(arr):
    """ Denormalizes a nparray to 0-255 values """
    min = arr.min()
    max = arr.max()

    new = (arr - min) * (255.0 / (max - min))
    return new.astype(np.uint8)


def leveldb_arrays(leveldbdir):
    """ Generator. Given leveldb directory, iterate the stored data as numpy arrays. Yields (Key, NumpyArray) """
    db = CaffeDatabase(leveldbdir)
    for k, v in db.iterator():
        yield k, to_numpy_matrix(v)


def nth_datum(caffedb, n):
    """ Returns nth datum. 0-based index"""
    n += 1
    it = caffedb.iterator()
    for _ in range(n):
        _, v = it.next()
    datum = caffe_pb2.Datum()
    datum.ParseFromString(v)
    return datum


def get_data_type(datum):
    """ By simple calculations, conclude the size of integers stored in datum.data """
    n_values = datum.height * datum.width * datum.channels
    n_bytes = len(datum.data)
    int_size = float(n_bytes) / n_values
    if int_size != int(int_size) or int_size not in [1, 2, 4, 8]:
        raise ValueError("Can't find int size. n_values : %i , n_bytes : %i" % (n_values, n_bytes))
    types = {1: np.int8, 2: np.int16, 4: np.int32, 8: np.int64}
    type_ = types[int(int_size)]
    return type_


def find_keycount(caffedb, count_values=None):
    """ Takes a CaffeDatabase or plyvel.DB instance and returns number of keys found and count of each value.
    count_values is a list of values to count, e.g. count_values=[0,1,2] will return [count of 1s, count of 2s, count of 3s]
    if count_values is None, return value of this function is [],key_count"""
    count = 0
    total_value_counts = np.array([0] * len(count_values or []))
    for _, v in caffedb.iterator():
        count += 1

        if count_values is not None:
            array = to_numpy_matrix(v)
            current_count = np.array([0] * len(count_values))
            for i, val in enumerate(count_values):
                current_count[i] = np.sum(array == val)
            total_value_counts += current_count

    return total_value_counts, count


def to_numpy_matrix(v):
    """ Convert leveldb/lmdb value to numpy matrix of shape N x N """
    datum = caffe_pb2.Datum()
    datum.ParseFromString(v)
    # Three cases
    # 1- int imgs in data,
    # 2- int8 labels in data
    if len(datum.data) > 0:
        type_ = get_data_type(datum)
        matrix = np.fromstring(datum.data, dtype=type_)
    # 3- float imgs in float_data,
    elif len(datum.float_data) > 0:
        matrix = np.array(datum.float_data)
    else:
        raise ValueError("Serialized datum have empty data and float_data.")

    matrix = matrix.reshape((datum.height, datum.width))
    return matrix


def norm_hounsfield_dyn(arr, c_min=0.1, c_max=0.3):
    """ Converts from hounsfield units to float64 image with range 0.0 to 1.0 """
    # calc min and max
    min, max = np.amin(arr), np.amax(arr)
    arr = arr.astype(IMG_DTYPE)
    if min <= 0:
        arr = np.clip(arr, min * c_min, max * c_max)
        # right shift to zero
        arr = np.abs(min * c_min) + arr
    else:
        arr = np.clip(arr, min, max * c_max)
        # left shift to zero
        arr = arr - min
    # normalization
    norm_fac = np.amax(arr)
    if norm_fac != 0:
        norm = np.divide(
            np.multiply(arr, 255),
            np.amax(arr))
    else:  # don't divide through 0
        norm = np.multiply(arr, 255)

    norm = np.clip(np.multiply(norm, 0.00390625), 0, 1)
    return norm


def norm_hounsfield_stat(arr, c_min=-100, c_max=200):
    min = np.amin(arr)

    arr = np.array(arr, dtype=IMG_DTYPE)

    if min <= 0:
        # clip
        c_arr = np.clip(arr, c_min, c_max)

        # right shift to zero
        slc_0 = np.add(np.abs(min), c_arr)
    else:
        # clip
        c_arr = np.clip(arr, c_min, c_max)

        # left shift to zero
        slc_0 = np.subtract(c_arr, min)

    # normalization
    norm_fac = np.amax(slc_0)
    if norm_fac != 0:
        norm = np.divide(
            np.multiply(
                slc_0,
                255
            ),
            np.amax(slc_0)
        )
    else:  # don't divide through 0
        norm = np.multiply(slc_0, 255)

        norm = np.clip(np.multiply(norm, 0.00390625), 0, 1)
    return norm


class CaffeDatabase():
    """ Abstraction layer over lmdb and leveldb """

    def __init__(self, path, backend='lmdb'):
        self.backend = backend
        assert backend in ['lmdb', 'leveldb'], "Database backend not known :%s" % backend

        if backend == 'lmdb':
            self.db = lmdb.open(path)
        elif backend == 'leveldb':
            self.db = plyvel.DB(path)

    def iterator(self):
        if self.backend == 'lmdb':
            txn = self.db.begin()
            cursor = txn.cursor()
            it = cursor.iternext()
        elif self.backend == 'leveldb':
            it = self.db.iterator()
        return it

验证5

import config
import logging

import scipy as sp
import scipy.misc, scipy.ndimage.interpolation
import caffe

caffe.set_mode_gpu()

import matplotlib
from matplotlib import pyplot as plt

matplotlib.use('Agg')
import os
from denseinference import CRFProcessor

from medpy import metric

import nibabel as nib

import numpy as np
import IPython
# this should actually be part of medpy. Apparently it isn't (anymore). So the surface.py file from http://pydoc.net/Python/MedPy/0.2.2/medpy.metric._surface/ should be manually imported
from surface import Surface

from utils import norm_hounsfield_stat, norm_hounsfield_dyn

IMG_DTYPE = np.float
SEG_DTYPE = np.uint8


def miccaiimshow(img, seg, preds, fname, titles=None, plot_separate_img=True):
    """Takes raw image img, seg in range 0-2, list of predictions in range 0-2"""
    plt.figure(figsize=(25, 25))
    ALPHA = 1
    n_plots = len(preds)
    subplot_offset = 0

    plt.set_cmap('gray')

    if plot_separate_img:
        n_plots += 1
        subplot_offset = 1
        plt.subplot(1, n_plots, 1)
        plt.subplots_adjust(wspace=0, hspace=0)
        plt.title("Image")
        plt.axis('off')
        plt.imshow(img, cmap="gray")

    if type(preds) != list:
        preds = [preds]

    for i, pred in enumerate(preds):
        # Order of overaly
        ########## OLD
        # lesion= pred==2
        # difflesion = set_minus(seg==2,lesion)
        # liver = set_minus(pred==1, [lesion, difflesion])
        # diffliver = set_minus(seg==1, [liver,lesion,difflesion])
        ##########

        lesion = pred == 2
        difflesion = np.logical_xor(seg == 2, lesion)
        liver = pred == 1
        diffliver = np.logical_xor(seg == 1, liver)

        plt.subplot(1, n_plots, i + 1 + subplot_offset)
        title = titles[i] if titles is not None and i < len(titles) else ""
        plt.title(title)
        plt.axis('off')
        plt.imshow(img);
        plt.hold(True)
        # Liver prediction
        plt.imshow(np.ma.masked_where(liver == 0, liver), cmap="Greens", vmin=0.1, vmax=1.2, alpha=ALPHA);
        plt.hold(True)
        # Liver : Pixels in ground truth, not in prediction
        plt.imshow(np.ma.masked_where(diffliver == 0, diffliver), cmap="Spectral", vmin=0.1, vmax=2.2, alpha=ALPHA);
        plt.hold(True)

        # Lesion prediction
        plt.imshow(np.ma.masked_where(lesion == 0, lesion), cmap="Blues", vmin=0.1, vmax=1.2, alpha=ALPHA);
        plt.hold(True)
        # Lesion : Pixels in ground truth, not in prediction
        plt.imshow(np.ma.masked_where(difflesion == 0, difflesion), cmap="Reds", vmin=0.1, vmax=1.5, alpha=ALPHA)

    plt.savefig(fname)
    plt.close()


def to_scale(img, shape=None):
    if shape is None:
        shape = config.slice_shape

    height, width = shape
    if img.dtype == SEG_DTYPE:
        return scipy.misc.imresize(img, (height, width), interp="nearest").astype(SEG_DTYPE)
    elif img.dtype == IMG_DTYPE:
        max_ = np.max(img)
        factor = 256.0 / max_ if max_ != 0 else 1
        return (scipy.misc.imresize(img, (height, width), interp="nearest") / factor).astype(IMG_DTYPE)
    else:
        raise TypeError(
            'Error. To scale the image array, its type must be np.uint8 or np.float64. (' + str(img.dtype) + ')')


def histeq_processor(img):
    """Histogram equalization"""
    nbr_bins = 256
    # get image histogram
    imhist, bins = np.histogram(img.flatten(), nbr_bins, normed=True)
    cdf = imhist.cumsum()  # cumulative distribution function
    cdf = 255 * cdf / cdf[-1]  # normalize
    # use linear interpolation of cdf to find new pixel values
    original_shape = img.shape
    img = np.interp(img.flatten(), bins[:-1], cdf)
    img = img / 255.0
    return img.reshape(original_shape)


def downscale_img_label(imgvol, label_vol):
    """
    Downscales an image volume and an label volume. Normalizes the hounsfield units of the image volume
    :param imgvol:
    :param label_vol:
    :return:
    """
    imgvol = imgvol.astype(IMG_DTYPE)
    label_vol = label_vol.astype(SEG_DTYPE)
    slc=None
    imgvol_downscaled = np.zeros((config.slice_shape[0], config.slice_shape[1], imgvol.shape[2]))
    label_vol_downscaled = np.zeros((config.slice_shape[0], config.slice_shape[1], imgvol.shape[2]))

    # Copy image volume
    # copy_imgvol = np.copy(imgvol)
    # Truncate metal and high absorbative objects
    logging.info('Found' + str(np.sum(imgvol > 1200)) + 'values > 1200 !!')
    imgvol[imgvol > 1200] = 0

    for i in range(imgvol.shape[2]):
        # Get the current slc, normalize and downscale
        slc = imgvol[:, :, i]

        if config.ct_window_type == 'dyn':
            slc = norm_hounsfield_dyn(slc, c_min=config.ct_window_type_min, c_max=config.ct_window_type_max)
        elif config.ct_window_type == 'stat':
            slc = norm_hounsfield_stat(slc, c_min=config.ct_window_type_min, c_max=config.ct_window_type_max)
        else:
            print "CT Windowing did not work."

        slc = to_scale(slc, config.slice_shape)

        # slc = histeq_processor(slc)

        imgvol_downscaled[:, :, i] = slc

        # downscale the label slc for the crf
        label_vol_downscaled[:, :, i] = to_scale(label_vol[:, :, i], config.slice_shape)

    return [imgvol_downscaled, label_vol_downscaled]


def scorer(pred, label):
    """
    :param pred:
    :param label:
    :param voxelspacing:
    :return:
    """

    volscores = {}

    volscores['dice'] = metric.dc(pred, label)
    volscores['jaccard'] = metric.binary.jc(pred, label)
    volscores['voe'] = 1. - volscores['jaccard']
    volscores['rvd'] = metric.ravd(label, pred)

    if np.count_nonzero(pred) == 0 or np.count_nonzero(label) == 0:
        volscores['assd'] = 0
        volscores['msd'] = 0
    # else:
    #     evalsurf = Surface(pred, label, physical_voxel_spacing=vxlspacing, mask_offset=[0., 0., 0.],
    #                        reference_offset=[0., 0., 0.])
    #     volscores['assd'] = evalsurf.get_average_symmetric_surface_distance()
    #
    #     volscores['msd'] = metric.hd(label, pred, voxelspacing=vxlspacing)

    logging.info("\tDice " + str(volscores['dice']))
    logging.info("\tJaccard " + str(volscores['jaccard']))
    logging.info("\tVOE " + str(volscores['voe']))
    logging.info("\tRVD " + str(volscores['rvd']))
    # logging.info("\tASSD " + str(volscores['assd']))
    # logging.info("\tMSD " + str(volscores['msd']))

    return volscores


def get_average_score(scorelist, scorename, mode=None):
    """
    :param scorelist:
    :param scorename:
    :return:
    """

    score = 0.

    for e in scorelist:
        if mode == 'abs':
            score += np.abs(e[scorename])
        else:
            score += e[scorename]

    score /= float(len(scorelist))

    return score


def zoomliver_UNET_processor(img, seg):
    """ Custom preprocessing of img,seg for UNET architecture:
    Crops the background and upsamples the found patch."""

    # Remove background !
    img = np.multiply(img, np.clip(seg, 0, 1))
    # get patch size
    col_maxes = np.max(seg, axis=0)  # a row
    row_maxes = np.max(seg, axis=1)  # a column

    nonzero_colmaxes = np.nonzero(col_maxes)[0]
    nonzero_rowmaxes = np.nonzero(row_maxes)[0]

    x1, x2 = nonzero_colmaxes[0], nonzero_colmaxes[-1]
    y1, y2 = nonzero_rowmaxes[0], nonzero_rowmaxes[-1]
    width = x2 - x1
    height = y2 - y1
    MIN_WIDTH = 60
    MIN_HEIGHT = 60
    x_pad = (MIN_WIDTH - width) / 2 if width < MIN_WIDTH else 0
    y_pad = (MIN_HEIGHT - height) / 2 if height < MIN_HEIGHT else 0

    x1 = max(0, x1 - x_pad)
    x2 = min(img.shape[1], x2 + x_pad)
    y1 = max(0, y1 - y_pad)
    y2 = min(img.shape[0], y2 + y_pad)

    img = img[y1:y2 + 1, x1:x2 + 1]
    seg = seg[y1:y2 + 1, x1:x2 + 1]

    img = to_scale(img, (388, 388))
    seg = to_scale(seg, (388, 388))
    # All non-lesion is background
    seg[seg == 1] = 0
    # Lesion label becomes 1
    seg[seg == 2] = 1

    # Now do padding for UNET, which takes 572x572
    # seg=np.pad(seg,((92,92),(92,92)),mode='reflect')
    img = np.pad(img, 92, mode='reflect')
    return img, (x1, x2, y1, y2)


if __name__ == '__main__':
    try:
        logging.basicConfig(filename=os.path.join(config.output_dir, config.logfile), filemode='w',
                            level=config.log_level, format='%(asctime)s %(levelname)s:%(message)s',
                            datefmt='%d-%m-%Y %I:%M:%S %p')

        # lists to calculate the overall score over all folds from, i.e. holds scores of all volumes
        overall_score_liver = []
        overall_score_lesion_crf = []
        overall_score_liver_crf = []
        overall_score_lesion = []

        # Iterate folds and corresponding models
        for fold, model, deployprototxt, model_step_two, deployprototxt_step_two in zip(config.dataset, config.models,
                                                                                        config.deployprototxt,
                                                                                        config.models_step_two,
                                                                                        config.deployprototxt_step_two):

            logging.info("Starting new fold")

            # Lists to save scores for each volume of this fold
            foldscore_lesion_crf = []
            foldscore_liver_crf = []
            foldscore_liver = []
            foldscore_lesion = []

            # Iterate volumes in fold
            for volidx, volpaths in enumerate(fold):

                logging.info("Loading Network for Step 1")
                # load new network for this fold
                try:
                    del net  # it is a good idea to delete the net object to free up memory before instantiating another one
                    net = caffe.Net(deployprototxt, model, caffe.TEST)
                except NameError:
                    net = caffe.Net(deployprototxt, model, caffe.TEST)

                logging.info("Loading " + volpaths[1])
                imgvol = np.load(volpaths[1])
                labelvol = np.load(volpaths[2])

                # the raw probabilites of step 1
                probvol = np.zeros((config.slice_shape[0], config.slice_shape[1], imgvol.shape[2], 2))
                # the probabilites of step 2 scaled back down into the volume
                pred_step_two = np.zeros((config.slice_shape[0], config.slice_shape[1], imgvol.shape[2]))
                pred_step_one = np.zeros((config.slice_shape[0], config.slice_shape[1], imgvol.shape[2]))
                probvol_step_two = np.zeros((config.slice_shape[0], config.slice_shape[1], imgvol.shape[2], 2))

                # rotate volumes so that the networks sees them in the same orientation like during training
                imgvol = np.rot90(imgvol)
                labelvol = np.rot90(labelvol)

                imgvol_downscaled, labelvol_downscaled = downscale_img_label(imgvol, labelvol)

                # iterate slices in volume and do prediction
                logging.info("Predicting " + volpaths[1])
                for i in range(imgvol_downscaled.shape[2]):
                    slc = imgvol_downscaled[:, :, i]
                    # create mirrored slc for unet
                    slc = np.pad(slc, ((92, 92), (92, 92)), mode='reflect')

                    # load slc into network and do forward pass
                    net.blobs['data'].data[...] = slc
                    net.forward()

                    # now save raw probabilities
                    probvol[:, :, i, :] = net.blobs['prob'].data.transpose((0, 2, 3, 1))[0]
                    pred_step_one[:, :, i] = np.argmax(probvol[:, :, i, :], axis=2)
                # result shape is batch_img_idx , height, width, probability_of_class


                # dump probabiliteis to .npy file for future use
                # np.save('./probfiles/' + ))
                ##FIX THIS

                logging.info("Here are the liver scores before CRF:")
                # calculate scores for liver
                pred_to_use = np.logical_or(probvol.argmax(3) == 1, probvol.argmax(3) == 2)
                label_to_use = np.logical_or(labelvol_downscaled == 1, labelvol_downscaled == 2)

                #voxelspacing = volpaths[3]
                volumescore_liver = scorer(pred_to_use, label_to_use)

                # Run Liver CRF
                logging.info("Now running CRF on Liver")
                crfparams = {'max_iterations': 10, 'dynamic_z': True, 'ignore_memory': True, 'pos_x_std': 1.5,
                             'pos_y_std': 1.5,
                             'pos_z_std': 1.5, 'pos_w': 3.0, 'bilateral_x_std': 9.0, 'bilateral_y_std': 9.0,
                             'bilateral_z_std': 9.0, 'bilateral_intensity_std': 20.0, 'bilateral_w': 10.0}
                pro = CRFProcessor.CRF3DProcessor(**crfparams)

                if config.save_probability_volumes:
                    np.save(os.path.join(config.output_dir, os.path.basename(volpaths[1])) + ".liver.npy", probvol)

                crf_pred_liver = pro.set_data_and_run(imgvol_downscaled, probvol)

                # calculate scores for liver
                label_to_use = np.logical_or(labelvol_downscaled == 1, labelvol_downscaled == 2)

                logging.info("Here are the liver scores after CRF:")
                volumescore_liver_crf = scorer(crf_pred_liver, label_to_use)

                # calculate scores for lesions
                # pred_to_use = probvol.argmax(3)==2
                # label_to_use = labelvol_downscaled==2

                # volumescore_lesion = scorer(pred_to_use,label_to_use,voxelspacing)




                # OK, we're done on the first step of the cascaded networks and have evaluated them.
                # Now let's get to the second step.

                del net
                logging.info("Deleted network for cascade step 1")
                net = caffe.Net(deployprototxt_step_two, model_step_two, caffe.TEST)

                logging.info("Loaded network for cascade step 2")

                # we again iterate over all slices in the volume
                for i in range(imgvol_downscaled.shape[2]):
                    slc = imgvol_downscaled[:, :, i]
                    # create mirrored slc for unet
                    # slc = np.pad(slc,((92,92),(92,92)),mode='reflect')

                    # now we crop and upscale the liver
                    slc_crf_pred_liver = crf_pred_liver[:, :, i].astype(SEG_DTYPE)
                    # slc_crf_pred_liver = pred_to_use[:,:,i].astype(SEG_DTYPE)
                    # slc_crf_pred_liver = labelvol_downscaled[:,:,i]
                    if np.count_nonzero(slc_crf_pred_liver) == 0:
                        probvol_step_two[:, :, i, :] = 0
                    else:
                        slc, bbox = zoomliver_UNET_processor(slc, slc_crf_pred_liver)
                        # load slc into network and do forward pass
                        net.blobs['data'].data[...] = slc
                        net.forward()

                        # scale output back down and insert into the probability volume

                        x1, x2, y1, y2 = bbox
                        leftpad, rightpad = x1, 388 - x2
                        toppad, bottompad = y1, 388 - y2
                        width, height = int(x2 - x1), int(y2 - y1)
                        # now save probabilities
                        prob = net.blobs['prob'].data.transpose((0, 2, 3, 1))[0]
                        # 						probvol[:,:,i,:]  = prob

                        slc_pred_step_two = np.argmax(prob, axis=2).astype(SEG_DTYPE)

                        slc_pred_step_two = to_scale(slc_pred_step_two, (height, width))
                        slc_pred_step_two = np.pad(slc_pred_step_two, ((toppad, bottompad), (leftpad, rightpad)),
                                                   mode='constant')
                        pred_step_two[:, :, i] = slc_pred_step_two

                        prob0 = prob[:, :, 0].astype(
                            IMG_DTYPE)  # use IMG_DTYPE bcoz we've probabiblities, not hard labels
                        prob0 = to_scale(prob0, (height, width))
                        prob0 = np.pad(prob0, ((toppad, bottompad), (leftpad, rightpad)), mode='constant')
                        #
                        #
                        prob1 = prob[:, :, 1].astype(IMG_DTYPE)
                        prob1 = to_scale(prob1, (height, width))
                        prob1 = np.pad(prob1, ((toppad, bottompad), (leftpad, rightpad)), mode='constant')

                        probvol_step_two[:, :, i, 0] = prob0
                        probvol_step_two[:, :, i, 1] = prob1

                        # probvol_step_two[bbox[0]:bbox[0] + bbox[1], bbox[2]:bbox[2] + bbox[3], i, :] =

                logging.info("Lesion scores after step 2 before CRF")
                # pred_to_use = probvol_step_two.argmax(3) == 2
                pred_to_use = pred_step_two.astype(SEG_DTYPE)
                label_to_use = labelvol_downscaled == 2

                volumescore_lesion = scorer(pred_to_use, label_to_use)

                # Save lesion npy probabilities
                if config.save_probability_volumes:
                    np.save(os.path.join(config.output_dir, os.path.basename(volpaths[1])) + ".lesion.npy",
                            probvol_step_two)

                ### SAVE PLOTS
                if config.plot_every_n_slices > 0:
                    for i in range(0, imgvol_downscaled.shape[2], config.plot_every_n_slices):
                        pred_vol_bothsteps = pred_step_one
                        pred_vol_bothsteps[pred_step_two == 1] = 2
                        liverdc = metric.dc(pred_step_one[:, :, i], labelvol_downscaled[:, :, i] == 1)
                        lesiondc = metric.dc(pred_step_two[:, :, i], labelvol_downscaled[:, :, i] == 2)

                        fname = os.path.join(config.output_dir, os.path.basename(volpaths[1]))
                        fname += "_slc" + str(i) + "_"
                        fname += "liv" + str(liverdc) + "_les" + str(lesiondc) + ".png"
                        # logging.info("Plotting "+fname)

                        miccaiimshow(imgvol_downscaled[:, :, i], labelvol_downscaled[:, :, i],
                                     [labelvol_downscaled[:, :, i], pred_vol_bothsteps[:, :, i]], fname=fname,
                                     titles=["Ground Truth", "Prediction"], plot_separate_img=True)

                logging.info("Now running LESION CRF on Liver")
                crf_params = {'ignore_memory': True, 'bilateral_intensity_std': 0.16982742320252908,
                              'bilateral_w': 6.406401876489639,
                              'pos_w': 2.3422381267344132, 'bilateral_x_std': 284.5377968491542,
                              'pos_x_std': 23.636281254341867,
                              'max_iterations': 10}
                pro = CRFProcessor.CRF3DProcessor(**crf_params)

                crf_pred_lesion = pro.set_data_and_run(imgvol_downscaled, probvol_step_two)
                volumescore_lesion_crf = scorer(crf_pred_lesion, label_to_use)

                # Append to results lists so that the average scores can be calculated later
                foldscore_liver.append(volumescore_liver)
                foldscore_lesion.append(volumescore_lesion)
                foldscore_liver_crf.append(volumescore_liver_crf)
                foldscore_lesion_crf.append(volumescore_lesion_crf)

                overall_score_liver_crf.append(volumescore_liver_crf)
                overall_score_lesion_crf.append(volumescore_lesion_crf)
                overall_score_liver.append(volumescore_liver)
                overall_score_lesion.append(volumescore_lesion)

            logging.info("=========================================")
            logging.info("Average Liver Scores before CRF for this fold: ")
            logging.info("Dice " + str(get_average_score(foldscore_liver, 'dice')))
            logging.info("Jaccard " + str(get_average_score(foldscore_liver, 'jaccard')))
            logging.info("VOE " + str(get_average_score(foldscore_liver, 'voe')))
            logging.info("RVD " + str(get_average_score(foldscore_liver, 'rvd')))
           # logging.info("ASSD " + str(get_average_score(foldscore_liver, 'assd')))
            #logging.info("MSD " + str(get_average_score(foldscore_liver, 'msd')))
            logging.info("=========================================")

            logging.info("=========================================")
            logging.info("Average Liver Scores after CRF for this fold: ")
            logging.info("Dice " + str(get_average_score(foldscore_liver_crf, 'dice')))
            logging.info("Jaccard " + str(get_average_score(foldscore_liver_crf, 'jaccard')))
            logging.info("VOE " + str(get_average_score(foldscore_liver_crf, 'voe')))
            logging.info("RVD " + str(get_average_score(foldscore_liver_crf, 'rvd')))
           # logging.info("ASSD " + str(get_average_score(foldscore_liver_crf, 'assd')))
           # logging.info("MSD " + str(get_average_score(foldscore_liver_crf, 'msd')))
            logging.info("=========================================")

            logging.info("=========================================")
            logging.info("Average Lesion Scores before CRF for this fold: ")
            logging.info("Dice " + str(get_average_score(foldscore_lesion, 'dice')))
            logging.info("Jaccard " + str(get_average_score(foldscore_lesion, 'jaccard')))
            logging.info("VOE " + str(get_average_score(foldscore_lesion, 'voe')))
            logging.info("RVD " + str(get_average_score(foldscore_lesion, 'rvd')))
            #logging.info("ASSD " + str(get_average_score(foldscore_lesion, 'assd')))
            #logging.info("MSD " + str(get_average_score(foldscore_lesion, 'msd')))
            logging.info("=========================================")

            logging.info("=========================================")
            logging.info("Average Lesion Scores AFTER CRF for this fold: ")
            logging.info("Dice " + str(get_average_score(foldscore_lesion_crf, 'dice')))
            logging.info("Jaccard " + str(get_average_score(foldscore_lesion_crf, 'jaccard')))
            logging.info("VOE " + str(get_average_score(foldscore_lesion_crf, 'voe')))
            logging.info("RVD " + str(get_average_score(foldscore_lesion_crf, 'rvd')))
            #logging.info("ASSD " + str(get_average_score(foldscore_lesion_crf, 'assd')))
           # logging.info("MSD " + str(get_average_score(foldscore_lesion_crf, 'msd')))
            logging.info("=========================================")

        logging.info("=========================================")
        logging.info("DONE WITH PROCESSING ALL FOLDS. NOW THE OVERALL RESULTS COME")
        logging.info("=========================================")
        logging.info("Average Liver Scores before CRF overall: ")
        logging.info("Dice " + str(get_average_score(overall_score_liver, 'dice')))
        logging.info("Jaccard " + str(get_average_score(overall_score_liver, 'jaccard')))
        logging.info("VOE " + str(get_average_score(overall_score_liver, 'voe')))
        logging.info("RVD " + str(get_average_score(overall_score_liver, 'rvd', mode='abs')))
        logging.info("ASSD " + str(get_average_score(overall_score_liver, 'assd')))
       # logging.info("MSD " + str(get_average_score(overall_score_liver, 'msd')))
       # logging.info("=========================================")
        logging.info("=========================================")
        logging.info("Average Liver Scores after CRF overall: ")
        logging.info("Dice " + str(get_average_score(overall_score_liver_crf, 'dice')))
        logging.info("Jaccard " + str(get_average_score(overall_score_liver_crf, 'jaccard')))
        logging.info("VOE " + str(get_average_score(overall_score_liver_crf, 'voe')))
        logging.info("RVD " + str(get_average_score(overall_score_liver_crf, 'rvd', mode='abs')))
        #logging.info("ASSD " + str(get_average_score(overall_score_liver_crf, 'assd')))
        #logging.info("MSD " + str(get_average_score(overall_score_liver_crf, 'msd')))
        logging.info("=========================================")
        logging.info("=========================================")
        logging.info("Average Lesion Scores before step2 CRF overall: ")
        logging.info("Dice " + str(get_average_score(overall_score_lesion, 'dice')))
        logging.info("Jaccard " + str(get_average_score(overall_score_lesion, 'jaccard')))
        logging.info("VOE " + str(get_average_score(overall_score_lesion, 'voe')))
        logging.info("RVD " + str(get_average_score(overall_score_lesion, 'rvd', mode='abs')))
        #logging.info("ASSD " + str(get_average_score(overall_score_lesion, 'assd')))
        #logging.info("MSD " + str(get_average_score(overall_score_lesion, 'msd')))
        logging.info("=========================================")
        logging.info("=========================================")
        logging.info("Average Lesion Scores after step2 CRF overall: ")
        logging.info("Dice " + str(get_average_score(overall_score_lesion_crf, 'dice')))
        logging.info("Jaccard " + str(get_average_score(overall_score_lesion_crf, 'jaccard')))
        logging.info("VOE " + str(get_average_score(overall_score_lesion_crf, 'voe')))
        logging.info("RVD " + str(get_average_score(overall_score_lesion_crf, 'rvd', mode='abs')))
        #logging.info("ASSD " + str(get_average_score(overall_score_lesion_crf, 'assd')))
       # logging.info("MSD " + str(get_average_score(overall_score_lesion_crf, 'msd')))
        logging.info("=========================================")

        # Creating CSV


        csvarray = np.zeros((len(overall_score_liver), 13))
        csvarray[:, 0] = range(1, len(overall_score_liver) + 1)

        # csvarray[:,1] = [s['dice'] for s in overall_score_liver]

        d = overall_score_liver.iteritems()
        for i in range(6):
            d.next()[1]
            csvarray[:, i + 1] = d.next()[1]

        d = overall_score_lesion.iteritems()
        for i in range(6):
            d.next()[1]
            csvarray[:, i + 1 + 6] = d.next()[1]

        np.savetxt("Numbers.csv", csvarray, delimiter=",")


    except:
        logging.exception("Exception happend...")
        IPython.embed()
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值