Ask Your Question

Drawing checkerboard's reference frame does not yield correct results (solvePnp+projectPoints)

asked 2020-04-12 15:32:09 -0500

mistermystere gravatar image

updated 2020-04-12 18:10:24 -0500


I have followed the tutorial at based on calibration data obtained following the tutorial at

The end objective is to obtain the pose of the checkerboard with respect to the camera, but first I am trying to draw the checkerboard's reference frame.

The input data is a set of 2 snapshots I have taken of my webcam feed pointed at a printed 10x7 checkerboard.

The calibration seems to succeed:

image description image description

But the output is totally wrong:

image description image description

Here is the patched-up code:

import cv2 as cv
import numpy as np
import glob
import argparse

# algorithm parameters

# termination criteria
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)

#=== CALIBRATE CAMERA ============================================================================

#Prepare object points
objp = np.zeros((CHECKERBOARD_HEIGHT * CHECKERBOARD_WIDTH, 3), np.float32)
objp[:,:2] = np.mgrid[0:CHECKERBOARD_HEIGHT, 0:CHECKERBOARD_WIDTH].T.reshape(-1,2)

# 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.

# Load the images
ap = argparse.ArgumentParser()
ap.add_argument('-f', '--folder', required=True,  help='Path to the images folder with last slash')
ap.add_argument('-e', '--ext', required=True,  help='Extension of image files without the dot')
args = vars(ap.parse_args())

images = glob.glob(args['folder']+'*.'+args['ext'])

#Process the images
for fname in images:
    print('Calibrating on '+fname)
    img = cv.imread(fname)
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    # Find the chess board corners
    ret, corners = cv.findChessboardCorners(gray, (CHECKERBOARD_WIDTH,CHECKERBOARD_HEIGHT), None)
    # If found, add object points, image points (after refining them)
    if ret == True:
        print('Found corners')
        corners2 = cv.cornerSubPix(gray,corners, (11,11), (-1,-1), criteria)
        # Draw and display the corners as feedback to the user
        cv.drawChessboardCorners(img, (CHECKERBOARD_WIDTH,CHECKERBOARD_HEIGHT), corners2, ret)
        cv.imshow('Calibration', img)
        k = cv.waitKey(0) & 0xFF
        if k == ord('s'):
            cv.imwrite(fname+'_calib.png', img)


#Obtain camera parameters
ret, mtx, dist, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

#=== FIND POSE OF TARGETS ===========================================================================

#Prepare object points
objp = np.zeros((CHECKERBOARD_HEIGHT * CHECKERBOARD_WIDTH, 3), np.float32)
objp[:,:2] = np.mgrid[0:CHECKERBOARD_HEIGHT, 0:CHECKERBOARD_WIDTH].T.reshape(-1,2)

axis = np.float32([[3,0,0], [0,3,0], [0,0,-3]]).reshape(-1,3)

def draw(img, corners, imgpts):
    corner = tuple(corners[0].ravel())
    img = cv.line(img, corner, tuple(imgpts[0].ravel()), (255,0,0), 5)
    img = cv.line(img, corner, tuple(imgpts[1].ravel()), (0,255,0), 5)
    img = cv.line(img, corner, tuple(imgpts[2].ravel()), (0,0,255), 5)
    return img

for fname in images:
    print('Processing '+fname)
    img = cv.imread(fname)
    gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
    ret, corners = cv.findChessboardCorners(gray, (CHECKERBOARD_WIDTH,CHECKERBOARD_HEIGHT), None)
    if ret == True:
        print('Found corners')
        corners2 = cv.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
        # Find the rotation and translation vectors.
        ret,rvecs, tvecs = cv.solvePnP(objp, corners2, mtx, dist)
        # project 3D points to image plane
        imgpts, jac ...
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2020-04-13 14:50:45 -0500

Eduardo gravatar image

The following code:

from __future__ import print_function
from __future__ import division

import numpy as np
import cv2 as cv

print('cv:\n', cv.getBuildInformation())

# img = cv.imread('8i77L.png')
img = cv.imread('left01.jpg')


ret, corners = cv.findChessboardCorners(img, (CHECKERBOARD_WIDTH, CHECKERBOARD_HEIGHT))

if ret == True:
    cv.drawChessboardCorners(img, (CHECKERBOARD_WIDTH, CHECKERBOARD_HEIGHT), corners, ret)

    objp = np.zeros((, 3), np.float32)
    objp[:, :2] = np.indices(pattern_size).T.reshape(-1, 2)
    square_size = 0.05
    objp *= square_size
    print('objp:', objp.shape)
    print('corners:', corners.shape)

    intrinsics = np.array([[600, 0, img.shape[1]/2],
                           [0, 600, img.shape[0]/2],
                           [0, 0, 1]],
    print('intrinsics: {}\n{}'.format(intrinsics.shape, intrinsics))

    ret, rvec, tvec = cv.solvePnP(objp, corners, intrinsics, None)
    print('rvec:', rvec.T)
    print('tvec:', tvec.T)

    img = cv.drawFrameAxes(img, intrinsics, None, rvec, tvec, square_size, 3)
    cv.imshow('Pose', img)
    cv.imwrite('test_solvePnP.png', img)


image description

edit flag offensive delete link more

Question Tools

1 follower


Asked: 2020-04-12 15:32:09 -0500

Seen: 99 times

Last updated: Apr 13 '20