我正在校准一些相机,并且焦距有轻微(5%左右)的误差,以及还可以但不是很大的重投影误差(〜0.7px)。对于我的应用程序,我需要精度尽可能接近完美,所以这个误差太大了。
我从校准中得到的焦距是
2530 px
。我正在使用这款相机。根据 (4056, 3040)
的分辨率、1.55 um
的像素大小和 75 degrees
的 H-FoV,我可以计算出我的预期焦距为 4.096558636989045 mm
或 2642.9410561219647 px
。
为了验证这个预期焦距是否正确,我设置了一个实验来测量焦距。相机聚焦后,我在垂直于相机的方向放置了一块查尔科板,并测量了深度。然后,我测量了图像中电路板的一部分,根据我的电路板尺寸,我当然知道它有多大(以毫米为单位)。使用针孔相机模型,我最终陷入了原始
2643 px
数字的实验误差范围内。所以,我确信这是正确的答案。
以下是我尝试改善焦距结果的方法。
这是我的一些问题。
这是一个使用 OpenCV 的最小示例。
from pathlib import Path
import cv2
import numpy as np
# Load images.
calib_images_path = Path("calibration_images")
image_files = list(calib_images_path.glob("*.png"))
images = [cv2.imread(str(image_file)) for image_file in image_files]
# Define the ChArUco board parameters.
charuco_size = (17, 24)
square_length = 30 # mm
marker_length = 22 # mm
aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_5X5_1000)
charuco_board = cv2.aruco.CharucoBoard(
size=charuco_size,
squareLength=square_length,
markerLength=marker_length,
dictionary=aruco_dict,
)
# Detect ChArUco corners.
all_charuco_corners = []
all_charuco_ids = []
for image_file in image_files:
# Grayscale image.
image = cv2.imread(str(image_file))
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Marker detection.
corners, ids, rejected = cv2.aruco.detectMarkers(gray, aruco_dict)
# Interpolation and refinement.
if ids is not None and len(ids) > 0:
cv2.aruco.refineDetectedMarkers(gray, charuco_board, corners, ids, rejected)
retval, charuco_corners, charuco_ids = cv2.aruco.interpolateCornersCharuco(
markerCorners=corners, markerIds=ids, image=gray, board=charuco_board
)
if retval > 0:
all_charuco_corners.append(charuco_corners)
all_charuco_ids.append(charuco_ids)
# Initial camera matrix and distortion coefficients.
expected_focal_length_px = 2642.9410561219647
image_size = gray.shape[::-1]
initial_camera_matrix = np.array(
[
[expected_focal_length_px, 0, image_size[0] / 2],
[0, expected_focal_length_px, image_size[1] / 2],
[0, 0, 1],
]
)
initial_dist_coeffs = np.zeros((5, 1))
# Camera calibration.
image_size = gray.shape[::-1]
ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.aruco.calibrateCameraCharuco(
charucoCorners=all_charuco_corners,
charucoIds=all_charuco_ids,
board=charuco_board,
imageSize=image_size,
cameraMatrix=initial_camera_matrix,
distCoeffs=initial_dist_coeffs,
)
这里有几个因素在起作用。
Calib.io 有校准器程序,它可以让您调查此类参数相关性是否存在,并让您获得最适合的线性相机模型,估计与您通过实验获得的“有效焦距”相当的“有效焦距”。 此外,校准器还可以让您分析剩余的 rpe 是由于未建模的镜头行为(不良)还是仅由于无偏图像噪声(无害)造成的。