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
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
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}
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
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
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}
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 }
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, }
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 }
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, }