Exemple #1
0
def detect_c2c3(nii_im, nii_seg, contrast, nb_sag_avg=7.0, verbose=1):
    """
    Detect the posterior edge of C2-C3 disc.
    :param nii_im:
    :param nii_seg:
    :param contrast:
    :param verbose:
    :return:
    """
    # path to the pmj detector
    path_model = os.path.join(sct.__data_dir__, 'c2c3_disc_models',
                              '{}_model'.format(contrast))

    orientation_init = nii_im.orientation
    z_seg_max = np.max(np.where(nii_seg.change_orientation('PIR').data)[1])

    # Flatten sagittal
    nii_im = flatten_sagittal(nii_im, nii_seg, verbose=verbose)
    nii_seg_flat = flatten_sagittal(nii_seg, nii_seg, verbose=verbose)

    # create temporary folder with intermediate results
    sct.log.info("Creating temporary folder...")
    tmp_folder = sct.TempFolder()
    tmp_folder.chdir()

    # Extract mid-slice
    nii_im.change_orientation('PIR')
    nii_seg_flat.change_orientation('PIR')
    mid_RL = int(np.rint(nii_im.dim[2] * 1.0 / 2))
    nb_sag_avg_half = int(nb_sag_avg / 2 / nii_im.dim[6])
    midSlice = np.mean(nii_im.data[:, :, mid_RL - nb_sag_avg_half:mid_RL +
                                   nb_sag_avg_half + 1], 2)  # average 7 slices
    midSlice_seg = nii_seg_flat.data[:, :, mid_RL]
    nii_midSlice = msct_image.zeros_like(nii_im)
    nii_midSlice.data = midSlice
    nii_midSlice.save('data_midSlice.nii')

    # Run detection
    sct.printv('Run C2-C3 detector...', verbose)
    os.environ["FSLOUTPUTTYPE"] = "NIFTI_PAIR"
    cmd_detection = 'isct_spine_detect -ctype=dpdt "%s" "%s" "%s"' % \
                    (path_model, 'data_midSlice', 'data_midSlice_pred')
    sct.run(cmd_detection, verbose=0, raise_exception=False)

    pred = nib.load('data_midSlice_pred_svm.hdr').get_data()
    if verbose >= 2:
        # copy the "prediction data before post-processing" in an Image object
        nii_pred_before_postPro = nii_midSlice.copy()
        nii_pred_before_postPro.data = pred  # 2D data with orientation, mid sag slice of the original data
        nii_pred_before_postPro.save(
            "pred_midSlice_before_postPro.nii.gz")  # save it)

    # Create mask along centerline
    midSlice_mask = np.zeros(midSlice_seg.shape)
    mask_halfSize = int(np.rint(25.0 / nii_midSlice.dim[4]))
    for z in range(midSlice_mask.shape[1]):
        row = midSlice_seg[:,
                           z]  # 2D data with PI orientation, mid sag slice of the original data
        if np.any(row > 0):
            med_y = int(np.rint(np.median(np.where(row > 0))))
            midSlice_mask[
                med_y - mask_halfSize:med_y + mask_halfSize,
                z] = 1  # 2D data with PI orientation, mid sag slice of the original data
    if verbose >= 2:
        # copy the created mask in an Image object
        nii_postPro_mask = nii_midSlice.copy()
        nii_postPro_mask.data = midSlice_mask  # 2D data with PI orientation, mid sag slice of the original data
        nii_postPro_mask.save("mask_midSlice.nii.gz")  # save it

    # mask prediction
    pred[midSlice_mask == 0] = 0
    pred[:, z_seg_max:] = 0  # Mask above SC segmentation
    if verbose >= 2:
        # copy the "prediction data after post-processing" in an Image object
        nii_pred_after_postPro = nii_midSlice.copy()
        nii_pred_after_postPro.data = pred
        nii_pred_after_postPro.save(
            "pred_midSlice_after_postPro.nii.gz")  # save it

    # assign label to voxel
    nii_c2c3 = zeros_like(nii_seg_flat)  # 3D data with PIR orientaion
    if np.any(pred > 0):
        sct.printv('C2-C3 detected...', verbose)

        pred_bin = (pred > 0).astype(np.int_)
        coord_max = np.where(pred == np.max(pred))
        pa_c2c3, is_c2c3 = coord_max[0][0], coord_max[1][0]
        nii_seg.change_orientation('PIR')
        rl_c2c3 = int(
            np.rint(center_of_mass(np.array(nii_seg.data[:, is_c2c3, :]))[1]))
        nii_c2c3.data[pa_c2c3, is_c2c3, rl_c2c3] = 3
    else:
        sct.printv('C2-C3 not detected...', verbose)

    # remove temporary files
    tmp_folder.chdir_undo()
    if verbose < 2:
        sct.log.info("Remove temporary files...")
        tmp_folder.cleanup()

    nii_c2c3.change_orientation(orientation_init)
    return nii_c2c3
