Single Camera Calibration - Carleton-SRCL/SPOT GitHub Wiki

CalibrationProcedure.py

Click here for raw code
"""
Used to calibrate the camera and eliminate lens distortion etc etc...

Pattern used is an 8x13 (8 rows x 13 col) chess board

Sudo:
Use Calibration Image Splitter to split original images

Run a test on the 'right' and 'left' eye on the camera for each package of split images

Generate the 3x3 calibration matrix for each

Compare to see if the same.

Written by Hayden Arms Sep 2023

"""
import numpy as np
import cv2
import os
import argparse
import glob

def main():
    print("Camera calibration beginning")
    dirpathLeft = r'/Users/PathforLeftEye' # "Path to folder containing checkerboard images for calibration"
    dirpathRight = r'/Users/PathforRightEye'
    dirPaths = [dirpathLeft,dirpathRight]
    # 16.1 mm == 0.0121 m
    square_size = 1.61/1000 # m # physical size of squares (manually measured)
    visualize = False
    width = 14
    height = 9

    CamMatrices = []
    DistMatrices = []
    for rpath in dirPaths:
        ret, mtx, dist, rvecs, tvecs = calibrate(rpath, square_size, width, height, visualize)
        print("Completed Calibration")
        print("Path " + rpath + ".....\n")
        CamMatrices.append(mtx)
        DistMatrices.append(dist)

    print("Matrices: ")
    print(np.around(CamMatrices,3))
    print("Measured Distances: ")
    print(np.around(DistMatrices,3))

    # np.save("calibration_matrix", mtx)
    # np.save("distortion_coefficients", dist)

def calibrate(dirpath, square_size, width, height, visualize=False):
    """ Apply camera calibration operation for images in the given directory path. """

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

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

    objp = objp * square_size

    # 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 = os.listdir(dirpath)
    ii = 1
    iiT = len(glob.glob(os.path.join(dirpath,"*.jpg")))
    for image_name in glob.glob(os.path.join(dirpath,"*.jpg")):
        print("Reading Image {}".format(ii))
        img = cv2.imread(image_name)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        # Find the chess board corners
        ret, corners = cv2.findChessboardCorners(gray, (width, 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, (width, height), corners2, ret)
            print("\tCorners Detected...")

        if visualize:
            cv2.imshow('img',img)
            cv2.waitKey(0)

        print("Completed {} %, of path".format(100*np.round(ii/iiT,2)))
        ii = ii + 1


    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
    # returns camera matrix, distortion coefficients, rotation and translation vectors etc
    return [ret, mtx, dist, rvecs, tvecs]


if __name__ == "__main__":
   main()

Purpose

  • This function is used to calibrate and eliminate distortion of a single lens camera, required for ArUco marker detection and pose determination.

Input Variables

  • size_of_chessboard_squares_mm
    • To calibrate a camera, a chessboard/checkerboard printout with known dimensions is required to measure lens distortion.
    • This variable represents the width in mm of a single square on the checker board.

Figure 1: Chessboard image used in calibration.

  • chessboardsize
    • The size of the chessboard is also required to determine number of squares on the printout. For example, a board with 13 columns and 8 rows of full squares would be input as (14,9) due to it having 13+1 columns and 8+1 rows.

Output Variables

  • calibration_matrix
    • This output provides a camera calibration matrix that is used in Live_Pose_Det.py for calibration.
  • distortion_coefficients
    • This output provides a camera distortion matrix that is used in Live_Pose_Det.py to accommodate lens distortion.

Click here to go BACK

⚠️ **GitHub.com Fallback** ⚠️