def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    GYRO = float(42.576 * 10**6)  # gyromagnetic ratio (in Hz.T^-1)
    gradamp = []
    bigdelta = []
    smalldelta = []
    gradamp = arguments.g
    bigdelta = arguments.b
    smalldelta = arguments.d

    # printv(arguments)
    printv('\nCheck parameters:')
    printv('  gradient amplitude ..... ' + str(gradamp) + ' mT/m')
    printv('  big delta .............. ' + str(bigdelta) + ' ms')
    printv('  small delta ............ ' + str(smalldelta) + ' ms')
    printv('  gyromagnetic ratio ..... ' + str(GYRO) + ' Hz/T')
    printv('')

    bvalue = (2 * math.pi * GYRO * gradamp * 0.001 * smalldelta *
              0.001)**2 * (bigdelta * 0.001 - smalldelta * 0.001 / 3)

    printv('b-value = ' + str(bvalue / 10**6) + ' mm^2/s\n')
    return bvalue
def main(argv=None):
    """
    Main function
    :param argv:
    :return:
    """
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    # check number of input args
    if not len(arguments.i) == len(arguments.order):
        raise Exception(
            "Number of items between flags '-i' and '-order' should be the same."
        )
    if not len(arguments.bval) == len(arguments.bvec):
        raise Exception(
            "Number of files for bval and bvec should be the same.")

    # Concatenate NIFTI files
    im_list = [Image(fname) for fname in arguments.i]
    im_concat = concat_data(im_list, dim=3, squeeze_data=False)
    im_concat.save(arguments.o)
    printv("Generated file: {}".format(arguments.o))

    # Concatenate bvals and bvecs
    bvals_concat = ''
    bvecs_concat = ['', '', '']
    i_dwi = 0  # counter for DWI files, to read in bvec/bval files
    for i_item in range(len(arguments.order)):
        if arguments.order[i_item] == 'b0':
            # count number of b=0
            n_b0 = Image(arguments.i[i_item]).dim[3]
            bval = np.array([0.0] * n_b0)
            bvec = np.array([[0.0, 0.0, 0.0]] * n_b0)
        elif arguments.order[i_item] == 'dwi':
            # read bval/bvec files
            bval, bvec = read_bvals_bvecs(arguments.bval[i_dwi],
                                          arguments.bvec[i_dwi])
            i_dwi += 1
        # Concatenate bvals
        bvals_concat += ' '.join(str(v) for v in bval)
        bvals_concat += ' '
        # Concatenate bvecs
        for i in (0, 1, 2):
            bvecs_concat[i] += ' '.join(
                str(v) for v in map(lambda n: '%.16f' % n, bvec[:, i]))
            bvecs_concat[i] += ' '
    bvecs_concat = '\n'.join(
        str(v) for v in bvecs_concat)  # transform list into lines of strings
    # Write files
    new_f = open(arguments.obval, 'w')
    new_f.write(bvals_concat)
    new_f.close()
    printv("Generated file: {}".format(arguments.obval))
    new_f = open(arguments.obvec, 'w')
    new_f.write(bvecs_concat)
    new_f.close()
    printv("Generated file: {}".format(arguments.obvec))
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    fname_in = arguments.bvec
    fname_out = arguments.o

    # get bvecs in proper orientation
    from dipy.io import read_bvals_bvecs
    bvals, bvecs = read_bvals_bvecs(None, fname_in)

    # # Transpose bvecs
    # printv('Transpose bvecs...', verbose)
    # # from numpy import transpose
    # bvecs = bvecs.transpose()

    # Write new file
    if fname_out == '':
        path_in, file_in, ext_in = extract_fname(fname_in)
        fname_out = path_in + file_in + ext_in
    fid = open(fname_out, 'w')
    for iLine in range(bvecs.shape[0]):
        fid.write(' '.join(str(i) for i in bvecs[iLine, :]) + '\n')
    fid.close()

    # display message
    printv('Created file:\n--> ' + fname_out + '\n', verbose, 'info')
