1

Heyho!
I've got an image of a flat surface (taken from above and with an angle of 30°) and I want the x & y coordinates of a specific pixel but in cm (with the coordinate system being in the surface).
Is there a method to archive this?
I'm using python but any help is appreciated! :)

Edit: I tried the homographie method from below however I didn't quiet manage to make it work. Her is what I did:

#two sets of points I used 
#src: corners + center of my 400px*460px image 
#dst: coordinate system being outside the image 
src = np.matrix(((1, 1, 1),(400, 1, 1),(1, 460, 1),(400, 460, 1),(200,230,1)))
dst= np.matrix(((31.6, 7, 1),(14.5, 7, 1),(28.4, 26.3, 1),(17, 26.3, 1),(22.6,18.6,1 )))

#src: random points from the image of my 400px*460px image 
#dst: coordinate system being in the actual image
src = np.matrix(((1, 1, 1),(400, 460, 1),(200,1,1), (100, 170, 1), (280, 320, 1),(300, 50, 1)))
dst= np.matrix(((0, 0, 1),(14.6, 19.3, 1),(17.1/2,0,1), (5.0, 9.2, 1), (11.65, 15.3, 1), (12.9, 2.9, 1) ))

H = cv2.findHomography(src,dst,0)[0]
print (H)    
for c in range(0,5):
    x= c*100
    y = 1
    print(x,y,np.dot(H,np.array((x,y,1))))  

Actual Photo of the setup
The square is the area visible on the (400px*460px) picture. The Camera is located in the black box on the right. The X & Y are my Pixelcoordinates.
Results with both sets of numbers are good as long as you stay on the x-axis. As soon as I move down the y-axis the numbers go wrong.

ShixX
  • 51
  • 4
  • 1
    This is a geometry problem. You need to know two things - the projection matrix of the camera (calculable by measuring the field of view), and the transformation matrix of the camera (its position relative to the table). – Eric May 26 '16 at 13:42
  • Alternatively, you could just throw an opencv camera calibration routine at it, and save yourself the effort of measuring things – Eric May 26 '16 at 13:43
  • The information you provide in your question is really not enough to solve your problem. If you don't know anything about the intrinsic parameters of your camera, there's no chance to find the right solution. Just consider that your flat surface could either be a very small surface seen from very close or a very large one seen from far away. – Sunreef May 26 '16 at 13:51
  • Hey Eric, thanks for the opencv camera calibration routine hint, looking through this right now... But I can't really figure out what to do after that? What can I do with the camera parameters? Hey Sunreef, the camera is a raspberry pi camera module if that helps? Camera and surface are on a fixed position – ShixX May 26 '16 at 13:58
  • @Sunreef actually you do not need the intrinsic parameters... for measuring on a plane it is enough to know the homography between the 3D real world plane and the image plane. – Alessandro Jacopson May 26 '16 at 20:11
  • @Eric actually you do not need to calibrate your camera, it is enough to estimate an homography. – Alessandro Jacopson May 26 '16 at 20:13
  • @AlessandroJacopson But you still need either the field of view or the focal length of the camera to identify the image plane. And those are intrinsic parameters. – Sunreef May 26 '16 at 20:14
  • 1
    @Sunreef Maybe you can use the intrinsic to solve the problem but they are not necessary. See: Antonio Criminisi. "Single-View Metrology: Algorithms and Applications (Invited Paper)". In: *Pattern Recognition*. Ed. by Luc Van Gool. Vol. 2449. Lecture Notes in Computer Science. Springer Berlin Heidelberg, 2002, pp. 224-239. – Alessandro Jacopson May 26 '16 at 20:27
  • @ShixX Do you take the picture http://i.stack.imgur.com/qHr00.jpg with the raspberry camera? Is that picture the one you used to estimate the homography? – Alessandro Jacopson May 28 '16 at 12:02
  • @Alessandro-Jacopson Hey, I added a new Photo of the actual Setup & I hope this makes thing more clear – ShixX May 30 '16 at 08:59
  • @ShixX I had access to the picture you posted at http://i.stack.imgur.com/qHr00.jpg but I have no access (it requires a username and a password for dropbox) to the image you posted at https://www.dropbox.com/home/Camera%20Uploads?preview=2016-05-30%2010.30.17.jpg Anyway in my opinion best thing to do would be to upload a picture (taken with your hardware) of the plane you need to measure. – Alessandro Jacopson May 30 '16 at 18:17

1 Answers1

1

One approach is to estimate the homography between the plane of your flat surface and your image plane. A simple way to estimate the homography:

  1. get the coordinates in cm of four (non collinear) points on your flat surface;
  2. find the same four point in the image and get their coordinates in pixel;
  3. estimate the homography with cv::findHomography;
  4. find in the image your point of interest and get its coordinate in pixel;
  5. compute the coordinate of your point in cm using the homography.

For a worked out sample in C++ with OpenCV see my answer https://stackoverflow.com/a/36388035/15485

If you need more accuracy you need also to compensate for the distortion of the lens and since you say you have a raspberry pi camera maybe the distortion is not negligible... but it depends on the accuracy you require. The homography is not capable to compensate for the distortion.

Community
  • 1
  • 1
Alessandro Jacopson
  • 18,047
  • 15
  • 98
  • 153
  • Hello Alessandro! Thanks for your reply! I tried to get this to work all day but failed :( I took four points and got their pixel and cm coordinates. Calculated H with cv2.findHomography (src(pixelCoords), dst (cmCoords),0). And for my Point of interest I calculated P(in cm) = H * p (in pixel). However I this works for me only on one particular line (with y (pixel) = 0) and all the other values are far off. Thanks for your help in advance! – ShixX May 27 '16 at 13:47
  • @ShixX I think that to get help from the StackOverflow community, the best you can do is to edit your question adding the code you tried and, if possible, the image. – Alessandro Jacopson May 27 '16 at 14:36