MathOnco / valis

Virtual Alignment of pathoLogy Image Series
https://valis.readthedocs.io/en/latest/
MIT License
121 stars 29 forks source link

Which registered version is saved? #106

Open ciaobladoo opened 8 months ago

ciaobladoo commented 8 months ago

Dear Chandler,

I am a bit confused about which registered version are saved when running registrar.warp_and_save_slides(registered_slide_dst_dir, crop="overlap") if I did both rigid and non-rigid registration (and what if I did micro-registration in addition?)

Thanks!

Chao

cdgatenbee commented 8 months ago

Hi @ciaobladoo, By default, if you performed the non-rigid registration, then the non-rigidly aligned images will be saved. However, this can be overridden by setting non_rigid=False when you call registrar.warp_and_save_slides, which will then save the rigidly aligned images. If you opted to skip non-rigid registration (by setting non_rigid_registrar_cls=None when initializing the Valis object), then the rigidly aligned images will be saved. Hope that helps, but if you have any other questions, please let me know.

Best, -Chandler

ciaobladoo commented 8 months ago

Thanks, Chandler. What if I also do micro-registration after rigid/non-rigid registration?

cdgatenbee commented 8 months ago

If you do micro-registration after rigid/non-rigid registration, then the non-rigid transformation parameters get updated, so the default would still be to save the non-rigidly aligned images.

ciaobladoo commented 7 months ago

Is rigid micro-registration necessary for non-rigid micro-registration? It seems rigid micro-registration takes an awful amount of time.

ciaobladoo commented 7 months ago

I am using 0.05 as micro-registration fraction. The micro rigid registration is extremely slow. Here is the output.

`Aligning AVD-44AOK-4698_1 to AVD-44AOK-4698-1_1008013. ROI width, height is [ 5109.33891213 5340.61272476] pixels QUEUEING TASKS | : 100%|████████████████████████████████████████████████████████████████████████████████████| 110/110 [00:00<00:00, 7867.23it/s] PROCESSING TASKS | : 0%| | 0/110 [00:00<?, ?it/s]Loaded SuperGlue model ("indoor" weights) PROCESSING TASKS | : 2%|█▌ | 2/110 [01:09<51:40, 28.71s/it]

PROCESSING TASKS | : 3%|██▏ | 3/110 [43:41<35:06:05, 1180.98s/it]/home/ssm-user/venv/myenv/lib/python3.10/site-packages/valis/valtils.py:24: UserWarning: Need at least 4 keypoints for RANSAC filtering, but only have 2 warnings.warn(warning_msg, warning_type)`

Any idea why it should be this slow (I am using AWS so it's possible I need a better configuration of memories, etc.)?

Thank you!

cdgatenbee commented 7 months ago

Hi @ciaobladoo, It's true that rigid micro-registration is pretty slow. It's because images gets divided into tiles, and each tile undergoes preprocessing, feature detection, and feature matching, which can end up taking a bit of time when the images are large. As far as speed ups go, in addition to reducing the size of the image used (the default scaling is 0.125), you could also try processing only the area inside which lower resolution feature matches were found. The default is to use the area inside the non-rigid mask, but the bounding box of the feature matches may be smaller. You can try this approach by setting the roi parameter:

micro_rigid_registrar_params = {"scale": 0.05, "roi": micro_rigid_registrar.ROI_MATCHES}
registrar = registration.Valis(src_dir, dst_dir, micro_rigid_registrar_cls=micro_rigid_registrar_cls, micro_rigid_registrar_params=micro_rigid_registrar_params)
rigid_registrar, non_rigid_registrar, error_df = registrar.register()

When I run this on my 2021 M1 macbook pro, it takes about 5 seconds per tile, which does seem much faster, so I guess it might also have something to do with AWS too?

To answer your other question, the rigid micro-registration is not needed to perform non-rigid micro-registration. In fact, if the rigid micro-registration doesn't produce better results (more matches that are closer together after registration), then the rigid micro-registration results are "thrown out", and the lower resolution results are kept. The error estimates from micro rigid registration should be more accurate, and the high resolution results can be better than the lower resolution ones, but it isn't always the case. So, if speed isn't an issue, it doesn't hurt to try rigid micro-registration because the best rigid transforms are kept. However, the differences may be small and when speed is an issue rigid micro-registration might not be worth it.

Best, -Chandler

ciaobladoo commented 7 months ago

Thanks, Chandler. I am trying this again on Databricks. Apologize for discussing a different issue here. But here is the error I got trying to do micro-registration.

Traceback (most recent call last): File "/databricks/python/lib/python3.10/site-packages/threadpoolctl.py", line 400, in match_module_callback self._make_module_from_path(filepath) File "/databricks/python/lib/python3.10/site-packages/threadpoolctl.py", line 515, in _make_module_from_path module = module_class(filepath, prefix, user_api, internal_api) File "/databricks/python/lib/python3.10/site-packages/threadpoolctl.py", line 606, in init self.version = self.get_version() File "/databricks/python/lib/python3.10/site-packages/threadpoolctl.py", line 646, in get_version config = get_config().split() AttributeError: 'NoneType' object has no attribute 'split' Exception ignored on calling ctypes callback function: <function _ThreadpoolInfo._find_modules_with_dl_iterate_phdr..match_module_callback at 0x7fd85a8d9120> Traceback (most recent call last): File "/databricks/python/lib/python3.10/site-packages/threadpoolctl.py", line 400, in match_module_callback self._make_module_from_path(filepath) File "/databricks/python/lib/python3.10/site-packages/threadpoolctl.py", line 515, in _make_module_from_path module = module_class(filepath, prefix, user_api, internal_api) File "/databricks/python/lib/python3.10/site-packages/threadpoolctl.py", line 606, in init self.version = self.get_version() File "/databricks/python/lib/python3.10/site-packages/threadpoolctl.py", line 646, in get_version config = get_config().split() AttributeError: 'NoneType' object has no attribute 'split'

Any idea what could have caused this?

Thank you so much!

Chao