Пример #1
0
def filter_export_landmarks(idx_row, path_output, path_dataset,
                            path_reference):
    """ filter all relevant landmarks which were used and copy them to experiment

    The case is that in certain challenge stage users had provided just a subset
     of all image landmarks which could be laos shuffled. The idea is to filter identify
     all user used (provided in dataset) landmarks and filter them from temporary
     reference dataset.

    :param tuple(idx,dict|Series) idx_row: experiment DataFrame
    :param str path_output: path to output folder
    :param str path_dataset: path to provided landmarks
    :param str path_reference: path to the complete landmark collection
    :return tuple(idx,float): record index and match ratio
    """
    idx, row = idx_row

    ratio_matches, lnds_filter_ref, lnds_filter_move = \
        filter_paired_landmarks(row, path_dataset, path_reference,
                                ImRegBenchmark.COL_POINTS_MOVE,
                                ImRegBenchmark.COL_POINTS_REF)

    # moving and reference landmarks
    for col, lnds_flt in [(ImRegBenchmark.COL_POINTS_REF, lnds_filter_ref),
                          (ImRegBenchmark.COL_POINTS_MOVE, lnds_filter_move)]:
        path_out = update_path(row[col], pre_path=path_output)
        create_folder(os.path.dirname(path_out), ok_existing=True)
        if os.path.isfile(path_out):
            assert np.array_equal(load_landmarks(path_out), lnds_flt), \
                'overwrite different set of landmarks'
        save_landmarks(path_out, lnds_flt)

    return idx, ratio_matches
Пример #2
0
    def _extract_warped_image_landmarks(self, record):
        """ get registration results - warped registered images and landmarks

        :param record: {str: value}, dictionary with registration params
        :return (str, str, str, str): paths to
        """
        logging.debug('.. warp the registered image and get landmarks')
        path_dir = self._get_path_reg_dir(record)
        _, path_img_move, _, path_lnds_move = self._get_paths(record)
        path_lnds_warp, path_img_warp = None, None

        # load warped landmarks from TXT
        path_lnds = os.path.join(path_dir, NAME_FILE_LANDMARKS)
        if os.path.isfile(path_lnds):
            points_warp = load_landmarks(path_lnds)
            path_lnds_warp = os.path.join(path_dir, os.path.basename(path_lnds_move))
            save_landmarks(path_lnds_warp, points_warp)
            os.remove(path_lnds)

        path_regist = os.path.join(path_dir, NAME_FILE_IMAGE)
        if os.path.isfile(path_regist):
            name_img_move = os.path.splitext(os.path.basename(path_img_move))[0]
            ext_img_warp = os.path.splitext(NAME_FILE_IMAGE)[-1]
            path_img_warp = os.path.join(path_dir, name_img_move + ext_img_warp)
            os.rename(path_regist, path_img_warp)

        return None, path_img_warp, None, path_lnds_warp
Пример #3
0
    def _extract_warped_image_landmarks(self, item):
        """ get registration results - warped registered images and landmarks

        :param dict item: dictionary with registration params
        :return dict: paths to warped images/landmarks
        """
        logging.debug('.. warp the registered image and get landmarks')
        path_dir = self._get_path_reg_dir(item)
        _, path_img_move, _, path_lnds_move = self._get_paths(item)
        path_lnds_warp, path_img_warp = None, None

        # load warped landmarks from TXT
        path_lnds = os.path.join(path_dir, self.NAME_FILE_LANDMARKS)
        if os.path.isfile(path_lnds):
            points_warp = load_landmarks(path_lnds)
            path_lnds_warp = os.path.join(path_dir, os.path.basename(path_lnds_move))
            save_landmarks(path_lnds_warp, points_warp)
            os.remove(path_lnds)

        path_regist = os.path.join(path_dir, self.NAME_FILE_IMAGE)
        if os.path.isfile(path_regist):
            name_img_move, _ = os.path.splitext(os.path.basename(path_img_move))
            _, ext_img_warp = os.path.splitext(self.NAME_FILE_IMAGE)
            path_img_warp = os.path.join(path_dir, name_img_move + ext_img_warp)
            os.rename(path_regist, path_img_warp)

        return {self.COL_IMAGE_MOVE_WARP: path_img_warp,
                self.COL_POINTS_MOVE_WARP: path_lnds_warp}
