diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml new file mode 100644 index 00000000..b2316674 --- /dev/null +++ b/.github/workflows/codespell.yml @@ -0,0 +1,25 @@ +# Codespell configuration is within pyproject.toml +--- +name: Codespell + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + codespell: + name: Check for spelling errors + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Annotate locations with typos + uses: codespell-project/codespell-problem-matcher@v1 + - name: Codespell + uses: codespell-project/actions-codespell@v2 diff --git a/docs/changelog.rst b/docs/changelog.rst index ece639a3..aba506d0 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -42,7 +42,7 @@ Version 1.0.3 (January 25, 2024) #. Setting :code:`colormap=None` to the various save functions will not add any color channels, and so the slide viewer's default colormaps will be used. #. Updated :code:`slide_io.get_slide_reader` to give preference to reading images with libvips/openslide. Should be faster since image will not need to be constructed from tiles. #. JVM will only be initialized if bioformats is needed to read the image. -#. Updated :code:`slide_io.VipsSlideReader` to use the ome-types pacakge to extract metadata, instead of Bio-formats. Should avoid having to launch JVM unless Bio-formats is really needed. +#. Updated :code:`slide_io.VipsSlideReader` to use the ome-types package to extract metadata, instead of Bio-formats. Should avoid having to launch JVM unless Bio-formats is really needed. #. Added checks to ensure that channels in merged image are in the correct order when :code:`imgs_ordered=True`, addressing the comment `github issue 56 `_ . #. Added tests for images with minimal ome-xml (i.e. no channel names, units, etc...) #. Removed usage of :code:`imghdr`, which is being deprecated @@ -88,11 +88,11 @@ Version 1.0.0rc15 (May 10, 2023) Version 1.0.0rc14 (April 24, 2023) ------------------------------------- #. Added :code:`max_ratio` as an argument for :code:`feature_matcher.match_desc_and_kp` (github issue 36). -#. Added :code:`CziJpgxrReader` to read CZI images that have JPGXR compression but can't be opened with Bioformats. It's very limited and experimental (only tested with single scence RGB), but may be an issue specific to Apple silcon? +#. Added :code:`CziJpgxrReader` to read CZI images that have JPGXR compression but can't be opened with Bioformats. It's very limited and experimental (only tested with single scene RGB), but may be an issue specific to Apple silcon? #. Supports scenario where images might be assigned the same name (e.g. same file names, but different directories). #. Support tiling for initial non-rigid registration, making it possible to perform non-rigid on much larger images #. Skips empty images (github issue 44). -#. Can now specify an :code:`ImageProcesser` for each image by passing a dicitonary to the :code:`processor_dict` argrument of :code:`Valis.register`. Keys should be the filename of the image, and values a list, where the first element is the :code:`ImageProcesser` to use, and the second element is a dictionary of keyword argruments passed to :code:`ImageProcesser.process_image`. This should make it easier to register different image modalities. +#. Can now specify an :code:`ImageProcesser` for each image by passing a dictionary to the :code:`processor_dict` argrument of :code:`Valis.register`. Keys should be the filename of the image, and values a list, where the first element is the :code:`ImageProcesser` to use, and the second element is a dictionary of keyword argruments passed to :code:`ImageProcesser.process_image`. This should make it easier to register different image modalities. #. Added an H&E color deconvolution :code:`ImageProcesser` using the method described in M. Macenko et al., ISBI 2009. Generously provided by Github user aelskens (Arthur Elskenson) (PR 42). #. Small improvements in :code:`valtils` functions, provided by Github user ajinkya-kulkarni (Ajinkya Kulkarni) (PR 46). #. Docker Images bundled with bioformats jar file, so does not require internet connection or Maven. Also now checks for bioformats jar in valis folder @@ -109,7 +109,7 @@ Version 1.0.0rc13 (January 31, 2023) #. Fixed bug reported in `github issue 33 `_ #. Default is to not compose non-rigid transformations, reducing accumulation of unwanted distortions, especially in 3D. #. The :code:`scale_factor` parameter for :code:`feature_detectors.VggFD` is now set to 5.0, as per the OpenCV documentation -#. Installlation now uses `poetry `_ via the pyproject.toml file. Includes a poetry.lock file, but it can be deleted before installation if so desired. +#. Installation now uses `poetry `_ via the pyproject.toml file. Includes a poetry.lock file, but it can be deleted before installation if so desired. #. Removed bioformats_jar as a dependency #. Added a datasets page #. Moved examples to separate page @@ -120,7 +120,7 @@ Version 1.0.0rc12 (November 7, 2022) #. Fixed bug where would get out of bounds errors when cropping with user provided transformations (github issue 14 https://github.com/MathOnco/valis/issues/14) #. Fixed bug where feature matches not drawn in correct location in :code:`src_img` in :code:`viz.draw_matches`. #. Can now check if refelcting/mirroring/flipping images improves alignment by setting :code:`check_for_reflections=True` when initializing the :code:`Valis` object. Addresses githib issue 22 (https://github.com/MathOnco/valis/issues/22) -#. Channel colors now transfered to registered image (github issue 23 https://github.com/MathOnco/valis/issues/23). Also option to provide a colormap when saving the slides. This replaces the :code:`perceputally_uniform_channel_colors` argument +#. Channel colors now transferred to registered image (github issue 23 https://github.com/MathOnco/valis/issues/23). Also option to provide a colormap when saving the slides. This replaces the :code:`perceputally_uniform_channel_colors` argument Version 1.0.0rc11 (August 26, 2022) @@ -151,13 +151,13 @@ Version 1.0.0rc8 (July 1, 2022) Version 1.0.0rc7 (June 27, 2022) -------------------------------- -#. Can set size of image to be used for non-rigid registration, which may help improve aligment of micro-architectural structures. However this will increase the amount of time it takes to perform non-rigid registration, and will increase amount of memory used during registration, and the size of the pickled :code: `Valis` object. To change this value, set the :code:`max_non_rigid_registartion_dim_px` parameter when initializing the :code:`Valis` object. -#. Can now do a second non-rigid registartion on higher resolution images, including the full resolution one. This can be done with the :code:`Valis.register_micro`. If the images are large, they will be sliced into tiles, and then each tile registered with one another. The deformation fields will be saved separately as .vips images within the data folder. +#. Can set size of image to be used for non-rigid registration, which may help improve alignment of micro-architectural structures. However this will increase the amount of time it takes to perform non-rigid registration, and will increase amount of memory used during registration, and the size of the pickled :code: `Valis` object. To change this value, set the :code:`max_non_rigid_registartion_dim_px` parameter when initializing the :code:`Valis` object. +#. Can now do a second non-rigid registration on higher resolution images, including the full resolution one. This can be done with the :code:`Valis.register_micro`. If the images are large, they will be sliced into tiles, and then each tile registered with one another. The deformation fields will be saved separately as .vips images within the data folder. #. Added :code:`registration.load_registrar` function to open a :code:`Valis` object. This should be used instead of `pickle.load`. #. Creating and applying tissue masks before registration. This improves image normalization, reduces the number of poor feature matches, and helps remove unwanted non-rigid deformations (especially around the image edges), all of which improve alignment accuracy. This step can be skipped by setting :code:`create_masks` to `False` when initializing the :code:`Valis` object. #. Now possible to directly non-rigidly align to the reference image specified by :code:`reference_img_f`. This can be done by setting :code:`align_to_reference` to `True` when initializing the :code:`Valis` object. The default is `False`, which means images will be aligned serially towards the reference image. This option is also available with :code:`Valis.register_micro`, meaning that one could do a second alignment, but aligning all directly to a reference image. #. RANSAC filtered matches found for rigid registration undergo second round of filtering, this time using Tukey's method to remove matches whose distance after being warped would be considered outliers. -#. Now have option off whether or not to compose non-rigid transformations. This can be set specifying the :code:`compose_non_rigid` argument when initialzing the `Valis` object. +#. Now have option off whether or not to compose non-rigid transformations. This can be set specifying the :code:`compose_non_rigid` argument when initializing the `Valis` object. #. Can provide rigid transformation matrices by passing in a dictionary to the :code:`do_rigid` parameter when initializing the :code:`Valis` object. Setting :code:`do_rigid` to `False` will completely skip the rigid registration step. See the documentation for initializing the `Valis` object for more details. #. Added examples of how to read slides and use custom transforms #. Benchmarked using ANHIR Grand Challenge dataset and posted results on leaderboard. @@ -175,12 +175,12 @@ Version 1.0.0rc5 (April 5, 2022) --------------------------------- #. Can provide a reference image that the others will be aligned towards. To do this, when initializinig the Valis object, set the :code:`reference_img_f` argument to be the file name of the reference image. If not set by the user, the reference image will be set as the one at the center of the ordered image stack #. Both non-rigid and rigid now align *towards* a reference image, meaning that reference image will have neither rigid nor non-rigid transformations applied to it. -#. Two cropping methods. First option is to crop seach registered slides to contain only the areas where all registered images overlap. The second option is to crop the registered slide to contain only the area that intersects with the reference image. It is also possible to not crop an image/slide. +#. Two cropping methods. First option is to crop each registered slides to contain only the areas where all registered images overlap. The second option is to crop the registered slide to contain only the area that intersects with the reference image. It is also possible to not crop an image/slide. #. Images are now cropped during the warp, not after, and so is now faster and requires less memory. For example, on a 2018 MacBook Pro with a 2.6 GHz Intel Core i7 processor, it takes 2-3 minutes to warp and save a 41399 x 43479 RGB image. #. Warping of images and slides done using the same function, built around pyvips. Faster, more consistent, and should prevent excessive memory usage. #. Fixed bug that caused a crash when warping large ome.tiff images. #. Read slides and images using pyvips whenever possible. #. Background color now automatically set to be same as the brightest (IHC) or darkest (IF) pixel in the image. Because of this, the "bg_color" argument in the slide warping functions was removed. #. Reduced accumulation of unwanted non-rigid deformations -#. Displacement fields drawn on top of non-rigid registered image to help determine where the deformations occured. +#. Displacement fields drawn on top of non-rigid registered image to help determine where the deformations occurred. #. If a slide has multiple series, and a series is not specficed, the slide reader will read the series containing the largest image. diff --git a/docs/datasets.rst b/docs/datasets.rst index 64a0c740..24bba882 100644 --- a/docs/datasets.rst +++ b/docs/datasets.rst @@ -34,7 +34,7 @@ As ACROBAT measures error in μm, and VALIS estimates error based on matched fea Kartasalo et al 2018 ===================== -Another potential use of image registration is to construct a 3D tissue from serial slices. In 2018, `Kartasalo et al. (2018) `_ performed a study in which they compared several different frameworks for constructing 3D images, using both free and commercial software. They peformed the analysis using two datasets: one murine prostate to be reconstructed from 260 serially sliced 20x H&E images (0.46μm/pixel, 5μm in depth), and one murine liver to be reconstructed from 47 serial slices (0.46μm/pixel, 5μm in depth). Accuracy of the alignment of the liver can be determined using the positions of laser cut holes that pass through the whole tissue, and should in theory form a straight line. In the case of the prostate, for each pair of images, human operators determined the location of structures visible on both slices, preferably nuclei split by the sectioning blade. The authors refer to these landmarks as "fiducial points". +Another potential use of image registration is to construct a 3D tissue from serial slices. In 2018, `Kartasalo et al. (2018) `_ performed a study in which they compared several different frameworks for constructing 3D images, using both free and commercial software. They performed the analysis using two datasets: one murine prostate to be reconstructed from 260 serially sliced 20x H&E images (0.46μm/pixel, 5μm in depth), and one murine liver to be reconstructed from 47 serial slices (0.46μm/pixel, 5μm in depth). Accuracy of the alignment of the liver can be determined using the positions of laser cut holes that pass through the whole tissue, and should in theory form a straight line. In the case of the prostate, for each pair of images, human operators determined the location of structures visible on both slices, preferably nuclei split by the sectioning blade. The authors refer to these landmarks as "fiducial points". VALIS was used to register both datasets, and error was measured as the physical distance (μm), i.e. TRE, between the fiducial points. These values can then be compared to those presented in Tables 1 and 2 of the manuscript, which provide the mean TRE using observer 1's landmarks (i.e. the "TRE μ" column). Benchmarking using the liver dataset indicates that VALIS produces a mean TRE of 52.98, compared to the compared to the baseline reference value of 27.3 (LS 1). In the case of prostate, VALIS scored 11.41, compared to the baseline reference value of 15.6 (LS 1). According to the authors, methods with scores approaching the LS 1 value can be considered "highly accurate", indicating that VALIS is suitable for 3D reconstruction. Below is a picture of the prostate tumor reconstructed from all 260 serial slices. diff --git a/docs/examples.rst b/docs/examples.rst index b5056523..7d91a358 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -10,7 +10,7 @@ Slide registration .. image:: https://github.com/MathOnco/valis/raw/main/docs/_images/challenging_dataset_adincar33.png .. important:: - One of the most important parameters used to initialize a Valis object is :code:`max_processed_image_dim_px`, which determines the size of the image used to find the rigid registration parameters. The default value is 850, but if registration fails or is poor, try adjusting that value. Generally speaking, values between 500-2000 work well. In cases where there is little empty space, around the tissue, smaller values may be better. However, if there is a large amount of empty space/slide (as in the images above), larger values may be needed so that the tissue is at a high enough resolution. To imporove alingment of the finer details in the images, larger images can be used in the non-rigid or micro-registration steps (set via the :code:`max_non_rigid_registration_dim_px` parameter). + One of the most important parameters used to initialize a Valis object is :code:`max_processed_image_dim_px`, which determines the size of the image used to find the rigid registration parameters. The default value is 850, but if registration fails or is poor, try adjusting that value. Generally speaking, values between 500-2000 work well. In cases where there is little empty space, around the tissue, smaller values may be better. However, if there is a large amount of empty space/slide (as in the images above), larger values may be needed so that the tissue is at a high enough resolution. To improve alignment of the finer details in the images, larger images can be used in the non-rigid or micro-registration steps (set via the :code:`max_non_rigid_registration_dim_px` parameter). .. important:: diff --git a/docs/index.rst b/docs/index.rst index 1b767ab0..c6fe1a3e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -8,7 +8,7 @@ VALIS .. include:: README.rst -Docmentation +Documentation ============ .. toctree:: diff --git a/docs/installation.rst b/docs/installation.rst index 3490856e..e94125b3 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -70,7 +70,7 @@ VALIS uses Bioformats to read many slide formats. Bioformats is written in Java, Install ~~~~~~~ -Once the above prerequisites have been satistifed, valis can be installed using pip, idealy within a virtual environment +Once the above prerequisites have been satistifed, valis can be installed using pip, ideally within a virtual environment .. code-block:: bash diff --git a/examples/EXAMPLES_README.md b/examples/EXAMPLES_README.md index 579c771f..1f84c543 100644 --- a/examples/EXAMPLES_README.md +++ b/examples/EXAMPLES_README.md @@ -31,7 +31,7 @@ The `register_ihc.py` example registers the slides in `examples/example_datasets These can be used to get a better sense of how the images were altered by non-rigid warping -6. *processed* shows thumnails of the processed images. +6. *processed* shows thumbnails of the processed images. This are thumbnails of the images that are actually used to perform the registration. The pre-processing and normalization methods should try to make these diff --git a/examples/acrobat_2023/valis/affine_optimizer.py b/examples/acrobat_2023/valis/affine_optimizer.py index bede3e79..c365e633 100644 --- a/examples/acrobat_2023/valis/affine_optimizer.py +++ b/examples/acrobat_2023/valis/affine_optimizer.py @@ -1,7 +1,7 @@ """Optimize rigid alignment Contains functions related to optimization, as well as the AffineOptimizer -class that performs the optimzation. This class can be subclassed to implement +class that performs the optimization. This class can be subclassed to implement custom optimization methods. There are several subclasses, but AffineOptimizerMattesMI is the @@ -222,7 +222,7 @@ def get_intersection(alpha1, alpha2, abc1, abc2): @nba.njit() def get_verts(img, x, y, pos=0): """ - Get veritices of triangle and intenisty at each vertex + Get veritices of triangle and intensity at each vertex """ if pos == 0: # Lower left @@ -285,7 +285,7 @@ def update_joint_H(binned_moving, binned_fixed, H, M, sample_pts, pos=0, img2_v = get_verts(binned_fixed, sxy[0], sxy[1], pos) abc2 = solve_abc(img2_v) else: - # ABC for fixed image's trianges are precomputed + # ABC for fixed image's triages are precomputed abc2 = precalcd_abc[i] x_lims = np.array([np.min(img1_v[:, 0]), np.max(img1_v[:, 0])]) @@ -348,7 +348,7 @@ def build_P(A, B, r, mask): @nba.njit() def entropy(x): """ - Caclulate Shannon's entropy for array x + Calculate Shannon's entropy for array x Parameters ---------- @@ -492,7 +492,7 @@ class AffineOptimizer(object): Type of transformation, "EuclideanTransform" or "SimilarityTransform" current_level : int - Current level of the Guassian pyramid that is being registered + Current level of the Gaussian pyramid that is being registered accepts_xy : bool Bool declaring whether or not the optimizer will use corresponding points to optimize the registration @@ -523,7 +523,7 @@ class AffineOptimizer(object): Major overhauls are possible too. See AffineOptimizerMattesMI for an example on using SimpleITK's optimization methods inside of an AffineOptimizer subclass - If the optimizer uses corressponding points, then the class attribute + If the optimizer uses corresponding points, then the class attribute accepts_xy needs to be set to True. The default is False. """ @@ -995,7 +995,7 @@ def shannon_entropy(self, X, k=1): def mutual_information(self, A, B): if self.HA_list[self.current_level] is None: - # Only need to caluclate once per level, becuase the fixed + # Only need to calculate once per level, because the fixed # image doesn't change self.HA_list[self.current_level] = self.shannon_entropy(A) diff --git a/examples/acrobat_2023/valis/feature_detectors.py b/examples/acrobat_2023/valis/feature_detectors.py index 45ab9c2f..1bb28de0 100644 --- a/examples/acrobat_2023/valis/feature_detectors.py +++ b/examples/acrobat_2023/valis/feature_detectors.py @@ -3,7 +3,7 @@ Bundles OpenCV feature detectors and descriptors into the FeatureDD class Also makes it easier to mix and match feature detectors and descriptors -from different pacakges (e.g. skimage and OpenCV). See CensureVggFD for +from different packages (e.g. skimage and OpenCV). See CensureVggFD for an example """ @@ -146,7 +146,7 @@ def detect_and_compute(self, image, mask=None): Returns ------- kp : ndarry - (N, 2) array positions of keypoints in xy corrdinates for N + (N, 2) array positions of keypoints in xy coordinates for N keypoints desc : ndarry @@ -289,7 +289,7 @@ def detect(self, image): Uses keypoint info to create KeyPoint objects for OpenCV - Paramters + Parameters --------- image : ndarray image from keypoints will be detected diff --git a/examples/acrobat_2023/valis/feature_matcher.py b/examples/acrobat_2023/valis/feature_matcher.py index f22ad469..22d3e579 100644 --- a/examples/acrobat_2023/valis/feature_matcher.py +++ b/examples/acrobat_2023/valis/feature_matcher.py @@ -19,7 +19,7 @@ Metrics found in both the valid metrics ang kernel methods in sklearn.metrics.pairwise. Issue is that metrics are distances, while kernels are similarities. Metrics in this set are assumed - to be distaces, unless the metric_type parameter in match_descriptors + to be distances, unless the metric_type parameter in match_descriptors is set to "similarity". """ @@ -59,7 +59,7 @@ def convert_distance_to_similarity(d, n_features=64): Value to convert n_features: int - Number of features used to calcuate distance. + Number of features used to calculate distance. Only needed when calc == 0 Returns ------- @@ -81,7 +81,7 @@ def convert_similarity_to_distance(s, n_features=64): Similarity to convert n_features: int - Number of features used to calcuate similarity. + Number of features used to calculate similarity. Only needed when calc == 0 Returns @@ -146,7 +146,7 @@ def filter_matches_gms(kp1_xy, kp2_xy, feature_d, img1_shape, img2_shape, Note that this function assumes the keypoints and distances have been sorted such that each keypoint in kp1_xy has the same index as the - matching keypoint in kp2_xy andd corresponding feautre distance in + matching keypoint in kp2_xy and corresponding feature distance in feature_d. For example, kp1_xy[0] should have the corresponding keypoint at kp2_xy[0] and the corresponding feature distance at feature_d[0]. @@ -399,7 +399,7 @@ def match_descriptors(descriptors1, descriptors2, metric=None, NOTE ---- - Modified from scikit-image to use scikit-learn's distance and kernal methods. + Modified from scikit-image to use scikit-learn's distance and kernel methods. """ if descriptors1.shape[1] != descriptors2.shape[1]: @@ -479,7 +479,7 @@ def match_desc_and_kp(desc1, kp1_xy, desc2, kp2_xy, metric=None, filtering_kwargs=None): """Match the descriptors of image 1 with those of image 2 and remove outliers. - Metric can be a string to use a distance in scipy.distnce.cdist(), + Metric can be a string to use a distance in scipy.distance.cdist(), or a custom distance function Parameters @@ -741,7 +741,7 @@ def set_names(self, img1_name, img2_name): class Matcher(object): - """Class that matchs the descriptors of image 1 with those of image 2 + """Class that matches the descriptors of image 1 with those of image 2 Outliers removed using RANSAC or GMS @@ -850,13 +850,13 @@ def match_images(self, desc1, kp1_xy, desc2, kp2_xy, additional_filtering_kwargs=None, *args, **kwargs): """Match the descriptors of image 1 with those of image 2, Outliers removed using match_filter_method. Metric can be a string - to use a distance in scipy.distnce.cdist(), or a custom distance - function. Sets atttributes for Matcher object + to use a distance in scipy.distance.cdist(), or a custom distance + function. Sets attributes for Matcher object Parameters ---------- desc1 : (N, P) array - Image 1s 2D array containinng N keypoints, each of which + Image 1s 2D array containing N keypoints, each of which has P features kp1_xy : (N, 2) array @@ -864,7 +864,7 @@ def match_images(self, desc1, kp1_xy, desc2, kp2_xy, N descriptors in desc1 desc2 : (M, P) array - Image 2s 2D array containinng M keypoints, each of which has + Image 2s 2D array containing M keypoints, each of which has P features kp2_xy : (M, 2) array diff --git a/examples/acrobat_2023/valis/non_rigid_registrars.py b/examples/acrobat_2023/valis/non_rigid_registrars.py index 7740416b..64b68224 100644 --- a/examples/acrobat_2023/valis/non_rigid_registrars.py +++ b/examples/acrobat_2023/valis/non_rigid_registrars.py @@ -90,7 +90,7 @@ def __init__(self, params=None): Parameters ---------- params : dictionary - Keyword: value dictionary of parameters to be used in reigstration. + Keyword: value dictionary of parameters to be used in registration. Will get used in the calc() method. In the case where simple ITK will be used, params should be @@ -128,9 +128,9 @@ def apply_mask(self, mask): return masked_moving, masked_fixed def calc(self, moving_img, fixed_img, mask, *args, **kwargs): - """Cacluate displacement fields + """Calculate displacement fields - Can record subclass specific atrributes here too + Can record subclass specific attributes here too Parameters ---------- @@ -388,7 +388,7 @@ def __init__(self, params=None): Parameters ---------- params : dictionary - Keyword: value dictionary of parameters to be used in reigstration. + Keyword: value dictionary of parameters to be used in registration. Will get used in the calc() method. In the case where simple ITK will be used, params should be @@ -577,7 +577,7 @@ def register(self, img_list, mask=None): self.shape = img_list[0].shape for img in img_list: - assert img.shape == self.shape, print("Images have differernt shapes") + assert img.shape == self.shape, print("Images have different shapes") self.img_list = img_list self.size = len(img_list) @@ -929,7 +929,7 @@ def __init__(self, params=None, optical_flow_obj=None, Parameters ---------- params : dictionary - Keyword: value dictionary of parameters to be used in reigstration. + Keyword: value dictionary of parameters to be used in registration. Will get used in the calc() method. optical_flow_obj : object @@ -1155,7 +1155,7 @@ def calc(self, img_list, mask=None, *args, **kwargs): class NonRigidTileRegistrar(object): - """Tile-wise non-rigid regisration + """Tile-wise non-rigid registration Slices moving and fixed images into tiles and then registers each tile. Probably best for very large images. @@ -1197,7 +1197,7 @@ def __init__(self, params=None, tile_wh=512, tile_buffer=100): Parameters ---------- params : dictionary - Keyword: value dictionary of parameters to be used in reigstration. + Keyword: value dictionary of parameters to be used in registration. Will get used when initializing the `non_rigid_registrar_cls` In the case where simple ITK will be used, params should be @@ -1354,7 +1354,7 @@ def reg_tile(self, tile_idx, lock): self.pbar.update(1) def calc(self, *args, **kwargs): - """Cacluate displacement fields + """Calculate displacement fields Each tile is registered and then stitched together """ @@ -1401,7 +1401,7 @@ def register(self, moving_img, fixed_img, mask=None, non_rigid_registrar_cls=Opt preprocessing.ImageProcesser used to process the images processing_kwargs : dict - Dictionary of keyward arguments to be passed to `processing_cls` + Dictionary of keyword arguments to be passed to `processing_cls` target_stats : ndarray Target stats used to normalize each tile after being processed. diff --git a/examples/acrobat_2023/valis/preprocessing.py b/examples/acrobat_2023/valis/preprocessing.py index e734d5b0..53625adf 100644 --- a/examples/acrobat_2023/valis/preprocessing.py +++ b/examples/acrobat_2023/valis/preprocessing.py @@ -331,7 +331,7 @@ def process_image(self, *args, **kwaargs): class HEDeconvolution(ImageProcesser): - """Normalize staining appearence of hematoxylin and eosin (H&E) stained image + """Normalize staining appearance of hematoxylin and eosin (H&E) stained image and get the H or E deconvolution image. Reference @@ -389,7 +389,7 @@ def standardize_colorfulness(img, c=DEFAULT_COLOR_STD_C, h=0): """Give image constant colorfulness and hue Image is converted to cylindrical CAM-16UCS assigned a constant - hue and colorfulness, and then coverted back to RGB. + hue and colorfulness, and then converted back to RGB. Parameters ---------- @@ -493,7 +493,7 @@ def calc_background_color_dist(img, brightness_q=0.99, mask=None): def normalize_he(img: np.array, Io: int = 240, alpha: int = 1, beta: int = 0.15): - """ Normalize staining appearence of H&E stained images. + """ Normalize staining appearance of H&E stained images. Parameters ---------- @@ -719,7 +719,7 @@ def combine_masks(mask1, mask2, op="or"): def remove_small_obj_and_lines_by_dist(mask): """ Will remove smaller objects and thin lines that - do not interesct with larger objects + do not intersect with larger objects """ dist_transform = cv2.distanceTransform(mask, cv2.DIST_L2, 5) @@ -795,7 +795,7 @@ def create_tissue_mask_from_rgb(img, brightness_q=0.99, kernel_size=3, gray_thre cam_d, cam = calc_background_color_dist(img, brightness_q=brightness_q, mask=color_mask) - # Reduce intensity of thick horizontal and vertial lines, usually artifacts like edges, streaks, folds, etc... + # Reduce intensity of thick horizontal and vertical lines, usually artifacts like edges, streaks, folds, etc... vert_knl = np.ones((1, 5)) no_v_lines = morphology.opening(cam_d, vert_knl) diff --git a/examples/acrobat_2023/valis/registration.py b/examples/acrobat_2023/valis/registration.py index 0da8c863..0628c38f 100644 --- a/examples/acrobat_2023/valis/registration.py +++ b/examples/acrobat_2023/valis/registration.py @@ -672,7 +672,7 @@ def warp_img(self, img=None, non_rigid=True, crop=True, interp_method="bicubic") image will not be cropped. If "overlap", the warped slide will be cropped to include only areas where all images overlapped. "reference" crops to the area that overlaps with the reference image, - defined by `reference_img_f` when initialzing the `Valis object`. + defined by `reference_img_f` when initializing the `Valis object`. interp_method : str Interpolation method used when warping slide. Default is "bicubic" @@ -835,7 +835,7 @@ def warp_slide(self, level, non_rigid=True, crop=True, image will not be cropped. If "overlap", the warped slide will be cropped to include only areas where all images overlapped. "reference" crops to the area that overlaps with the reference image, - defined by `reference_img_f` when initialzing the `Valis object`. + defined by `reference_img_f` when initializing the `Valis object`. src_f : str, optional Path of slide to be warped. If None (the default), Slide.src_f @@ -1048,7 +1048,7 @@ def warp_xy(self, xy, M=None, slide_level=0, pt_level=0, image will not be cropped. If "overlap", the warped slide will be cropped to include only areas where all images overlapped. "reference" crops to the area that overlaps with the reference image, - defined by `reference_img_f` when initialzing the `Valis object`. + defined by `reference_img_f` when initializing the `Valis object`. """ if M is None: @@ -1224,7 +1224,7 @@ def warp_geojson(self, geojson_f, M=None, slide_level=0, pt_level=0, image will not be cropped. If "overlap", the warped slide will be cropped to include only areas where all images overlapped. "reference" crops to the area that overlaps with the reference image, - defined by `reference_img_f` when initialzing the `Valis object`. + defined by `reference_img_f` when initializing the `Valis object`. """ if M is None: @@ -1330,7 +1330,7 @@ def warp_geojson_from_to(self, geojson_f, to_slide_obj, src_slide_level=0, src_p Returns ------- warped_geojson : dict - Dictionry of warped geojson geometries + Dictionary of warped geojson geometries """ @@ -1420,7 +1420,7 @@ class Valis(object): 5. Rigid registration is performed serially, with each image being rigidly aligned to the previous image in the stack. - 6. Non-rigid registration is then performed either by 1) aliging each image + 6. Non-rigid registration is then performed either by 1) aligning each image towards the center of the stack, composing the deformation fields along the way, or 2) using groupwise registration that non-rigidly aligns the images to a common frame of reference. @@ -1503,7 +1503,7 @@ class Valis(object): the `img_obj_list` has been sorted during rigid registration. align_to_reference : bool - Whether or not images should be aligne to a reference image + Whether or not images should be align to a reference image specified by `reference_img_f`. Will be set to True if `reference_img_f` is provided. @@ -1514,7 +1514,7 @@ class Valis(object): SerialRigidRegistrar object that performs the rigid registration. rigid_reg_kwargs : dict - Dictionary of keyward arguments passed to + Dictionary of keyword arguments passed to `serial_rigid.register_images`. feature_descriptor_str : str @@ -1537,7 +1537,7 @@ class Valis(object): non-rigid registration. non_rigid_reg_kwargs : dict - Dictionary of keyward arguments passed to + Dictionary of keyword arguments passed to `serial_non_rigid.register_images`. non_rigid_registrar_cls : NonRigidRegistrar @@ -1578,13 +1578,13 @@ class Valis(object): as the error, shape of aligned slides, time to completion, etc... start_time : float - The time at which registation was initiated. + The time at which registration was initiated. end_rigid_time : float - The time at which rigid registation was completed. + The time at which rigid registration was completed. end_non_rigid_time : float - The time at which non-rigid registation was completed. + The time at which non-rigid registration was completed. qt_emitter : PySide2.QtCore.Signal Used to emit signals that update the GUI's progress bars @@ -1725,7 +1725,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, are already in the correct order. If True, then each filename should begin with the number that indicates its position in the z-stack. If False, then the images will be sorted by ordering a feature distance - matix. Default is False. + matrix. Default is False. reference_img_f : str, optional Filename of image that will be treated as the center of the stack. @@ -1740,7 +1740,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, non_rigid_registrar_cls : NonRigidRegistrar, optional Uninstantiated NonRigidRegistrar class that will be used to calculate the deformation fields between images. See - the `non_rigid_registrars` module for a desciption of available + the `non_rigid_registrars` module for a description of available methods. If a desired non-rigid registration method is not available, one can be implemented by subclassing.NonRigidRegistrar. If None, then only rigid registration will be performed @@ -1749,7 +1749,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, Dictionary containing key, value pairs to be used to initialize `non_rigid_registrar_cls`. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. See the NonRigidRegistrar classes in `non_rigid_registrars` for the available non-rigid registration methods and arguments. @@ -1775,7 +1775,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, registration will be skipped. If `do_rigid` is a dictionary, it should contain inverse transformation - matrices to rigidly align images to the specificed by `reference_img_f`. + matrices to rigidly align images to the specified by `reference_img_f`. M will be estimated for images that are not in the dictionary. Each key is the filename of the image associated with the transformation matrix, and value is a dictionary containing the following values: @@ -1806,7 +1806,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, mask too much if there is a lot of variation in the image. check_for_reflections : bool, optional - Determine if alignments are improved by relfecting/mirroring/flipping + Determine if alignments are improved by reflecting/mirroring/flipping images. Optional because it requires re-detecting features in each version of the images and then re-matching features, and so can be time consuming and not always necessary. @@ -1837,7 +1837,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, max_non_rigid_registration_dim_px : int, optional Maximum width or height of images used for non-rigid registration. - Larger values may yeild more accurate results, at the expense of + Larger values may yield more accurate results, at the expense of speed and memory. There is also a practical limit, as the specified size may be too large to fit in memory. @@ -1860,7 +1860,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, this step is skipped. micro_rigid_registrar_params : dictionary - Dictionary of keyword arguments used intialize the `MicroRigidRegistrar` + Dictionary of keyword arguments used initialize the `MicroRigidRegistrar` qt_emitter : PySide2.QtCore.Signal, optional Used to emit signals that update the GUI's progress bars @@ -1960,7 +1960,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, compose_non_rigid=compose_non_rigid, qt_emitter=qt_emitter) - # Info realted to saving images to view results # + # Info related to saving images to view results # self.mask_dict = None self.create_masks = create_masks @@ -2169,7 +2169,7 @@ def get_slide(self, src_f): msg = (f"\n{src_f} matches {n_matching} images in this dataset:\n" f"{pformat(self._dup_names_dict[default_name])}" f"\n\nPlease see `Valis.name_dict` to find correct name in " - f"the dictionary. Either key (filenmae) or value (assigned name) will work:\n" + f"the dictionary. Either key (filename) or value (assigned name) will work:\n" f"{pformat(possible_names_dict)}") valtils.print_warning(msg) @@ -2425,14 +2425,14 @@ def create_img_processor_dict(self, brightfield_processing_cls=DEFAULT_BRIGHTFIE Should return a single channel uint8 image. brightfield_processing_kwargs : dict - Dictionary of keyward arguments to be passed to `brightfield_processing_cls` + Dictionary of keyword arguments to be passed to `brightfield_processing_cls` if_processing_cls : ImageProcesser ImageProcesser to pre-process immunofluorescent images to make them look as similar as possible. Should return a single channel uint8 image. if_processing_kwargs : dict - Dictionary of keyward arguments to be passed to `if_processing_cls` + Dictionary of keyword arguments to be passed to `if_processing_cls` processor_dict : dict Each key should be the filename of the image, and the value either a subclassed @@ -3349,7 +3349,7 @@ def prep_images_for_large_non_rigid_registration(self, max_img_dim, else: s = np.min(max_img_dim/np.array(ref_slide.processed_img_shape_rc)) else: - # Determine how big image would have to be to get mask with maxmimum dimension = max_img_dim + # Determine how big image would have to be to get mask with maximum dimension = max_img_dim if isinstance(mask, pyvips.Image): mask_shape_rc = np.array((mask.height, mask.width)) else: @@ -3724,10 +3724,10 @@ def measure_error(self): `summary_df` contains various information about the registration. The "from" column is the name of the image, while the "to" column - name of the image it was aligned to. "from" is analagous to "moving" - or "current", while "to" is analgous to "fixed" or "previous". + name of the image it was aligned to. "from" is analogous to "moving" + or "current", while "to" is analogous to "fixed" or "previous". - Columns begining with "original" refer to error measurements of the + Columns beginning with "original" refer to error measurements of the unregistered images. Those beginning with "rigid" or "non_rigid" refer to measurements related to rigid or non-rigid registration, respectively. @@ -3751,7 +3751,7 @@ def measure_error(self): "aligned_shape" is the shape of the registered full resolution slide - "physical_units" are the names of the pixels physcial unit, e.g. u'\u00B5m' + "physical_units" are the names of the pixels physical unit, e.g. u'\u00B5m' "resolution" is the physical unit per pixel @@ -3932,13 +3932,13 @@ def register(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, then conduct rigid registration. Non-rigid registration will then be performed if the `non_rigid_registrar_cls` argument used to initialize the Valis object was not None. - In addition to the objects returned, the desination directory (i.e. `dst_dir`) + In addition to the objects returned, the destination directory (i.e. `dst_dir`) will contain thumbnails so that one can visualize the results: converted image thumbnails will be in "images/"; processed images in "processed/"; rigidly aligned images in "rigid_registration/"; non-rigidly aligned images in "non_rigid_registration/"; non-rigid deformation field images (i.e. warped grids colored by the direction and magntidue) of the deformation) will be in ""deformation_fields/". The size of these thumbnails - is determined by the `thumbnail_size` argument used to initialze this object. + is determined by the `thumbnail_size` argument used to initialize this object. One can get a sense of how well the registration worked by looking in the "overlaps/", which shows how the images overlap before @@ -3959,14 +3959,14 @@ def register(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, them look as similar as possible. brightfield_processing_kwargs : dict - Dictionary of keyward arguments to be passed to `brightfield_processing_cls` + Dictionary of keyword arguments to be passed to `brightfield_processing_cls` if_processing_cls : preprocessing.ImageProcesser preprocessing.ImageProcesser used to pre-process immunofluorescent images to make them look as similar as possible. if_processing_kwargs : dict - Dictionary of keyward arguments to be passed to `if_processing_cls` + Dictionary of keyword arguments to be passed to `if_processing_cls` processor_dict : dict Each key should be the filename of the image, and the value either a subclassed @@ -3997,10 +3997,10 @@ def register(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, `summary_df` contains various information about the registration. The "from" column is the name of the image, while the "to" column - name of the image it was aligned to. "from" is analagous to "moving" - or "current", while "to" is analgous to "fixed" or "previous". + name of the image it was aligned to. "from" is analogous to "moving" + or "current", while "to" is analogous to "fixed" or "previous". - Columns begining with "original" refer to error measurements of the + Columns beginning with "original" refer to error measurements of the unregistered images. Those beginning with "rigid" or "non_rigid" refer to measurements related to rigid or non-rigid registration, respectively. @@ -4024,7 +4024,7 @@ def register(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, "aligned_shape" is the shape of the registered full resolution slide - "physical_units" are the names of the pixels physcial unit, e.g. u'\u00B5m' + "physical_units" are the names of the pixels physical unit, e.g. u'\u00B5m' "resolution" is the physical unit per pixel @@ -4123,7 +4123,7 @@ def register_micro(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, non_rigid_registrar_cls=DEFAULT_NON_RIGID_CLASS, non_rigid_reg_params=DEFAULT_NON_RIGID_KWARGS, reference_img_f=None, align_to_reference=False, mask=None, tile_wh=DEFAULT_NR_TILE_WH): - """Improve alingment of microfeatures by performing second non-rigid registration on larger images + """Improve alignment of microfeatures by performing second non-rigid registration on larger images Caclculates additional non-rigid deformations using a larger image @@ -4134,14 +4134,14 @@ def register_micro(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, them look as similar as possible. brightfield_processing_kwargs : dict - Dictionary of keyward arguments to be passed to `brightfield_processing_cls` + Dictionary of keyword arguments to be passed to `brightfield_processing_cls` if_processing_cls : preprocessing.ImageProcesser preprocessing.ImageProcesser used to pre-process immunofluorescent images to make them look as similar as possible. if_processing_kwargs : dict - Dictionary of keyward arguments to be passed to `if_processing_cls` + Dictionary of keyword arguments to be passed to `if_processing_cls` max_non_rigid_registration_dim_px : int, optional Maximum width or height of images used for non-rigid registration. @@ -4163,7 +4163,7 @@ def register_micro(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, non_rigid_registrar_cls : NonRigidRegistrar, optional Uninstantiated NonRigidRegistrar class that will be used to calculate the deformation fields between images. See - the `non_rigid_registrars` module for a desciption of available + the `non_rigid_registrars` module for a description of available methods. If a desired non-rigid registration method is not available, one can be implemented by subclassing.NonRigidRegistrar. @@ -4171,7 +4171,7 @@ def register_micro(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, Dictionary containing key, value pairs to be used to initialize `non_rigid_registrar_cls`. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. See the NonRigidRegistrar classes in `non_rigid_registrars` for the available non-rigid registration methods and arguments. @@ -4207,7 +4207,7 @@ def register_micro(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, if using_tiler: # Have determined that these images will be too big msg = (f"Registration would more than {TILER_THRESH_GB} GB if all images opened in memory. " - f"Will use NonRigidTileRegistrar to register cooresponding tiles to reduce memory consumption, " + f"Will use NonRigidTileRegistrar to register corresponding tiles to reduce memory consumption, " f"but this method is experimental") valtils.print_warning(msg) @@ -4424,7 +4424,7 @@ def warp_and_save_slides(self, dst_dir, level=0, non_rigid=True, image will not be cropped. If "overlap", the warped slide will be cropped to include only areas where all images overlapped. "reference" crops to the area that overlaps with the reference image, - defined by `reference_img_f` when initialzing the `Valis object`. + defined by `reference_img_f` when initializing the `Valis object`. colormap : list List of RGB colors (0-255) to use for channel colors @@ -4491,7 +4491,7 @@ def warp_and_merge_slides(self, dst_f=None, level=0, non_rigid=True, image will not be cropped. If "overlap", the warped slide will be cropped to include only areas where all images overlapped. "reference" crops to the area that overlaps with the reference image, - defined by `reference_img_f` when initialzing the `Valis object`. + defined by `reference_img_f` when initializing the `Valis object`. channel_name_dict : dict of lists, optional. key = slide file name, value = list of channel names for that slide. If None, diff --git a/examples/acrobat_2023/valis/serial_non_rigid.py b/examples/acrobat_2023/valis/serial_non_rigid.py index fb9c68b0..0e826d74 100644 --- a/examples/acrobat_2023/valis/serial_non_rigid.py +++ b/examples/acrobat_2023/valis/serial_non_rigid.py @@ -373,7 +373,7 @@ def calc_deformation(self, registered_fixed_image, non_rigid_reg_class, Used to warp the registered_img before finding deformation fields. params : dictionary, optional - Keyword: value dictionary of parameters to be used in reigstration. + Keyword: value dictionary of parameters to be used in registration. Passed to the non_rigid_reg_class' init() method. In the case where simple ITK will be used, params should be @@ -553,7 +553,7 @@ class SerialNonRigidRegistrar(object): Dictionary containing parameters {name: value} to be used to initialize the NonRigidRegistrar. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. mask : ndarray @@ -607,7 +607,7 @@ def __init__(self, src, reference_img_f=None, moving_to_fixed_xy=None, To deterime which pairs of images will be aligned, use `get_alignment_indices`. Can use `get_imgs_from_dir` to see the order inwhich the images will be read, which will correspond - to the indices retuned by `get_alignment_indices`. + to the indices returned by `get_alignment_indices`. If `src` is a SerialRigidRegistrar and `moving_to_fixed_xy` is True, then the matching features in the SerialRigidRegistrar will @@ -832,7 +832,7 @@ def register_serial(self, non_rigid_reg_class, non_rigid_reg_params=None, img_pa Dictionary containing parameters {name: value} to be used to initialize the NonRigidRegistrar. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. """ @@ -882,7 +882,7 @@ def register_to_ref(self, non_rigid_reg_class, non_rigid_reg_params=None, img_pa Dictionary containing parameters {name: value} to be used to initialize the NonRigidRegistrar. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. """ @@ -916,7 +916,7 @@ def register_groupwise(self, non_rigid_reg_class, non_rigid_reg_params=None): Dictionary containing parameters {name: value} to be used to initialize the NonRigidRegistrar. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. """ @@ -950,7 +950,7 @@ def register(self, non_rigid_reg_class, non_rigid_reg_params, img_params=None): Dictionary containing parameters {name: value} to be used to initialize the NonRigidRegistrar. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. img_params : dict, optional Dictionary of parameters to be used for each particular image. @@ -981,7 +981,7 @@ def summarize(self): Returns ------- summary_df: Dataframe - Pandas dataframe containin the registration error of the + Pandas dataframe containing the registration error of the alignment between each image and the previous one in the stack. """ @@ -1069,11 +1069,11 @@ def register_images(src, non_rigid_reg_class=non_rigid_registrars.OpticalFlowWar Dictionary containing parameters {name: value} to be used to initialize the NonRigidRegistrar. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. dst_dir : str, optional - Top directory where aliged images should be save. SerialNonRigidRegistrar will + Top directory where aligned images should be save. SerialNonRigidRegistrar will be in this folder, and aligned images in the "registered_images" sub-directory. If None, the images will not be written to file @@ -1093,7 +1093,7 @@ def register_images(src, non_rigid_reg_class=non_rigid_registrars.OpticalFlowWar To deterime which pairs of images will be aligned, use `warp_tools.get_alignment_indices`. Can use `get_imgs_from_dir` to see the order inwhich the images will be read, which will correspond - to the indices retuned by `warp_tools.get_alignment_indices`. + to the indices returned by `warp_tools.get_alignment_indices`. If `src` is a SerialRigidRegistrar and `moving_to_fixed_xy` is True, then the matching features in the SerialRigidRegistrar will @@ -1113,7 +1113,7 @@ def register_images(src, non_rigid_reg_class=non_rigid_registrars.OpticalFlowWar Optional name for this SerialNonRigidRegistrar align_to_reference : bool, optional - Whether or not images should be aligne to a reference image + Whether or not images should be align to a reference image specified by `reference_img_f`. Will be set to True if `reference_img_f` is provided. diff --git a/examples/acrobat_2023/valis/serial_rigid.py b/examples/acrobat_2023/valis/serial_rigid.py index 1ddb46da..2302bc20 100644 --- a/examples/acrobat_2023/valis/serial_rigid.py +++ b/examples/acrobat_2023/valis/serial_rigid.py @@ -34,7 +34,7 @@ def get_image_files(img_dir, imgs_ordered=False): img_dir : str Path to directory containing the images. - imgs_ordered: bool, optinal + imgs_ordered: bool, optional Whether or not the order of images already known. If True, the file names should start with ascending numbers, with the first image file having the smallest number, and the last image file having the largest @@ -86,7 +86,7 @@ def order_Dmat(D): Leaf sorting is accomplished using optimal leaf ordering (Bar-Joseph 2001) - Parmaters + Parameters --------- D: ndarray (N, N) Symmetric distance matrix for N samples @@ -138,7 +138,7 @@ class ZImage(object): Name of the image. Usually `img_f` but with the extension removed. desc : ndarray - (N, M) array of N desciptors for each keypoint, each of which has + (N, M) array of N descriptors for each keypoint, each of which has M features kp_pos_xy : ndarray @@ -287,7 +287,7 @@ class SerialRigidRegistrar(object): Registration is conducted by first detecting features in all images. Features are then matched between images, which are then used to construct a distance matrix, D. D is then sorted such that the most similar images - are adjcent to one another. The rigid transformation matrics are then found to + are adjacent to one another. The rigid transformation matrices are then found to align each image with the previous image. Optionally, optimization can be performed to improve the alignments, although the "optimized" matrix will be discarded if it increases the distances between matched features. @@ -329,7 +329,7 @@ class SerialRigidRegistrar(object): distance_metric_type : str Name of the type of metric used to determine the dis/similarity between each pair of images. Despite the name, it could be "similarity" - if the Matcher object compares image feautres using a similarity + if the Matcher object compares image features using a similarity metric. In that case, similarities are converted to distances. img_obj_list : list @@ -374,7 +374,7 @@ class SerialRigidRegistrar(object): the `img_obj_list` has been sorted. align_to_reference : bool, optional - Whether or not images should be aligne to a reference image + Whether or not images should be align to a reference image specified by `reference_img_f`. Will be set to True if `reference_img_f` is provided. @@ -385,7 +385,7 @@ class SerialRigidRegistrar(object): image. summary_df : Dataframe - Pandas dataframe containin the registration error of the + Pandas dataframe containing the registration error of the alignment between each image and the previous one in the stack. """ @@ -419,7 +419,7 @@ def __init__(self, img_dir, imgs_ordered=False, reference_img_f=None, Descriptive name of registrar, such as the sample's name align_to_reference : bool, optional - Whether or not images should be aligne to a reference image + Whether or not images should be align to a reference image specified by `reference_img_f`. Will be set to True if `reference_img_f` is provided. @@ -668,7 +668,7 @@ def get_common_desc(self, current_img_obj, neighbor_obj, nf_kp_idx): Parameters ---------- nf_kp_idx : ndarray - Indicies of already matched keypoints that were found after + Indices of already matched keypoints that were found after neighbonr filtering """ @@ -960,7 +960,7 @@ def align_to_prev_check_reflections(self, transformer, feature_detector, matcher else: filter_kwargs = None - # Estimate curent error without reflections. Don't need to re-detect and match features + # Estimate current error without reflections. Don't need to re-detect and match features to_prev_match_info = img_obj.match_dict[prev_img_obj] transformer.estimate(to_prev_match_info.matched_kp2_xy, to_prev_match_info.matched_kp1_xy) unreflected_warped_src_xy = warp_tools.warp_xy(to_prev_match_info.matched_kp1_xy, transformer.params) @@ -1037,7 +1037,7 @@ def align_to_prev_check_reflections(self, transformer, feature_detector, matcher ref_x, ref_y = best_reflect_M[[0, 1], [0, 1]] < 0 if ref_x or ref_y: - msg = f'detected relfections between {img_obj.name} and {prev_img_obj.name} along the' + msg = f'detected reflections between {img_obj.name} and {prev_img_obj.name} along the' if ref_x and ref_y: msg = f'{msg} x and y axes' elif ref_x: @@ -1344,7 +1344,7 @@ def summarize(self): Returns ------- summary_df: Dataframe - Pandas dataframe containin the registration error of the + Pandas dataframe containing the registration error of the alignment between each image and the previous one in the stack. """ @@ -1433,7 +1433,7 @@ def register_images(img_dir, dst_dir=None, name="registrar", to be registered. These images need to be single channel, uint8 images dst_dir : str, optional - Top directory where aliged images should be save. SerialRigidRegistrar will + Top directory where aligned images should be save. SerialRigidRegistrar will be in this folder, and aligned images in the "registered_images" sub-directory. If None, the images will not be written to file @@ -1459,14 +1459,14 @@ def register_images(img_dir, dst_dir=None, name="registrar", are already in the correct order. If True, then each filename should begin with the number that indicates its position in the z-stack. If False, then the images will be sorted by ordering a feature distance - matix. + matrix. reference_img_f : str, optional Filename of image that will be treated as the center of the stack. If None, the index of the middle image will be the reference. check_for_reflections : bool, optional - Determine if alignments are improved by relfecting/mirroring/flipping + Determine if alignments are improved by reflecting/mirroring/flipping images. Optional because it requires re-detecting features in each version of the images and then re-matching features, and so can be time consuming and not always necessary. @@ -1489,7 +1489,7 @@ def register_images(img_dir, dst_dir=None, name="registrar", Returns ------- registrar : SerialRigidRegistrar - SerialRigidRegistrar object contains general information about the alginments, + SerialRigidRegistrar object contains general information about the alignments, but also a list of Z-images. Each ZImage contains the warp information for an image in the stack, including the transformation matrices calculated at each step, keypoint poisions, image descriptors, and diff --git a/examples/acrobat_2023/valis/slide_io.py b/examples/acrobat_2023/valis/slide_io.py index 0e5cb02f..cd443894 100644 --- a/examples/acrobat_2023/valis/slide_io.py +++ b/examples/acrobat_2023/valis/slide_io.py @@ -52,7 +52,7 @@ """str: Physical unit when the unit can't be found in the metadata""" MICRON_UNIT = u'\u00B5m' -"""str: Phyiscal unit for micron/micrometers""" +"""str: Physical unit for micron/micrometers""" ALL_OPENSLIDE_READABLE_FORMATS = [".svs", ".tif", ".vms", ".vmu", ".ndpi", ".scn", ".mrxs", ".tiff", ".svslide", ".bif"] """list: File extensions that OpenSlide can read""" @@ -737,7 +737,7 @@ def get_channel_index(self, channel): elif len(matching_channels) > 1: all_matching_channels = ", ".join([f"'{self.metadata.channel_names[i]}'" for i in matching_channels]) - msg = f"Fount multiple channels that match '{channel}' in {self.src_f}. These are: {all_matching_channels}. Using channel 0" + msg = f"Found multiple channels that match '{channel}' in {self.src_f}. These are: {all_matching_channels}. Using channel 0" valtils.print_warning(msg) matching_channel_idx = 0 @@ -927,7 +927,7 @@ def slide2vips(self, level, series=None, xywh=None, tile_wh=None, *args, **kwarg the region to be sliced. tile_wh : int, optional - Size of tiles used to contstruct `vips_slide` + Size of tiles used to construct `vips_slide` Returns ------- @@ -1277,7 +1277,7 @@ class VipsSlideReader(SlideReader): Whether or not openslide can be used to read this slide. is_ome : bool - Whether ot not the side is an ome.tiff. + Whether or not the side is an ome.tiff. Notes ----- @@ -2329,7 +2329,7 @@ def get_slide_reader(src_f, series=None): can_only_use_openslide = f_extension in OPENSLIDE_ONLY if can_only_use_openslide and not can_use_openslide: msg = (f"file {os.path.split(src_f)[1]} can only be read by OpenSlide, " - f"which is required to open files with the follwing extensions: {', '.join(OPENSLIDE_ONLY)}. " + f"which is required to open files with the following extensions: {', '.join(OPENSLIDE_ONLY)}. " f"However, OpenSlide cannot be found. Unable to read this slide." ) @@ -2462,7 +2462,7 @@ def get_shape_xyzct(shape_wh, n_channels): Parameters ---------- shape_wh : tuple of int - Width and heigth of image + Width and height of image n_channels : int Number of channels in the image @@ -2486,7 +2486,7 @@ def create_channel(channel_id, name=None, color=None): channel_id : int Channel number - name : str, optinal + name : str, optional Channel name color : tuple of int @@ -2816,7 +2816,7 @@ def save_ome_tiff(img, dst_f, ome_xml=None, tile_wh=1024, compression="lzw"): to a pyvips.Image. ome_xml : str, optional - ome-xml string describing image's metadata. If None, it will be createdd + ome-xml string describing image's metadata. If None, it will be created tile_wh : int Tile shape used to save `img`. Used to create a square tile, so `tile_wh` diff --git a/examples/acrobat_2023/valis/slide_tools.py b/examples/acrobat_2023/valis/slide_tools.py index dd13dedf..62ecff1c 100644 --- a/examples/acrobat_2023/valis/slide_tools.py +++ b/examples/acrobat_2023/valis/slide_tools.py @@ -225,7 +225,7 @@ def determine_if_staining_round(src_dir): def um_to_px(um, um_per_px): - """Conver mircon to pixel + """Convert mircon to pixel """ return um * 1/um_per_px @@ -272,7 +272,7 @@ def warp_slide(src_f, transformation_src_shape_rc, transformation_dst_shape_rc, interp_method : str, optional bbox_xywh : tuple - Bounding box to crop warped slide. Should be in refernce the + Bounding box to crop warped slide. Should be in reference the warped slide Returns diff --git a/examples/acrobat_2023/valis/viz.py b/examples/acrobat_2023/valis/viz.py index 143d04a9..72b355e1 100644 --- a/examples/acrobat_2023/valis/viz.py +++ b/examples/acrobat_2023/valis/viz.py @@ -43,7 +43,7 @@ def draw_outline(img, mask, clr=(100, 240, 39), thickness=2): clr : ndarray RGB (0-255) color of outline - thicknes : int + thickness : int Thickness of outline Returns diff --git a/examples/acrobat_2023/valis/warp_tools.py b/examples/acrobat_2023/valis/warp_tools.py index d37382ab..ebc88d34 100644 --- a/examples/acrobat_2023/valis/warp_tools.py +++ b/examples/acrobat_2023/valis/warp_tools.py @@ -95,7 +95,7 @@ def get_alignment_indices(n_imgs, ref_img_idx=None): Indices go from bottom to center, then top to center. In each case, the alignments go from closest to the center, to next closet, etc... - The reference image is exclued from this list. + The reference image is excluded from this list. For example, if `ref_img_idx` is 2, then the order is [(1, 2), (0, 1), (3, 2), ..., (`n_imgs`-1, `n_imgs` - 2)]. @@ -669,8 +669,8 @@ def mattes_mi(img1, img2, nbins=50, mask=None): Number of histogram bins mask : ndarray, None - Mask with shape (N, M) that indiates where the metric - should be calulated. If None, the metric will be calculated + Mask with shape (N, M) that indicates where the metric + should be calculated. If None, the metric will be calculated for all NxM pixels. Returns @@ -730,7 +730,7 @@ def order_points(pts_xy): ### https://math.stackexchange.com/questions/978642/how-to-sort-vertices-of-a-polygon-in-counter-clockwise-order - # warnings.warn("Outpout is now clockwise. May need update functions that call this") + # warnings.warn("Output is now clockwise. May need update functions that call this") # sort the points based on their x-coordinates xSorted = pts_xy[np.argsort(pts_xy[:, 0]), :] # grab the left-most and right-most points from the sorted @@ -901,7 +901,7 @@ def warp_img(img, M=None, bk_dxdy=None, out_shape_rc=None, interp_method="bicubic"): """Warp an image using rigid and/or non-rigid transformations - Warp an image using the trasformations defined by `M` and the optional + Warp an image using the transformations defined by `M` and the optional displacement field, `bk_dxdy`. Transformations will be scaled so that they can be applied to the image. @@ -1076,7 +1076,7 @@ def warp_img(img, M=None, bk_dxdy=None, out_shape_rc=None, warp_index = (index[0] + warp_dxdy[0]).bandjoin(index[1] + warp_dxdy[1]) try: - #Option to set backround color in mapim added in libvips 8.13 + #Option to set background color in mapim added in libvips 8.13 warped = affine_warped.mapim(warp_index, premultiplied=True, background=bg_color, @@ -1103,9 +1103,9 @@ def warp_img(img, M=None, bk_dxdy=None, out_shape_rc=None, def warp_img_inv(img, M=None, fwd_dxdy=None, transformation_src_shape_rc=None, transformation_dst_shape_rc=None, src_shape_rc=None, bk_dxdy=None, bg_color=None, interp_method="bicubic"): """Unwarp an image using rigid and/or non-rigid transformations - Unwarp an image using the trasformations defined by `M` and the optional + Unwarp an image using the transformations defined by `M` and the optional displacement field, `bk_dxdy`. This is accomplished by inverting `M` and - using the "foward" displacements in `fwd_dxdy`. If `fwd_dxdy` is not provided, + using the "forward" displacements in `fwd_dxdy`. If `fwd_dxdy` is not provided, `bk_dxdy` will be inverted. Transformations will be scaled so that they can be applied to the images with different sizes. @@ -1206,7 +1206,7 @@ def warp_img_inv(img, M=None, fwd_dxdy=None, transformation_src_shape_rc=None, t warp_index = (index[0] + warp_dxdy[0]).bandjoin(index[1] + warp_dxdy[1]) try: - #Option to set backround color in mapim added in libvips 8.13 + #Option to set background color in mapim added in libvips 8.13 nr_warped = img.mapim(warp_index, premultiplied=True, background=bg_color, @@ -1266,7 +1266,7 @@ def warp_img_from_to(img, from_M=None, from_transformation_src_shape_rc=None, Warps `img` to registered coordinates using the "from" parameters, and then uses the inverse "to" parameters to warp that image to the "to" image's coordinate system. - Can be useful for transfering annotations from one image to another. + Can be useful for transferring annotations from one image to another. Note: If `img` is a labeled image, it is recommended to set `interp_method` to "nearest" @@ -1661,7 +1661,7 @@ def get_rotate_around_center_M(img_shape, rotation_rad): def calc_d(pt1, pt2): """ - Calculate euclidean disrances between each pair coresponding points in pt1 and pt2 + Calculate euclidean disrances between each pair corresponding points in pt1 and pt2 Parameters ---------- @@ -1674,7 +1674,7 @@ def calc_d(pt1, pt2): Returns ------- d : [N] - distnace between correspoing points in pt1 and pt2 + distance between correspoing points in pt1 and pt2 """ d = np.sqrt(np.sum((pt1 - pt2)**2, axis=1)) @@ -1809,7 +1809,7 @@ def warp_xy_rigid(xy, inv_matrix): Warp xy given an inverse transformation matrix found using one of scikit-image's transform objects Inverse matrix should have been found using tform(dst, src) - Adpated from skimage._geometric.ProjectiveTransform._apply_mat + Adapted from skimage._geometric.ProjectiveTransform._apply_mat Changed so that inverse matrix (found using dst -> src) automatically inverted to warp points forward (src -> dst) """ xy = np.array(xy, copy=False, ndmin=2) @@ -2398,7 +2398,7 @@ def warp_xy_from_to(xy, from_M=None, from_transformation_src_shape_rc=None, def clip_xy(xy, shape_rc): - """Clip xy coordintaes to be within image + """Clip xy coordinates to be within image """ clipped_x = np.clip(xy[:, 0], 0, shape_rc[1]) @@ -2410,7 +2410,7 @@ def clip_xy(xy, shape_rc): def _warp_shapely(geom, warp_fxn, warp_kwargs, shift_xy=None): """Warp a shapely geometry - Based on shapely.ops.trasform + Based on shapely.ops.transform """ if "dst_shape_rc" in warp_kwargs: @@ -2685,7 +2685,7 @@ def bbox2xy(xywh): Parameters ----------- xywh: [4, ] array - (top left x-coordinate, top left y coordiante, width, height) of a bounding box + (top left x-coordinate, top left y coordinate, width, height) of a bounding box Returns ------- @@ -2798,7 +2798,7 @@ def measure_error(src_xy, dst_xy, shape, feature_similarity=None): Median relative Target Registration Error (rTRE) between images med_d : float - Median Euclidean distance between src_xy and dst_xy, optinally weighted by feature similarity + Median Euclidean distance between src_xy and dst_xy, optionally weighted by feature similarity """ d = np.sqrt((src_xy[:, 0]-dst_xy[:, 0])**2 + (src_xy[:, 1]-dst_xy[:, 1])**2) @@ -2966,7 +2966,7 @@ def remove_folds_in_dxdy(dxdy, n_grid_pts=50, method="inpaint", paint_size=5000, method : str, optional "inpaint" will use inpainting to fill in areas idenetified as containing folds. "regularize" will unfold those regions - using the mehod described in "Foldover-free maps in 50 lines of code" + using the method described in "Foldover-free maps in 50 lines of code" Garanzha et al. 2021. n_grid_pts : int @@ -3115,7 +3115,7 @@ def __init__(self, dxdy, n_grid_pts=50): padded_dy = transform.warp(dxdy[1], self.padding_T, output_shape=padded_shape, preserve_range=True) self.padded_dxdy = np.array([padded_dx, padded_dy]) - # Flattend indices for each pixel in a quadrat + # Flattened indices for each pixel in a quadrat quads = [[r*nc + c, r*nc + c + 1, (r+1)*nc + c + 1, (r+1)*nc + c] for r in range(nr-1) for c in range(nc-1)] self.quads = quads self.boundary = [None] * self.nverts diff --git a/examples/register_and_merge_cycif.py b/examples/register_and_merge_cycif.py index db56f8ce..64e62566 100644 --- a/examples/register_and_merge_cycif.py +++ b/examples/register_and_merge_cycif.py @@ -33,7 +33,7 @@ These can be used to get a better sense of how the images were altered by non-rigid warping -6. *processed* shows thumnails of the processed images. +6. *processed* shows thumbnails of the processed images. This are thumbnails of the images that are actually used to perform the registration. The pre-processing and normalization methods should try to make these @@ -41,7 +41,7 @@ After registraation is complete, one should view the -results to determine if they aare acceptable. +results to determine if they are acceptable. Since the slides are being merged, one may want to provide channel names. This can be accomplished by passing a @@ -65,7 +65,7 @@ stop = time.time() elapsed = stop - start -print(f"regisration time is {elapsed/60} minutes") +print(f"registration time is {elapsed/60} minutes") # Merge registered channels diff --git a/examples/register_high_rez.py b/examples/register_high_rez.py index 721bb18d..bbd187ba 100644 --- a/examples/register_high_rez.py +++ b/examples/register_high_rez.py @@ -3,7 +3,7 @@ This example shows how to register the slides using higher resolution images. An initial rigid transform is found using low resolition images, but the `MicroRigidRegistrar` can be used to update that transform using feature matches -found in higher resoltion images. This can be followed up by the high resolution +found in higher resolution images. This can be followed up by the high resolution non-rigid registration (i.e. micro-registration). """ @@ -49,7 +49,7 @@ stop = time.time() elapsed = stop - start -print(f"regisration time is {elapsed/60} minutes") +print(f"registration time is {elapsed/60} minutes") # We can also plot the high resolution matches using `Valis.draw_matches`: matches_dst_dir = os.path.join(registrar.dst_dir, "hi_rez_matches") diff --git a/examples/register_ihc.py b/examples/register_ihc.py index e4bd66f5..fafcbbbb 100644 --- a/examples/register_ihc.py +++ b/examples/register_ihc.py @@ -33,7 +33,7 @@ These can be used to get a better sense of how the images were altered by non-rigid warping -6. *processed* shows thumnails of the processed images. +6. *processed* shows thumbnails of the processed images. This are thumbnails of the images that are actually used to perform the registration. The pre-processing and normalization methods should try to make these @@ -41,7 +41,7 @@ After registraation is complete, one should view the -results to determine if they aare acceptable. If they +results to determine if they are acceptable. If they are, then one can warp and save all of the slides. """ @@ -60,7 +60,7 @@ rigid_registrar, non_rigid_registrar, error_df = registrar.register() stop = time.time() elapsed = stop - start -print(f"regisration time is {elapsed/60} minutes") +print(f"registration time is {elapsed/60} minutes") # Check results in registered_slide_dst_dir. If they look good, export the registered slides diff --git a/examples/warp_annotation_image.py b/examples/warp_annotation_image.py index 15cc5000..52eb9ca6 100644 --- a/examples/warp_annotation_image.py +++ b/examples/warp_annotation_image.py @@ -14,7 +14,7 @@ -# Perform registration. Can optinally set the reference image to be the same as the one the annotations are based on (i.e. `reference_img_f`) +# Perform registration. Can optionally set the reference image to be the same as the one the annotations are based on (i.e. `reference_img_f`) registrar = registration.Valis(slide_src_dir, results_dst_dir, reference_img_f=reference_img_f) rigid_registrar, non_rigid_registrar, error_df = registrar.register() diff --git a/pyproject.toml b/pyproject.toml index d99d3dc5..fbb264b9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,3 +52,10 @@ priority = "supplemental" name = "PyPI" priority = "primary" + +[tool.codespell] +# Ref: https://github.com/codespell-project/codespell#using-a-config-file +skip = '.git*,*.pdf,*.lock' +check-hidden = true +ignore-regex = '\bTRE\b' +# ignore-words-list = '' diff --git a/valis/affine_optimizer.py b/valis/affine_optimizer.py index 9e551b47..0c83f7a9 100644 --- a/valis/affine_optimizer.py +++ b/valis/affine_optimizer.py @@ -1,7 +1,7 @@ """Optimize rigid alignment Contains functions related to optimization, as well as the AffineOptimizer -class that performs the optimzation. This class can be subclassed to implement +class that performs the optimization. This class can be subclassed to implement custom optimization methods. There are several subclasses, but AffineOptimizerMattesMI is the @@ -211,7 +211,7 @@ def get_intersection(alpha1, alpha2, abc1, abc2): def get_verts(img, x, y, pos=0): """ - Get veritices of triangle and intenisty at each vertex + Get veritices of triangle and intensity at each vertex """ if pos == 0: # Lower left @@ -272,7 +272,7 @@ def update_joint_H(binned_moving, binned_fixed, H, M, sample_pts, pos=0, img2_v = get_verts(binned_fixed, sxy[0], sxy[1], pos) abc2 = solve_abc(img2_v) else: - # ABC for fixed image's trianges are precomputed + # ABC for fixed image's triages are precomputed abc2 = precalcd_abc[i] x_lims = np.array([np.min(img1_v[:, 0]), np.max(img1_v[:, 0])]) @@ -332,7 +332,7 @@ def build_P(A, B, r, mask): def entropy(x): """ - Caclulate Shannon's entropy for array x + Calculate Shannon's entropy for array x Parameters ---------- @@ -474,7 +474,7 @@ class AffineOptimizer(object): Type of transformation, "EuclideanTransform" or "SimilarityTransform" current_level : int - Current level of the Guassian pyramid that is being registered + Current level of the Gaussian pyramid that is being registered accepts_xy : bool Bool declaring whether or not the optimizer will use corresponding points to optimize the registration @@ -505,7 +505,7 @@ class AffineOptimizer(object): Major overhauls are possible too. See AffineOptimizerMattesMI for an example on using SimpleITK's optimization methods inside of an AffineOptimizer subclass - If the optimizer uses corressponding points, then the class attribute + If the optimizer uses corresponding points, then the class attribute accepts_xy needs to be set to True. The default is False. """ @@ -977,7 +977,7 @@ def shannon_entropy(self, X, k=1): def mutual_information(self, A, B): if self.HA_list[self.current_level] is None: - # Only need to caluclate once per level, becuase the fixed + # Only need to calculate once per level, because the fixed # image doesn't change self.HA_list[self.current_level] = self.shannon_entropy(A) diff --git a/valis/feature_detectors.py b/valis/feature_detectors.py index 35abd496..e972135d 100644 --- a/valis/feature_detectors.py +++ b/valis/feature_detectors.py @@ -3,7 +3,7 @@ Bundles OpenCV feature detectors and descriptors into the FeatureDD class Also makes it easier to mix and match feature detectors and descriptors -from different pacakges (e.g. skimage and OpenCV). See CensureVggFD for +from different packages (e.g. skimage and OpenCV). See CensureVggFD for an example """ @@ -149,7 +149,7 @@ def detect_and_compute(self, image, mask=None): Returns ------- kp : ndarry - (N, 2) array positions of keypoints in xy corrdinates for N + (N, 2) array positions of keypoints in xy coordinates for N keypoints desc : ndarry @@ -298,7 +298,7 @@ def detect(self, image): Uses keypoint info to create KeyPoint objects for OpenCV - Paramters + Parameters --------- image : ndarray image from keypoints will be detected diff --git a/valis/feature_matcher.py b/valis/feature_matcher.py index d7b7e638..c994591e 100644 --- a/valis/feature_matcher.py +++ b/valis/feature_matcher.py @@ -19,7 +19,7 @@ Metrics found in both the valid metrics ang kernel methods in sklearn.metrics.pairwise. Issue is that metrics are distances, while kernels are similarities. Metrics in this set are assumed - to be distaces, unless the metric_type parameter in match_descriptors + to be distances, unless the metric_type parameter in match_descriptors is set to "similarity". """ @@ -58,7 +58,7 @@ def convert_distance_to_similarity(d, n_features=64): Value to convert n_features: int - Number of features used to calcuate distance. + Number of features used to calculate distance. Only needed when calc == 0 Returns ------- @@ -79,7 +79,7 @@ def convert_similarity_to_distance(s, n_features=64): Similarity to convert n_features: int - Number of features used to calcuate similarity. + Number of features used to calculate similarity. Only needed when calc == 0 Returns @@ -145,7 +145,7 @@ def filter_matches_gms(kp1_xy, kp2_xy, feature_d, img1_shape, img2_shape, Note that this function assumes the keypoints and distances have been sorted such that each keypoint in kp1_xy has the same index as the - matching keypoint in kp2_xy andd corresponding feautre distance in + matching keypoint in kp2_xy and corresponding feature distance in feature_d. For example, kp1_xy[0] should have the corresponding keypoint at kp2_xy[0] and the corresponding feature distance at feature_d[0]. @@ -397,7 +397,7 @@ def match_descriptors(descriptors1, descriptors2, metric=None, NOTE ---- - Modified from scikit-image to use scikit-learn's distance and kernal methods. + Modified from scikit-image to use scikit-learn's distance and kernel methods. """ if descriptors1.shape[1] != descriptors2.shape[1]: @@ -477,7 +477,7 @@ def match_desc_and_kp(desc1, kp1_xy, desc2, kp2_xy, metric=None, filtering_kwargs=None): """Match the descriptors of image 1 with those of image 2 and remove outliers. - Metric can be a string to use a distance in scipy.distnce.cdist(), + Metric can be a string to use a distance in scipy.distance.cdist(), or a custom distance function Parameters @@ -739,7 +739,7 @@ def set_names(self, img1_name, img2_name): class Matcher(object): - """Class that matchs the descriptors of image 1 with those of image 2 + """Class that matches the descriptors of image 1 with those of image 2 Outliers removed using RANSAC or GMS @@ -848,13 +848,13 @@ def match_images(self, desc1, kp1_xy, desc2, kp2_xy, additional_filtering_kwargs=None, *args, **kwargs): """Match the descriptors of image 1 with those of image 2, Outliers removed using match_filter_method. Metric can be a string - to use a distance in scipy.distnce.cdist(), or a custom distance - function. Sets atttributes for Matcher object + to use a distance in scipy.distance.cdist(), or a custom distance + function. Sets attributes for Matcher object Parameters ---------- desc1 : (N, P) array - Image 1s 2D array containinng N keypoints, each of which + Image 1s 2D array containing N keypoints, each of which has P features kp1_xy : (N, 2) array @@ -862,7 +862,7 @@ def match_images(self, desc1, kp1_xy, desc2, kp2_xy, N descriptors in desc1 desc2 : (M, P) array - Image 2s 2D array containinng M keypoints, each of which has + Image 2s 2D array containing M keypoints, each of which has P features kp2_xy : (M, 2) array diff --git a/valis/micro_rigid_registrar.py b/valis/micro_rigid_registrar.py index 6d86bfb6..dbc7eea4 100644 --- a/valis/micro_rigid_registrar.py +++ b/valis/micro_rigid_registrar.py @@ -153,14 +153,14 @@ def register(self, Should return a single channel uint8 image. brightfield_processing_kwargs : dict - Dictionary of keyward arguments to be passed to `brightfield_processing_cls` + Dictionary of keyword arguments to be passed to `brightfield_processing_cls` if_processing_cls : ImageProcesser ImageProcesser to pre-process immunofluorescent images to make them look as similar as possible. Should return a single channel uint8 image. if_processing_kwargs : dict - Dictionary of keyward arguments to be passed to `if_processing_cls` + Dictionary of keyword arguments to be passed to `if_processing_cls` """ diff --git a/valis/non_rigid_registrars.py b/valis/non_rigid_registrars.py index 9ec75516..95651abc 100644 --- a/valis/non_rigid_registrars.py +++ b/valis/non_rigid_registrars.py @@ -102,7 +102,7 @@ def __init__(self, params=None): Parameters ---------- params : dictionary - Keyword: value dictionary of parameters to be used in reigstration. + Keyword: value dictionary of parameters to be used in registration. Will get used in the calc() method. In the case where simple ITK will be used, params should be @@ -140,9 +140,9 @@ def apply_mask(self, mask): return masked_moving, masked_fixed def calc(self, moving_img, fixed_img, mask, *args, **kwargs): - """Cacluate displacement fields + """Calculate displacement fields - Can record subclass specific atrributes here too + Can record subclass specific attributes here too Parameters ---------- @@ -400,7 +400,7 @@ def __init__(self, params=None): Parameters ---------- params : dictionary - Keyword: value dictionary of parameters to be used in reigstration. + Keyword: value dictionary of parameters to be used in registration. Will get used in the calc() method. In the case where simple ITK will be used, params should be @@ -589,7 +589,7 @@ def register(self, img_list, mask=None): self.shape = img_list[0].shape for img in img_list: - assert img.shape == self.shape, print("Images have differernt shapes") + assert img.shape == self.shape, print("Images have different shapes") self.img_list = img_list self.size = len(img_list) @@ -941,7 +941,7 @@ def __init__(self, params=None, optical_flow_obj=None, Parameters ---------- params : dictionary - Keyword: value dictionary of parameters to be used in reigstration. + Keyword: value dictionary of parameters to be used in registration. Will get used in the calc() method. optical_flow_obj : object @@ -1167,7 +1167,7 @@ def calc(self, img_list, mask=None, *args, **kwargs): class NonRigidTileRegistrar(object): - """Tile-wise non-rigid regisration + """Tile-wise non-rigid registration Slices moving and fixed images into tiles and then registers each tile. Probably best for very large images. @@ -1206,7 +1206,7 @@ def __init__(self, params=None, tile_wh=512, tile_buffer=100): Parameters ---------- params : dictionary - Keyword: value dictionary of parameters to be used in reigstration. + Keyword: value dictionary of parameters to be used in registration. Will get used when initializing the `non_rigid_registrar_cls` In the case where simple ITK will be used, params should be @@ -1272,12 +1272,12 @@ def process_tile(self, img, img_processer_cls, processer_init_kwargs={}, process processer_init_kwargs["image"] = img processer_init_kwargs['reader'] = deepcopy(processer_init_kwargs["reader"]) processer_init_kwargs['level'] = 0 - processer = img_processer_cls(**processer_init_kwargs) + processor = img_processer_cls(**processer_init_kwargs) try: - processed_img = processer.process_image(**processer_kwargs) + processed_img = processor.process_image(**processer_kwargs) except TypeError: # processor.process_image doesn't take kwargs - processed_img = processer.process_image() + processed_img = processor.process_image() return processed_img @@ -1360,7 +1360,7 @@ def reg_tile(self, tile_idx, lock): self.fwd_dxdy_tiles[tile_idx] = vips_tile_fwd_dxdy def calc(self, *args, **kwargs): - """Cacluate displacement fields + """Calculate displacement fields Each tile is registered and then stitched together """ @@ -1410,7 +1410,7 @@ def register(self, moving_img, fixed_img, mask=None, non_rigid_registrar_cls=Opt preprocessing.ImageProcesser used to process the images processing_kwargs : dict - Dictionary of keyward arguments to be passed to `processing_cls` + Dictionary of keyword arguments to be passed to `processing_cls` target_stats : ndarray Target stats used to normalize each tile after being processed. diff --git a/valis/preprocessing.py b/valis/preprocessing.py index fe774efc..66517a99 100644 --- a/valis/preprocessing.py +++ b/valis/preprocessing.py @@ -502,7 +502,7 @@ def process_image(self, *args, **kwaargs): class HEDeconvolution(ImageProcesser): - """Normalize staining appearence of hematoxylin and eosin (H&E) stained image + """Normalize staining appearance of hematoxylin and eosin (H&E) stained image and get the H or E deconvolution image. Reference @@ -624,7 +624,7 @@ def standardize_colorfulness(img, c=DEFAULT_COLOR_STD_C, h=0): """Give image constant colorfulness and hue Image is converted to cylindrical CAM-16UCS assigned a constant - hue and colorfulness, and then coverted back to RGB. + hue and colorfulness, and then converted back to RGB. Parameters ---------- @@ -728,7 +728,7 @@ def calc_background_color_dist(img, brightness_q=0.99, mask=None, cspace="CAM16U def normalize_he(img: np.array, Io: int = 240, alpha: int = 1, beta: int = 0.15): - """ Normalize staining appearence of H&E stained images. + """ Normalize staining appearance of H&E stained images. Parameters ---------- @@ -1336,7 +1336,7 @@ def polygon_tortuosity(img, window_size=3): def remove_small_obj_and_lines_by_dist(mask): """ Will remove smaller objects and thin lines that - do not interesct with larger objects + do not intersect with larger objects """ dist_transform = cv2.distanceTransform(mask, cv2.DIST_L2, 5) @@ -1412,7 +1412,7 @@ def create_tissue_mask_from_rgb(img, brightness_q=0.99, kernel_size=3, gray_thre cam_d, cam = calc_background_color_dist(img, brightness_q=brightness_q, mask=color_mask) - # Reduce intensity of thick horizontal and vertial lines, usually artifacts like edges, streaks, folds, etc... + # Reduce intensity of thick horizontal and vertical lines, usually artifacts like edges, streaks, folds, etc... vert_knl = np.ones((1, 5)) no_v_lines = morphology.opening(cam_d, vert_knl) @@ -1433,7 +1433,7 @@ def create_tissue_mask_from_rgb(img, brightness_q=0.99, kernel_size=3, gray_thre def jc_dist(img, cspace="IHLS", p=99, metric="euclidean"): """ - Cacluate distance between backround and each pixel + Calculate distance between background and each pixel using a luminosity and colofulness/saturation in a polar colorspace Parameters @@ -1446,7 +1446,7 @@ def jc_dist(img, cspace="IHLS", p=99, metric="euclidean"): p: int Percentile used to determine background values, i.e. - background pixels have a luminosity greather 99% of other + background pixels have a luminosity greater 99% of other pixels. Needs to be between 0-100 metric: str @@ -1455,7 +1455,7 @@ def jc_dist(img, cspace="IHLS", p=99, metric="euclidean"): Returns ------- jc_dist : np.ndarray - Color distance between backround and each pixel + Color distance between background and each pixel """ @@ -1611,7 +1611,7 @@ def separate_colors(img, cspace="JzAzBz", min_colorfulness=0.005, px_thresh=0.00 Colorspace to use to detect and separate colors using `separate_colors` min_colorfulness : str - Pixels with colorfulness/saturation less that this will be exluded. + Pixels with colorfulness/saturation less that this will be excluded. Calculated after binning colors. px_thresh: float @@ -1804,7 +1804,7 @@ def find_dominant_colors(img, cspace="JzAzBz", min_colorfulness=0, px_thresh=0.0 Colorspace to use to detect and separate colors using `separate_colors` min_colorfulness : str - Pixels with colorfulness/saturation less that this will be exluded. + Pixels with colorfulness/saturation less that this will be excluded. Calculated after binning colors. px_thresh: float diff --git a/valis/registration.py b/valis/registration.py index a0329d32..72bfc3ad 100644 --- a/valis/registration.py +++ b/valis/registration.py @@ -732,7 +732,7 @@ def warp_img(self, img=None, non_rigid=True, crop=True, interp_method="bicubic") image will not be cropped. If "overlap", the warped slide will be cropped to include only areas where all images overlapped. "reference" crops to the area that overlaps with the reference image, - defined by `reference_img_f` when initialzing the `Valis object`. + defined by `reference_img_f` when initializing the `Valis object`. interp_method : str Interpolation method used when warping slide. Default is "bicubic" @@ -899,7 +899,7 @@ def warp_slide(self, level, non_rigid=True, crop=True, image will not be cropped. If "overlap", the warped slide will be cropped to include only areas where all images overlapped. "reference" crops to the area that overlaps with the reference image, - defined by `reference_img_f` when initialzing the `Valis object`. + defined by `reference_img_f` when initializing the `Valis object`. src_f : str, optional Path of slide to be warped. If None (the default), Slide.src_f @@ -1134,7 +1134,7 @@ def warp_xy(self, xy, M=None, slide_level=0, pt_level=0, image will not be cropped. If "overlap", the warped slide will be cropped to include only areas where all images overlapped. "reference" crops to the area that overlaps with the reference image, - defined by `reference_img_f` when initialzing the `Valis object`. + defined by `reference_img_f` when initializing the `Valis object`. """ if M is None: @@ -1310,7 +1310,7 @@ def warp_geojson(self, geojson_f, M=None, slide_level=0, pt_level=0, image will not be cropped. If "overlap", the warped slide will be cropped to include only areas where all images overlapped. "reference" crops to the area that overlaps with the reference image, - defined by `reference_img_f` when initialzing the `Valis object`. + defined by `reference_img_f` when initializing the `Valis object`. """ if M is None: @@ -1416,7 +1416,7 @@ def warp_geojson_from_to(self, geojson_f, to_slide_obj, src_slide_level=0, src_p Returns ------- warped_geojson : dict - Dictionry of warped geojson geometries + Dictionary of warped geojson geometries """ @@ -1521,7 +1521,7 @@ class Valis(object): 5. Rigid registration is performed serially, with each image being rigidly aligned to the previous image in the stack. - 6. Non-rigid registration is then performed either by 1) aliging each image + 6. Non-rigid registration is then performed either by 1) aligning each image towards the center of the stack, composing the deformation fields along the way, or 2) using groupwise registration that non-rigidly aligns the images to a common frame of reference. @@ -1604,7 +1604,7 @@ class Valis(object): the `img_obj_list` has been sorted during rigid registration. align_to_reference : bool - Whether or not images should be aligne to a reference image + Whether or not images should be align to a reference image specified by `reference_img_f`. Will be set to True if `reference_img_f` is provided. @@ -1615,7 +1615,7 @@ class Valis(object): SerialRigidRegistrar object that performs the rigid registration. rigid_reg_kwargs : dict - Dictionary of keyward arguments passed to + Dictionary of keyword arguments passed to `serial_rigid.register_images`. feature_descriptor_str : str @@ -1638,7 +1638,7 @@ class Valis(object): non-rigid registration. non_rigid_reg_kwargs : dict - Dictionary of keyward arguments passed to + Dictionary of keyword arguments passed to `serial_non_rigid.register_images`. non_rigid_registrar_cls : NonRigidRegistrar @@ -1679,13 +1679,13 @@ class Valis(object): as the error, shape of aligned slides, time to completion, etc... start_time : float - The time at which registation was initiated. + The time at which registration was initiated. end_rigid_time : float - The time at which rigid registation was completed. + The time at which rigid registration was completed. end_non_rigid_time : float - The time at which non-rigid registation was completed. + The time at which non-rigid registration was completed. qt_emitter : PySide2.QtCore.Signal Used to emit signals that update the GUI's progress bars @@ -1829,7 +1829,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, are already in the correct order. If True, then each filename should begin with the number that indicates its position in the z-stack. If False, then the images will be sorted by ordering a feature distance - matix. Default is False. + matrix. Default is False. reference_img_f : str, optional Filename of image that will be treated as the center of the stack. @@ -1844,7 +1844,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, non_rigid_registrar_cls : NonRigidRegistrar, optional Uninstantiated NonRigidRegistrar class that will be used to calculate the deformation fields between images. See - the `non_rigid_registrars` module for a desciption of available + the `non_rigid_registrars` module for a description of available methods. If a desired non-rigid registration method is not available, one can be implemented by subclassing.NonRigidRegistrar. If None, then only rigid registration will be performed @@ -1853,7 +1853,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, Dictionary containing key, value pairs to be used to initialize `non_rigid_registrar_cls`. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. See the NonRigidRegistrar classes in `non_rigid_registrars` for the available non-rigid registration methods and arguments. @@ -1879,7 +1879,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, registration will be skipped. If `do_rigid` is a dictionary, it should contain inverse transformation - matrices to rigidly align images to the specificed by `reference_img_f`. + matrices to rigidly align images to the specified by `reference_img_f`. M will be estimated for images that are not in the dictionary. Each key is the filename of the image associated with the transformation matrix, and value is a dictionary containing the following values: @@ -1915,14 +1915,14 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, crop_for_rigid_reg : bool, optional Whether or not to crop the images used for rigid registration. If `True`, - then higher resolution images may be used for rigid registeration, as valis + then higher resolution images may be used for rigid registration, as valis will "zoom" in to the area around the mask created by `ImageProcesser.create_mask()`, and slice out that region and resize it to have a maximum dimension the same as `max_processed_image_dim_px`. If `False`, the full image will be used, although the tissue may be at a lower resolution. check_for_reflections : bool, optional - Determine if alignments are improved by relfecting/mirroring/flipping + Determine if alignments are improved by reflecting/mirroring/flipping images. Optional because it requires re-detecting features in each version of the images and then re-matching features, and so can be time consuming and not always necessary. @@ -1953,7 +1953,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, max_non_rigid_registration_dim_px : int, optional Maximum width or height of images used for non-rigid registration. - Larger values may yeild more accurate results, at the expense of + Larger values may yield more accurate results, at the expense of speed and memory. There is also a practical limit, as the specified size may be too large to fit in memory. @@ -1982,7 +1982,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, this step is skipped. micro_rigid_registrar_params : dictionary - Dictionary of keyword arguments used intialize the `MicroRigidRegistrar` + Dictionary of keyword arguments used initialize the `MicroRigidRegistrar` qt_emitter : PySide2.QtCore.Signal, optional Used to emit signals that update the GUI's progress bars @@ -2010,7 +2010,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, elif hasattr(img_list, "__iter__"): self.original_img_list = list(img_list) else: - msg = (f"Cannot upack `img_list`, which is type {type(img_list).__name__}. " + msg = (f"Cannot unpack `img_list`, which is type {type(img_list).__name__}. " "Please provide an iterable object (list, tuple, array, etc...) that has the location of the images") valtils.print_warning(msg, rgb=Fore.RED) else: @@ -2100,7 +2100,7 @@ def __init__(self, src_dir, dst_dir, series=None, name=None, image_type=None, compose_non_rigid=compose_non_rigid, qt_emitter=qt_emitter) - # Info realted to saving images to view results # + # Info related to saving images to view results # self.mask_dict = None self.create_masks = create_masks @@ -2314,7 +2314,7 @@ def get_slide(self, src_f): msg = (f"\n{src_f} matches {n_matching} images in this dataset:\n" f"{pformat(self._dup_names_dict[default_name])}" f"\n\nPlease see `Valis.name_dict` to find correct name in " - f"the dictionary. Either key (filenmae) or value (assigned name) will work:\n" + f"the dictionary. Either key (filename) or value (assigned name) will work:\n" f"{pformat(possible_names_dict)}") valtils.print_warning(msg, rgb=Fore.RED) @@ -2444,7 +2444,7 @@ def convert_imgs(self, series=None, reader_dict=None, reader_cls=None): reader_dict: dict, optional Dictionary specifying which readers to use for individual images. The keys, value pairs are image filename and instantiated `slide_io.SlideReader` - to use to read that file. Valis will try to find an appropritate reader + to use to read that file. Valis will try to find an appropriate reader for any omitted files, or will use `reader_cls` as the default. """ @@ -2607,14 +2607,14 @@ def create_img_processor_dict(self, brightfield_processing_cls=DEFAULT_BRIGHTFIE Should return a single channel uint8 image. brightfield_processing_kwargs : dict - Dictionary of keyward arguments to be passed to `brightfield_processing_cls` + Dictionary of keyword arguments to be passed to `brightfield_processing_cls` if_processing_cls : ImageProcesser ImageProcesser to pre-process immunofluorescent images to make them look as similar as possible. Should return a single channel uint8 image. if_processing_kwargs : dict - Dictionary of keyward arguments to be passed to `if_processing_cls` + Dictionary of keyword arguments to be passed to `if_processing_cls` processor_dict : dict Each key should be the filename of the image, and the value either a subclassed @@ -3400,7 +3400,7 @@ def micro_rigid_register(self): micro_rigid_registar = self.micro_rigid_registrar_cls(val_obj=self, **self.micro_rigid_registrar_params) micro_rigid_registar.register() - # Not all pairs will have keept high resolution M, so re-estimate M based on final matches + # Not all pairs will have kept high resolution M, so re-estimate M based on final matches slide_idx, slide_names = list(zip(*[[slide_obj.stack_idx, slide_obj.name] for slide_obj in self.slide_dict.values()])) slide_order = np.argsort(slide_idx) # sorts ascending slide_list = [self.slide_dict[slide_names[i]] for i in slide_order] @@ -3568,7 +3568,7 @@ def _create_mask_from_processed(self, slide_list=None): rigid_mask = slide_obj.warp_img(slide_obj.rigid_reg_mask, non_rigid=False, crop=False, interp_method="nearest") combo_mask[rigid_mask > 0] += 1 - # Caclulate running average + # Calculate running average padded_processed = slide_obj.pad_cropped_processed_img() padded_processed[slide_obj.rigid_reg_mask == 0] = 0 padded_processed[slide_obj.rigid_reg_mask > 0] = exposure.rescale_intensity(padded_processed[slide_obj.rigid_reg_mask > 0], out_range=(0, 255)) @@ -3758,7 +3758,7 @@ def prep_images_for_large_non_rigid_registration(self, max_img_dim, else: s = np.min(max_img_dim/np.array(ref_slide.processed_img_shape_rc)) else: - # Determine how big image would have to be to get mask with maxmimum dimension = max_img_dim + # Determine how big image would have to be to get mask with maximum dimension = max_img_dim if isinstance(mask, pyvips.Image): mask_shape_rc = np.array((mask.height, mask.width)) else: @@ -4269,10 +4269,10 @@ def measure_error(self): `summary_df` contains various information about the registration. The "from" column is the name of the image, while the "to" column - name of the image it was aligned to. "from" is analagous to "moving" - or "current", while "to" is analgous to "fixed" or "previous". + name of the image it was aligned to. "from" is analogous to "moving" + or "current", while "to" is analogous to "fixed" or "previous". - Columns begining with "original" refer to error measurements of the + Columns beginning with "original" refer to error measurements of the unregistered images. Those beginning with "rigid" or "non_rigid" refer to measurements related to rigid or non-rigid registration, respectively. @@ -4296,7 +4296,7 @@ def measure_error(self): "aligned_shape" is the shape of the registered full resolution slide - "physical_units" are the names of the pixels physcial unit, e.g. u'\u00B5m' + "physical_units" are the names of the pixels physical unit, e.g. u'\u00B5m' "resolution" is the physical unit per pixel @@ -4476,13 +4476,13 @@ def register(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, then conduct rigid registration. Non-rigid registration will then be performed if the `non_rigid_registrar_cls` argument used to initialize the Valis object was not None. - In addition to the objects returned, the desination directory (i.e. `dst_dir`) + In addition to the objects returned, the destination directory (i.e. `dst_dir`) will contain thumbnails so that one can visualize the results: converted image thumbnails will be in "images/"; processed images in "processed/"; rigidly aligned images in "rigid_registration/"; non-rigidly aligned images in "non_rigid_registration/"; non-rigid deformation field images (i.e. warped grids colored by the direction and magntidue) of the deformation) will be in ""deformation_fields/". The size of these thumbnails - is determined by the `thumbnail_size` argument used to initialze this object. + is determined by the `thumbnail_size` argument used to initialize this object. One can get a sense of how well the registration worked by looking in the "overlaps/", which shows how the images overlap before @@ -4503,14 +4503,14 @@ def register(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, them look as similar as possible. brightfield_processing_kwargs : dict - Dictionary of keyward arguments to be passed to `brightfield_processing_cls` + Dictionary of keyword arguments to be passed to `brightfield_processing_cls` if_processing_cls : preprocessing.ImageProcesser preprocessing.ImageProcesser used to pre-process immunofluorescent images to make them look as similar as possible. if_processing_kwargs : dict - Dictionary of keyward arguments to be passed to `if_processing_cls` + Dictionary of keyword arguments to be passed to `if_processing_cls` processor_dict : dict, optional Each key should be the filename of the image, and the value either a subclassed @@ -4530,7 +4530,7 @@ def register(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, reader_dict: dict, optional Dictionary specifying which readers to use for individual images. The keys should be the image's filename, and the values the instantiated slide_io.SlideReader - to use to read that file. Valis will try to find an appropritate reader + to use to read that file. Valis will try to find an appropriate reader for any omitted files, or will use `reader_cls` as the default. Returns @@ -4547,10 +4547,10 @@ def register(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, `summary_df` contains various information about the registration. The "from" column is the name of the image, while the "to" column - name of the image it was aligned to. "from" is analagous to "moving" - or "current", while "to" is analgous to "fixed" or "previous". + name of the image it was aligned to. "from" is analogous to "moving" + or "current", while "to" is analogous to "fixed" or "previous". - Columns begining with "original" refer to error measurements of the + Columns beginning with "original" refer to error measurements of the unregistered images. Those beginning with "rigid" or "non_rigid" refer to measurements related to rigid or non-rigid registration, respectively. @@ -4574,7 +4574,7 @@ def register(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, "aligned_shape" is the shape of the registered full resolution slide - "physical_units" are the names of the pixels physcial unit, e.g. u'\u00B5m' + "physical_units" are the names of the pixels physical unit, e.g. u'\u00B5m' "resolution" is the physical unit per pixel @@ -4671,7 +4671,7 @@ def register_micro(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, non_rigid_registrar_cls=DEFAULT_NON_RIGID_CLASS, non_rigid_reg_params=DEFAULT_NON_RIGID_KWARGS, reference_img_f=None, align_to_reference=False, mask=None, tile_wh=DEFAULT_NR_TILE_WH): - """Improve alingment of microfeatures by performing second non-rigid registration on larger images + """Improve alignment of microfeatures by performing second non-rigid registration on larger images Caclculates additional non-rigid deformations using a larger image @@ -4682,14 +4682,14 @@ def register_micro(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, them look as similar as possible. brightfield_processing_kwargs : dict - Dictionary of keyward arguments to be passed to `brightfield_processing_cls` + Dictionary of keyword arguments to be passed to `brightfield_processing_cls` if_processing_cls : preprocessing.ImageProcesser preprocessing.ImageProcesser used to pre-process immunofluorescent images to make them look as similar as possible. if_processing_kwargs : dict - Dictionary of keyward arguments to be passed to `if_processing_cls` + Dictionary of keyword arguments to be passed to `if_processing_cls` max_non_rigid_registration_dim_px : int, optional Maximum width or height of images used for non-rigid registration. @@ -4711,7 +4711,7 @@ def register_micro(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, non_rigid_registrar_cls : NonRigidRegistrar, optional Uninstantiated NonRigidRegistrar class that will be used to calculate the deformation fields between images. See - the `non_rigid_registrars` module for a desciption of available + the `non_rigid_registrars` module for a description of available methods. If a desired non-rigid registration method is not available, one can be implemented by subclassing.NonRigidRegistrar. @@ -4719,7 +4719,7 @@ def register_micro(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, Dictionary containing key, value pairs to be used to initialize `non_rigid_registrar_cls`. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. See the NonRigidRegistrar classes in `non_rigid_registrars` for the available non-rigid registration methods and arguments. @@ -4755,7 +4755,7 @@ def register_micro(self, brightfield_processing_cls=DEFAULT_BRIGHTFIELD_CLASS, if using_tiler: # Have determined that these images will be too big msg = (f"Registration would more than {TILER_THRESH_GB} GB if all images opened in memory. " - f"Will use NonRigidTileRegistrar to register cooresponding tiles to reduce memory consumption, " + f"Will use NonRigidTileRegistrar to register corresponding tiles to reduce memory consumption, " f"but this method is experimental") valtils.print_warning(msg) @@ -4977,7 +4977,7 @@ def warp_and_save_slides(self, dst_dir, level=0, non_rigid=True, image will not be cropped. If "overlap", the warped slide will be cropped to include only areas where all images overlapped. "reference" crops to the area that overlaps with the reference image, - defined by `reference_img_f` when initialzing the `Valis object`. + defined by `reference_img_f` when initializing the `Valis object`. colormap : list List of RGB colors (0-255) to use for channel colors. @@ -5074,7 +5074,7 @@ def warp_and_merge_slides(self, dst_f=None, level=0, non_rigid=True, image will not be cropped. If "overlap", the warped slide will be cropped to include only areas where all images overlapped. "reference" crops to the area that overlaps with the reference image, - defined by `reference_img_f` when initialzing the `Valis object`. + defined by `reference_img_f` when initializing the `Valis object`. channel_name_dict : dict of lists, optional. key = slide file name, value = list of channel names for that slide. If None, diff --git a/valis/serial_non_rigid.py b/valis/serial_non_rigid.py index b7985f3f..85e9df3e 100644 --- a/valis/serial_non_rigid.py +++ b/valis/serial_non_rigid.py @@ -372,7 +372,7 @@ def calc_deformation(self, registered_fixed_image, non_rigid_reg_class, Used to warp the registered_img before finding deformation fields. params : dictionary, optional - Keyword: value dictionary of parameters to be used in reigstration. + Keyword: value dictionary of parameters to be used in registration. Passed to the non_rigid_reg_class' init() method. In the case where simple ITK will be used, params should be @@ -552,7 +552,7 @@ class SerialNonRigidRegistrar(object): Dictionary containing parameters {name: value} to be used to initialize the NonRigidRegistrar. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. mask : ndarray @@ -606,7 +606,7 @@ def __init__(self, src, reference_img_f=None, moving_to_fixed_xy=None, To deterime which pairs of images will be aligned, use `get_alignment_indices`. Can use `get_imgs_from_dir` to see the order inwhich the images will be read, which will correspond - to the indices retuned by `get_alignment_indices`. + to the indices returned by `get_alignment_indices`. If `src` is a SerialRigidRegistrar and `moving_to_fixed_xy` is True, then the matching features in the SerialRigidRegistrar will @@ -849,7 +849,7 @@ def register_serial(self, non_rigid_reg_class, non_rigid_reg_params=None, img_pa Dictionary containing parameters {name: value} to be used to initialize `non_rigid_reg_class`. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. """ @@ -900,7 +900,7 @@ def register_to_ref(self, non_rigid_reg_class, non_rigid_reg_params=None, img_pa Dictionary containing parameters {name: value} to be used to initialize the NonRigidRegistrar. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. """ @@ -935,7 +935,7 @@ def register_groupwise(self, non_rigid_reg_class, non_rigid_reg_params=None): Dictionary containing parameters {name: value} to be used to initialize the NonRigidRegistrar. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. """ @@ -970,7 +970,7 @@ def register(self, non_rigid_reg_class, non_rigid_reg_params, img_params=None): Dictionary containing parameters {name: value} to be used to initialize the NonRigidRegistrar. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. img_params : dict, optional Dictionary of parameters to be used for each particular image. @@ -1000,7 +1000,7 @@ def summarize(self): Returns ------- summary_df: Dataframe - Pandas dataframe containin the registration error of the + Pandas dataframe containing the registration error of the alignment between each image and the previous one in the stack. """ @@ -1088,11 +1088,11 @@ def register_images(src, non_rigid_reg_class=non_rigid_registrars.OpticalFlowWar Dictionary containing parameters {name: value} to be used to initialize the NonRigidRegistrar. In the case where simple ITK is used by the, params should be - a SimpleITK.ParameterMap. Note that numeric values nedd to be + a SimpleITK.ParameterMap. Note that numeric values need to be converted to strings. dst_dir : str, optional - Top directory where aliged images should be save. SerialNonRigidRegistrar will + Top directory where aligned images should be save. SerialNonRigidRegistrar will be in this folder, and aligned images in the "registered_images" sub-directory. If None, the images will not be written to file @@ -1112,7 +1112,7 @@ def register_images(src, non_rigid_reg_class=non_rigid_registrars.OpticalFlowWar To deterime which pairs of images will be aligned, use `warp_tools.get_alignment_indices`. Can use `get_imgs_from_dir` to see the order inwhich the images will be read, which will correspond - to the indices retuned by `warp_tools.get_alignment_indices`. + to the indices returned by `warp_tools.get_alignment_indices`. If `src` is a SerialRigidRegistrar and `moving_to_fixed_xy` is True, then the matching features in the SerialRigidRegistrar will @@ -1132,7 +1132,7 @@ def register_images(src, non_rigid_reg_class=non_rigid_registrars.OpticalFlowWar Optional name for this SerialNonRigidRegistrar align_to_reference : bool, optional - Whether or not images should be aligne to a reference image + Whether or not images should be align to a reference image specified by `reference_img_f`. Will be set to True if `reference_img_f` is provided. diff --git a/valis/serial_rigid.py b/valis/serial_rigid.py index e09eec0c..ee377df4 100644 --- a/valis/serial_rigid.py +++ b/valis/serial_rigid.py @@ -46,7 +46,7 @@ def get_image_files(img_dir, imgs_ordered=False): img_dir : str Path to directory containing the images. - imgs_ordered: bool, optinal + imgs_ordered: bool, optional Whether or not the order of images already known. If True, the file names should start with ascending numbers, with the first image file having the smallest number, and the last image file having the largest @@ -98,7 +98,7 @@ def order_Dmat(D): Leaf sorting is accomplished using optimal leaf ordering (Bar-Joseph 2001) - Parmaters + Parameters --------- D: ndarray (N, N) Symmetric distance matrix for N samples @@ -150,7 +150,7 @@ class ZImage(object): Name of the image. Usually `img_f` but with the extension removed. desc : ndarray - (N, M) array of N desciptors for each keypoint, each of which has + (N, M) array of N descriptors for each keypoint, each of which has M features kp_pos_xy : ndarray @@ -299,7 +299,7 @@ class SerialRigidRegistrar(object): Registration is conducted by first detecting features in all images. Features are then matched between images, which are then used to construct a distance matrix, D. D is then sorted such that the most similar images - are adjcent to one another. The rigid transformation matrics are then found to + are adjacent to one another. The rigid transformation matrices are then found to align each image with the previous image. Optionally, optimization can be performed to improve the alignments, although the "optimized" matrix will be discarded if it increases the distances between matched features. @@ -341,7 +341,7 @@ class SerialRigidRegistrar(object): distance_metric_type : str Name of the type of metric used to determine the dis/similarity between each pair of images. Despite the name, it could be "similarity" - if the Matcher object compares image feautres using a similarity + if the Matcher object compares image features using a similarity metric. In that case, similarities are converted to distances. img_obj_list : list @@ -386,7 +386,7 @@ class SerialRigidRegistrar(object): the `img_obj_list` has been sorted. align_to_reference : bool, optional - Whether or not images should be aligne to a reference image + Whether or not images should be align to a reference image specified by `reference_img_f`. Will be set to True if `reference_img_f` is provided. @@ -397,7 +397,7 @@ class SerialRigidRegistrar(object): image. summary_df : Dataframe - Pandas dataframe containin the registration error of the + Pandas dataframe containing the registration error of the alignment between each image and the previous one in the stack. """ @@ -431,7 +431,7 @@ def __init__(self, img_dir, imgs_ordered=False, reference_img_f=None, Descriptive name of registrar, such as the sample's name align_to_reference : bool, optional - Whether or not images should be aligne to a reference image + Whether or not images should be align to a reference image specified by `reference_img_f`. Will be set to True if `reference_img_f` is provided. @@ -668,7 +668,7 @@ def get_common_desc(self, current_img_obj, neighbor_obj, nf_kp_idx): Parameters ---------- nf_kp_idx : ndarray - Indicies of already matched keypoints that were found after + Indices of already matched keypoints that were found after neighbonr filtering """ @@ -1033,7 +1033,7 @@ def align_to_prev_check_reflections(self, transformer, feature_detector, matcher ref_x, ref_y = best_reflect_M[[0, 1], [0, 1]] < 0 if ref_x or ref_y: - msg = f'detected relfections between {img_obj.name} and {prev_img_obj.name} along the' + msg = f'detected reflections between {img_obj.name} and {prev_img_obj.name} along the' if ref_x and ref_y: msg = f'{msg} x and y axes' elif ref_x: @@ -1340,7 +1340,7 @@ def summarize(self): Returns ------- summary_df: Dataframe - Pandas dataframe containin the registration error of the + Pandas dataframe containing the registration error of the alignment between each image and the previous one in the stack. """ @@ -1428,7 +1428,7 @@ def register_images(img_dir, dst_dir=None, name="registrar", to be registered. These images need to be single channel, uint8 images dst_dir : str, optional - Top directory where aliged images should be save. SerialRigidRegistrar will + Top directory where aligned images should be save. SerialRigidRegistrar will be in this folder, and aligned images in the "registered_images" sub-directory. If None, the images will not be written to file @@ -1454,14 +1454,14 @@ def register_images(img_dir, dst_dir=None, name="registrar", are already in the correct order. If True, then each filename should begin with the number that indicates its position in the z-stack. If False, then the images will be sorted by ordering a feature distance - matix. + matrix. reference_img_f : str, optional Filename of image that will be treated as the center of the stack. If None, the index of the middle image will be the reference. check_for_reflections : bool, optional - Determine if alignments are improved by relfecting/mirroring/flipping + Determine if alignments are improved by reflecting/mirroring/flipping images. Optional because it requires re-detecting features in each version of the images and then re-matching features, and so can be time consuming and not always necessary. @@ -1484,7 +1484,7 @@ def register_images(img_dir, dst_dir=None, name="registrar", Returns ------- registrar : SerialRigidRegistrar - SerialRigidRegistrar object contains general information about the alginments, + SerialRigidRegistrar object contains general information about the alignments, but also a list of Z-images. Each ZImage contains the warp information for an image in the stack, including the transformation matrices calculated at each step, keypoint poisions, image descriptors, and diff --git a/valis/slide_io.py b/valis/slide_io.py index 831b3aae..9ba85df4 100644 --- a/valis/slide_io.py +++ b/valis/slide_io.py @@ -67,7 +67,7 @@ """str: Physical unit when the unit can't be found in the metadata""" MICRON_UNIT = u'\u00B5m' -"""str: Phyiscal unit for micron/micrometers""" +"""str: Physical unit for micron/micrometers""" ALL_OPENSLIDE_READABLE_FORMATS = [".svs", ".tif", ".vms", ".vmu", ".ndpi", ".scn", ".mrxs", ".tiff", ".svslide", ".bif"] """list: File extensions that OpenSlide can read""" @@ -462,7 +462,7 @@ def check_to_use_openslide(src_f): def get_ome_obj(x): """Get ome_types.model.ome.OME object - Paramters + Parameters --------- x: str Either OME-XML or path to ome.tiff @@ -1262,7 +1262,7 @@ def slide2vips(self, level, series=None, xywh=None, tile_wh=None, z=0, t=0, *arg the region to be sliced. tile_wh : int, optional - Size of tiles used to contstruct `vips_slide` + Size of tiles used to construct `vips_slide` Returns ------- @@ -1607,7 +1607,7 @@ class VipsSlideReader(SlideReader): Whether or not openslide can be used to read this slide. is_ome : bool - Whether ot not the side is an ome.tiff. + Whether or not the side is an ome.tiff. Notes ----- @@ -2980,7 +2980,7 @@ def get_shape_xyzct(shape_wh, n_channels, nt=1, nz=1): Parameters ---------- shape_wh : tuple of int - Width and heigth of image + Width and height of image n_channels : int Number of channels in the image @@ -3004,7 +3004,7 @@ def create_channel(channel_id, name=None, color=None, samples_per_pixel=1): channel_id : int Channel number - name : str, optinal + name : str, optional Channel name color : tuple of int diff --git a/valis/slide_tools.py b/valis/slide_tools.py index f1f7d0a5..4f549333 100644 --- a/valis/slide_tools.py +++ b/valis/slide_tools.py @@ -276,7 +276,7 @@ def determine_if_staining_round(src_dir): def um_to_px(um, um_per_px): - """Conver mircon to pixel + """Convert mircon to pixel """ return um * 1/um_per_px @@ -323,7 +323,7 @@ def warp_slide(src_f, transformation_src_shape_rc, transformation_dst_shape_rc, interp_method : str, optional bbox_xywh : tuple - Bounding box to crop warped slide. Should be in refernce the + Bounding box to crop warped slide. Should be in reference the warped slide Returns diff --git a/valis/superglue_models/utils.py b/valis/superglue_models/utils.py index 65c64d10..57946247 100644 --- a/valis/superglue_models/utils.py +++ b/valis/superglue_models/utils.py @@ -376,7 +376,7 @@ def compute_epipolar_error(kpts0, kpts1, T_0to1, K0, K1): def angle_error_mat(R1, R2): cos = (np.trace(np.dot(R1.T, R2)) - 1) / 2 - cos = np.clip(cos, -1., 1.) # numercial errors can make it out of bounds + cos = np.clip(cos, -1., 1.) # numerical errors can make it out of bounds return np.rad2deg(np.abs(np.arccos(cos))) diff --git a/valis/viz.py b/valis/viz.py index 7840aec8..c6acc0d9 100644 --- a/valis/viz.py +++ b/valis/viz.py @@ -45,7 +45,7 @@ def draw_outline(img, mask, clr=(100, 240, 39), thickness=2): clr : ndarray RGB (0-255) color of outline - thicknes : int + thickness : int Thickness of outline Returns diff --git a/valis/warp_tools.py b/valis/warp_tools.py index 69d89396..c7c95718 100644 --- a/valis/warp_tools.py +++ b/valis/warp_tools.py @@ -96,7 +96,7 @@ def get_alignment_indices(n_imgs, ref_img_idx=None): Indices go from bottom to center, then top to center. In each case, the alignments go from closest to the center, to next closet, etc... - The reference image is exclued from this list. + The reference image is excluded from this list. For example, if `ref_img_idx` is 2, then the order is [(1, 2), (0, 1), (3, 2), ..., (`n_imgs`-1, `n_imgs` - 2)]. @@ -671,8 +671,8 @@ def mattes_mi(img1, img2, nbins=50, mask=None): Number of histogram bins mask : ndarray, None - Mask with shape (N, M) that indiates where the metric - should be calulated. If None, the metric will be calculated + Mask with shape (N, M) that indicates where the metric + should be calculated. If None, the metric will be calculated for all NxM pixels. Returns @@ -732,7 +732,7 @@ def order_points(pts_xy): ### https://math.stackexchange.com/questions/978642/how-to-sort-vertices-of-a-polygon-in-counter-clockwise-order - # warnings.warn("Outpout is now clockwise. May need update functions that call this") + # warnings.warn("Output is now clockwise. May need update functions that call this") # sort the points based on their x-coordinates xSorted = pts_xy[np.argsort(pts_xy[:, 0]), :] # grab the left-most and right-most points from the sorted @@ -904,7 +904,7 @@ def warp_img(img, M=None, bk_dxdy=None, out_shape_rc=None, interp_method="bicubic"): """Warp an image using rigid and/or non-rigid transformations - Warp an image using the trasformations defined by `M` and the optional + Warp an image using the transformations defined by `M` and the optional displacement field, `bk_dxdy`. Transformations will be scaled so that they can be applied to the image. @@ -1084,7 +1084,7 @@ def warp_img(img, M=None, bk_dxdy=None, out_shape_rc=None, warp_index = (index[0] + warp_dxdy[0]).bandjoin(index[1] + warp_dxdy[1]) try: - #Option to set backround color in mapim added in libvips 8.13 + #Option to set background color in mapim added in libvips 8.13 warped = affine_warped.mapim(warp_index, premultiplied=True, background=bg_color, @@ -1111,9 +1111,9 @@ def warp_img(img, M=None, bk_dxdy=None, out_shape_rc=None, def warp_img_inv(img, M=None, fwd_dxdy=None, transformation_src_shape_rc=None, transformation_dst_shape_rc=None, src_shape_rc=None, bk_dxdy=None, bg_color=None, interp_method="bicubic"): """Unwarp an image using rigid and/or non-rigid transformations - Unwarp an image using the trasformations defined by `M` and the optional + Unwarp an image using the transformations defined by `M` and the optional displacement field, `bk_dxdy`. This is accomplished by inverting `M` and - using the "foward" displacements in `fwd_dxdy`. If `fwd_dxdy` is not provided, + using the "forward" displacements in `fwd_dxdy`. If `fwd_dxdy` is not provided, `bk_dxdy` will be inverted. Transformations will be scaled so that they can be applied to the images with different sizes. @@ -1214,7 +1214,7 @@ def warp_img_inv(img, M=None, fwd_dxdy=None, transformation_src_shape_rc=None, t warp_index = (index[0] + warp_dxdy[0]).bandjoin(index[1] + warp_dxdy[1]) try: - # Option to set backround color in mapim added in libvips 8.13 + # Option to set background color in mapim added in libvips 8.13 nr_warped = img.mapim(warp_index, premultiplied=True, background=bg_color, @@ -1274,7 +1274,7 @@ def warp_img_from_to(img, from_M=None, from_transformation_src_shape_rc=None, Warps `img` to registered coordinates using the "from" parameters, and then uses the inverse "to" parameters to warp that image to the "to" image's coordinate system. - Can be useful for transfering annotations from one image to another. + Can be useful for transferring annotations from one image to another. Note: If `img` is a labeled image, it is recommended to set `interp_method` to "nearest" @@ -1669,7 +1669,7 @@ def get_rotate_around_center_M(img_shape, rotation_rad): def calc_d(pt1, pt2): """ - Calculate euclidean disrances between each pair coresponding points in pt1 and pt2 + Calculate euclidean disrances between each pair corresponding points in pt1 and pt2 Parameters ---------- @@ -1682,7 +1682,7 @@ def calc_d(pt1, pt2): Returns ------- d : [N] - distnace between correspoing points in pt1 and pt2 + distance between correspoing points in pt1 and pt2 """ d = np.sqrt(np.sum((pt1 - pt2)**2, axis=1)) @@ -1821,7 +1821,7 @@ def warp_xy_rigid(xy, inv_matrix): Warp xy given an inverse transformation matrix found using one of scikit-image's transform objects Inverse matrix should have been found using tform(dst, src) - Adpated from skimage._geometric.ProjectiveTransform._apply_mat + Adapted from skimage._geometric.ProjectiveTransform._apply_mat Changed so that inverse matrix (found using dst -> src) automatically inverted to warp points forward (src -> dst) """ xy = np.array(xy, copy=False, ndmin=2) @@ -2420,7 +2420,7 @@ def warp_xy_from_to(xy, from_M=None, from_transformation_src_shape_rc=None, def clip_xy(xy, shape_rc): - """Clip xy coordintaes to be within image + """Clip xy coordinates to be within image """ clipped_x = np.clip(xy[:, 0], 0, shape_rc[1]) @@ -2432,7 +2432,7 @@ def clip_xy(xy, shape_rc): def _warp_shapely(geom, warp_fxn, warp_kwargs, shift_xy=None): """Warp a shapely geometry - Based on shapely.ops.trasform + Based on shapely.ops.transform """ if "dst_shape_rc" in warp_kwargs: @@ -2716,7 +2716,7 @@ def bbox2xy(xywh): Parameters ----------- xywh: [4, ] array - (top left x-coordinate, top left y coordiante, width, height) of a bounding box + (top left x-coordinate, top left y coordinate, width, height) of a bounding box Returns ------- @@ -2814,7 +2814,7 @@ def measure_error(src_xy, dst_xy, shape, feature_similarity=None): Median relative Target Registration Error (rTRE) between images med_d : float - Median Euclidean distance between src_xy and dst_xy, optinally weighted by feature similarity + Median Euclidean distance between src_xy and dst_xy, optionally weighted by feature similarity """ d = np.sqrt((src_xy[:, 0]-dst_xy[:, 0])**2 + (src_xy[:, 1]-dst_xy[:, 1])**2) @@ -2981,7 +2981,7 @@ def clip_poly(i): # method : str, optional # "inpaint" will use inpainting to fill in areas idenetified # as containing folds. "regularize" will unfold those regions -# using the mehod described in "Foldover-free maps in 50 lines of code" +# using the method described in "Foldover-free maps in 50 lines of code" # Garanzha et al. 2021. # n_grid_pts : int @@ -3130,7 +3130,7 @@ def clip_poly(i): # padded_dy = transform.warp(dxdy[1], self.padding_T, output_shape=padded_shape, preserve_range=True) # self.padded_dxdy = np.array([padded_dx, padded_dy]) -# # Flattend indices for each pixel in a quadrat +# # Flattened indices for each pixel in a quadrat # quads = [[r*nc + c, r*nc + c + 1, (r+1)*nc + c + 1, (r+1)*nc + c] for r in range(nr-1) for c in range(nc-1)] # self.quads = quads # self.boundary = [None] * self.nverts