· Hakan Çelik · OpenCV / Camera Calibration · 3 dk okuma

Pose Estimation

Learn to exploit the calib3d module to create 3D effects in images. We cover cv.solvePnP() and cv.projectPoints() to draw 3D coordinate axes and a cube on a chessboard.

Pose Estimation

Goal

In this section,

  • We will learn to exploit calib3d module to create some 3D effects in images.

Basics

During the last session on camera calibration, you have found the camera matrix, distortion coefficients etc. Given a pattern image, we can utilize the above information to calculate its pose, or how the object is situated in space. For a planar object, we can assume Z=0.

Our problem is, we want to draw our 3D coordinate axis (X, Y, Z axes) on our chessboard’s first corner. X axis in blue color, Y axis in green color and Z axis in red color.

First, let’s load the camera matrix and distortion coefficients from the previous calibration result:

import numpy as np
import cv2 as cv
import glob

# Load previously saved data
with np.load('B.npz') as X:
    mtx, dist, _, _ = [X[i] for i in ('mtx', 'dist', 'rvecs', 'tvecs')]

Now let’s create a function, draw which takes the corners in the chessboard and axis points to draw a 3D axis:

def draw(img, corners, imgpts):
    corner = tuple(corners[0].ravel().astype("int32"))
    imgpts = imgpts.astype("int32")
    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

Then we create termination criteria, object points and axis points. Axis points are points in 3D space for drawing the axis. We draw axis of length 3. X axis is drawn from (0,0,0) to (3,0,0), Z axis from (0,0,0) to (0,0,-3):

criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)
objp = np.zeros((6 * 7, 3), np.float32)
objp[:, :2] = np.mgrid[0:7, 0:6].T.reshape(-1, 2)

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

for fname in glob.glob('left*.jpg'):
    img = cv.imread(fname)
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    ret, corners = cv.findChessboardCorners(gray, (7, 6), None)

    if ret == True:
        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 = cv.projectPoints(axis, rvecs, tvecs, mtx, dist)

        img = draw(img, corners2, imgpts)
        cv.imshow('img', img)
        k = cv.waitKey(0) & 0xFF
        if k == ord('s'):
            cv.imwrite(fname[:6] + '.png', img)

cv.destroyAllWindows()

See some results below. Notice that each axis is 3 squares long:

3D axis pose estimation

Render a Cube

If you want to draw a cube, modify the draw() function and axis points as follows:

def draw(img, corners, imgpts):
    imgpts = np.int32(imgpts).reshape(-1, 2)

    # draw ground floor in green
    img = cv.drawContours(img, [imgpts[:4]], -1, (0, 255, 0), -3)

    # draw pillars in blue color
    for i, j in zip(range(4), range(4, 8)):
        img = cv.line(img, tuple(imgpts[i]), tuple(imgpts[j]), (255), 3)

    # draw top layer in red color
    img = cv.drawContours(img, [imgpts[4:]], -1, (0, 0, 255), 3)

    return img

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

And look at the result below:

3D cube pose estimation


Source: OpenCV Python Tutorials — Original Documentation

Back to Blog

Related Posts

View All Posts »
How OpenCV-Python Bindings Work

How OpenCV-Python Bindings Work

OpenCV · 3 dk

Learn how OpenCV-Python bindings are generated from C++ headers. We cover CV_EXPORTS_W, CV_WRAP, and other macros, plus the gen2.py generator and hdr_parser.py header parser scripts.

Face Detection using Haar Cascades

Face Detection using Haar Cascades

OpenCV · 3 dk

Learn to use Haar Cascade classifiers in OpenCV for face and eye detection. This tutorial covers the theory behind Haar features, integral images, AdaBoost, and cascade classifiers.

High Dynamic Range (HDR) Imaging

High Dynamic Range (HDR) Imaging

OpenCV · 3 dk

Learn how to generate and display HDR images from an exposure sequence in OpenCV. We cover Debevec, Robertson, and Mertens exposure fusion algorithms with camera response function estimation.

Image Inpainting

Image Inpainting

OpenCV · 2 dk

Learn how to remove small noises, strokes, and damage from old photographs using OpenCV's cv.inpaint(). We cover the Telea and Navier-Stokes inpainting algorithms.