def main(argv=None):
    """
    Main function
    :param fname_anat:
    :param fname_centerline:
    :param verbose:
    :return:
    """
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    fname_anat = arguments.i
    fname_centerline = arguments.s

    # load input images
    im_anat = Image(fname_anat)
    im_centerline = Image(fname_centerline)

    # flatten sagittal
    im_anat_flattened = flatten_sagittal(im_anat, im_centerline, verbose)

    # save output
    fname_out = add_suffix(fname_anat, '_flatten')
    im_anat_flattened.save(fname_out)

    display_viewer_syntax([fname_anat, fname_out])
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    fname_bval_list = arguments.i
    # Build fname_out
    if arguments.o is not None:
        fname_out = arguments.o
    else:
        path_in, file_in, ext_in = extract_fname(fname_bval_list[0])
        fname_out = path_in + 'bvals_concat' + ext_in

    # Open bval files and concatenate
    bvals_concat = ''
    # for file_i in fname_bval_list:
    #     f = open(file_i, 'r')
    #     for line in f:
    #         bvals_concat += line
    #     f.close()
    from dipy.data.fetcher import read_bvals_bvecs
    for i_fname in fname_bval_list:
        bval_i, bvec_i = read_bvals_bvecs(i_fname, None)
        bvals_concat += ' '.join(str(v) for v in bval_i)
        bvals_concat += ' '

    # Write new bval
    new_f = open(fname_out, 'w')
    new_f.write(bvals_concat)
    new_f.close()
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    fname_bvecs_list = arguments.i
    # Build fname_out
    if arguments.o is not None:
        fname_out = arguments.o
    else:
        path_in, file_in, ext_in = extract_fname(fname_bvecs_list[0])
        fname_out = path_in + 'bvecs_concat' + ext_in

    # # Open bvec files and collect values
    # nb_files = len(fname_bvecs_list)
    # bvecs_all = []
    # for i_fname in fname_bvecs_list:
    #     bvecs = []
    #     with open(i_fname) as f:
    #         for line in f:
    #             bvec_line = map(float, line.split())
    #             bvecs.append(bvec_line)
    #     bvecs_all.append(bvecs)
    #     f.close()
    # # Concatenate
    # bvecs_concat = ''
    # for i in range(0, 3):
    #     for j in range(0, nb_files):
    #         bvecs_concat += ' '.join(str(v) for v in bvecs_all[j][i])
    #         bvecs_concat += ' '
    #     bvecs_concat += '\n'
    #

    # Open bvec files and collect values
    bvecs_all = ['', '', '']
    for i_fname in fname_bvecs_list:
        from dipy.data.fetcher import read_bvals_bvecs
        bval_i, bvec_i = read_bvals_bvecs(None, i_fname)
        for i in range(0, 3):
            bvecs_all[i] += ' '.join(
                str(v) for v in map(lambda n: '%.16f' % n, bvec_i[:, i]))
            bvecs_all[i] += ' '

    # Concatenate
    bvecs_concat = '\n'.join(str(v) for v in bvecs_all)

    # Write new bvec
    new_f = open(fname_out, 'w')
    new_f.write(bvecs_concat)
    new_f.close()
예제 #7
0
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    param.fname_data = arguments.i
    arg = 0
    if arguments.f is not None:
        param.new_size = arguments.f
        param.new_size_type = 'factor'
        arg += 1
    elif arguments.mm is not None:
        param.new_size = arguments.mm
        param.new_size_type = 'mm'
        arg += 1
    elif arguments.vox is not None:
        param.new_size = arguments.vox
        param.new_size_type = 'vox'
        arg += 1
    elif arguments.ref is not None:
        param.ref = arguments.ref
        arg += 1
    else:
        printv(
            parser.error(
                'ERROR: you need to specify one of those three arguments : -f, -mm or -vox'
            ))

    if arg > 1:
        printv(
            parser.error(
                'ERROR: you need to specify ONLY one of those three arguments : -f, -mm or -vox'
            ))

    if arguments.o is not None:
        param.fname_out = arguments.o
    if arguments.x is not None:
        if len(arguments.x) == 1:
            param.interpolation = int(arguments.x)
        else:
            param.interpolation = arguments.x

    spinalcordtoolbox.resampling.resample_file(param.fname_data,
                                               param.fname_out,
                                               param.new_size,
                                               param.new_size_type,
                                               param.interpolation,
                                               param.verbose,
                                               fname_ref=param.ref)
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    # Get parser info
    di = arguments.di
    da = arguments.da
    db = arguments.db

    # Compute MSCC
    MSCC = mscc(di, da, db)

    # Display results
    printv('\nMSCC = ' + str(MSCC) + '\n', verbose, 'info')
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    param = Param()

    fname_src = arguments.i
    if arguments.o is not None:
        fname_dst = arguments.o
    else:
        fname_dst = add_suffix(fname_src, "_tsnr")

    # call main function
    tsnr = Tsnr(param=param, fmri=fname_src, out=fname_dst)
    tsnr.compute()
