def maskImage(upsampled_tra, cor, sag, GT): res_cor = utils.resampleToReference(cor, upsampled_tra, sitk.sitkLinear, defaultValue=-1) res_sag = utils.resampleToReference(sag, upsampled_tra, sitk.sitkLinear, defaultValue=-1) mask_cor = sitk.BinaryThreshold(res_cor, -1, 0.01, 1, 0) mask_sag = sitk.BinaryThreshold(res_sag, -1, 0.01, 1, 0) # mask images tra = sitk.Multiply(upsampled_tra, mask_cor) tra = sitk.Multiply(tra, mask_sag) cor = sitk.Multiply(res_cor, mask_sag) sag = sitk.Multiply(res_sag, mask_cor) GT = sitk.Multiply(GT, mask_cor) GT = sitk.Multiply(GT, mask_sag) return tra, cor, sag, GT
def getCroppedIsotropicImgs(outputDirectory, *imgs): img_tra = imgs[0] img_cor = imgs[1] img_sag = imgs[2] # normalize intensities print('... normalize intensities ...') img_tra, img_cor, img_sag = utils.normalizeIntensitiesPercentile( img_tra, img_cor, img_sag) # get intersecting region (bounding box) print('... get intersecting region (ROI) ...') # upsample transversal image to isotropic voxel size (isotropic transversal image coordinate system is used as reference coordinate system) tra_HR = utils.resampleImage(img_tra, [0.5, 0.5, 0.5], sitk.sitkLinear, 0) tra_HR = utils.sizeCorrectionImage(tra_HR, factor=6, imgSize=168) # resample coronal and sagittal to tra_HR space # resample coronal to tra_HR and obtain mask (voxels that are defined in coronal image ) cor_toTraHR = utils.resampleToReference(img_cor, tra_HR, sitk.sitkLinear, -1) cor_mask = utils.binaryThresholdImage(cor_toTraHR, 0) tra_HR_Float = utils.castImage(tra_HR, sitk.sitkFloat32) cor_mask_Float = utils.castImage(cor_mask, sitk.sitkFloat32) # mask transversal volume (set voxels, that are defined only in transversal image but not in coronal image, to 0) coronal_masked_traHR = sitk.Multiply(tra_HR_Float, cor_mask_Float) # resample sagittal to tra_HR and obtain mask (voxels that are defined in sagittal image ) sag_toTraHR = utils.resampleToReference(img_sag, tra_HR, sitk.sitkLinear, -1) sag_mask = utils.binaryThresholdImage(sag_toTraHR, 0) # mask sagittal volume sag_mask_Float = utils.castImage(sag_mask, sitk.sitkFloat32) # masked image contains voxels, that are defined in tra, cor and sag images maskedImg = sitk.Multiply(sag_mask_Float, coronal_masked_traHR) boundingBox = utils.getBoundingBox(maskedImg) # correct the size and start position of the bounding box according to new size start, size = sizeCorrectionBoundingBox(boundingBox, newSize=168, factor=6) start[2] = 0 size[2] = tra_HR.GetSize()[2] # resample cor and sag to isotropic transversal image space cor_traHR = utils.resampleToReference(img_cor, tra_HR, sitk.sitkLinear, -1) sag_traHR = utils.resampleToReference(img_sag, tra_HR, sitk.sitkLinear, -1) ## extract bounding box for all planes region_tra = sitk.RegionOfInterest(tra_HR, [size[0], size[1], size[2]], [start[0], start[1], start[2]]) maxVal = utils.getMaximumValue(region_tra) region_tra = utils.thresholdImage(region_tra, 0, maxVal, 0) region_cor = sitk.RegionOfInterest(cor_traHR, [size[0], size[1], size[2]], [start[0], start[1], start[2]]) maxVal = utils.getMaximumValue(region_cor) region_cor = utils.thresholdImage(region_cor, 0, maxVal, 0) region_sag = sitk.RegionOfInterest(sag_traHR, [size[0], size[1], size[2]], [start[0], start[1], start[2]]) maxVal = utils.getMaximumValue(region_sag) region_sag = utils.thresholdImage(region_sag, 0, maxVal, 0) # save cropped images to output directory # if not os.path.exists(outputDirectory+ '/ROI/'): # os.makedirs(outputDirectory+ '/ROI/') # # sitk.WriteImage(region_tra, outputDirectory + '/ROI/'+ 'croppedIsotropic_tra.nrrd') # sitk.WriteImage(region_cor, outputDirectory + '/ROI/'+ 'croppedIsotropic_cor.nrrd') # sitk.WriteImage(region_sag, outputDirectory + '/ROI/'+ 'croppedIsotropic_sag.nrrd') return region_tra, region_cor, region_sag, start, size
def segment(inputDirectory, outputDirectory, multistream=True): # load images files = os.listdir(inputDirectory) for file in files: if 'tra' in file: img_tra = sitk.ReadImage(inputDirectory + '/' + file) if 'cor' in file: img_cor = sitk.ReadImage(inputDirectory + '/' + file) if 'sag' in file: img_sag = sitk.ReadImage(inputDirectory + '/' + file) # make directory of the output if not os.path.exists(outputDirectory): os.makedirs(outputDirectory) # save original and upsampled version of transversal image img_tra_original = img_tra img_tra_HR = utils.resampleImage(img_tra, [0.5, 0.5, 0.5], sitk.sitkLinear, 0) img_tra_HR = utils.sizeCorrectionImage(img_tra_HR, 6, 168) sitk.WriteImage(img_tra_HR, outputDirectory + '/tra_HR.nrrd') # save upsampled version of coronal image cor_toTraHR = utils.resampleToReference(img_cor, img_tra_HR, sitk.sitkLinear, 0) sitk.WriteImage(cor_toTraHR, outputDirectory + '/cor_HR.nrrd') # save upsampled version of sagittal image sag_toTraHR = utils.resampleToReference(img_sag, img_tra_HR, sitk.sitkLinear, 0) sitk.WriteImage(sag_toTraHR, outputDirectory + '/sag_HR.nrrd') # preprocess and save to numpy array print('... preprocess images and save to array...') img_tra, img_cor, img_sag, startROI, sizeROI = preprocessing.getCroppedIsotropicImgs( outputDirectory, img_tra, img_cor, img_sag) input_array = preprocessing.createInputArray(multistream, img_tra, img_cor, img_sag) #TODO: delete directory with cropped images? # get net and model if multistream: weightFile = 'weights/weights_multiStream.h5' model = UNET3D.get_net_multiPlane() else: weightFile = 'weights/weights_singleStream.h5' model = UNET3D.get_net_singlePlane() #TODO: compile network here print('... load weights into model...') model.load_weights(weightFile) # predict image with CNN (either multistream or single stream) print('... predict image ...') if multistream: img_labels = model.predict([ input_array[0:1, :, :, :, 0:1], input_array[0:1, :, :, :, 1:2], input_array[0:1, :, :, :, 2:3] ], verbose=1) else: img_labels = model.predict([input_array[0:1, :, :, :, 0:1]], verbose=1) pred_img = sitk.GetImageFromArray(img_labels[0, :, :, :, 0]) pred_img = utils.binaryThresholdImage(pred_img, 0.5) pred_img = utils.getLargestConnectedComponents(pred_img) pred_img.SetSpacing(img_tra.GetSpacing()) pred_img.SetOrigin(img_tra.GetOrigin()) pred_img.SetDirection(img_tra.GetDirection()) print('... save predicted image...') # transform prediction back to original and upsampled transversal input space # upsampled transversal space output_predicted_original = sitk.Image(img_tra_HR.GetSize(), sitk.sitkUInt8) arr = sitk.GetArrayFromImage(output_predicted_original) arr[startROI[2]:startROI[2] + sizeROI[2], startROI[1]:startROI[1] + sizeROI[1], startROI[0]:startROI[0] + sizeROI[0]] = img_labels[0, :, :, :, 0] output_predicted = sitk.GetImageFromArray(arr) output_predicted.SetOrigin(img_tra_HR.GetOrigin()) output_predicted.SetDirection(img_tra_HR.GetDirection()) output_predicted.SetSpacing(img_tra_HR.GetSpacing()) sitk.WriteImage(output_predicted, outputDirectory + '/predicted_HR.nrrd') # original transversal space (high slice thickness), transform perdiction with shape-based interpolation (via distance transformation) segm_dis = sitk.SignedMaurerDistanceMap(output_predicted, insideIsPositive=True, squaredDistance=False, useImageSpacing=False) segm_dis = utils.resampleToReference(segm_dis, img_tra_original, sitk.sitkLinear, -1) #smoothed = sitk.DiscreteGaussian(gt_traHR, variance=1.0) thresholded = utils.binaryThresholdImage(segm_dis, 0) sitk.WriteImage(thresholded, outputDirectory + '/predicted_transversal_space.nrrd') K.clear_session() tf.reset_default_graph()