Wednesday, February 13, 2019

Analysis of an Antibiogram




In this case study based on the article entitled Single bacterial super-clone behind world epidemic of drug-resistant E. coli of M. McCarthy [Link], there is an image of an Antibiotic Susceptibility Testing and the question is: "Is it possible to automatically detect the wafers and the inhibitory areas?"...

In Fig.1, two Petri boxes corresponding to Antibiotic Susceptibility Testing are presented and we would like to analyze some features. For this example, only the right one will be processed.

Fig.1: Original image from the article of Michael McCarthy entitled Single bacterial super-clone behind world epidemic of drug-resistant E. coli [Link].


Download this image and only keep the right one by choosing the Rectangle tool and selecting the Petri box, then duplicate the selection. Because, this image is large, you can reduce its size by 2 with Image > Adjust > Size...

Note: In my case, the crop image is 764x802 pixels.

1.Number of disks

To compute the number and location of all the disks, we need to enhance the image.
  • First, convert this color (RGB) image into a 8-bit gray-level image. Rather than using a Image > Type > 8-bit, it may be interesting to split the various channels of this image with Image > Colors > Split Channels. Only keep the most contrasted like the Red or Green channels (I chose the Green one).
  • Second, there is some text on top of the Petri box that we need to remove by applying three times a Median Filter with a radius of 4.0.
  • Third, we need to remove all kind of defects due to non-uniform illumination. A Process  > Subtract Background... with a radius of 40.0 must be run.
  • Fourth, choose a segmentation mode like Otsu to binarize the image (Fig.2 Left). Set up correctly the LUT to get black blots surrounded by white background.
  • Fifth, run a Analyze > Analyze Particles... by setting the size in the range of [500,Infinity] and the circularity between 0.8 and 1.0 to get measurements about the blots (Fig. 2 Right).

Fig.2: Segmentation of the wafers. Left: Image after segmentation with Otsu mode. Right: Results of Analyze > Analyze Particles... using Outlines rendering.

let imp = IJ.getImage(); // Load the cropped image
// Step #1
channels = ChannelSplitter.split(imp);
imp.close(); // Close the blue channel
imp.close(); // Close the red channel
// Step #2
IJ.run(imp, "Median...", "radius=4");
IJ.run(imp, "Median...", "radius=4");
IJ.run(imp, "Median...", "radius=4");
// Step #3
IJ.run(imp, "Subtract Background...", "rolling=40");
// Step #4
IJ.setAutoThreshold(imp, "Otsu");
// Step #5
IJ.run(imp, "Analyze Particles...", "size=500-Infinity circularity=0.80-1.00 show=Outlines display exclude clear");

2. Radii of inhibitory areas

  • First, Image > Color > Split Channels and keep the Green one.
  • Second, apply once a Median Filter of radius = 2.0
  • Third, run a Triangle segmentation.
  • Fourth, Fill the holes (Fig.2 Left).
  • Fifth, run the Watershed to split the areas
  • Sixth, run the Analyze > Analyze Particles...
Fig.2: Processing to get the radii of the inhibitory areas. Left: Segmented image using Triangle mode. Middle: Split areas after Fill Holes and Watershed. Right: Outlines generated by the Analyze Particles... command.

Here is the generated JS script summarizing the new steps.

// Step #2
IJ.run(imp, "Median...", "radius=2");
IJ.setAutoThreshold(imp, "Triangle");
IJ.run(imp, "Fill Holes", "");
IJ.run(imp, "Watershed", "");
IJ.run(imp, "Analyze Particles...", "size=1000-Infinity show=Outlines display exclude clear");

... and the measurements...
+++ csv +++ +++ End of csv +++

3. Small script to draw the disks and inhibitory areas

let imp=IJ.getImage(); // Get ID of the Ultimate Points image
let table = ResultsTable.getResultsTable();
let x = table.getColumn(table.getColumnIndex('X'));
let y = table.getColumn(table.getColumnIndex('Y'));
let diam = table.getColumn(table.getColumnIndex('Feret'));

//// MAIN /////

for (let i = 0; i < x.length; i++) {
  let radius = diam[i];
  imp.setColor(new java.awt.Color(255,0,128));
  imp.getProcessor().drawOval(x[i]-radius,y[i]-radius,radius*2,radius*2);
}
imp.updateAndDraw();



There are many other ways to analyze this image that you can experiment on your own. Use it as a primer, try to process the other Petri box and hope that helps!

Thank you for reading.

4. Other crazybiocomputing posts

Further readings are available in ...
  • Analysis Series  [Link]
  • Image Processing TOC [Link]

No comments:

Post a Comment