def detect_c2c3(nii_im, nii_seg, contrast, nb_sag_avg=7.0, verbose=1):
    """
    Detect the posterior edge of C2-C3 disc.

    :param nii_im:
    :param nii_seg:
    :param contrast:
    :param verbose:
    :return:
    """
    # path to the pmj detector
    path_model = os.path.join(sct.__data_dir__, 'c2c3_disc_models',
                              '{}_model'.format(contrast))
    # check if model exists
    if not os.path.isfile(path_model + '.yml'):
        raise FileNotFoundError(
            "The model file {} does not exist. Please download it using sct_download_data"
            .format(path_model + '.yml'))

    orientation_init = nii_im.orientation
    z_seg_max = np.max(np.where(nii_seg.change_orientation('PIR').data)[1])

    # Flatten sagittal
    nii_im = flatten_sagittal(nii_im, nii_seg, verbose=verbose)
    nii_seg_flat = flatten_sagittal(nii_seg, nii_seg, verbose=verbose)

    # create temporary folder with intermediate results
    logger.info("Creating temporary folder...")
    tmp_folder = sct.TempFolder()
    tmp_folder.chdir()

    # Extract mid-slice
    nii_im.change_orientation('PIR')
    nii_seg_flat.change_orientation('PIR')
    mid_RL = int(np.rint(nii_im.dim[2] * 1.0 / 2))
    nb_sag_avg_half = int(nb_sag_avg / 2 / nii_im.dim[6])
    midSlice = np.mean(nii_im.data[:, :, mid_RL - nb_sag_avg_half:mid_RL +
                                   nb_sag_avg_half + 1], 2)  # average 7 slices
    midSlice_seg = nii_seg_flat.data[:, :, mid_RL]
    nii_midSlice = zeros_like(nii_im)
    nii_midSlice.data = midSlice
    nii_midSlice.save('data_midSlice.nii')

    # Run detection
    logger.info('Run C2-C3 detector...')
    os.environ["FSLOUTPUTTYPE"] = "NIFTI_PAIR"
    cmd_detection = 'isct_spine_detect -ctype=dpdt "%s" "%s" "%s"' % \
                    (path_model, 'data_midSlice', 'data_midSlice_pred')
    # The command below will fail, but we don't care because it will output an image (prediction), which we
    # will use later on.
    s, o = run_proc(cmd_detection,
                    verbose=0,
                    is_sct_binary=True,
                    raise_exception=False)
    pred = nib.load('data_midSlice_pred_svm.hdr').get_data()
    if verbose >= 2:
        # copy the "prediction data before post-processing" in an Image object
        nii_pred_before_postPro = nii_midSlice.copy()
        nii_pred_before_postPro.data = pred  # 2D data with orientation, mid sag slice of the original data
        nii_pred_before_postPro.save(
            "pred_midSlice_before_postPro.nii.gz")  # save it)
    # DEBUG trick: check if the detection succeed by running: fsleyes data_midSlice data_midSlice_pred_svm -cm red -dr 0 100
    # If a "red cluster" is observed in the neighbourhood of C2C3, then the model detected it.

    # Create mask along centerline
    midSlice_mask = np.zeros(midSlice_seg.shape)
    mask_halfSize = int(np.rint(25.0 / nii_midSlice.dim[4]))
    for z in range(midSlice_mask.shape[1]):
        row = midSlice_seg[:,
                           z]  # 2D data with PI orientation, mid sag slice of the original data
        if np.any(row > 0):
            med_y = int(np.rint(np.median(np.where(row > 0))))
            midSlice_mask[
                med_y - mask_halfSize:med_y + mask_halfSize,
                z] = 1  # 2D data with PI orientation, mid sag slice of the original data
    if verbose >= 2:
        # copy the created mask in an Image object
        nii_postPro_mask = nii_midSlice.copy()
        nii_postPro_mask.data = midSlice_mask  # 2D data with PI orientation, mid sag slice of the original data
        nii_postPro_mask.save("mask_midSlice.nii.gz")  # save it

    # mask prediction
    pred[midSlice_mask == 0] = 0
    pred[:, z_seg_max:] = 0  # Mask above SC segmentation
    if verbose >= 2:
        # copy the "prediction data after post-processing" in an Image object
        nii_pred_after_postPro = nii_midSlice.copy()
        nii_pred_after_postPro.data = pred
        nii_pred_after_postPro.save(
            "pred_midSlice_after_postPro.nii.gz")  # save it

    # assign label to voxel
    nii_c2c3 = zeros_like(nii_seg_flat)  # 3D data with PIR orientaion
    if np.any(pred > 0):
        logger.info('C2-C3 detected...')

        pred_bin = (pred > 0).astype(np.int_)
        coord_max = np.where(pred == np.max(pred))
        pa_c2c3, is_c2c3 = coord_max[0][0], coord_max[1][0]
        nii_seg.change_orientation('PIR')
        rl_c2c3 = int(
            np.rint(center_of_mass(np.array(nii_seg.data[:, is_c2c3, :]))[1]))
        nii_c2c3.data[pa_c2c3, is_c2c3, rl_c2c3] = 3
    else:
        logger.warning('C2-C3 not detected...')

    # remove temporary files
    tmp_folder.chdir_undo()
    if verbose < 2:
        logger.info("Remove temporary files...")
        tmp_folder.cleanup()
    else:
        logger.info("Temporary files saved to " + tmp_folder.get_path())

    nii_c2c3.change_orientation(orientation_init)
    return nii_c2c3