Пример #4
0
def filter_landmarks(idx_row, path_output, path_dataset, path_reference):
    """ filter all relevant landmarks which were used and copy them to experiment

    :param (idx, {}|Series) idx_row: experiment DataFrame
    :param str path_output: path to output folder
    :param str path_dataset: path to provided landmarks
    :param str path_reference: path to the complete landmark collection
    :return (idx, float): record index and match ratio
    """
    idx, row = idx_row
    path_ref = update_path_(row[COL_POINTS_MOVE], path_reference)
    path_load = update_path_(row[COL_POINTS_MOVE], path_dataset)
    pairs = common_landmarks(load_landmarks(path_ref),
                             load_landmarks(path_load),
                             threshold=1)
    pairs = sorted(pairs.tolist(), key=lambda p: p[1])
    ind_ref = np.asarray(pairs)[:, 0]

    # moving and reference landmarks
    for col in [COL_POINTS_REF, COL_POINTS_MOVE]:
        path_in = update_path_(row[col], path_reference)
        path_out = update_path_(row[col], path_output)
        create_folder(os.path.dirname(path_out), ok_existing=True)
        save_landmarks(path_out, load_landmarks(path_in)[ind_ref])

    # save ratio of found landmarks
    len_lnds_ref = len(
        load_landmarks(update_path_(row[COL_POINTS_REF], path_reference)))
    ratio_matches = len(pairs) / float(len_lnds_ref)
    return idx, ratio_matches
Пример #5
0
    def _extract_warped_image_landmarks(self, record):
        """ get registration results - warped registered images and landmarks

        :param record: {str: value}, dictionary with registration params
        :return (str, str, str, str): paths to
        """
        logging.debug('.. warp the registered image and get landmarks')
        path_dir = self._get_path_reg_dir(record)
        path_im_ref, path_im_move, _, path_lnds_move = self._get_paths(record)
        path_log = os.path.join(path_dir, NAME_LOG_REGISTRATION)

        # warp moving landmarks to reference frame
        path_regist = os.path.join(path_dir, os.path.basename(path_im_move))
        dict_params = {
            'path_fiji': self.params['path_fiji'],
            'path_bsh': PATH_SCRIPT_WARP_LANDMARKS,
            'source': path_im_move, 'target': path_im_ref,
            'output': path_dir, 'warp': path_regist}
        # export source points to TXT
        pts_source = load_landmarks(path_lnds_move)
        save_landmarks(os.path.join(path_dir, NAME_LANDMARKS), pts_source)
        # execute transformation
        exec_commands(COMMAND_WARP_LANDMARKS % dict_params, path_logger=path_log)
        # load warped landmarks from TXT
        path_lnds = os.path.join(path_dir, NAME_LANDMARKS_WARPED)
        if os.path.isfile(path_lnds):
            points_warp = load_landmarks(path_lnds)
            path_lnds = os.path.join(path_dir, os.path.basename(path_lnds_move))
            save_landmarks(path_lnds, points_warp)
        else:
            path_lnds = None
        return None, path_regist, None, path_lnds
Пример #6
0
    def _extract_warped_image_landmarks(self, item):
        """ get registration results - warped registered images and landmarks

        :param dict item: dictionary {str: value} with registration params
        :return dict: paths to results
        """
        path_dir = self._get_path_reg_dir(item)
        path_im_ref, path_im_move, _, path_lnds_move = self._get_paths(item)
        name_im_move, _ = os.path.splitext(os.path.basename(path_lnds_move))
        name_lnds_move, _ = os.path.splitext(os.path.basename(path_lnds_move))

        # simplified version of landmarks
        lnds = load_landmarks(path_lnds_move)
        path_lnds_warp = os.path.join(path_dir, name_lnds_move + '.csv')
        # https://github.com/ANTsX/ANTs/issues/733#issuecomment-472049427
        pd.DataFrame(lnds * -1, columns=['x', 'y']).to_csv(path_lnds_warp, index=None)

        # list output transformations
        tf_elast_inv = sorted(glob.glob(os.path.join(path_dir, 'trans*InverseWarp.nii*')))
        tf_elast = [os.path.join(os.path.dirname(p), os.path.basename(p).replace('Inverse', ''))
                    for p in tf_elast_inv]
        tf_affine = sorted(glob.glob(os.path.join(path_dir, 'trans*GenericAffine.mat')))
        # generate commands
        cmd_warp_img = self.COMMAND_WARP_IMAGE % {
            'antsApplyTransforms': self.exec_transf_img,
            'output': path_dir,
            'img_target': item[self.COL_IMAGE_REF_NII],
            'img_source': item[self.COL_IMAGE_MOVE_NII],
            'transfs': ' -t '.join(sorted(tf_affine + tf_elast, reverse=True)),
            'img_name': name_im_move
        }
        cmd_warp_pts = self.COMMAND_WARP_POINTS % {
            'antsApplyTransformsToPoints': self.exec_transf_pts,
            'output': path_dir,
            'path_points': path_lnds_warp,
            'transfs': ' -t '.join(['[ %s , 1]' % tf if 'Affine' in tf else tf
                                    for tf in sorted(tf_affine + tf_elast_inv)]),
            'pts_name': name_lnds_move
        }
        # execute commands
        exec_commands([cmd_warp_img, cmd_warp_pts],
                      path_logger=os.path.join(path_dir, 'warping.log'))

        path_im_nii = os.path.join(path_dir, name_im_move + '.nii')
        if os.path.isfile(path_im_nii):
            path_img_warp = convert_image_from_nifti(path_im_nii)
        else:
            path_img_warp = None

        if os.path.isfile(path_lnds_warp):
            lnds = pd.read_csv(path_lnds_warp, index_col=None).values
            save_landmarks(path_lnds_warp, lnds * -1)
        else:
            path_lnds_warp = None

        return {self.COL_IMAGE_MOVE_WARP: path_img_warp,
                self.COL_POINTS_MOVE_WARP: path_lnds_warp}
