Pixels to float coordinates

Take the following grid (those pixel shapes were returned by findContours):


The blue square coordinates goes from 1x1 to 2x2, whereas the red square goes from 3x1 to 4x2. However, if I was to use this data the 3d space, I’d have a problem - because those same 2d coordinates, which work fine in pixel world, would only map to the following black square in floating space:

(see post below)

Is there a native OpenCV tool to “fix” the coordinates and make them suitable for a 3d-like coordinate space?

Second image I couldn’t put in the first post:


this has nothing to do with 2D/3D.

findContours gives you the coordinates of the boundary pixels of the blob. that’s different from the boundary itself.

you should consider the contours to mean this:

generally, pixel centers are integer values. pixel corners/edges sit half fractions away from the grid.

this way, if one were to draw a polygon from that contour data, which means drawing 1-pixel lines on those coordinates, one would get the blob boundary exactly.

I don’t think OpenCV has a function to calculate an offset on a contour, or to tell findContours to emit pixel edge coordinates.

OpenCV’s somewhat neglected and sloppy in those old parts, which also includes drawing (line thickness…). I’ve tried to call attention to it for bug fixes but some people flat out refused to understand what I was showing them. getStructuringElement for an ellipse also returns atrocious results but nobody else complains so nobody must be caring about precision.

calculating an offset to a contour isn’t a trivial operation. I think this would be solved better by an extension and flag to findContours so it emits pixel border coordinates.

here’s some demo of its behavior:

>>> im
array([[  0,   0,   0,   0,   0],
       [  0, 255, 255,   0,   0],
       [  0, 255, 255, 255,   0],
       [  0, 255,   0,   0,   0],
       [  0,   0,   0,   0,   0]], dtype=uint8)
>>> cv.findContours(im, cv.RETR_LIST, cv.CHAIN_APPROX_NONE)
([array([[[1, 1]],

       [[1, 2]],

       [[1, 3]],

       [[2, 2]],

       [[3, 2]],

       [[2, 1]]], dtype=int32)], array([[[-1, -1, -1, -1]]], dtype=int32))
1 Like