Fine-tuning positioning accuracy

The number of microns per pixel in BakingTray is used to move the stage to the correct positions in order to perform a tile scan with the desired overlap between adjacent tiles. The number of microns per pixel is also used by StitchIt to assemble the image tiles into a stitched image. i.e. The tiles aren't "registered into place". They are positioned where they ought to be in theory. We find this works well so long as the system is aligned correctly and the number of microns per pixel is accurately measured.

After conducting the above procedures you may still see errors in tile placement. These errors should be due to the following sources:

  • Scanners being not quite orthogonal.

  • Stages being not quite aligned with the scan axes.

  • The number of microns per pixel being slightly wrong.

  • Stage positioning errors.

The last error is will be random but with high quality PI stages that are running properly it will be very small. So small, in fact, that for most situations we stitch using the theoretical stage positions and lose no accuracy compared to using the real stage positions.

Tile position errors should therefore be due to remaining factors, should be constant across the sample. Furthermore, these errors will be more apparent for larger tiles. Why is this? Consider tile A and the tile to the right of it, tile B. A structure on the right edge of tile A will be on the left edge of tile B. Imagine that the only error we have is due to the stages and scanners being slightly non-square with respect to each other. Structures at tile edges will appear shifted (non-contiguous) by an amount that is proportional to this misalignment. For a given angular misalignment, the measured offset at the edge will increase with FOV. Similarly, if the number of microns per pixel is off by 1 nm this will translate into a 1 micron error over 1000 pixels but only a half micron error over 500 pixels. So for a fixed image resolution, larger fields of view will be more prone to misalignment.

Minimising the above issues

To reduce errors arising from the number of microns per pixel being slightly off, you can tweak this value in the sample's recipe file. Acquire one section of a small area (e.g. 5x5 tiles) where there are a lot of features. Ensure StitchIt is installed and stitch the data with the "chessboard" feature: (e.g. stitchSection([1,1],3,'Chessboard',true)) and visualise in Icy or Fiji. Look at the tile overlap regions.

Can they be improved? Likely yes. To do this, go into the recipe file and modify the X and Y values on the line that looks like: VoxelSize: {X: 1.322, Y: 1.322}. This is the line just after StitchingParameters. Change one at a time to see the effect. Then re-stitch. If you have no other sources of error, it's possible to get near-perfect stitching this way. Once happy, you can go back to the frameSizes.yml file and update it. BakingTray can be made to re-read this file using hBT.scanner.readFrameSizeSettings. You can confirm this worked by looking in hBT.scanner.frameSizeSettings(x).stitchingVoxelSize You can then go back and tweak the objective resolution in ScanImage to reflect this new value so you don't need to tweak it each time.

The following image shows the effect of fine-tuning stitching accuracy. On the left is the stitching accuracy using the number of microns per pixel obtained by measuring with a grid (1.316 microns per pixel) on the right is the with this number manually over-ridden to 1.323 microns per pixel. So that's a tiny difference: only 7 nm per pixel! In this case the images shown have been downsampled such that 1 pixel is 2.632 microns.

Once you have the more accurate number for the microns per pixel, you could try running Grid2MicsPerPixel using a grid pitch that produces this number. For example, our grid will reliably produce 1.316 microns per pixel using a certain set of scan settings. However, we found stitching accuracy was better at 1.323. So we can instead do Grid2MicsPerPixel(ImageData,'GridPitch',25.125), which produces a microns per pixel value of 1.322. From now on, using this tweaked value for the number of microns per pixel (e.g. when measuring for different objectives or image resolutions) should produce a slightly more accurate value.

Handling other sources of error

If the above does not work, then probably there is a rotation issue at play or possibly barrel/pincushion distortion. Both of these can be handled. StitchIt includes a function called lensdistort which will deal with different sorts of distortion along the two axes if needed. The best way to assess this is to image an EM grid and see how much correction is needed. You can use the above tool directly on the image. Then enter the distortion parameters into the lensDistort section of frameSizes.yml. In addition to this, affine transformations are supported and this includes the option of correcting rotation. Do this by editing affineMat in the recipe file (for testing) then copy parameters to frameSizes.yml. i.e. No transformation would be:

1 0 0
0 1 0
0 0 1

And you can rotate tiles by doing:

1 0.15 0
0  1   0
0  0   1

It's just a normal affine matrix. Google for more.

Last updated