Open kaizen89 opened 2 years ago
Can you explain the experimental protocol a bit more? Do you strip the DAB-labeled antibody and re-stain each time?
Exactly. Scan, strip and restain again.
Hi @kaizen89, we need a bit more info - what are your imaging data files? Do you know whether each scan outputs field-of-views or a stitched image?
I would say a stitched image, the instrument scans the whole slide but there is no alignement needed inside each image. The only alignment that is needed is between different images /markers. I can send example images if it would help.
Thanks, having the example images would be helpful! ASHLAR is designed for stitching and registering imaging data that are not stitched. However, we recently took the idea in ASHLAR and started another module that hopefully works with pre-stitched images. Do you know what scanner was used and what type of files can it export? Like .tif .czi?
Most brightfield slide scanners/microscopes emit pre-stitched images which are generally impossible to register accurately down to the single-cell level across the entire image. See Figure 5 in our preprint and the associated section of the text for more (imagine your scanner's internal stitching algorithm in place of the MIST algorithm we used in our comparison) : https://www.biorxiv.org/content/10.1101/2021.04.20.440625v1.full . You can try non-rigid or piecewise-rigid registration on the pre-stitched images, but there will always be "local deformations" as described by the MICSSS paper you cited. Depending on what you want to get out of the registered images, this loss may be acceptable. The tool @Yu-AnChen mentioned uses piecwise-rigid registration.
We did learn that some Aperio histology-focused microscopes and scanners do have an undocumented option to emit all the unstitched tile images instead of a single stitched image, but this only configurable at scan time (i.e. you can't "fix" an existing scan). It's possibly other vendors have similar support but we haven't been able to identify any others yet. One other microscope vendor we are aware of (Zeiss) generates files that appear pre-stitched but do actually contain the raw tiles.
The scanner is a Hamamatsu and exports ndpi images. What we currently do is to export ROIs that are relatively big 10x10mm2 as ome.tif
file and then launch an alignment process that we adapted from scripts found on forums to align 10-13 images each stained with a different marker. The alignement quality is fairly good allowing cell level measurements. However the process is time and RAM consuming, especially if we want to align the whole slide and not just an ROI, and in this cas the process usually fails to align correctly. We also know that HALO software can register those images (Whole slide) with good quality and in short amount of time, unfortunately this software is costly and does not allow to export the final composite image.
Here's a link to access example images. The ndpi images are the original ones and ome.tif are exported ROIs that we were able to align. Ideally we would like to align the whole slide and then select ROI to analyze on the composite images with all the markers.
Thanks for sharing the files, I did a quick run using palom. The result is here, you can toggle on/off channels on the top or in the left panel. What color separation you are using? The current method in palom isn't working well for your image, as you see in the 4th and 8th channel.
Here's the script I used
import palom
c1r = palom.reader.SvsReader('B11_CD3_PanelLymphoid_25287_6.ndpi')
c2r = palom.reader.SvsReader('B11_PanCK_PanelLymphoid_25287_6.ndpi')
LEVEL = 0
THUMBNAIL_LEVEL = 4
c1rp = palom.color.PyramidHaxProcessor(c1r.pyramid, thumbnail_level=THUMBNAIL_LEVEL)
c2rp = palom.color.PyramidHaxProcessor(c2r.pyramid, thumbnail_level=THUMBNAIL_LEVEL)
c21l = palom.align.Aligner(
c1rp.get_processed_color(LEVEL),
c2rp.get_processed_color(LEVEL),
ref_thumbnail=c1rp.get_processed_color(THUMBNAIL_LEVEL).compute(),
moving_thumbnail=c2rp.get_processed_color(THUMBNAIL_LEVEL).compute(),
ref_thumbnail_down_factor=c1r.level_downsamples[THUMBNAIL_LEVEL] / c1r.level_downsamples[LEVEL],
moving_thumbnail_down_factor=c2r.level_downsamples[THUMBNAIL_LEVEL] / c2r.level_downsamples[LEVEL]
)
c21l.coarse_register_affine()
c21l.compute_shifts()
c21l.constrain_shifts()
c2m = palom.align.block_affine_transformed_moving_img(
c1rp.get_processed_color(LEVEL),
c2rp.get_processed_color(LEVEL, 'aec'),
mxs=c21l.block_affine_matrices_da
)
c2m_color = palom.align.block_affine_transformed_moving_img(
c1rp.get_processed_color(LEVEL),
c2rp.get_processed_color(LEVEL, 'color'),
mxs=c21l.block_affine_matrices_da
)
palom.pyramid.write_pyramid(
palom.pyramid.normalize_mosaics([
c1rp.get_processed_color(LEVEL, 'color'),
c1rp.get_processed_color(LEVEL, 'aec'),
c2m_color,
c2m
]),
r"PanelLymphoid_25287-CD3_PanCK.ome.tif",
pixel_size=c1r.pixel_size*c1r.level_downsamples[LEVEL],
channel_names=['CD3_color', 'CD3', 'PanCK_color', 'PanCK']
)
Thanks for doing the test. Palom seems to be very suited to my use case but it seems that there is something weird in the color deconvolution. What I use in Fiji is:
run("RGB Color");
run("Colour Deconvolution", "vectors=[H DAB]");
And then save channel 1 (hematox) and Channel 2 (marker staining) for each image. After alignment the final stack will have all the marker stainings and only one hematox (ref image).
Cool, thanks for the info on the color deconvolution. Looks like the vector ([H DAB]
) is the same in scikit-image
. It was easy to add that to palom and here's what it looks like with the H DAB
vector. I'll probably update the release shortly, happy to learn about what you think.
It looks really great. Did you use the CD3 hematox as a reference or the panCK?
Could you please share the script that you used with the H DAB
deconvolution. I have lots of samples with 13 different markers to align, looking forward to try the updated release.
One final thought, In order to reduce image composite size I was thinking to use an autothresholding estimator to convert to NaN
every pixel with a value below this threshold. What do you think about this? Thanks a lot!
I have updated the release (v2021.12.0). Please try to follow along with the README for installation and running. With the latest release, I now can use the following configuration (as config.yml
) to run the two images you provided -
input dir: Y:\data\YC-20211201-ashlar-ndpi-files
output full path: Y:\data\YC-20211201-ashlar-ndpi-files\palom-test.ome.tif
reference image:
filename: B11_CD3_PanelLymphoid_25287_6.ndpi
output mode: hematoxylin
channel name: Hematoxylin
moving images:
- filename: B11_CD3_PanelLymphoid_25287_6.ndpi
output mode: dab
channel name: CD3
- filename: B11_PanCK_PanelLymphoid_25287_6.ndpi
output mode: dab
channel name: PanCK
and run palom with the command
palom-svs run -c config.yml
The above config will write out the color-deconvoled images, resulting in a 3-channel image. If you have additional palom usage questions and issues, happy to discuss them there!
Hi, I have 10 images, each with hematoxylin and a DAB staining for different markers on the same slide that were stained sequentially. Now I would like to align and register the images based on the hematoxylin staining using a reference image. Can I use Ashlar for this purpose? If yes, how should I input all the image files at once in the command? Thank you