Ask Your Question
0

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

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

mistermystere gravatar image

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

Greetings,

I have followed the tutorial at https://docs.opencv.org/master/d7/d53... based on calibration data obtained following the tutorial at https://docs.opencv.org/master/dc/dbb....

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
CHECKERBOARD_WIDTH = 9
CHECKERBOARD_HEIGHT = 6


# 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')
        objpoints.append(objp)
        corners2 = cv.cornerSubPix(gray,corners, (11,11), (-1,-1), criteria)
        imgpoints.append(corners)
        # 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)

cv.destroyAllWindows()

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

#Display 
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 ...
(more)
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

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

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')

CHECKERBOARD_WIDTH = 9
CHECKERBOARD_HEIGHT = 6

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

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

    pattern_size = (CHECKERBOARD_WIDTH, CHECKERBOARD_HEIGHT)
    objp = np.zeros((np.prod(pattern_size), 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]],
                           dtype=np.float32)
    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)
    cv.waitKey()

gives:

image description

edit flag offensive delete link more

Question Tools

1 follower

Stats

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

Seen: 1,825 times

Last updated: Apr 13 '20