Extract image center position from .CZI metadata in Fiji

Dear image people,

I’m seeking to extract the correct stage center position of a tiled 10x fluorescence scan that is saved in the .czi format. If I open this file in the ZEN software, I get the following readings:

The value “Image Center Position” is the value I would like to extract automatically with an ImageJ macro script. However, I can find this value nowhere in the metadata. The marked entry seems to contain the center position:


which obviously doesn’t match the coordinates above in the readings of the ZEN software. Anything I’m overlooking?

For context, here’s what I’m trying to do: I have a 10x overview image with some few 40x detail scans that are spread across the whole slice. I did some analysis (quantification, registration, etc) on the 10x image and I would like to trace the position of the 40x images through this process.

Thanks in advance for any help!

Edit:
The same occurs for the (tiled) 40x images, for which ZEN tells me

whereas Fiji tells me

The two values are closer to each other in this case, but still do not coincide perfectly.

Probably an @sebi06 question, but did you do any stitching? That might have altered the center position. Alternatively, if you have not stitched, there is going to be some overlap between the tiles, so the absolute center may vary slightly depending on how you define it. All of the rest of the pixels in the image will also vary by how much they overlap with other tiles nearby.

I am guessing you did not stitch, since that tends to ruin most of the absolute positioning in Zen (you can no longer use the Stage tool on a stitched image).

If you did not Calibrate the stage prior to imaging both areas, I am not sure how well the values will line up either, but I have never really tried (I just mark the high res areas on the overview image using the graphics tools since there usually are not very many in our use cases).

Side note: it looks like your 40x goes outside the range of your 10x image, based on the image sizes and center coordinates from Zen?

Thanks for the answer. The stitching is indeed a source I’ve not yet taken into account.

However, I did some more digging in the metadata with the “Visualize OME metadata” plugin (Plugins -> Utilities -> Visualize OME metadata) and found this entry:

Which is exactly what ZEN is displaying and very likely what I’m looking for. Any idea how I can access these fields in ImageJ macro? I tried using Python’s czifile package to read the header, but I do not know how to access it.

I don’t have any other suggestions here, but hopefully someone will come along with something. I would be interested in this as well, though I have no immediate use for it.

Hi, here is a little python script how to retrieve the CenterPosition(s) using the czifile library.

import numpy as np
import czifile as zis

filename = r"C:\temp\yourfile.czi"

# get CZI object
czi = zis.CziFile(filename)

# parse the XML into a dictionary
metadatadict_czi = czi.metadata(raw=False)

# get the complete scene information
allscenes = metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['Dimensions']['S']['Scenes']['Scene']
centerposX = []
centerposY = []

# check if there is a list of scenes
if isinstance(allscenes, list):
    for s in range(len(allscenes)):
        for k, v in allscenes[s].items():
            print(k, ':', v)
        # get the SceneCenter Position for all scenes
        centerposX.append(np.double(allscenes[s]['CenterPosition'].split(',')[0]))
        centerposY.append(np.double(allscenes[s]['CenterPosition'].split(',')[1]))

# and in case of only one scence (= allscenes is not a list)
if not isinstance(allscenes, list):
    for k, v in allscenes.items():
        print(k, ':', v)
    centerposX.append(np.double(allscenes['CenterPosition'].split(',')[0]))
    centerposY.append(np.double(allscenes['CenterPosition'].split(',')[1]))

# show the positions
print(centerposX)
print(centerposY)

a typical output may look like this:

