def _prepare_img_registration(self, record): """ prepare the experiment folder if it is required :param {str: str|float} dict record: dictionary with regist. params :return {str: str|float}: the same or updated registration info """ logging.debug('.. prepare image before registration experiment') # set the paths for this experiment path_dir = self._get_path_reg_dir(record) path_im_ref, path_im_move, _, _ = self._get_paths(record) # if histograms matching was selected if self.params.get('hist_matching', False): path_img_out = os.path.join(path_dir, os.path.basename(path_im_move)) cmd_hist_match = COMMAND_HIST_MATCHING % { 'path_fiji': self.params['path_fiji'], 'path_bsh': PATH_SCRIPT_HIST_MATCHING, 'target': path_im_ref, 'source': path_im_move, 'output': path_img_out } t_start = time.time() path_log = os.path.join(path_dir, NAME_LOG_REGISTRATION) exec_commands([cmd_hist_match], path_logger=path_log) record[COL_TIME_HIST_MATCH] = (time.time() - t_start) / 60. record[COL_IMAGE_MOVE_TEMP] = path_img_out return record
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 _execute_img_registration(self, item): """ execute the image registration itself :param dict item: record :return dict: record """ logging.debug('.. execute image registration as command line') path_dir_reg = self._get_path_reg_dir(item) commands = self._generate_regist_command(item) # in case it is just one command if not isinstance(commands, (list, tuple)): commands = [commands] path_log = os.path.join(path_dir_reg, self.NAME_LOG_REGISTRATION) # TODO, add lock to single thread, create pool with possible thread ids # (USE taskset [native], numactl [need install]) if not isinstance(commands, (list, tuple)): commands = [commands] # measure execution time cmd_result = exec_commands(commands, path_log, timeout=self.EXECUTE_TIMEOUT) # if the experiment failed, return back None if not cmd_result: item = None return item
def _execute_img_registration(self, record): """ execute the image registration itself :param {} record: :return {}: """ logging.debug('.. execute image registration as command line') path_dir_reg = self._get_path_reg_dir(record) commands = self._generate_regist_command(record) # in case it is just one command if not (isinstance(commands, list) or isinstance(commands, tuple)): commands = [commands] path_log = os.path.join(path_dir_reg, NAME_LOG_REGISTRATION) # TODO, add lock to single thread, create pool with possible thread ids # (USE taskset [native], numactl [need install]) if not (isinstance(commands, list) or isinstance(commands, tuple)): commands = [commands] # measure execution time cmd_result = exec_commands(commands, path_log) # if the experiment failed, return back None if not cmd_result: return None return record
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 _prepare_img_registration(self, record): """ prepare the experiment folder if it is required, * create registration macros :param {str: str|float} dict record: dictionary with regist. params :return {str: str|float}: the same or updated registration info """ logging.debug('.. generate macros before registration experiment') # set the paths for this experiment path_dir = self._get_path_reg_dir(record) path_im_ref, path_im_move, _, _ = self._get_paths(record) path_regist = os.path.join(path_dir, os.path.basename(path_im_move)) # if histograms matching was selected if self.params.get('hist_matching', False): path_img_out = os.path.join(path_dir, os.path.basename(path_im_move)) cmd_hist_match = COMMAND_HIST_MATCHING % { 'path_fiji': self.params['path_fiji'], 'path_bsh': PATH_SCRIPT_HIST_MATCHING, 'target': path_im_ref, 'source': path_im_move, 'output': path_img_out } t_start = time.time() path_log = os.path.join(path_dir, NAME_LOG_REGISTRATION) exec_commands([cmd_hist_match], path_logger=path_log) record['Time hist. matrching'] = (time.time() - t_start) / 60. path_im_move = path_img_out with open(self.params['path_config_bUnwarpJ'], 'r') as fp: lines = fp.readlines() # merge lines into one string config_bunwarpj = ' '.join(l.strip() for l in lines) # define set of all possible parameters for macros generating dict_params = { 'source': path_im_move, 'target': path_im_ref, 'config_bUnwarpJ': config_bunwarpj, 'output': path_dir, 'warp': path_regist } dict_params['SIFT'] = 'print("no SIFT performed");' # if config for SIFT is defined add SIFT extraction if 'path_config_IJ_SIFT' in self.params: with open(self.params['path_config_IJ_SIFT'], 'r') as fp: lines = fp.readlines() dict_params['config_SIFT'] = ' '.join(l.strip() for l in lines) dict_params['SIFT'] = MACRO_SIFT % dict_params dict_params['MOPS'] = 'print("no MOPS performed");' # if config for MOPS is defined add MOPS extraction if 'path_config_IJ_MOPS' in self.params: with open(self.params['path_config_IJ_MOPS'], 'r') as fp: lines = fp.readlines() dict_params['config_MOPS'] = ' '.join(l.strip() for l in lines) dict_params['MOPS'] = MACRO_MOPS % dict_params # dict_params['hist_matching'] = 'print("no histogram-matching performed");' # # if histograms matching was selected # if self.params.get('hist_matching', False): # dict_params['hist_matching'] = MACRO_HIST_MATCHING # generate the registration macro macro_regist = MACRO_REGISTRATION % dict_params with open(os.path.join(path_dir, NAME_MACRO_REGISTRATION), 'w') as fp: fp.write(macro_regist) return record