Analysis of radiation field size using gafchromic film scanned as tiff

Dear all

we use gafchromic film for radiation field size measurements. We scan the exposed film on an Epson scanner and analyse the .tiff file image using an imageJ macro which determines the radiation field size from the 50% intensity value on two orthogonal profiles (red image channel). I wish to perform this analysis using python/pylinac with the goal of integrating the analysis into our QAtrack workflow.

I have made a good start on the analysis below. I have cheated a bit here, since I manually cropped the part of the scan image which covers the film. It would be nice to automatically detect this region.

Next I want to subtract the background from the profile (pixels < ~ 45000), and identify the points of 50% intensity of the profile. From the 50% points I can determine the field width (cm). This will be a bit complicated by the noise in the profile, so I am considering a fit to the profile (top hat function?) to exclude the background/noise automatically…

Perhaps someone has performed this sort of analysis already, and can offer some tips?

Please note I have used skimage to load the .tiff file since our .tiff are 48 bit and this cannot be handled by the pylinac image.load method…

Hey Robin,
It looks like the 48 bit limitation may come from pillow, which is what pylinac uses for tiff files but I’d have to test the file to know for sure.

Detecting the film or exposed part of the film could be done a few ways, depending on how reproducible your scanning pipeline is. The simple way is to apply a binary operation over the image, keeping only the pixels above a threshold. For the threshold, skimage provides several and depending on how reproducible your images are, that may be enough. You could also use a threshold based on, e.g., a difference between max pixel value and the median pixel value (assuming your film is much bigger than the exposed area).

As for noise, a median filter works nicely as it’s edge-preserving. That’s assuming your noise is salt and pepper. You could also improve your signal by averaging the nearby profiles. E.g. apply a mean to a 5- or 10-pixel profile band. I have yet to use a tophat filter so I can’t comment there.

Let us know how it turns out!

OK I have a rudimentary but working method, see below. I would like to explore the flatsym module, but this currently can only load from a .dcm, and does not accept a numpy array? Can flatsym correctly orient the image to correct for slight tilts? Currently in our imageJ macro the user has to correct the alignment of the image manually…

The flatsym module needs some love; it hasn’t been updated in a while. It was also designed for used with the EPID, not film. The original reason it only accepts dicom files is so that it can read the tags for dpi and SID without passing that info in.

The flatsym module does not correct for tilt. My assumption was people were using their EPID and thus it would be a dicom file and that (assuming coll=0) the image would be parallel to the image edges.

It seems you’ve got your own version working now which is great!

Hi Mr Cole

I wonder whether you got it to work with GafChromic films? If so would you mind sending me the python file so that I can try it.

Thanks for your help


Hi Senthil
My code is on
I haven't taken this any further but feel free to steal the code and improve!