예제 #10
0
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    input_filename = arguments.i
    if arguments.o is not None:
        output_filename = arguments.o
    else:
        output_filename = add_suffix(input_filename, '_gmseg')

    use_tta = arguments.t
    model_name = arguments.m
    threshold = arguments.thr

    if threshold > 1.0 or threshold < 0.0:
        raise RuntimeError("Threshold should be between 0.0 and 1.0.")

    # Threshold zero means no thresholding
    if threshold == 0.0:
        threshold = None

    from spinalcordtoolbox.deepseg_gm import deepseg_gm
    deepseg_gm.check_backend()

    out_fname = deepseg_gm.segment_file(input_filename,
                                        output_filename, model_name, threshold,
                                        int(verbose), use_tta)

    path_qc = arguments.qc
    qc_dataset = arguments.qc_dataset
    qc_subject = arguments.qc_subject
    if path_qc is not None:
        generate_qc(fname_in1=input_filename,
                    fname_seg=out_fname,
                    args=sys.argv[1:],
                    path_qc=os.path.abspath(path_qc),
                    dataset=qc_dataset,
                    subject=qc_subject,
                    process='sct_deepseg_gm')

    display_viewer_syntax([input_filename, format(out_fname)],
                          colormaps=['gray', 'red'],
                          opacities=['1', '0.7'],
                          verbose=verbose)
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    fname_mtr = arguments.o

    # compute MTR
    printv('\nCompute MTR...', verbose)
    nii_mtr = compute_mtr(nii_mt1=Image(arguments.mt1),
                          nii_mt0=Image(arguments.mt0),
                          threshold_mtr=arguments.thr)

    # save MTR file
    nii_mtr.save(fname_mtr, dtype='float32')

    display_viewer_syntax([arguments.mt0, arguments.mt1, fname_mtr])
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    printv('Load data...', verbose)
    nii_mt = Image(arguments.mt)
    nii_pd = Image(arguments.pd)
    nii_t1 = Image(arguments.t1)
    if arguments.b1map is None:
        nii_b1map = None
    else:
        nii_b1map = Image(arguments.b1map)

    if arguments.trmt is None:
        arguments.trmt = fetch_metadata(get_json_file_name(arguments.mt, check_exist=True), 'RepetitionTime')
    if arguments.trpd is None:
        arguments.trpd = fetch_metadata(get_json_file_name(arguments.pd, check_exist=True), 'RepetitionTime')
    if arguments.trt1 is None:
        arguments.trt1 = fetch_metadata(get_json_file_name(arguments.t1, check_exist=True), 'RepetitionTime')
    if arguments.famt is None:
        arguments.famt = fetch_metadata(get_json_file_name(arguments.mt, check_exist=True), 'FlipAngle')
    if arguments.fapd is None:
        arguments.fapd = fetch_metadata(get_json_file_name(arguments.pd, check_exist=True), 'FlipAngle')
    if arguments.fat1 is None:
        arguments.fat1 = fetch_metadata(get_json_file_name(arguments.t1, check_exist=True), 'FlipAngle')

    # compute MTsat
    nii_mtsat, nii_t1map = compute_mtsat(nii_mt, nii_pd, nii_t1,
                                         arguments.trmt, arguments.trpd, arguments.trt1,
                                         arguments.famt, arguments.fapd, arguments.fat1,
                                         nii_b1map=nii_b1map)

    # Output MTsat and T1 maps
    printv('Generate output files...', verbose)
    nii_mtsat.save(arguments.omtsat)
    nii_t1map.save(arguments.ot1map)

    display_viewer_syntax([arguments.omtsat, arguments.ot1map],
                              colormaps=['gray', 'gray'],
                              minmax=['-10,10', '0, 3'],
                              opacities=['1', '1'],
                              verbose=verbose)
예제 #13
0
def main(argv=None):
    """
    Main function
    :param args:
    :return:
    """
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    # Building the command, do sanity checks
    fname_in = arguments.i
    fname_out = arguments.o
    squeeze_data = bool(arguments.squeeze)

    # convert file
    img = image.Image(fname_in)
    img = image.convert(img, squeeze_data=squeeze_data)
    img.save(fname_out, mutable=True, verbose=verbose)
예제 #14
0
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    # initialization
    file_mask = ''
    fname_in = arguments.i
    fname_bvals = arguments.bval
    fname_bvecs = arguments.bvec
    prefix = arguments.o
    method = arguments.method
    evecs = arguments.evecs
    if arguments.m is not None:
        file_mask = arguments.m

    # compute DTI
    if not compute_dti(fname_in, fname_bvals, fname_bvecs, prefix, method,
                       evecs, file_mask, verbose):
        printv('ERROR in compute_dti()', 1, 'error')