RegionId : 637356616788573529
ScanMode : Comb
CenterPosition : 13500,17500
ContourSize : 1024,1344
ContourType : Rectangle
Shape : {'ColumnIndex': 2, 'RowIndex': 2, 'CenterPosition': '13500,17500', 'Size': '7250,7250', 'Contour': {'Type': 'Rectangle'}, 'Name': 'B2', 'Id': '2-2'}
PyramidInfo : {'IsSane': True, 'PyramidLayersCount': 2, 'IsMinimalCoverage': True, 'MinificationFactor': 2, 'MinificationMethod': 'Gaussian'}
Index : 0
Name : B2
RegionId : 637356616788753535
ScanMode : Comb
CenterPosition : 31500,17500
ContourSize : 1024,1344
ContourType : Rectangle
Shape : {'ColumnIndex': 4, 'RowIndex': 2, 'CenterPosition': '31500,17500', 'Size': '7250,7250', 'Contour': {'Type': 'Rectangle'}, 'Name': 'B4', 'Id': '2-4'}
PyramidInfo : {'IsSane': True, 'PyramidLayersCount': 2, 'IsMinimalCoverage': True, 'MinificationFactor': 2, 'MinificationMethod': 'Gaussian'}
Index : 1
Name : B4
[13500.0, 31500.0]
[17500.0, 17500.0]
1 Like

Thanks @sebi06,

unfortunately, I’m still getting the same missmatch between the center coordinates as displayed in ZEN/OME metadata and the coordinates I can extract with the metadtaviewer and the czifile library as in the above python example :confused:

Can you grant me access to your czi file?

Sure can do. You can download one example file here: https://www.dropbox.com/s/8lfkz32w6cwojp5/P2A_B6_M1_GIN-0004-Scene-2-ScanRegion1.czi?dl=0

Hi @EL_Pollo_Diablo,

so I had a deeper look and I hope I find the “correct words” to explain what is going on here

  • you acquired a CZI with multiple scenes in the 1st place --> this will result in an “virtual” StageCenterXY position
  • inside a CZI the absolute and correct StageXY position for every tile are attached to the respective image subblocks
  • them you used split scenes to extract a particular scan region --> at this step the new StageCenterXY for such a region (created by a processing function) has to calculated --> the shown result might not be exactly the same as the original
  • inside the “real” metadata created during the image acquisition one will still find the other value as shown below

Bottom Line: The simple value shown inside the image info tab can differ (slightly) because it can be a virtually calculated value. For the values derived from the hardware during the acquisition please use the OME data, or the one from Python or have a look in the ZEN tree view.

Sidenote: For what you plan to do (align 40X region inside an 10X scan) we have a dedicated SW module, that will deal with all the complexity of those coordinate systems for you: ZEN Connect

This allows you the register and align those images as well as extracting a new multichannel CZI combining the data from the 10X and the 40X scan for subsequent image analysis in ZEN or any external software.

I hope this helps (but the business of image metadata can be a dirty one … :slight_smile:

image

1 Like

Hi @sebi06,

thanks for the quick answer! I’ll try to paraphrase with my own words:
The “image Center Position” that is displayed in the metadata is a “virtual” center position, which is calculated when I split multiple scenes in one image file?
The “true” center position would still be the one that I can access through the tree tab or the normal way to access the metadata as shown in my initial post?

In that case that should solve the issue.

Regarding your suggestion for 40x/10x alignment: I didn’t know about the SW module - will defintely give it a look! However, what I do is a little different: I quantify the 10x image tilewise and then I align the tiled images (then only ~500x500 large or so) with a 3D volume (e.g. Atlas or CT) with Elastix. I then trace the positions of the 40x images along this process (->tile-wise processing/registration/transformation). That’s why I need to get the positions of the 40x images with regard to the 10x motor coordinates automatically.

Bit of advertising: In case you’re present at the Ibsb Jena online conference in two weeks or so - I’ll show that workflow (“Slice2Volume”) in a tandem talk :slight_smile:

Hi @EL_Pollo_Diablo,

yes, especially when your original CZI already contains two scenes, the “simple” ImageCenterPositionXY is a “virtual” point, that is calculated. And therefore this is even more true when splitting scenes. Then a new “virtual” value must be calulated again.

So the real tile coordinates are in any case stored with the subblocks. At least this is true for the newer CZIs.

On the APEER platform I created a module with with create CSV file with all XYZ data for every tile. Feel free to give it a try. It can be also used directly from within ZEN via the Docker Integration (required ZEN 3.2)

Display PlaneTable and XYZ-Surface