def detect_c2c3(nii_im, nii_seg, contrast, verbose=1):
    """
    Detect the posterior edge of C2-C3 disc.
    :param nii_im:
    :param nii_seg:
    :param contrast:
    :param verbose:
    :return:
    """
    # path to the pmj detector
    path_sct = os.environ.get("SCT_DIR",
                              os.path.dirname(os.path.dirname(__file__)))
    path_model = os.path.join(path_sct, 'data', 'c2c3_disc_models',
                              '{}_model'.format(contrast))

    orientation_init = nii_im.orientation

    # Flatten sagittal
    nii_im = flatten_sagittal(nii_im,
                              nii_seg,
                              centerline_fitting='hanning',
                              verbose=verbose)
    nii_seg_flat = flatten_sagittal(nii_seg,
                                    nii_seg,
                                    centerline_fitting='hanning',
                                    verbose=verbose)

    # create temporary folder with intermediate results
    sct.log.info("Creating temporary folder...")
    tmp_folder = sct.TempFolder()
    tmp_folder.chdir()

    # Extract mid-slice
    nii_im.change_orientation('PIR')
    nii_seg_flat.change_orientation('PIR')
    mid_RL = int(np.rint(nii_im.dim[2] * 1.0 / 2))
    midSlice = nii_im.data[:, :, mid_RL]
    midSlice_seg = nii_seg_flat.data[:, :, mid_RL]
    nii_midSlice = msct_image.zeros_like(nii_im)
    nii_midSlice.data = midSlice
    nii_midSlice.save('data_midSlice.nii')

    # Run detection
    sct.printv('Run C2-C3 detector...', verbose)
    os.environ["FSLOUTPUTTYPE"] = "NIFTI_PAIR"
    cmd_detection = 'isct_spine_detect -ctype=dpdt "%s" "%s" "%s"' % \
                    (path_model, 'data_midSlice', 'data_midSlice_pred')
    sct.run(cmd_detection, verbose=0, raise_exception=False)

    # sct.run(cmd_detection, verbose=0)
    pred = nib.load('data_midSlice_pred_svm.hdr').get_data()

    # Create mask along centerline
    midSlice_mask = np.zeros(midSlice_seg.shape)
    mask_halfSize = 25
    for z in range(midSlice_mask.shape[1]):
        row = midSlice_seg[:, z]
        if np.any(row):
            med_y = int(np.rint(np.median(np.where(row))))
            midSlice_mask[med_y - mask_halfSize:med_y + mask_halfSize] = 1

    # mask prediction
    pred[midSlice_mask == 0] = 0

    # assign label to voxel
    nii_c2c3 = zeros_like(nii_seg_flat)
    if np.any(pred > 0):
        sct.printv('C2-C3 detected...', verbose)
        coord_max = np.where(pred == np.max(pred))
        pa_c2c3, is_c2c3 = coord_max[0][0], coord_max[1][0]
        nii_seg.change_orientation('PIR')
        rl_c2c3 = int(np.rint(center_of_mass(nii_seg.data[:, is_c2c3, :])[1]))
        nii_c2c3.data[pa_c2c3, is_c2c3, rl_c2c3] = 3
    else:
        sct.printv('C2-C3 not detected...', verbose)

    # remove temporary files
    tmp_folder.chdir_undo()
    sct.log.info("Remove temporary files...")
    tmp_folder.cleanup()

    nii_c2c3.change_orientation(orientation_init)
    return nii_c2c3