예제 #15
0
def main(argv=None):
    """
    Main function
    :param argv:
    :return:
    """
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    # initialize ImageCropper
    cropper = ImageCropper(Image(arguments.i))
    cropper.verbose = verbose

    # Switch across cropping methods
    if arguments.g:
        cropper.get_bbox_from_gui()
    elif arguments.m:
        cropper.get_bbox_from_mask(Image(arguments.m))
    elif arguments.ref:
        cropper.get_bbox_from_ref(Image(arguments.ref))
    else:
        cropper.get_bbox_from_minmax(
            BoundingBox(arguments.xmin, arguments.xmax,
                        arguments.ymin, arguments.ymax,
                        arguments.zmin, arguments.zmax)
        )

    # Crop image
    img_crop = cropper.crop(background=arguments.b)

    # Write cropped image to file
    if arguments.o is None:
        fname_out = add_suffix(arguments.i, '_crop')
    else:
        fname_out = arguments.o
    img_crop.save(fname_out)

    display_viewer_syntax([arguments.i, fname_out])
예제 #16
0
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    from spinalcordtoolbox.reports.qc import generate_qc
    # Build args list (for display)
    args_disp = '-i ' + arguments.i
    if arguments.d:
        args_disp += ' -d ' + arguments.d
    if arguments.s:
        args_disp += ' -s ' + arguments.s
    generate_qc(fname_in1=arguments.i,
                fname_in2=arguments.d,
                fname_seg=arguments.s,
                args=args_disp,
                path_qc=arguments.qc,
                dataset=arguments.qc_dataset,
                subject=arguments.qc_subject,
                process=arguments.p,
                fps=arguments.fps,)
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    # Default params
    param = Param()

    # Get parser info
    fname_data = arguments.i
    fname_mask = arguments.m
    fname_mask_noise = arguments.m_noise
    method = arguments.method
    file_name = arguments.o
    rayleigh_correction = arguments.rayleigh

    # Check parameters
    if method in ['diff', 'single']:
        if not fname_mask:
            raise parser.error(
                f"Argument '-m' must be specified when using '-method {method}'."
            )

    # Load data
    im_data = Image(fname_data)
    data = im_data.data
    dim = len(data.shape)
    nz = data.shape[2]
    if fname_mask:
        mask = Image(fname_mask).data

    # Check dimensionality
    if method in ['diff', 'mult']:
        if dim != 4:
            raise ValueError(
                f"Input data dimension: {dim}. Input dimension for this method should be 4."
            )
    if method in ['single']:
        if dim not in [3, 4]:
            raise ValueError(
                f"Input data dimension: {dim}. Input dimension for this method should be 3 or 4."
            )

    # Check dimensionality of mask
    if fname_mask:
        if len(mask.shape) != 3:
            raise ValueError(
                f"Mask should be a 3D image, but the input mask has shape '{mask.shape}'."
            )

    # Retrieve selected volumes
    index_vol = parse_num_list(arguments.vol)
    if not index_vol:
        if method == 'mult':
            index_vol = range(data.shape[3])
        elif method == 'diff':
            index_vol = [0, 1]
        elif method == 'single':
            index_vol = [0]

    # Compute SNR
    # NB: "time" is assumed to be the 4th dimension of the variable "data"
    if method == 'mult':
        # Compute mean and STD across time
        data_mean = np.mean(data[:, :, :, index_vol], axis=3)
        data_std = np.std(data[:, :, :, index_vol], axis=3, ddof=1)
        # Generate mask where std is different from 0
        mask_std_nonzero = np.where(data_std > param.almost_zero)
        snr_map = np.zeros_like(data_mean)
        snr_map[mask_std_nonzero] = data_mean[mask_std_nonzero] / data_std[
            mask_std_nonzero]
        # Output SNR map
        fname_snr = add_suffix(fname_data, '_SNR-' + method)
        im_snr = empty_like(im_data)
        im_snr.data = snr_map
        im_snr.save(fname_snr, dtype=np.float32)
        # Output non-zero mask
        fname_stdnonzero = add_suffix(fname_data, '_mask-STD-nonzero' + method)
        im_stdnonzero = empty_like(im_data)
        data_stdnonzero = np.zeros_like(data_mean)
        data_stdnonzero[mask_std_nonzero] = 1
        im_stdnonzero.data = data_stdnonzero
        im_stdnonzero.save(fname_stdnonzero, dtype=np.float32)
        # Compute SNR in ROI
        if fname_mask:
            snr_roi = np.average(snr_map[mask_std_nonzero],
                                 weights=mask[mask_std_nonzero])

    elif method == 'diff':
        # Check user selected exactly 2 volumes for this method.
        if not len(index_vol) == 2:
            raise ValueError(
                f"Number of selected volumes: {len(index_vol)}. The method 'diff' should be used with "
                f"exactly 2 volumes. You can specify the number of volumes with the flag '-vol'."
            )
        data_2vol = np.take(data, index_vol, axis=3)
        # Compute mean across the two volumes
        data_mean = np.mean(data_2vol, axis=3)
        # Compute mean in ROI for each z-slice, if the slice in the mask is not null
        mean_in_roi = [
            np.average(data_mean[..., iz], weights=mask[..., iz])
            for iz in range(nz) if np.any(mask[..., iz])
        ]
        data_sub = np.subtract(data_2vol[:, :, :, 1], data_2vol[:, :, :, 0])
        # Compute STD in the ROI for each z-slice. The "np.sqrt(2)" results from the variance of the subtraction of two
        # distributions: var(A-B) = var(A) + var(B).
        # More context in: https://github.com/spinalcordtoolbox/spinalcordtoolbox/issues/3481
        std_in_roi = [
            weighted_std(data_sub[..., iz] / np.sqrt(2), weights=mask[..., iz])
            for iz in range(nz) if np.any(mask[..., iz])
        ]
        # Compute SNR
        snr_roi_slicewise = [m / s for m, s in zip(mean_in_roi, std_in_roi)]
        snr_roi = sum(snr_roi_slicewise) / len(snr_roi_slicewise)

    elif method == 'single':
        # Check that the input volume is 3D, or if it is 4D, that the user selected exactly 1 volume for this method.
        if dim == 3:
            data3d = data
        elif dim == 4:
            if not len(index_vol) == 1:
                raise ValueError(
                    f"Selected volumes: {index_vol}. The method 'single' should be used with "
                    f"exactly 1 volume. You can specify the index of the volume with the flag '-vol'."
                )
            data3d = np.squeeze(data[..., index_vol])
        # Check that input noise mask is provided
        if fname_mask_noise:
            mask_noise = Image(fname_mask_noise).data
        else:
            raise parser.error(
                "A noise mask is mandatory with '-method single'.")
        # Check dimensionality of the noise mask
        if len(mask_noise.shape) != 3:
            raise ValueError(
                f"Input noise mask dimension: {dim}. Input dimension for the noise mask should be 3."
            )
        # Check that non-null slices are consistent between mask and mask_noise.
        for iz in range(nz):
            if not np.any(mask[..., iz]) == np.any(mask_noise[..., iz]):
                raise ValueError(
                    f"Slice {iz} is empty in either mask or mask_noise. Non-null slices should be "
                    f"consistent between mask and mask_noise.")
        # Compute mean in ROI for each z-slice, if the slice in the mask is not null
        mean_in_roi = [
            np.average(data3d[..., iz], weights=mask[..., iz])
            for iz in range(nz) if np.any(mask[..., iz])
        ]
        std_in_roi = [
            weighted_std(data3d[..., iz], weights=mask_noise[..., iz])
            for iz in range(nz) if np.any(mask_noise[..., iz])
        ]
        # Compute SNR
        snr_roi_slicewise = [m / s for m, s in zip(mean_in_roi, std_in_roi)]
        snr_roi = sum(snr_roi_slicewise) / len(snr_roi_slicewise)
        if rayleigh_correction:
            # Correcting for Rayleigh noise (see eq. A12 in Dietrich et al.)
            snr_roi *= np.sqrt((4 - np.pi) / 2)

    # Display result
    if fname_mask:
        printv('\nSNR_' + method + ' = ' + str(snr_roi) + '\n', type='info')

    # Added function for text file
    if file_name is not None:
        with open(file_name, "w") as f:
            f.write(str(snr_roi))
            printv('\nFile saved to ' + file_name)
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    parameter = arguments.p
    remove_temp_files = arguments.r
    noise_threshold = arguments.d

    file_to_denoise = arguments.i
    output_file_name = arguments.o
    std_noise = arguments.std

    param = Param()
    param.verbose = verbose
    param.remove_temp_files = remove_temp_files
    param.parameter = parameter

    path, file, ext = extract_fname(file_to_denoise)

    img = nib.load(file_to_denoise)
    hdr_0 = img.get_header()

    data = img.get_data()
    aff = img.get_affine()

    if min(data.shape) <= 5:
        printv(
            'One of the image dimensions is <= 5 : reducing the size of the block radius.'
        )
        block_radius = min(data.shape) - 1
    else:
        block_radius = 5  # default value

    # Process for manual detecting of background
    # mask = data[:, :, :] > noise_threshold
    # data = data[:, :, :]

    if arguments.std is not None:
        sigma = std_noise
        # Application of NLM filter to the image
        printv('Applying Non-local mean filter...')
        if param.parameter == 'Rician':
            den = nlmeans(data,
                          sigma=sigma,
                          mask=None,
                          rician=True,
                          block_radius=block_radius)
        else:
            den = nlmeans(data,
                          sigma=sigma,
                          mask=None,
                          rician=False,
                          block_radius=block_radius)
    else:
        # # Process for manual detecting of background
        mask = data > noise_threshold
        sigma = np.std(data[~mask])
        # Application of NLM filter to the image
        printv('Applying Non-local mean filter...')
        if param.parameter == 'Rician':
            den = nlmeans(data,
                          sigma=sigma,
                          mask=mask,
                          rician=True,
                          block_radius=block_radius)
        else:
            den = nlmeans(data,
                          sigma=sigma,
                          mask=mask,
                          rician=False,
                          block_radius=block_radius)

    t = time()
    printv("total time: %s" % (time() - t))
    printv("vol size", den.shape)

    axial_middle = int(data.shape[2] / 2)

    before = data[:, :, axial_middle].T
    after = den[:, :, axial_middle].T

    diff_3d = np.absolute(den.astype('f8') - data.astype('f8'))
    difference = np.absolute(after.astype('f8') - before.astype('f8'))
    if arguments.std is None:
        difference[~mask[:, :, axial_middle].T] = 0

    if param.verbose == 2:
        import matplotlib.pyplot as plt
        fig, ax = plt.subplots(1, 3)
        ax[0].imshow(before, cmap='gray', origin='lower')
        ax[0].set_title('before')
        ax[1].imshow(after, cmap='gray', origin='lower')
        ax[1].set_title('after')
        ax[2].imshow(difference, cmap='gray', origin='lower')
        ax[2].set_title('difference')
        for i in range(3):
            ax[i].set_axis_off()

        plt.show()

    # Save files
    img_denoise = nib.Nifti1Image(den, None, hdr_0)
    img_diff = nib.Nifti1Image(diff_3d, None, hdr_0)
    if output_file_name is not None:
        output_file_name = output_file_name
    else:
        output_file_name = file + '_denoised' + ext
    nib.save(img_denoise, output_file_name)
    nib.save(img_diff, file + '_difference' + ext)

    printv('\nDone! To view results, type:', param.verbose)
    printv('fsleyes ' + file_to_denoise + ' ' + output_file_name + ' & \n',
           param.verbose, 'info')
