Python implements camera calibration and evaluation of calibration results

Python implements camera calibration and evaluation of calibration results

  • Python implements camera calibration (internal parameters and distortion coefficients)
  • average reprojection error
  • Estimation Error of Distortion Parameters

1.Python realizes camera calibration

import numpy as np
import cv2
import os
from PIL import Image

# 遍历照片
def read_images_from_folder(folder_path):
    images = []
    for filename in os.listdir(folder_path):
        if filename.endswith(".jpg") or filename.endswith(".png"):
            image_path = os.path.join(folder_path, filename)
            try:
                image = Image.open(image_path)
                images.append(image_path)
            except IOError:
                print("Cannot open image: ", filename)
    return images

# 标定板格点数量和大小
pattern_size = (9, 6)  # 内部角点数量
square_size = 25  # 棋盘格方块大小(毫米)

# 存储棋盘格角点的3D坐标
obj_points = []
# 存储棋盘格对应的图像点坐标
img_points = []

# 准备棋盘格的3D坐标
objp = np.zeros((pattern_size[0] * pattern_size[1], 3), dtype=np.float32)
objp[:, :2] = np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2) * square_size

# 指定文件夹路径
folder_path = "G:/实习/image/2"
# 调用函数读取图片
images = read_images_from_folder(folder_path)

# 遍历所有标定图像
for image_path in images:
    # 读取图像并将其转换为灰度图
    image = cv2.imread(image_path)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 查找棋盘格角点
    ret, corners = cv2.findChessboardCorners(gray, pattern_size, None)

    # 如果找到棋盘格角点则存储对应的3D和2D坐标
    if ret:
        obj_points.append(objp)
        img_points.append(corners)

        # 在图像上绘制棋盘格角点
        cv2.drawChessboardCorners(image, pattern_size, corners, ret)
        cv2.imshow('Chessboard Corners', image)
        cv2.waitKey(500)

# 进行相机内参标定
ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, gray.shape[::-1], None, None)

# 打印相机内参和畸变系数
print("Camera Matrix:\n", camera_matrix)
print("\nDistortion Coefficients:\n", dist_coeffs)
np.savetxt('camera_matrix.txt', camera_matrix)
np.savetxt('dist_coeffs.txt', dist_coeffs)

Camera internal parameters and distortion coefficients (k1, k2, k3, p1, p2)
insert image description here

2. Average reprojection error

**Reprojection Error (Reprojection Error)** refers to the difference between the 2D point obtained by reprojecting the camera parameters obtained through calibration and the 3D space point onto the image plane and the actually observed 2D point. On a per spatial point basis, the reprojection error is calculated as follows:

  1. Project the 3D space point to the image plane through the internal and external parameters of the camera to obtain the reprojected 2D point.
  2. Computes the Euclidean distance or other distance metric between the reprojected 2D point and the actual observed 2D point.
  3. The overall reprojection error can be obtained by summing the reprojection errors of all spatial points and taking the average value.
import cv2
import numpy as np
from PIL import Image
import os

def read_images_from_folder(folder_path):
    images = []
    for filename in os.listdir(folder_path):
        if filename.endswith(".jpg") or filename.endswith(".png"):
            image_path = os.path.join(folder_path, filename)
            try:
                image = Image.open(image_path)
                images.append(image_path)
            except IOError:
                print("Cannot open image: ", filename)
    return images
# 加载标定结果
camera_matrix = np.loadtxt('camera_matrix.txt')
dist_coeffs = np.loadtxt('dist_coeffs.txt')

# 指定文件夹路径
folder_path = "G:/实习/image/2"
# 调用函数读取图片
images = read_images_from_folder(folder_path)

# 计算评估指标
reprojection_errors = []
for image_file in images:
    # 加载图像
    image = cv2.imread(image_file)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 检测角点
    ret, corners = cv2.findChessboardCorners(gray, (9, 6), None)

    # 如果检测到角点,则进行评估
    if ret:
        # 畸变校正
        undistorted_corners = cv2.undistortPoints(corners, camera_matrix, dist_coeffs)

        # 计算重投影误差
        mean_error = np.sqrt(np.mean(np.square(undistorted_corners - corners)))
        reprojection_errors.append(mean_error)

# 计算平均重投影误差
mean_reprojection_error = np.mean(reprojection_errors)
# 打印结果
print("mean_reprojection_error:\n", mean_reprojection_error)
np.savetxt('mean_reprojection_error.txt', mean_reprojection_error.flatten()

mean_reprojection_error:
 1580.7643

3. Estimation error of distortion parameters

import cv2
import numpy as np
from PIL import Image
import os

def read_images_from_folder(folder_path):
    images = []
    for filename in os.listdir(folder_path):
        if filename.endswith(".jpg") or filename.endswith(".png"):
            image_path = os.path.join(folder_path, filename)
            try:
                image = Image.open(image_path)
                images.append(image_path)
            except IOError:
                print("Cannot open image: ", filename)
    return images

# 设置棋盘格角点的行数和列数
rows = 9
cols = 6

# 生成棋盘格角点的世界坐标
world_points = np.zeros((rows * cols, 3), np.float32)
world_points[:, :2] = np.mgrid[0:cols, 0:rows].T.reshape(-1, 2)

# 存储棋盘格角点的世界坐标和图像坐标
world_points_list = []  # 世界坐标系中的点
image_points_list = []  # 图像坐标系中的点

folder_path = "G:/实习/image/2"
# 加载图片进行角点检测
images = read_images_from_folder(folder_path)

for image_path in images:
    image = cv2.imread(image_path)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 查找棋盘格角点
    ret, corners = cv2.findChessboardCorners(gray, (cols, rows), None)

    # 如果找到棋盘格角点,则进行相机标定
    if ret:
        world_points_list.append(world_points)
        image_points_list.append(corners)

# 进行相机标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(world_points_list, image_points_list, gray.shape[::-1], None, None)

# 通过反投影误差估计畸变参数的估计误差
mean_error = 0
for i in range(len(world_points_list)):
    image_points, _ = cv2.projectPoints(world_points_list[i], rvecs[i], tvecs[i], mtx, dist)
    error = cv2.norm(image_points_list[i], image_points, cv2.NORM_L2) / len(image_points)
    mean_error += error

reprojection_error=mean_error / len(world_points_list)
print("畸变参数的估计误差: ", reprojection_error)
np.savetxt('reprojection_error.txt', reprojection_error.astype(float).flatten())
畸变参数的估计误差:  0.19547892484795085

In summary, the estimation error of the distortion parameters and the average reprojection error are two important indicators used to evaluate the camera calibration results. The estimation error indicates the accuracy of the distortion parameter estimation, and the average reprojection error indicates the accuracy and stability of the calibration results. sex. For high-quality camera calibration, the estimation error of the distortion parameters should be as small as possible, and the average reprojection error should be as small as possible.
Pictures taken by myself for calibration

Guess you like

Origin blog.csdn.net/m0_46406029/article/details/131573717