Пример #7
0
    def _extract_warped_image_landmarks(self, item):
        """ get registration results - warped registered images and landmarks

        :param dict item: dictionary with registration params
        :return dict: paths to warped images/landmarks
        """
        logging.debug('.. warp the registered image and get landmarks')
        path_dir = self._get_path_reg_dir(item)
        path_im_ref, path_im_move, _, path_lnds_move = self._get_paths(
            item, prefer_pproc=False)
        path_log = os.path.join(path_dir, self.NAME_LOG_REGISTRATION)

        # warp moving landmarks to reference frame
        path_dir_out = os.path.join(path_dir, self.DIR_OUTPUTS)
        # name_ref, _ = os.path.splitext(os.path.basename(path_im_ref))
        name_move, _ = os.path.splitext(os.path.basename(path_im_move))
        path_img_warp = os.path.join(path_dir, os.path.basename(path_im_move))
        dict_params = {
            'exec_Fiji': self.params['exec_Fiji'],
            'path_bsh': self.PATH_SCRIPT_WARP_LANDMARKS,
            'source': path_im_move,
            'target': path_im_ref,
            'output': path_dir,
            # 'transf': os.path.join(path_dir_out, name_ref + '.xml'),
            'transf': os.path.join(path_dir_out, name_move + '.xml'),
            'warp': path_img_warp,
        }

        # export source points to TXT
        pts_source = load_landmarks(path_lnds_move)
        save_landmarks(os.path.join(path_dir, BmUnwarpJ.NAME_LANDMARKS),
                       pts_source)
        # execute transformation
        exec_commands(self.COMMAND_WARP_LANDMARKS % dict_params,
                      path_logger=path_log,
                      timeout=self.EXECUTE_TIMEOUT)
        # load warped landmarks from TXT
        path_lnds_warp = os.path.join(path_dir,
                                      BmUnwarpJ.NAME_LANDMARKS_WARPED)
        if os.path.isfile(path_lnds_warp):
            points_warp = load_landmarks(path_lnds_warp)
            path_lnds_warp = os.path.join(path_dir,
                                          os.path.basename(path_lnds_move))
            save_landmarks(path_lnds_warp, points_warp)
        else:
            path_lnds_warp = None

        # return results
        return {
            self.COL_IMAGE_MOVE_WARP: path_img_warp,
            self.COL_POINTS_MOVE_WARP: path_lnds_warp
        }
Пример #8
0
    def _extract_warped_image_landmarks(self, item):
        """ get registration results - warped registered images and landmarks

        :param dict item: dictionary with registration params
        :return dict: paths to warped images/landmarks
        """
        path_reg_dir = self._get_path_reg_dir(item)
        _, path_im_move, path_lnds_ref, _ = self._get_paths(item)
        # convert MHD image
        path_img_ = convert_image_from_mhd(os.path.join(
            path_reg_dir, 'output.mhd'),
                                           scaling=item.get('scaling', 1.))
        img_name, _ = os.path.splitext(os.path.basename(path_im_move))
        _, img_ext = os.path.splitext(os.path.basename(path_img_))
        path_img_warp = path_img_.replace('output' + img_ext,
                                          img_name + img_ext)
        shutil.move(path_img_, path_img_warp)

        # load transform and warp landmarks
        # lnds_move = load_landmarks(path_lnds_move)
        lnds_ref = load_landmarks(path_lnds_ref)
        lnds_name = os.path.basename(path_lnds_ref)
        path_lnds_warp = os.path.join(path_reg_dir, lnds_name)
        if lnds_ref is None:
            raise ValueError('missing landmarks to be transformed "%s"' %
                             lnds_name)

        # down-scale landmarks if defined
        lnds_ref = lnds_ref / item.get('scaling', 1.)
        # extract deformation
        path_deform_x = os.path.join(path_reg_dir, 'output_x.mhd')
        path_deform_y = os.path.join(path_reg_dir, 'output_y.mhd')
        try:
            shift = self.extract_landmarks_shift_from_mhd(
                path_deform_x, path_deform_y, lnds_ref)
        except Exception:
            logging.exception(path_reg_dir)
            shift = np.zeros(lnds_ref.shape)

        # lnds_warp = lnds_move - shift
        lnds_warp = lnds_ref + shift
        # upscale landmarks if defined
        lnds_warp = lnds_warp * item.get('scaling', 1.)
        save_landmarks(path_lnds_warp, lnds_warp)

        # return formatted results
        return {
            self.COL_IMAGE_MOVE_WARP: path_img_warp,
            self.COL_POINTS_REF_WARP: path_lnds_warp,
        }