예제 #19
0
#!/usr/bin/env python
# -*- coding: utf-8
# pytest unit tests for spinalcordtoolbox.qmri

import numpy as np
import nibabel
import pytest

from spinalcordtoolbox.qmri import mt
from spinalcordtoolbox.image import Image
from spinalcordtoolbox.utils import init_sct, set_loglevel

# Set logger to "DEBUG"
init_sct()
set_loglevel(verbose=2)


def make_sct_image(data):
    """
    :return: an Image (3D) in RAS+ (aka SCT LPI) space
    data: scalar
    """
    affine = np.eye(4)
    nii = nibabel.nifti1.Nifti1Image(np.array([data, data]), affine)
    img = Image(nii.get_data(),
                hdr=nii.header,
                orientation="LPI",
                dim=nii.header.get_data_shape())
    return img

def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    fname_bvecs = arguments.bvec
    fname_bvals = arguments.bval
    # Read bvals and bvecs files (if arguments.bval is not passed, bvals will be None)
    bvals, bvecs = read_bvals_bvecs(fname_bvals, fname_bvecs)
    # if first dimension is not equal to 3 (x,y,z), transpose bvecs file
    if bvecs.shape[0] != 3:
        bvecs = bvecs.transpose()
    # if bvals file was not passed, create dummy unit bvals array (necessary fot scatter plots)
    if bvals is None:
        bvals = np.repeat(1, bvecs.shape[1])
    # multiply unit b-vectors by b-values
    x, y, z = bvecs[0] * bvals, bvecs[1] * bvals, bvecs[2] * bvals

    # Set different color for each shell (bval)
    shell_colors = {}
    # Create iterator with different colors from brg palette
    colors = iter(cm.nipy_spectral(np.linspace(0, 1, len(np.unique(bvals)))))
    for unique_bval in np.unique(bvals):
        # skip b=0
        if unique_bval < BZERO_THRESH:
            continue
        shell_colors[unique_bval] = next(colors)

    # Get total number of directions
    n_dir = len(x)

    # Get effective number of directions
    bvecs_eff = []
    n_b0 = 0
    for i in range(0, n_dir):
        add_direction = True
        # check if b=0
        if abs(x[i]) < BZERO_THRESH and abs(x[i]) < BZERO_THRESH and abs(
                x[i]) < BZERO_THRESH:
            n_b0 += 1
            add_direction = False
        else:
            # loop across bvecs_eff
            for j in range(0, len(bvecs_eff)):
                # if bvalue already present, then do not add to bvecs_eff
                if bvecs_eff[j] == [x[i], y[i], z[i]]:
                    add_direction = False
        if add_direction:
            bvecs_eff.append([x[i], y[i], z[i]])
    n_dir_eff = len(bvecs_eff)

    # Display scatter plot
    fig = plt.figure(facecolor='white', figsize=(9, 8))
    fig.suptitle('Number of b=0: ' + str(n_b0) + ', Number of b!=0: ' +
                 str(n_dir - n_b0) +
                 ', Number of effective directions (without duplicates): ' +
                 str(n_dir_eff))

    # Display three views
    plot_2dscatter(fig_handle=fig,
                   subplot=221,
                   x=x,
                   y=y,
                   xlabel='X',
                   ylabel='Y',
                   bvals=bvals,
                   colors=shell_colors)
    plot_2dscatter(fig_handle=fig,
                   subplot=222,
                   x=x,
                   y=z,
                   xlabel='X',
                   ylabel='Z',
                   bvals=bvals,
                   colors=shell_colors)
    plot_2dscatter(fig_handle=fig,
                   subplot=223,
                   x=y,
                   y=z,
                   xlabel='Y',
                   ylabel='Z',
                   bvals=bvals,
                   colors=shell_colors)

    # 3D
    ax = fig.add_subplot(224, projection='3d')
    # ax.auto_scale_xyz([-1, 1], [-1, 1], [-1, 1])
    for i in range(0, n_dir):
        # x, y, z = bvecs[0], bvecs[1], bvecs[2]
        # if b=0, do not plot
        if not (abs(x[i]) < BZERO_THRESH and abs(x[i]) < BZERO_THRESH
                and abs(x[i]) < BZERO_THRESH):
            ax.scatter(x[i],
                       y[i],
                       z[i],
                       color=shell_colors[bvals[i]],
                       alpha=0.7)
    ax.set_xlim3d(-max(bvals), max(bvals))
    ax.set_ylim3d(-max(bvals), max(bvals))
    ax.set_zlim3d(-max(bvals), max(bvals))
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    plt.title('3D view (use mouse to rotate)')
    plt.axis('on')
    # plt.draw()

    plt.tight_layout()
    # add legend with b-values if bvals file was passed
    if arguments.bval is not None:
        create_custom_legend(fig, shell_colors, bvals)

    # Save image
    printv("Saving figure: bvecs.png\n")
    plt.savefig('bvecs.png')
