Import Annotations from Matlab into BigTiff XML (Ventana)

In the previous post  we discussed how to export annotations from a Ventana Image Viewer program and create binary masks. Now we explain how to do the opposite and import the mask back into Image Viewer.

The overarching work-flow  of the entire process is:

  1. Pathologist annotates/marks up objects of interest in Image Viewer
  2. Export annotation and use it for some “process”, e.g., supervised classification algorithms
  3. Generate results
  4. Import results back into Image Viewer so that the pathologist can review/validate/correct/comment.

Especially in the case of these extremely large histology files (i.e., BigTiff or SVS), there are few programs available which allow for easy viewing and annotations. Additionally, since the pathologists are typically already familiar with these software tools, it makes sense to work in their framework to avoid any confusion or additional training.

Using the previous post, we can see that the output is a set of regions of interest (ROI) of the filename format: [base]_[x]_[y].tif , where x and y identify in the image where the ROI was cropped from. In this case, we have the following files, which are focused around (16475, 54931):

  • PT 32_201501010818.tif: original BigTiff image
  • PT 32_201501010818_16475_54931.tif: ROI cropped from it
  • PT 32_201501010818_16475_54931_class: a binary mask we want to generate an xml annotation for:
  • PT 32_201501010818.xml: the final xml output


We describe a function called make_xml_from_binary_mask. This requires two input parameters, the base file name (as mentioned above) , without filename extension, and the color of the annotation we’d like to draw. The color is specified as an RGB int.


  1. function make_xml_from_binary_mask(base,color)
  3. fid=fopen(sprintf('%s.xml',base),'w');
  5. fprintf(fid,'<?xml version="1.0"?><Annotations file=""><SlideAnnotation Text="" Voice=""/>');
  7. files=dir(sprintf('%s*class.png',base));


We begin by opening the xml file for writing which will contain our annotations. The xml file should have the same filename as the final image except with an “xml” extension, as this allows for automatic loading (otherwise the xml file can be selected from the file menu -> import annotations).

Next we lay down the minimum requirement for the xml, this is just the header that we poached from the xmls we’ve used previously.

PT 32_201501010818_16475_54931 PT 32_201501010818_16475_54931_class

Then we look for the binary images we want to export the annotations for. In our case, we have extracted many ROIs and generated results on them, so we’re going to loop through all of those ROIs and stick them into the same xml file.

  1. for fi=1:length(files)
  2.     fname=files(fi).name;```
  3.     iob=imread(fname);
  4.     fname_pieces=strsplit(fname,'_');
  5.     offsety=str2double(fname_pieces(3));
  6.     offsetx=str2double(fname_pieces(4));

We load our binary mask, and parse the filename to identify where the region of interest is. As mentioned above, this is basically the last 2 integers in the filename which contain the x and y coordinates of the upper left hand corner of the ROI.

  1. [iol,num]=bwlabel(iob);
  2.     for zz=1:num
  4.         p=bwperim(iol==zz);
  5.         [r,c]=find(p);
  6.         C=bwtraceboundary(p,[r(1) c(1)],'N');
  9.         fprintf(fid,'<Annotation LineColor="%d">',color);
  10.         fprintf(fid,'<Regions><Region Type="rtPolyline" regSelected="FALSE">');
  11.         fprintf(fid,'<Vertices>');
  12.         for yy=1:length(C)
  13.             fprintf(fid,'<Vertex X="%d" Y="%d"/>\n',C(yy,2)+offsetx,C(yy,1)+offsety);
  14.         end


We then iterate over each of the objects in the annotation (in our case we’re doing lymphocyte segmentation). First we identify the perimeter, then we use bwtraceboundary to provide a set of points which form a polygon around the boundary. Then we write the annotation of that specific object to the file, translated by the offset of the ROI , with the desired color. Once all of the points are written, we close the that region:

  1. fprintf(fid,'</Vertices></Region></Regions></Annotation>');

After all of the ROIs are looped through, we close the xml file with:

  1. fprintf(fid,'</Annotations>');
  2. fclose(fid);

Now that we’re done, we can open the bigtiff in ImageViewer and see our annotations, which can now be modified/deleted/added to! Its interesting to note, that through this part of the whole process, we don’t need to open or use the original bigtiff file at all.


That’s it!

Full source available here


5 thoughts on “Import Annotations from Matlab into BigTiff XML (Ventana)”

    1. yea sure. nothing specific to matlab here. a quick look makes me think that its pretty close to working in python with just some syntax changes

Leave a Reply

Your email address will not be published. Required fields are marked *