3

I have this picture:

enter image description here

I'de like to obtain the distance between two of these points. The black scale bar is 3$\mu m$.

To do so, I import the image to Mathematica and call it pic. Then by finding dominant colors, I define red as

red = RGBColor[0.827134595933227, 0.00309700865836607, 
      0.08256587730260687, 1.];

And then I obtain the coordinates of the centers of the dots as

  centroid[pic_,color_] := ComponentMeasurements[
  Binarize@ColorDetect[pic,color],
  "Centroid"
  ][[All,2]]

coordinates = centroid[pic,red]

So

            {{5.5, 39.5}, {13.9828, 37.5345}, {34.2308, 37.8846}, {23.6034, 
            34.8103}, {5.38571, 32.5571}, {15., 29.}, {1.19231, 24.8077}}

Now, let's say we want to obtain the distance between two points of coordinates: {15., 29.} and {23.6034, 34.8103} which is 10.3816.

Now, my question is that how can I also determine the size of scale and obtain the real distance between these two points?

1 Answers1

1

First, let's get the scale bar out of the image. There are a few ways to do this (MorphologicalBinarize and friends), but I went with the more eye-bally approach of using ColorReplace. Here, we're replacing black pixels with white, and all other pixels with black, to get a mask. Note that ColorReplace has a third argument d, which you could use to fine-tune what it sees as "black".

i = Import["https://i.stack.imgur.com/yR6UY.gif"]

c = ColorReplace[i, {Black -> White, _ -> Black}]

enter image description here

Compare with a simple MorphologicalBinarize - the choice is yours:

enter image description here

Now we can get the bounding box of our rectangle, and simply take the difference:

box = ComponentMeasurements[c, "BoundingBox"][[1, 2]]

Differences /@ Transpose@box

{{38.}, {5.}}

So the longest dimension of our bounding box is 38 pixels long, and the short side is 5 pixels long.

Just to check, I counted the pixels another way, using SequenceCases on our replaced image, and each line of 1s, the pixels of the scale bar, had a length of 38.

SequenceCases[
 Flatten@MorphologicalComponents[c], {p : Repeated[1]} :> Length@{p}]

{38, 38, 38, 38, 38}

Either way, we get about 38 pixels, so now we know the length of the bar, and thus we can get the size of a pixel (assuming pixels are square here).

pixelLength = Quantity[3, "Microns"] / 38

Quantity[0.0789474, "Microns"]

and now if we get the Euclidean distance between your points and multiply it by our pixel length, we get the distance in microns.

EuclideanDistance[{5.5, 39.5}, {13.9828, 37.5345}] * pixelLength

Quantity[0.687437, "Microns"]

This answer will not hold up well if the bar is not always aligned perfectly to the image border, as it is in your test image. You could consider ComponentMeasurements[c, "Length"] or "CaliperLength" to get the length of the bar instead in that case. However, it may take the distances between opposite corners of the bar, which may not be what you want.

Carl Lange
  • 13,065
  • 1
  • 36
  • 70
  • I did not have my coffee before this answer - I would wait until a better-caffeinated person comes by and gives a better response. I suspect my approach is not scientific enough and potentially just plain wrong. – Carl Lange Feb 10 '21 at 09:43
  • Not that I'm aware of, but you could simply create a function called pixelDistanceInMicrons[p1_, p2_, pixelLength_] := EuclideanDistance[p1, p2] * pixelLength and call it like pixelDistanceInMicrons[{5.5, 39.5}, {13.9828, 37.5345}, Quantity[0.0789474, "Microns"]]. – Carl Lange Feb 10 '21 at 10:36
  • You could also count the pixels by hand, I suppose. – Carl Lange Feb 11 '21 at 09:02
  • If the bar is diagonal, counting pixels in the way I have done it here will not work, as I am counting them left to right. As I mention, I think "CaliperLength" will do a reasonable job in this case. I am hopeful someone else will post a more scientific answer as I'm not convinced this method would be enough for Real Science and I'm not sure I can help you further because of that. Hope my answer at least helps you find your way to a more useful result :) – Carl Lange Feb 11 '21 at 12:06