예제 #21
0
def main(argv: Sequence[str]):
    """
    Main function. When this script is run via CLI, the main function is called using main(sys.argv[1:]).

    :param argv: A list of unparsed arguments, which is passed to ArgumentParser.parse_args()
    """
    for i, arg in enumerate(argv):
        if arg == '-create-seg' and len(argv) > i + 1 and '-1,' in argv[i + 1]:
            raise DeprecationWarning(
                "The use of '-1' for '-create-seg' has been deprecated. Please use "
                "'-create-seg-mid' instead.")

    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    input_filename = arguments.i
    output_fname = arguments.o

    img = Image(input_filename)
    dtype = None

    if arguments.add is not None:
        value = arguments.add
        out = sct_labels.add(img, value)
    elif arguments.create is not None:
        labels = arguments.create
        out = sct_labels.create_labels_empty(img, labels)
    elif arguments.create_add is not None:
        labels = arguments.create_add
        out = sct_labels.create_labels(img, labels)
    elif arguments.create_seg is not None:
        labels = arguments.create_seg
        out = sct_labels.create_labels_along_segmentation(img, labels)
    elif arguments.create_seg_mid is not None:
        labels = [(-1, arguments.create_seg_mid)]
        out = sct_labels.create_labels_along_segmentation(img, labels)
    elif arguments.cubic_to_point:
        out = sct_labels.cubic_to_point(img)
    elif arguments.display:
        display_voxel(img, verbose)
        return
    elif arguments.increment:
        out = sct_labels.increment_z_inverse(img)
    elif arguments.disc is not None:
        ref = Image(arguments.disc)
        out = sct_labels.labelize_from_discs(img, ref)
    elif arguments.vert_body is not None:
        levels = arguments.vert_body
        if len(levels) == 1 and levels[0] == 0:
            levels = None  # all levels
        out = sct_labels.label_vertebrae(img, levels)
    elif arguments.vert_continuous:
        out = sct_labels.continuous_vertebral_levels(img)
        dtype = 'float32'
    elif arguments.MSE is not None:
        ref = Image(arguments.MSE)
        mse = sct_labels.compute_mean_squared_error(img, ref)
        printv(f"Computed MSE: {mse}")
        return
    elif arguments.remove_reference is not None:
        ref = Image(arguments.remove_reference)
        out = sct_labels.remove_missing_labels(img, ref)
    elif arguments.remove_sym is not None:
        # first pass use img as source
        ref = Image(arguments.remove_reference)
        out = sct_labels.remove_missing_labels(img, ref)

        # second pass use previous pass result as reference
        ref_out = sct_labels.remove_missing_labels(ref, out)
        ref_out.save(path=ref.absolutepath)
    elif arguments.remove is not None:
        labels = arguments.remove
        out = sct_labels.remove_labels_from_image(img, labels)
    elif arguments.keep is not None:
        labels = arguments.keep
        out = sct_labels.remove_other_labels_from_image(img, labels)
    elif arguments.create_viewer is not None:
        msg = "" if arguments.msg is None else f"{arguments.msg}\n"
        if arguments.ilabel is not None:
            input_labels_img = Image(arguments.ilabel)
            out = launch_manual_label_gui(
                img, input_labels_img, parse_num_list(arguments.create_viewer),
                msg)
        else:
            out = launch_sagittal_viewer(
                img, parse_num_list(arguments.create_viewer), msg)

    printv("Generating output files...")
    out.save(path=output_fname, dtype=dtype)
    display_viewer_syntax([input_filename, output_fname])

    if arguments.qc is not None:
        generate_qc(fname_in1=input_filename,
                    fname_seg=output_fname,
                    args=argv,
                    path_qc=os.path.abspath(arguments.qc),
                    dataset=arguments.qc_dataset,
                    subject=arguments.qc_subject,
                    process='sct_label_utils')
