5

I need to get the Center of Mass (Centroid) for components in a set of binary images with subpixel accuracy.

Mathematica 8 comes with a nice addition:

i =  Import@"https://i.stack.imgur.com/2pxrN.png";  
m1 = ComponentMeasurements[MorphologicalComponents[i], "Centroid"] /. 
                                                                Rule[_, x_] -> x
(*
-> {{403.229, 453.551}, {660.404, 371.383}, {114.389, 434.646}, {295.5, 206.}}
*)

But I went through some troubles when those results showed some inconsistencies with other calculations done elsewhere.

So I rolled my own, perhaps not nice:

i = Import@"https://i.stack.imgur.com/2pxrN.png";
f[i_] := N@{#[[2]], ImageDimensions[i][[2]] - #[[1]]} & /@
         ( Mean /@
             Function[x, Map[
                Position[x, #, 2] &,
                Complement[Union@Flatten[x], {0}]]]
             [MorphologicalComponents[i]]);
f[i]
Show[i, Graphics[{Red, Disk[#, 10] & /@ f[i]}]]
(*
-> {{403.729, 453.051}, {660.904, 370.883}, {114.889, 434.146}, {296., 205.5}}
*)

enter image description here

You can see that there is a .5 offset between these results:

Thread[Subtract[m1, f[i]]]
(*
-> {{-0.5, -0.5, -0.5, -0.5}, {0.5, 0.5, 0.5, 0.5}}
*)

At first I thought that the problem was related with the image dimensions being even or odd, but that is not the case.

I'd prefer using ComponentMeasurements[ ..,"Centroid"] and correcting the results, but I'm afraid future Mma versions may modify this behavior and spoil the results.

I could also run a previous "calibration" with a known image and calculate the offsets, so it will auto-correct, but I would like to understand what is going on first.

Is this a bug?
Any ideas about why is this happening?

Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
Dr. belisarius
  • 60,527
  • 15
  • 115
  • 190
  • 1
    i would guess this could have to do with the convention where the pixel centers are located relative to the coordinate grid. If one algorithm assumes the coordinate grid aligned with pixel-boundaries and the other assumes the grid aligned with pixel-centers you get inconsistent results. – Thies Heidecke Jun 24 '11 at 17:31

1 Answers1

6

I feel the doc page for ComponentMeasurements contains the solution:

Position, area, and length measurements are taken in the standard image coordinate system where position {0,0} corresponds to the bottom-left corner, x runs from 0 to width, and y runs from 0 to height.

You are counting whole pixels and ComponentMeasurements measures pixel positions. In this system, the center of the bottom left pixel is at {1/2,1/2}.

Sjoerd C. de Vries
  • 16,122
  • 3
  • 42
  • 94
  • Seems that is it. Of course I've read that before posting, but I understood it as it fitted me. Now I have to take care of three different coordinate systems: the one used by ImageData[], the other one used by Graphics[], and this one. I'll need to suffix my vars, or I'll mess up everything. Thanks a lot. – Dr. belisarius Jun 24 '11 at 19:41
  • 1
    Count in `MatrixPlot` and `ArrayPlot` too. The latter one has `DataReversed` to set things straight, though. – Sjoerd C. de Vries Jun 24 '11 at 19:56