def detect_c2c3(nii_im, nii_seg, contrast, nb_sag_avg=7.0, verbose=1):
    """
    Detect the posterior edge of C2-C3 disc.
    :param nii_im:
    :param nii_seg:
    :param contrast:
    :param verbose:
    :return:
    """
    # path to the pmj detector
    path_sct = os.environ.get("SCT_DIR",
                              os.path.dirname(os.path.dirname(__file__)))
    path_model = os.path.join(path_sct, 'data', 'c2c3_disc_models',
                              '{}_model'.format(contrast))

    orientation_init = nii_im.orientation
    z_seg_max = np.max(np.where(nii_seg.change_orientation('PIR').data)[1])

    # Flatten sagittal
    nii_im = flatten_sagittal(nii_im,
                              nii_seg,
                              centerline_fitting='hanning',
                              verbose=verbose)
    nii_seg_flat = flatten_sagittal(nii_seg,
                                    nii_seg,
                                    centerline_fitting='hanning',
                                    verbose=verbose)

    # create temporary folder with intermediate results
    sct.log.info("Creating temporary folder...")
    tmp_folder = sct.TempFolder()
    # print tmp_folder.path_tmp
    tmp_folder.chdir()

    # Extract mid-slice
    nii_im.change_orientation('PIR')
    nii_seg_flat.change_orientation('PIR')
    mid_RL = int(np.rint(nii_im.dim[2] * 1.0 / 2))
    nb_sag_avg_half = int(nb_sag_avg / 2 / nii_im.dim[6])
    midSlice = np.mean(nii_im.data[:, :, mid_RL - nb_sag_avg_half:mid_RL +
                                   nb_sag_avg_half + 1], 2)  # average 7 slices
    midSlice_seg = nii_seg_flat.data[:, :, mid_RL]
    nii_midSlice = msct_image.zeros_like(nii_im)
    nii_midSlice.data = midSlice
    nii_midSlice.save('data_midSlice.nii')

    # Run detection
    sct.printv('Run C2-C3 detector...', verbose)
    os.environ["FSLOUTPUTTYPE"] = "NIFTI_PAIR"
    cmd_detection = 'isct_spine_detect -ctype=dpdt "%s" "%s" "%s"' % \
                    (path_model, 'data_midSlice', 'data_midSlice_pred')
    sct.run(cmd_detection, verbose=0, raise_exception=False)

    pred = nib.load('data_midSlice_pred_svm.hdr').get_data()

    # Create mask along centerline
    midSlice_mask = np.zeros(midSlice_seg.shape)
    mask_halfSize = int(np.rint(25.0 / nii_midSlice.dim[4]))
    for z in range(midSlice_mask.shape[1]):
        row = midSlice_seg[:, z]
        if np.any(row):
            med_y = int(np.rint(np.median(np.where(row))))
            midSlice_mask[med_y - mask_halfSize:med_y + mask_halfSize] = 1

    # mask prediction
    pred[midSlice_mask == 0] = 0
    # dist_medulla = 30.0 if contrast == 't1' else 40.0  # Observation: segmentation ends higher on t2 images than t1
    # z_seg_max -= int(np.rint(dist_medulla / nii_midSlice.dim[5])) # TODO: take into account the curvature
    pred[:, z_seg_max:] = 0  # Mask above SC segmentation

    # assign label to voxel
    nii_c2c3 = zeros_like(nii_seg_flat)
    if np.any(pred > 0):
        sct.printv('C2-C3 detected...', verbose)

        pred_bin = (pred > 0).astype(np.int_)
        # labeled_pred, nb_regions = label_regions(pred_bin, return_num=True)
        # if nb_regions > 1:  # if there are several clusters of voxels detected
        #     region_idx_top, region_z_top = 0, 0
        #     for region_idx in range(1, nb_regions+1):
        #         pred_idx = (labeled_pred == region_idx).astype(np.int_)
        #         pa_com, is_com = center_of_mass(pred_idx)
        #         if is_com >= region_z_top:
        #             region_idx_top = region_idx
        #             region_z_top = is_com
        #     pred[labeled_pred != region_idx_top] = 0  # then keep the one located at the top (IS direction)

        coord_max = np.where(pred == np.max(pred))
        pa_c2c3, is_c2c3 = coord_max[0][0], coord_max[1][0]
        nii_seg.change_orientation('PIR')
        rl_c2c3 = int(np.rint(center_of_mass(nii_seg.data[:, is_c2c3, :])[1]))
        nii_c2c3.data[pa_c2c3, is_c2c3, rl_c2c3] = 3
    else:
        sct.printv('C2-C3 not detected...', verbose)

    # remove temporary files
    tmp_folder.chdir_undo()
    sct.log.info("Remove temporary files...")
    tmp_folder.cleanup()

    nii_c2c3.change_orientation(orientation_init)
    return nii_c2c3
