Source code for cubats.slide_collection.registration

# Standard Library
import os
from time import time

# Third Party
import numpy as np
from valis import registration

SLIDE_SRC_DIR = ""
RESULTS_DST_DIR = ""
REGISTERED_SLIDE_DEST_DIR = ""
REFERENCE_SLIDE = ""
DEFAULT_MAX_NON_RIGID_REG_SIZE = 2000
CROP_OVERLAP = "overlap"
CROP_REFERENCE = "reference"


[docs] def register_slides( slide_src_dir, results_dst_dir, registered_slides_dst=None, microregistration=False, max_non_rigid_registration_dim_px=DEFAULT_MAX_NON_RIGID_REG_SIZE, crop=None, ): """ Register the slides using Valis. This function automatically registers the slides and saves the registered slides in the specified directory. Args: slide_src_dir (str): Path to input slides. results_dst_dir (str): Path to directory where results will be saved. registered_slides_dst (str, optional): Path to directory where registered slides will be saved. If no path is provided, the registered slides will be saved in the results directory under "registered_slides". microregistration (bool, optional): Whether to perform microregistration after rigid and non-rigid registration. Defaults to False. max_non_rigid_registration_dim_px (int, optional): Maximum size of the non-rigid registration dimension in pixels. Defaults to 2000. crop (str, optional): Crop type for the registered slides. Can be "overlap" or "reference". Defaults to "overlap". """ # Input validation if not isinstance(slide_src_dir, str) or not os.path.exists(slide_src_dir): raise ValueError("Invalid or non-existent source directory") if not isinstance(results_dst_dir, str): raise ValueError("Invalid destination directory") if not isinstance(microregistration, bool): raise ValueError("microregistration must be a boolean") if not isinstance(max_non_rigid_registration_dim_px, int): raise ValueError( "max_non_rigid_registartion_dim_px must be an integer") if not isinstance(crop, str): raise ValueError("crop must be a string") if crop not in [CROP_OVERLAP, CROP_REFERENCE, None]: raise ValueError( f"crop must be one of {CROP_OVERLAP} or {CROP_REFERENCE}" ) if registered_slides_dst is None: registered_slides_dst = os.path.join( results_dst_dir, "registered_slides") if crop is None: crop = CROP_OVERLAP # Start registration registrar = registration.Valis(slide_src_dir, results_dst_dir) # Rigid and non-rigid registration rigid_registrar, non_rigid_registrar, error_df = registrar.register() # Micro registration if microregistration: registrar.register_micro( max_non_rigid_registartion_dim_px=max_non_rigid_registration_dim_px ) # Save registered slides registrar.warp_and_save_slides(registered_slides_dst, crop=crop) registration.kill_jvm()
[docs] def register_slides_with_reference( slide_src_dir, results_dst_dir, referenceSlide, registered_slides_dst=None, microregistration=False, max_non_rigid_registration_dim_px=DEFAULT_MAX_NON_RIGID_REG_SIZE, crop=None ): """ Register the slides with a reference slide using Valis. This function automatically registers the slides and saves the registered slides in the specified directory. Args: slide_src_dir (str): Path to input slides results_dst_dir (str): Path to directory where results will be saved referenceSlide (str): Path to reference slide registered_slides_dst (str, optional): Path to directory where registered slides will be saved. If no path is provided, the registered slides will be saved in the results directory under "registered_slides". microregistration (bool, optional): Whether to perform microregistration after rigid and non-rigid registration. Defaults to False. max_non_rigid_registration_dim_px (int, optional): Maximum size of the non-rigid registration dimension in pixels. Defaults to 2000. crop (str, optional): Crop type for the registered slides. Can be "overlap" or "reference". Defaults to "reference". """ # Input validation if not isinstance(slide_src_dir, str) or not os.path.exists(slide_src_dir): raise ValueError("Invalid or non-existent source directory") if not isinstance(results_dst_dir, str): raise ValueError("Invalid destination directory") if not isinstance(referenceSlide, str) or not os.path.exists(referenceSlide): raise ValueError("Invalid or non-existent reference slide") if not isinstance(microregistration, bool): raise ValueError("microregistration must be a boolean") if not isinstance(max_non_rigid_registration_dim_px, int): raise ValueError( "max_non_rigid_registartion_dim_px must be an integer") if registered_slides_dst is None: registered_slides_dst = os.path.join( results_dst_dir, "registered_slides") if crop is None: crop = CROP_REFERENCE registrar = registration.Valis( slide_src_dir, results_dst_dir, reference_img_f=referenceSlide ) rigid_registrar, non_rigid_registrar, error_df = registrar.register() if microregistration: registrar.register_micro( max_non_rigid_registration_dim_px=max_non_rigid_registration_dim_px, align_to_reference=True, ) registrar.warp_and_save_slides(registered_slides_dst, crop=crop) registration.kill_jvm()
[docs] def register_slides_high_resolution( slide_src_dir, results_dst_dir, registered_slides_dst=None, micro_reg_fraction=None, ): """ Performs high resolution alignment. """ # Perform high resolution rigid registration using the MicroRigidRegistrar start = time() if registered_slides_dst is None: registered_slides_dst = os.path.join( results_dst_dir, "registered_slides") if micro_reg_fraction is None: micro_reg_fraction = 0.25 registrar = registration.Valis(slide_src_dir, results_dst_dir) # , micro_rigid_registrar_cls=MicroRigidRegistrar rigid_registrar, non_rigid_registrar, error_df = registrar.register() # Calculate what `max_non_rigid_registration_dim_px` needs to be to do non-rigid registration # on an image that is 25% full resolution. img_dims = np.array( [ slide_obj.slide_dimensions_wh[0] for slide_obj in registrar.slide_dict.values() ] ) min_max_size = np.min([np.max(d) for d in img_dims]) img_areas = [np.multiply(*d) for d in img_dims] max_img_w, max_img_h = tuple(img_dims[np.argmax(img_areas)]) micro_reg_size = np.floor(min_max_size * micro_reg_fraction).astype(int) print(micro_reg_size) # Perform high resolution non-rigid registration using 25% full resolution micro_reg, micro_error = registrar.register_micro( max_non_rigid_registration_dim_px=micro_reg_size ) registrar.warp_and_save_slides( registered_slides_dst, crop=CROP_OVERLAP) registration.kill_jvm() end = time() print(f"High-resolution alignement completed in {end-start:.2f} seconds")