Пример #9
0
    def _extract_warped_image_landmarks(self, item):
        """ get registration results - warped registered images and landmarks

        :param dict item: dictionary with registration params
        :return dict: paths to warped images/landmarks
        """
        path_dir = self._get_path_reg_dir(item)
        path_img_ref, path_img_move, path_lnds_ref, path_lnds_move = self._get_paths(
            item)
        path_img_warp, path_lnds_warp = None, None
        path_log = os.path.join(path_dir, self.NAME_LOG_REGISTRATION)

        name_lnds = os.path.basename(path_lnds_ref)
        path_lnds_local = save_landmarks_pts(os.path.join(path_dir, name_lnds),
                                             load_landmarks(path_lnds_ref))

        # warping the image and points
        cmd = self.COMMAND_TRANSFORMATION % {
            'exec_transformix': self.exec_transformix,
            'source': path_img_move,
            'output': path_dir,
            'landmarks': path_lnds_local,
        }
        exec_commands(cmd, path_logger=path_log, timeout=self.EXECUTE_TIMEOUT)

        # if there is an output image copy it
        path_im_out = glob.glob(os.path.join(path_dir, self.NAME_IMAGE_WARPED))
        if path_im_out:
            path_im_out = sorted(path_im_out)[0]
            _, ext_img = os.path.splitext(path_im_out)
            name_img, _ = os.path.splitext(os.path.basename(path_img_move))
            path_img_warp = os.path.join(path_dir, name_img + ext_img)
            os.rename(path_im_out, path_img_warp)

        path_lnds_out = os.path.join(path_dir, self.NAME_LNDS_WARPED)
        if os.path.isfile(path_lnds_out):
            path_lnds_warp = os.path.join(path_dir, name_lnds)
            lnds = self.parse_warped_points(path_lnds_out)
            save_landmarks(path_lnds_warp, lnds)

        return {
            self.COL_IMAGE_MOVE_WARP: path_img_warp,
            self.COL_POINTS_REF_WARP: path_lnds_warp
        }
Пример #10
0
    def _extract_warped_image_landmarks(self, item):
        """ get registration results - warped registered images and landmarks

        :param dict item: dictionary with registration params
        :return dict: paths to warped images/landmarks
        """
        path_reg_dir = self._get_path_reg_dir(item)
        _, path_im_move, path_lnds_ref, path_lnds_move = self._get_paths(item)

        path_img_warp = os.path.join(path_reg_dir,
                                     os.path.basename(path_im_move))
        shutil.move(os.path.join(path_reg_dir, 'output.jpeg'), path_img_warp)

        # load transform and warp landmarks
        lnds_ = load_landmarks(path_lnds_ref)
        # this was in case you run inverse registration co you could warp the landmarks directly
        # lnds_ = load_landmarks(path_lnds_move)
        lnds_name = os.path.basename(path_lnds_move)
        path_lnds_warp = os.path.join(path_reg_dir, lnds_name)
        if lnds_ is None:
            raise ValueError('missing landmarks to be transformed "%s"' %
                             lnds_name)

        # extract deformation
        path_deform_x = os.path.join(path_reg_dir, 'output_field_x.nii.gz')
        path_deform_y = os.path.join(path_reg_dir, 'output_field_y.nii.gz')
        try:
            shift = self.extract_landmarks_shift_from_nifty(
                path_deform_x, path_deform_y, lnds_)
        except Exception:
            logging.exception(path_reg_dir)
            shift = np.zeros(lnds_.shape)

        lnds_warp = lnds_ + shift
        save_landmarks(path_lnds_warp, lnds_warp)

        # return formatted results
        return {
            self.COL_IMAGE_MOVE_WARP: path_img_warp,
            self.COL_POINTS_REF_WARP: path_lnds_warp,
        }