# Problem when extracting data of a closed curve from a black and white image: how to find the correct transformation of coordinates?

I am trying to extract the data of the closed curve from a black and white image.

But the coordinates of the curve I extraced are wrong, as seen in my result .

For example, the x-coordinate of my result ranges from -150 to 0, which is different from the true range, i.e., -6 to 6.

I found some very useful discussions here about extracting data from images.

However, when I tried to apply the techniques discussed to extract data from a black and white image, the results were incorrect.

Here is my naive try. Where did I go wrong?

It seems I didn't find a correct transformation?

Any suggestions? Thank you.

imgImport = Import["https://i.sstatic.net/c0KCa.png"];
img = ImageTake[imgImport, {55, 286}, {125, 469}]

cor = ImageValuePositions[img, {0., 0., 0.}];
{o, x, y} = {{6.56169201921564,
22.11360816415005}, {28.934949660676992,
5.2325141690732515}, {6.679185088841892, 6.554693779835269}};
trans = FindGeometricTransform[{o, y}, {{-6, -14}, {-6, 16}}][[2]];

ListPlot[trans /@ cor]


• Would you like to reproduce img with ListPlot? Commented Mar 2 at 22:38
• Could you explain what it is you're trying to achieve, and how the current results of your current code differ from that? Commented Mar 2 at 22:39
• @AlexTrounev Thanks! Yes, I want to reproduce img with ListPlot :) Commented Mar 3 at 1:29
• @MelaGo Thanks for your attension. I am trying to extract data of the closed curve in the image, but the result I got are wrong. For example, the x-coordinate of my result ranges from -150 to 0, which is different from the true range, i.e., -6 to 6. Commented Mar 3 at 1:30
• @xinxinguo We should know some points on this curve. Commented Mar 3 at 2:00

Here is an approximation.

Identify axes

ls = ImageLines[ColorNegate@imgImport, .2];
HighlightImage[imgImport, ls]


Find the origin

origin = Flatten[MeshPrimitives[RegionIntersection[MeshRegion /@ ls], 0] /.
Point -> List]
(* {111.145, 85.2972} *)


Crop the image at the axes

{w, h} = ImageDimensions[imgImport];
img = ImageTake[imgImport, {0, h - origin[[2]]}, {origin[[1]], w}]


Get the coordinates from the cropped image and transform according to a manual inspection of the axes

d = ImageValuePositions[img, {0., 0., 0.}];
{w2, h2} = ImageDimensions[img];
dtxf = {(#[[1]]/w2) 12 - 6, (#[[2]]/h2) 34 - 16} & /@ d;

ListPlot[dtxf, AspectRatio -> 1]