def get_lung_mask(f, use_sitk=False): if use_sitk: series_IDs = sitk.ImageSeriesReader.GetGDCMSeriesIDs(f) sorted_file_names = sitk.ImageSeriesReader.GetGDCMSeriesFileNames( f, series_IDs[0]) series_reader = sitk.ImageSeriesReader() series_reader.SetFileNames(sorted_file_names) series_reader.MetaDataDictionaryArrayUpdateOn() series_reader.LoadPrivateTagsOn() image = series_reader.Execute() segmentation = (lungmask_mask.apply(image) > 0).astype('uint8') else: image, sorted_file_names = load_dicom_array(f) segmentation = (lungmask_mask.apply(image=None, inimg_raw=image) > 0).astype('uint8') return segmentation, sorted_file_names
def Image2Mask(path, file_name): input_image = sitk.ReadImage(path + 'dicom/' + file_name) segmentation = mask.apply(input_image) x = segmentation[0] img = sitk.GetImageFromArray(x) sitk.WriteImage(img, path + '/Mask/Mask-' + file_name)
def main(): parser = argparse.ArgumentParser() parser.add_argument( 'input', metavar='input', type=path, help='Path to the input image, can be a folder for dicoms') parser.add_argument('output', metavar='output', type=str, help='Filepath for output lungmask') parser.add_argument('--modeltype', help='Default: unet', type=str, choices=['unet', 'resunet'], default='unet') parser.add_argument('--modelname', help="spcifies the trained model, Default: R231", type=str, choices=['R231', 'LTRCLobes', 'R231CovidWeb'], default='R231') parser.add_argument( '--cpu', help= "Force using the CPU even when a GPU is available, will override batchsize to 1", action='store_true') parser.add_argument( '--nopostprocess', help= "Deactivates postprocessing (removal of unconnected components and hole filling", action='store_true') parser.add_argument( '--batchsize', type=int, help= "Number of slices processed simultaneously. Lower number requires less memory but may be slower.", default=20) argsin = sys.argv[1:] args = parser.parse_args(argsin) batchsize = args.batchsize if args.cpu: batchsize = 1 logging.info(f'Load model') model = mask.get_model(args.modeltype, args.modelname) input_image = utils.get_input_image(args.input) logging.info(f'Infer lungmask') result = mask.apply(input_image, model, force_cpu=args.cpu, batch_size=batchsize, volume_postprocessing=not (args.nopostprocess)) result_out = sitk.GetImageFromArray(result) result_out.CopyInformation(input_image) logging.info(f'Save result to: {args.output}') sys.exit(sitk.WriteImage(result_out, args.output))
def get_lung(filename, output): reader = sitk.ImageSeriesReader() dcm_series = reader.GetGDCMSeriesFileNames(filename) reader.SetFileNames(dcm_series) img = reader.Execute() segmentation = mask.apply(img) result_out = sitk.GetImageFromArray(segmentation) output = output + '.mhd' sitk.WriteImage(result_out, output)
def get_lung_mask(f): series_IDs = sitk.ImageSeriesReader.GetGDCMSeriesIDs(f) sorted_file_names = sitk.ImageSeriesReader.GetGDCMSeriesFileNames( f, series_IDs[0]) series_reader = sitk.ImageSeriesReader() series_reader.SetFileNames(sorted_file_names) series_reader.MetaDataDictionaryArrayUpdateOn() series_reader.LoadPrivateTagsOn() image = series_reader.Execute() segmentation = (lungmask_mask.apply(image) > 0).astype('uint8') return segmentation, sorted_file_names
def segment_lung(mask, model, volume_path): # model = mask.get_model('unet','R231CovidWeb') #loop through all dcm files lstFilesDCM = [] # create an empty list for dirName, subdirList, fileList in os.walk(volume_path): for filename in fileList: if ".dcm" in filename.lower(): # check whether the file's DICOM lstFilesDCM.append(os.path.join(dirName, filename)) dataset = pydicom.dcmread(lstFilesDCM[0]) # a sample image slice_numbers = len(lstFilesDCM) #number of slices # print('Slices:',slice_numbers) if 'PixelData' in dataset: rows = int(dataset.Rows) cols = int(dataset.Columns) # print('Image size:',rows,cols) slice_z_locations = [] for filenameDCM in lstFilesDCM: ds = pydicom.dcmread(filenameDCM) slice_z_locations.append(ds.get('SliceLocation')) #sorting slices based on z locations slice_locations = list(zip(lstFilesDCM, slice_z_locations)) sorted_slice_locations = sorted(slice_locations, key=lambda x: x[1])[-1::-1] # Saving Slices in a numpy array ArrayDicom = np.zeros((slice_numbers, rows, cols)) lung_mask = np.uint8(np.zeros((slice_numbers, rows, cols))) # loop through all the DICOM files i = 0 for filenameDCM, z_location in sorted_slice_locations: # read the file ds = sitk.ReadImage(filenameDCM) segmentation = mask.apply(ds, model) lung_mask[i, :, :] = np.uint8(((segmentation > 0) * 1)[0]) ArrayDicom[i, :, :] = sitk.GetArrayFromImage(ds) i = i + 1 lungs = np.zeros((ArrayDicom.shape[0], 256, 256, 1)) # resizing the data for i in range(ArrayDicom.shape[0]): ct = normalize_image(ArrayDicom[i, :, :]) mask_l = lung_mask[i, :, :] seg = mask_l * ct #apply mask on the image img = cv2.resize(seg, (256, 256)) img = normalize_image(img) lungs[i, :, :, :] = np.expand_dims(img, axis=-1) # print('Successfully segmented.') return lung_mask, ArrayDicom, lungs
def crop(self,imagepath,labelpath=None): input_image = sitk.ReadImage(imagepath) image_array = sitk.GetArrayFromImage(input_image) try: segmentation = mask.apply(input_image, model = None, force_cpu=False,batch_size=3) except: print(imagepath) labels = measure.label(segmentation) if labels.max()>2: props = measure.regionprops(labels) for i in range(len(props)): if props[i].area/512/512/segmentation.shape[0]<0.001: labels[labels==props[i].label] =0 labels[labels>0]=1 props = measure.regionprops(labels) xmin,ymin,zmin,xmax,ymax,zmax = props[0].bbox image_array = image_array[xmin:xmax,ymin:ymax,zmin:zmax] segmentation = labels[xmin:xmax,ymin:ymax,zmin:zmax] x,y,z = image_array.shape image_array = zoom(image_array,(40/x,160/y,160/z),order=1) # normalization image_array = image_array+1250 image_array[image_array<0]=0 image_array[image_array>1500]=1500 image_array = image_array/1500*255 segmentation = zoom(segmentation,(40/x,160/y,160/z),order=0) segmentation = segmentation.astype('uint8') image_image = sitk.GetImageFromArray(image_array) seg_image = sitk.GetImageFromArray(segmentation) if labelpath is not None: label_image = sitk.ReadImage(labelpath) label_array = sitk.GetArrayFromImage(label_image) label_seg = label_array[xmin:xmax,ymin:ymax,zmin:zmax] x,y,z = label_seg.shape label_seg = zoom(label_seg,(40/x,160/y,160/z),order=0) label_image = sitk.GetImageFromArray(label_seg.astype('uint8')) return image_image,seg_image,label_image return image_image,seg_image
def main(): args = parse_args() DATADIR = '../../data/train/' df = pd.read_csv(osp.join(DATADIR, 'train_kfold.csv')) dicom_folders = list((DATADIR + '/' + df.StudyInstanceUID + '/' + df.SeriesInstanceUID).unique())[args.start:args.end] dset = Lungs(dicom_folders) loader = DataLoader(dset, batch_size=1, shuffle=False, num_workers=args.num_workers, collate_fn=lambda x: x) pct_lung_in_slice = [] for data in tqdm(loader, total=len(loader)): data = data[0] if type(data) == type(None): continue try: image, file_names = data mask = (lungmask_mask.apply(image=None, inimg_raw=image) > 0).astype('uint8') lung_slice_indices = np.mean(mask, axis=(1, 2)) pct_lung_df = pd.DataFrame({ 'filepath': ['/'.join(_.split('/')[-3:]) for _ in file_names], 'pct_lung': lung_slice_indices }) pct_lung_in_slice += [pct_lung_df] except Exception as e: print(e) pct_lung_in_slice = pd.concat(pct_lung_in_slice) pct_lung_in_slice['StudyInstanceUID'] = pct_lung_in_slice.filepath.apply( lambda x: x.split('/')[-3]) pct_lung_in_slice['SeriesInstanceUID'] = pct_lung_in_slice.filepath.apply( lambda x: x.split('/')[-2]) pct_lung_in_slice['SOPInstanceUID'] = pct_lung_in_slice.filepath.apply( lambda x: x.split('/')[-1].replace('.dcm', '')) pct_lung_in_slice.to_csv(osp.join(DATADIR, args.save_file), index=False)
def do_prediction(input_image, force_cpu): # Run segmentation print("Running segmentation...") segmentation = mask.apply(input_image, force_cpu=force_cpu) # free memory torch.cuda.empty_cache() # Convert to itk image # isVector=True to get a 2D vector image instead of 3D image out_img = sitk.GetImageFromArray(segmentation) spacing = input_image.GetSpacing() direction = input_image.GetDirection() origin = input_image.GetOrigin() out_img.SetSpacing(spacing) out_img.SetDirection(direction) out_img.SetOrigin(origin) # Write output print("Writing output...") sitk.WriteImage(out_img, "lung_segmentation.nrrd") return segmentation
# -------------- Test example ----------------- # input_image = sitk.ReadImage("/data/UM/COVID/Kaggle_Mosmed/studies/study_0001.nii") # segmentation = mask.apply(input_image) # default model is U-net(R231) # viz_obj = MedicalImageVisualizer(disp_images=False, output_folder="/home/olmozavala/Dropbox/MyProjects/UM/Covid19_Prognosis/COVID_DL_Segmentation/LungSegmentationSoftware/OUTPUT") # viz_obj.plot_img_and_ctrs_np(sitk.GetArrayFromImage(input_image), [segmentation], # title="Test Lung seg") # Visualizing Mosmed data data_folder = "/data/UM/COVID/Kaggle_Mosmed" output_folder = "/data/UM/COVID/Kaggle_Mosmed/lung_masks" viz_obj = MedicalImageVisualizer(output_folder=join(data_folder, "output_imgs"), disp_images=False) mask_files = os.listdir(join(data_folder, "masks")) mask_files.sort() for c_mask_file_name in mask_files: c_case = int(c_mask_file_name.split("_")[1]) c_img_file_name = F"study_0{c_case:03d}.nii" c_img_file = join(data_folder, "studies", c_img_file_name) print(F"--- Working with {c_img_file} ---") itk_img = sitk.ReadImage(c_img_file) np_lung_mask = mask.apply(itk_img) # default model is U-net(R231) itk_lung_mask = copyItkImage(itk_img, np_lung_mask) viz_obj.plot_img_and_ctrs_itk(itk_img, [itk_lung_mask], title=c_img_file_name, draw_only_ctrs=True, file_name_prefix=c_img_file_name) save_image(itk_lung_mask, output_folder, c_mask_file_name)
def main(): parser = argparse.ArgumentParser() parser.add_argument('input', metavar='input', help='filepath for input folder') parser.add_argument('output', metavar='output', help='filepath for output folder') parser.add_argument('--save-overlap', dest='overlap', action='store_true', help='save folder with overlapped images') parser.add_argument('--save-mask', dest='mask', action='store_true', help="save folder with mask images") parser.add_argument('--save-images', dest='images', action='store_true', help="save folder with converted png images") parser.add_argument( '--color', metavar='color', help= "result segmented color map (gray, bone, cool, copper, flag, hot, jet, pink, prism, spring, summer, winter)" ) parser.add_argument( '--model', metavar='model', help= "model used to segment image (R231, LTRCLobes, LTRCLobes_R231, R231CovidWeb)" ) parser.set_defaults(overlap=False, color='bone') args = parser.parse_args() input_folder = args.input.rstrip('/') output_folder = create_output_folders(args) files = sorted(glob.glob('{}/*'.format(input_folder.rstrip('/')))) time_start = time.ctime() for index, file_path in enumerate(files): print('Processing {}/{} {}'.format(index + 1, len(files), file_path)) try: dataset = pydicom.dcmread(file_path) acquisition_time = dataset.get('AcquisitionTime', index + 1) new_filename = '{}_{}'.format(acquisition_time, file_path.split('/')[-1]) ds_shape = dataset.pixel_array.shape ds_2d = dataset.pixel_array.astype(float) ds_2d_scaled = np.uint8( (np.maximum(ds_2d, 0) / ds_2d.max()) * 255.0) if args.images: with open( '{}/{}/{}.png'.format(output_folder, I_FOLDER, new_filename), 'wb') as png_file: w = png.Writer(ds_shape[1], ds_shape[0], greyscale=True) w.write(png_file, ds_2d_scaled) input_image = sitk.ReadImage(file_path) if args.model: if args.model == 'LTRCLobes_R231': segmentations = mask.apply_fused(input_image) if args.model == 'L3Net': segmentations = get_model_segmentation(args, file_path) else: model = mask.get_model('unet', args.model) segmentations = mask.apply(input_image, model) else: segmentations = mask.apply(input_image) for s_i, segmentation in enumerate(segmentations): try: shape = segmentation.shape mask_scaled = np.uint8( np.maximum(segmentation, 0) / segmentation.max() * 255.0) mask_scaled = np.uint8(np.where(mask_scaled > 0, 255, 0)) if args.mask: with open( '{}/{}/{}/{}.png'.format( output_folder, s_i + 1, M_FOLDER, new_filename), 'wb') as png_file: w = png.Writer(shape[1], shape[0], greyscale=True) w.write(png_file, mask_scaled) if args.overlap: image_superimposed = ds_2d_scaled image_superimposed[mask_scaled == 0] = 0 with open( '{}/{}/{}/{}.png'.format( output_folder, s_i + 1, O_FOLDER, new_filename), 'wb') as png_file: w = png.Writer(shape[1], shape[0], greyscale=True) w.write(png_file, image_superimposed) plt.imshow( make_mb_image(args, ds_2d, mask_scaled, color=COLORS[s_i])) plt.gca().set_axis_off() plt.subplots_adjust(top=1, bottom=0, right=1, left=0, hspace=0, wspace=0) plt.margins(0, 0) plt.savefig('{}/{}/{}/{}.png'.format( output_folder, s_i + 1, S_FOLDER, new_filename), transparent=True, bbox_inches='tight', pad_inches=0) plt.cla() except Exception as e: print('Error in segmentation "{}":'.format(s_i + 1)) print(e) if len(segmentations) > 1: masks = [] for s_i, segmentation in enumerate(segmentations): shape = segmentation.shape mask_scaled = np.uint8( np.maximum(segmentation, 0) / segmentation.max() * 255.0) mask_scaled = np.uint8(np.where(mask_scaled > 0, 255, 0)) masks.append(mask_scaled) plt.imshow( make_mb_image(args, ds_2d, mask_scaled, masks=masks, color=COLORS[s_i])) plt.gca().set_axis_off() plt.subplots_adjust(top=1, bottom=0, right=1, left=0, hspace=0, wspace=0) plt.margins(0, 0) plt.savefig('{}/{}/{}/{}.png'.format(output_folder, 'all', S_FOLDER, new_filename), transparent=True, bbox_inches='tight', pad_inches=0) plt.cla() except Exception as e: print('Error while processing "{}":'.format(file_path)) print(e) print('Process started at:', time_start) print('Process finished at:', time.ctime())
def lung_segmentation(img: np.ndarray) -> np.ndarray: input_image = sitk.GetImageFromArray(img) input_image.SetDirection(np.eye(3).ravel()) # TODO: input_image and the return of mask.apply must be same shape return mask.apply(input_image)
import os from metric import scores image_dir = 'path/to/your/original/images' lesion_dir = 'path/to/the/lesion/prediction/by/GASNet' save_dir = 'path/to/your/save/dir' filelist = glob.glob(image_dir) model2 = mask.get_model('unet', 'LTRCLobes') model1 = mask.get_model('unet', 'R231CovidWeb') for imagepath in filelist: if 1: imagename = imagepath.split('/')[-1] input_image = sitk.ReadImage(imagepath) image_array = sitk.GetArrayFromImage(input_image) try: segmentation = mask.apply(input_image, model=model1, batch_size=3) except: print(imagepath) import pdb pdb.set_trace() labels = measure.label(segmentation) if labels.max() > 2: props = measure.regionprops(labels) for i in range(len(props)): if props[i].area / 512 / 512 / segmentation.shape[0] < 0.001: labels[labels == props[i].label] = 0 labels[labels > 0] = 1 props = measure.regionprops(labels) xmin, ymin, zmin, xmax, ymax, zmax = props[0].bbox image_array_part = image_array[xmin:xmax, ymin:ymax, zmin:zmax] x, y, z = image_array_part.shape
def main(): parser = argparse.ArgumentParser() parser.add_argument('--in-folder', type=str, default=in_folder) parser.add_argument('--out-folder', type=str, default=out_mask_folder) parser.add_argument('--file-list-txt', type=str, default=file_list_txt) parser.add_argument('--failed-list-txt', type=str) parser.add_argument('--modeltype', help='Default: unet', type=str, choices=['unet'], default='unet') parser.add_argument( '--modelname', help="spcifies the trained model, Default: R231", type=str, choices=['R231', 'LTRCLobes', 'LTRCLobes_R231', 'R231CovidWeb'], default='R231') parser.add_argument( '--cpu', help= "Force using the CPU even when a GPU is available, will override batchsize to 1", action='store_true') parser.add_argument( '--nopostprocess', help= "Deactivates postprocessing (removal of unconnected components and hole filling", action='store_true') parser.add_argument( '--noHU', help= "For processing of images that are not encoded in hounsfield units (HU). E.g. png or jpg images from the web. Be aware, results may be substantially worse on these images", action='store_true') parser.add_argument( '--batchsize', type=int, help= "Number of slices processed simultaneously. Lower number requires less memory but may be slower.", default=20) argsin = sys.argv[1:] args = parser.parse_args(argsin) batchsize = args.batchsize if args.cpu: batchsize = 1 logging.info(f'Load model') file_list = read_file_contents_list(args.file_list_txt) failed_case_list = [] for file_idx in range(len(file_list)): file_name = file_list[file_idx] logging.info(f'Process {file_name}, {file_idx} / {len(file_list)}') try: in_nii = os.path.join(args.in_folder, file_name) out_nii_mask = os.path.join(args.out_folder, file_name) input_image = utils.get_input_image(in_nii) logging.info(f'Infer lungmask') if args.modelname == 'LTRCLobes_R231': result = mask.apply_fused( input_image, force_cpu=args.cpu, batch_size=batchsize, volume_postprocessing=not (args.nopostprocess), noHU=args.noHU) else: model = mask.get_model(args.modeltype, args.modelname) result = mask.apply( input_image, model, force_cpu=args.cpu, batch_size=batchsize, volume_postprocessing=not (args.nopostprocess), noHU=args.noHU) result_out = sitk.GetImageFromArray(result) result_out.CopyInformation(input_image) logging.info(f'Save result to: {out_nii_mask}') # sys.exit(sitk.WriteImage(result_out, out_nii_mask)) sitk.WriteImage(result_out, out_nii_mask) except: print(f'Something wrong with {file_name}') failed_case_list.append(file_name) save_file_contents_list(args.failed_list_txt, failed_case_list)
config.min_covid_pixels) for mask_file in os.listdir(config.masks): try: mask_id = re.search(r"(.+)\_(.+)\_.+", mask_file).group(2) # masks are available only for images from category CT1 study_path = os.path.join( os.path.join(config.data["CT1"], "study_{}.nii.gz".format(mask_id))) mask_nib = nib.load(os.path.join(config.masks, mask_file)) scan_nib = nib.load(study_path) scan_sitk = sitk.ReadImage(study_path) mask_nib_data = mask_nib.get_fdata().transpose(1, 0, 2) scan_nib_data = scan_nib.get_fdata().transpose(1, 0, 2) lung_mask = segmentation_mask.apply(scan_sitk, batch_size=1, noHU=False).transpose(1, 2, 0) combined_masks = np.where(mask_nib_data == 1, config.mask_values["covid_tissue"], lung_mask) scan_nib_data, resize_factor = resample(scan_nib_data, scan_nib.header["pixdim"][1:4]) combined_masks, _ = resample(combined_masks, scan_nib.header["pixdim"][1:4]) scan_nib_data = pad_volume(scan_nib_data) combined_masks = pad_volume(combined_masks) combined_masks, scan_nib_data = select_slices(combined_masks, scan_nib_data) for i, (mask, scan) in enumerate(zip(combined_masks, scan_nib_data)): with open( os.path.join(
from lungmask import mask import SimpleITK as sitk import matplotlib.pyplot as plt from img_viz.medical import MedicalImageVisualizer input_image = sitk.ReadImage("/data/UM/COVID/Kaggle_Mosmed/studies/study_0001.nii") segmentation = mask.apply(input_image) # default model is U-net(R231) # viz_obj = MedicalImageVisualizer(disp_images=False, output_folder="/home/olmozavala/Dropbox/MyProjects/UM/Covid19_Prognosis/COVID_DL_Segmentation/LungSegmentationSoftware/OUTPUT") # viz_obj.plot_img_and_ctrs_np(sitk.GetArrayFromImage(input_image), [segmentation], # title="Test Lung seg")
level=logging.INFO, force=True) apply_mask = ApplyMask(config.mask_values["non_lung_tissue"]) pad_volume = PadVolume(config.padding_shape) get_middle_lung_slice = GetMiddleSlices(n=5) resample = ResampleVolume(new_spacing=(1, 1, 8)) remove_empty_slices = RemoveEmptySlices() for key, path in config.data.items(): for f in os.listdir(path): try: sitk_img = sitk.ReadImage(os.path.join(path, f)) nib_img = nib.load(os.path.join(path, f)) img = nib_img.get_fdata().transpose(1, 0, 2) img_s = mask.apply(sitk_img, batch_size=1, noHU=False).transpose(1, 2, 0) img, resize_factor = resample(img, nib_img.header["pixdim"][1:4]) img_s, _ = resample(img_s, nib_img.header["pixdim"][1:4]) img, img_s = pad_volume(img), pad_volume(img_s) img, img_s = remove_empty_slices(img), remove_empty_slices(img_s) slices, slices_s = get_middle_lung_slice( img), get_middle_lung_slice(img_s) for i, (_slice, _slice_s) in enumerate(zip(slices, slices_s)): with open( os.path.join( config.cyclegan_data[key], f.split(".")[0] + "slice " + str(i) + ".pkl"), "wb") as handle: pickle.dump( { "data": _slice,
def __call__(self, sample): mask = lungmask.apply(sample['image'], force_cpu=self.device == 'cpu') mask = mask.transpose((1, 2, 0))[::-1, :, :] sample['mask'] = mask return sample
import os import shutil from time import time import numpy as np import SimpleITK as sitk import scipy.ndimage as ndimage import lungmask from lungmask import mask if __name__ == "__main__": input_image = sitk.ReadImage('./imagesTr/lung_016.nii.gz') segmentation = mask.apply(input_image) save_file = sitk.GetImageFromArray(segmentation) save_file.SetSpacing(input_image.GetSpacing()) save_file.SetDirection(input_image.GetDirection()) save_file.SetOrigin(input_image.GetOrigin()) sitk.WriteImage(save_file, './results/lung_016_results.nii.gz')
def get_lung_mhd(filename, output): img = sitk.ReadImage(filename) segmentation = mask.apply(img) result_out= sitk.GetImageFromArray(segmentation) output = output+'.mhd' sitk.WriteImage(result_out, output)