def detect_c2c3(nii_im, nii_seg, contrast, nb_sag_avg=7.0, verbose=1):
    """
    Detect the posterior edge of C2-C3 disc.
    :param nii_im:
    :param nii_seg:
    :param contrast:
    :param verbose:
    :return:
    """
    # path to the pmj detector
    path_model = os.path.join(sct.__data_dir__, 'c2c3_disc_models', '{}_model'.format(contrast))

    orientation_init = nii_im.orientation
    z_seg_max = np.max(np.where(nii_seg.change_orientation('PIR').data)[1])

    # Flatten sagittal
    nii_im = flatten_sagittal(nii_im, nii_seg,verbose=verbose)
    nii_seg_flat = flatten_sagittal(nii_seg, nii_seg, verbose=verbose)

    # create temporary folder with intermediate results
    logger.info("Creating temporary folder...")
    tmp_folder = sct.TempFolder()
    tmp_folder.chdir()

    # Extract mid-slice
    nii_im.change_orientation('PIR')
    nii_seg_flat.change_orientation('PIR')
    mid_RL = int(np.rint(nii_im.dim[2] * 1.0 / 2))
    nb_sag_avg_half = int(nb_sag_avg / 2 / nii_im.dim[6])
    midSlice = np.mean(nii_im.data[:, :, mid_RL-nb_sag_avg_half:mid_RL+nb_sag_avg_half+1], 2) # average 7 slices
    midSlice_seg = nii_seg_flat.data[:, :, mid_RL]
    nii_midSlice = msct_image.zeros_like(nii_im)
    nii_midSlice.data = midSlice
    nii_midSlice.save('data_midSlice.nii')

    # Run detection
    logger.info('Run C2-C3 detector...')
    os.environ["FSLOUTPUTTYPE"] = "NIFTI_PAIR"
    cmd_detection = 'isct_spine_detect -ctype=dpdt "%s" "%s" "%s"' % \
                    (path_model, 'data_midSlice', 'data_midSlice_pred')
    # The command below will fail, but we don't care because it will output an image (prediction), which we
    # will use later on.
    s, o = sct.run(cmd_detection, verbose=0, is_sct_binary=True, raise_exception=False)
    pred = nib.load('data_midSlice_pred_svm.hdr').get_data()
    if verbose >= 2:
        # copy the "prediction data before post-processing" in an Image object
        nii_pred_before_postPro = nii_midSlice.copy()
        nii_pred_before_postPro.data = pred  # 2D data with orientation, mid sag slice of the original data
        nii_pred_before_postPro.save("pred_midSlice_before_postPro.nii.gz")  # save it)

    # Create mask along centerline
    midSlice_mask = np.zeros(midSlice_seg.shape)
    mask_halfSize = int(np.rint(25.0 / nii_midSlice.dim[4]))
    for z in range(midSlice_mask.shape[1]):
        row = midSlice_seg[:, z]  # 2D data with PI orientation, mid sag slice of the original data
        if np.any(row > 0):
            med_y = int(np.rint(np.median(np.where(row > 0))))
            midSlice_mask[med_y-mask_halfSize:med_y+mask_halfSize, z] = 1  # 2D data with PI orientation, mid sag slice of the original data
    if verbose >= 2:
        # copy the created mask in an Image object
        nii_postPro_mask = nii_midSlice.copy()
        nii_postPro_mask.data = midSlice_mask  # 2D data with PI orientation, mid sag slice of the original data
        nii_postPro_mask.save("mask_midSlice.nii.gz")  # save it

    # mask prediction
    pred[midSlice_mask == 0] = 0
    pred[:, z_seg_max:] = 0  # Mask above SC segmentation
    if verbose >= 2:
        # copy the "prediction data after post-processing" in an Image object
        nii_pred_after_postPro = nii_midSlice.copy()
        nii_pred_after_postPro.data = pred
        nii_pred_after_postPro.save("pred_midSlice_after_postPro.nii.gz")  # save it

    # assign label to voxel
    nii_c2c3 = zeros_like(nii_seg_flat)  # 3D data with PIR orientaion
    if np.any(pred > 0):
        logger.info('C2-C3 detected...')

        pred_bin = (pred > 0).astype(np.int_)
        coord_max = np.where(pred == np.max(pred))
        pa_c2c3, is_c2c3 = coord_max[0][0], coord_max[1][0]
        nii_seg.change_orientation('PIR')
        rl_c2c3 = int(np.rint(center_of_mass(np.array(nii_seg.data[:, is_c2c3, :]))[1]))
        nii_c2c3.data[pa_c2c3, is_c2c3, rl_c2c3] = 3
    else:
        logger.warning('C2-C3 not detected...')

    # remove temporary files
    tmp_folder.chdir_undo()
    if verbose < 2:
        logger.info("Remove temporary files...")
        tmp_folder.cleanup()

    nii_c2c3.change_orientation(orientation_init)
    return nii_c2c3