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