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())
Exemple #2
0
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', '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(
        '--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')
    if modelname == 'LTRCLobes_R231':
        result = mask.apply_fused('LTRCLobes', 'R231')
    else:
        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))
Exemple #3
0
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)