9/13/2023

OpenCV Camera Calibration source code

refer to code:

.

import numpy as np
import cv2
import glob
import yaml
from icecream import ic
import os

def calibrate_camera(images, chess_box_scale_mm):
# Termination criteria for refining the detected corners
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

# Prepare object points: (0,0,0), (1,0,0), (2,0,0), ..., (9,6,0)
objp = np.zeros((9*6,3), np.float32)
objp[:,:2] = np.mgrid[0:6, 0:9].T.reshape(-1,2) * chess_box_scale_mm# Scale by 7.5mm or 17.5mm or 25mm

# Arrays to store object and image points from all the images
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane

if not images:
raise Exception("No images found in the calibration directory.")

for fname in images:
ic(fname)
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Find the chessboard corners
ret, corners = cv2.findChessboardCorners(gray, (6,9), None)
ic(ret)

# If found, add object points and image points
if ret == True:
objpoints.append(objp)
corners2 = cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
imgpoints.append(corners2)

# Draw and display the corners
cv2.drawChessboardCorners(img, (6,9), corners2, ret)
# Save the image with corners in the same directory but with a .png extension
base_name = os.path.basename(fname)
file_root, file_ext = os.path.splitext(base_name)
save_path = os.path.join(os.path.dirname(fname), f"{file_root}.png")
cv2.imwrite(save_path, img)
cv2.imshow('img', img)
cv2.waitKey(500)


cv2.destroyAllWindows()

if not objpoints or not imgpoints:
raise Exception("Chessboard corners not found in any images.")

# Calibrate the camera using the last value of gray from the loop
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
return ret, mtx, dist, rvecs, tvecs

def main():
path = "./path/to/images/"
images = glob.glob(f'{path}/*.JPG')

ret, mtx, dist, rvecs, tvecs = calibrate_camera(images, 7.5) #chess_box_scale_mm is 7.5 mm

print("Camera matrix: \n", mtx)
print("Distortion coefficients: \n", dist)

# Save to YAML file
data = {'camera_matrix': np.asarray(mtx).tolist(), 'dist_coeff': np.asarray(dist).tolist()}
with open(f"{path}/calibration.yaml", "w") as f:
yaml.dump(data, f)

# Display one of the images after undistortion
img = cv2.imread(images[0]) # Replace with an image from your calibration set
h, w = img.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))

# Undistort
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)

# Crop the image
x, y, w, h = roi
dst = dst[y:y+h, x:x+w]
cv2.imshow('origin Image', img)
cv2.imshow('Undistorted Image', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

if __name__ == "__main__":
main()

.. 


Here is chess board which has 10x7.


png files in same folder are that images succeed for finding pattern.

yaml file will be generated in image folder for camera intrinsic params.


Thank you.

www.marearts.com

πŸ™‡πŸ»‍♂️


No comments:

Post a Comment