First we'll import the stuff we need and declare some variables:
import numpy as np
import cv2, os, glob
objectPoints = []
imagePoints = []
cameraIntrinsicValues = []
# Distortion coefficients
cameraExtrinsicValues = []
Now we'll implement the function that finds and returns the object and image points, given images of a chessboard:
def getObjectAndImagePoints():
global objectPoints, imagePoints
# Number of inside corners per row and column
cornersPerRow = 10
cornersPerColumn = 7
# Initializing the object points to zero
chessboardObjectPoints = np.zeros((cornersPerColumn * cornersPerRow, 3), np.float32)
# Prepare a meshgrid for object points
# (0,0,0), (1,0,0), (2,0,0) ..., (cornersPerRow,cornersPerColumn,0)
# We can do this since we know how many corners there are on our printed chessboard
chessboardObjectPoints[:,:2] = np.mgrid[0:cornersPerRow, 0:cornersPerColumn].T.reshape(-1, 2)
# List of calibration images
images = []
# To make sure you can run the script on any image filetype
extensions = ['*.gif', '*.png', '*.jpeg', '*.jpg', '*.tiff']
for extension in extensions:
images.extend(glob.glob('calibration_images/'+extension))
# Step through the list and search for chessboard corners
for calibrationImageFileName in images:
calibrationImage = cv2.imread(calibrationImageFileName)
# The detector doesn't work well with images larger than 1280x720
# So we'll resize any until they're 720p or smaller
height, width = calibrationImage.shape[:2]
while width > 1280:
width //= 2
height //= 2
calibrationImage = cv2.resize(calibrationImage, (width, height))
# Convert it to grayscale
grayCalibrationImage = cv2.cvtColor(calibrationImage, cv2.COLOR_BGR2GRAY)
# Find the image points
cornersFound, foundCorners = cv2.findChessboardCorners(grayCalibrationImage, (cornersPerRow, cornersPerColumn),None)
# If corners were found on the images
# Append the found image points and defined object points to global variables
if cornersFound:
objectPoints.append(chessboardObjectPoints)
imagePoints.append(foundCorners)
# If you want to visualize the found corners
cv2.drawChessboardCorners(calibrationImage, (cornersPerRow, cornersPerColumn), foundCorners, cornersFound)
cv2.imshow('Preview', calibrationImage)
cv2.waitKey(500)
Now we can call the calibrateCamera function to get our extrinsic and intrinsic values:
def calibrateCamera(imageSize):
global cameraIntrinsicValues, cameraExtrinsicValues, objectPoints, imagePoints
retVal, cameraIntrinsicValues, cameraExtrinsicValues, rotationVectors, translationVectors = cv2.calibrateCamera(objectPoints, imagePoints, imageSize, None, None)
And finally, with all of the values, we can undistort our image:
def undistortImage(image):
return cv2.undistort(image, cameraIntrinsicValues, cameraExtrinsicValues, None, cameraIntrinsicValues)