Below is an image of cells (adapted from here, Figure 1):
where the scale bar is $20 \mu m$. Is there any way to calculate the areas of cells with Mathematica?
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityBelow is an image of cells (adapted from here, Figure 1):
where the scale bar is $20 \mu m$. Is there any way to calculate the areas of cells with Mathematica?
figA = Import["https://i.stack.imgur.com/XM8fK.jpg"];
figB = Import["https://i.stack.imgur.com/4WFEF.jpg"];
figBSmall = Import["https://i.stack.imgur.com/LjnRy.png"];
imgOrig = figBSmall;
img = ImageCrop[imgOrig];
We look for the scale bar in the bottom-right part of the image. Only one morphological component should be found.
imgLowerThird =
ImageTake[
img, -ImageDimensions[img][[2]]/3, -ImageDimensions[img][[1]]/3];
imgBW = Dilation[Erosion[Binarize[imgLowerThird, .9], 1], 1];
scaleBar = MorphologicalComponents[DeleteBorderComponents@imgBW];
Max[scaleBar]
(* 1 *)
scaleBar // Colorize
scaleBarRealHeight = Quantity[20, "Micrometers"];
scaleBarHeight = #[[2, 2]] - #[[1, 2]] &@(1 /.
ComponentMeasurements[scaleBar, "BoundingBox"])
(* 25. *)
areaFactor = scaleBarRealHeight^2/scaleBarHeight^2
(* Quantity[0.64, ("Micrometers")^2] *)
First, we remove the image label (b) and the scalebar, as proposed by @GeorgeVarnavides in the comment.
maxComponentSize = 15;
inpaintDilation = 1;
imgInpaint =
Inpaint[img,
Dilation[DeleteBorderComponents[
DeleteSmallComponents[Binarize[img, 0.9], maxComponentSize]],
inpaintDilation]]
Since cell borders are much darker than the interior, we convert the image to HSL color space and take the lightness channel. Furthermore, we crop the image and make a thin border so that the boundary cells are well separated. Small specks are removed by DeleteSmallComponents
(once for the black and once for the white specks).
In this step, manual adjustment of four parameters can be made so that the output image edgesWithBorder
has well-defined and connected cell boundaries without any black or white specks.
contrastAdj = 1;
threshold = .95;
cropWidth = 2;
specksSize = 50;
imgAdj = ImageAdjust[imgInpaint, contrastAdj];
imgB = ColorSeparate[ColorConvert[imgAdj, "HSB"]][[3]];
imgBinarized = Binarize[imgB, threshold];
edges = ColorNegate@
DeleteSmallComponents[ColorNegate@imgBinarized, specksSize,
CornerNeighbors -> False];
edges = DeleteSmallComponents[edges, specksSize,
CornerNeighbors -> False];
edgesCropped =
ImageTake[edges, {cropWidth, -cropWidth}, {cropWidth, -cropWidth}];
edgesWithBorder = ImagePad[edgesCropped, 1];
{imgB, edgesWithBorder} // GraphicsRow
cells = MorphologicalComponents[edgesWithBorder,
CornerNeighbors -> False];
cells // Colorize
centroid = ComponentMeasurements[cells, {"Centroid"}];
centroidLoc = centroid[[All, 2, 1]];
area = ComponentMeasurements[cells, {"Area"}];
HighlightImage[#, Table[ImageMarker[centroidLoc[[i]],
Graphics[Style[Text@ToString@i, White, Bold]]], {i, 1,
Length@centroidLoc}]
] & /@ {img,
Colorize[cells, ColorFunction -> "DarkRainbow"]} // GraphicsRow
Grid[Transpose@(PadRight[#, 10, ""] & /@
Partition[
Table[Row[{ToString@i, ": ",
Round[areaFactor*First[i /. area]]}], {i, 1,
Length@centroid}], UpTo[10]]), Alignment -> Left]
inpaintDilation = 6;
threshold = .94;
cropWidth = 8;
specksSize = 300;
Most of the cells seem to be correctly recognized and measured. However, expect the results to have an error of about $5 \%$ for the middle cells (and significantly more for the cells on the edge of the figure). This can be seen by varying the preprocessing parameters or using high-resolution image (figB
vs. figBSmall
). Also note that the removal of image label and scalebar with InPaint
produces artificial cell boundaries, which means the areas of surrounding cells have greater error.
Inpaint
can help. E.g. pre-processing with something like this seems to work well Inpaint[imageA, Dilation[DeleteBorderComponents[ DeleteSmallComponents[Binarize[imageA, 0.9], 250]], 5]]
(where imageA
is a 1048x962 image of Figure 1a from the attached paper)
$\endgroup$
Aug 23, 2021 at 21:16
ComponentMeasurements
andMorphologicalComponents
. However, some image preprocessing will be needed, together with the appropriate calibration with the scale bar. Simple, but quite inaccurate example:ComponentMeasurements[ColorNegate@Erosion[Dilation[EdgeDetect[img, 1.5, .05], 1.6], 1.4], "Area"]
. $\endgroup$(b)
marking from the image. $\endgroup$