# SolvePnP wrong x, y coordinates

**URL:** <https://forum.opencv.org/t/solvepnp-wrong-x-y-coordinates/5372>\
**Category:** Python\
**Tags:** calib3d\
**Created:** [September 27, 2021, 12:46pm UTC](https://forum.opencv.org/t/solvepnp-wrong-x-y-coordinates/5372 "2021-09-27T12:46:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![a.civit](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/a.civit/32/2564_2.png) [@a.civit](https://forum.opencv.org/u/a.civit)\
**Post date:** [September 27, 2021, 12:46pm UTC](https://forum.opencv.org/t/solvepnp-wrong-x-y-coordinates/5372/1 "2021-09-27T12:46:42Z")

</div>

Hello!

I’m using the solvePnP function to get a face 3D coordinates.

The camera is properly calibrated since I plotted the x, y and z axis on the chessboard image after the calibration (with the same chessboard image) and the axis are orthonormal.

But when using the function:

(success, rotation\_vector, translation\_vector) = cv2.solvePnP(  
self.model\_points,  
image\_points,  
camera\_matrix,  
dist\_coeffs,  
flags=cv2.cv2.SOLVEPNP\_ITERATIVE,  
)

The translation vector gives the face coordinates (the nose endpoint is the origin coordinate so the translation vector should give the 3d pose of the nose endpoint). The ‘z’ coordinate is correct, but the x and y don’t change when i move the face around the image. In fact, they increase / decrease as i move away/closer to the camera.

Anyone knows why might this happen?

Thanks!

PD: The face coords i’m using are:

self.model\_points = np.array(  
[  
(0.0, 0.0, 0.0), # Nose tip  
(0.0, -330.0, -65.0), # Chin  
(-225.0, 170.0, -135.0), # Left eye left corner  
(225.0, 170.0, -135.0), # Right eye right corner  
(-150.0, -150.0, -125.0), # Left Mouth corner  
(150.0, -150.0, -125.0), # Right mouth corner  
]  
)

---

<div class="post-metadata">

**Author:** ![berak](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@berak](https://forum.opencv.org/u/berak)\
**Post date:** [September 27, 2021, 1:13pm UTC](https://forum.opencv.org/t/solvepnp-wrong-x-y-coordinates/5372/2 "2021-09-27T13:13:59Z")

</div>

where do you get the 2d image\_points from ?

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [September 27, 2021, 1:22pm UTC](https://forum.opencv.org/t/solvepnp-wrong-x-y-coordinates/5372/3 "2021-09-27T13:22:48Z")

</div>

please present values for all arguments, including camera matrix and a set of image points.

---

<div class="post-metadata">

**Author:** ![a.civit](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/a.civit/32/2564_2.png) [@a.civit](https://forum.opencv.org/u/a.civit)\
**Post date:** [September 27, 2021, 1:40pm UTC](https://forum.opencv.org/t/solvepnp-wrong-x-y-coordinates/5372/4 "2021-09-27T13:40:18Z")

</div>

Hi @crackwitz @berak Thanks for the answers.

The 2d image\_points come from the library face\_recognition → face\_recognition.face\_landmarks(face\_image)

[https://face-recognition.readthedocs.io/en/latest/face\_recognition.html#face\_recognition.api.face\_landmarks](https://face-recognition.readthedocs.io/en/latest/face_recognition.html#face_recognition.api.face_landmarks)

image\_points = np.array(  
[  
face[“nose\_bridge”][3], # Nose tip  
face[“chin”][8], # Chin  
face[“left\_eye”][0], # Left eye left corner  
face[“right\_eye”][3], # Right eye right corner  
face[“top\_lip”][0], # Left Mouth corner  
face[“top\_lip”][6], # Right mouth corner  
],  
dtype=“double”,  
)

Where face is the result from the previous function.

The camera matrix comes from the calibration I make with a chessboard and multiple images.

```
    # termination criteria
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) # Type, max_count, epsilon

    # prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
    objp = np.zeros((chess_width * chess_height, 3), np.float32)
    objp[:, :2] = np.mgrid[0:chess_width, 0:chess_height].T.reshape(-1, 2)

    objp = objp * square_size # Square size from the settings.py file

    print("Objp: ", objp)

    # Arrays to store object points and image points from all the images.
    objpoints = [] # 3d point in real world space
    imgpoints = [] # 2d points in image plane.

    images = glob.glob(calibration_images_path)
    print(images)
    gray = cv2.cvtColor(cv2.imread(images[0]), cv2.COLOR_BGR2GRAY)

    for frame in images:
        img = cv2.imread(frame)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # Find the chess board corners
        ret, corners = cv2.findChessboardCorners(
            gray, (chess_width, chess_height), None
        )

        # If found, add object points, image points (after refining them)
        if ret:
            objpoints.append(objp)

            corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
            imgpoints.append(corners2)

            # Draw and display the corners
            img = cv2.drawChessboardCorners(
                img, (chess_width, chess_height), corners2, ret
            )
            cv2.imshow("img", img)
            cv2.waitKey(500)

    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(
        objpoints, imgpoints, gray.shape[::-1], None, None
    )
    print("Translation vectors of chessboards: ", tvecs)

    cv2.destroyAllWindows()
```