예제 #22
0
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    model = arguments.model
    if "," in arguments.radius:
        patch_radius = list_type(",", int)(arguments.radius)
    else:
        patch_radius = int(arguments.radius)

    file_to_denoise = arguments.i
    bval_file = arguments.b
    output_file_name = arguments.o

    path, file, ext = extract_fname(file_to_denoise)

    img = nib.load(file_to_denoise)
    bvals = np.loadtxt(bval_file)
    hdr_0 = img.get_header()
    data = img.get_data()

    printv('Applying Patch2Self Denoising...')
    den = patch2self(data,
                     bvals,
                     patch_radius=patch_radius,
                     model=model,
                     verbose=True)

    if verbose == 2:
        import matplotlib.pyplot as plt
        fig, ax = plt.subplots(1, 3)
        axial_middle = int(data.shape[2] / 2)
        middle_vol = int(data.shape[3] / 2)
        before = data[:, :, axial_middle, middle_vol].T
        ax[0].imshow(before, cmap='gray', origin='lower')
        ax[0].set_title('before')
        after = den[:, :, axial_middle, middle_vol].T
        ax[1].imshow(after, cmap='gray', origin='lower')
        ax[1].set_title('after')
        difference = np.absolute(after.astype('f8') - before.astype('f8'))
        ax[2].imshow(difference, cmap='gray', origin='lower')
        ax[2].set_title('difference')
        for i in range(3):
            ax[i].set_axis_off()
        plt.show()

    # Save files
    img_denoise = nib.Nifti1Image(den, None, hdr_0)
    diff_4d = np.absolute(den.astype('f8') - data.astype('f8'))
    img_diff = nib.Nifti1Image(diff_4d, None, hdr_0)
    if output_file_name is not None:
        output_file_name_den = output_file_name
        output_file_name_diff = add_suffix(output_file_name, "_difference")
    else:
        output_file_name_den = file + '_patch2self_denoised' + ext
        output_file_name_diff = file + '_patch2self_difference' + ext
    nib.save(img_denoise, output_file_name_den)
    nib.save(img_diff, output_file_name_diff)

    printv('\nDone! To view results, type:', verbose)
    printv('fsleyes ' + file_to_denoise + ' ' + output_file_name + ' & \n',
           verbose, 'info')