# Distance between two points in a picture

I have this picture: 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?

• You can try using the function copyCurve [here]. It was aimed for other purposes, but it can also easily do what you need. : mathematica.stackexchange.com/questions/44355/… Feb 10 at 8:55
• This can be done with the copyCurve function. As well as the distance definition. Feb 10 at 13:05

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}] Compare with a simple MorphologicalBinarize - the choice is yours: 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} :> 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.

• 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. Feb 10 at 9: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"]]. Feb 10 at 10:36
• You could also count the pixels by hand, I suppose. Feb 11 at 9: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 :) Feb 11 at 12:06