更新 Docx/双目标定.md

main
靳和颜 2024-10-23 20:40:38 +08:00
parent f11b74b431
commit 77e5631530
1 changed files with 114 additions and 113 deletions

View File

@ -1,114 +1,115 @@
## 双目标定过程 ## ## 双目标定过程 ##
1. **获取棋盘格图片** 1. **获取棋盘格图片**
要进行标定首先需要双目拍摄的各种角度的棋盘格图片左右图像各不少于20张棋盘格文件在同级目录下。 要进行标定首先需要双目拍摄的各种角度的棋盘格图片左右图像各不少于20张棋盘格文件在同级目录下。
由于该双目摄像头只有一个设备号拍出照片为左右图像堆叠的形式故在拍摄完照片之后还需要将左右图像分割出来分别保存到左右图片文件夹中。分割代码如下代码为Code/stereo.py 由于该双目摄像头只有一个设备号拍出照片为左右图像堆叠的形式故在拍摄完照片之后还需要将左右图像分割出来分别保存到左右图片文件夹中。分割代码如下代码为Code/stereo.py
```python ```python
import cv2 import cv2
import os import os
# 定义输入文件夹路径和输出文件夹路径 # 定义输入文件夹路径和输出文件夹路径
input_folder = 'images' # 替换为你的输入文件夹路径 input_folder = 'images' # 替换为你的输入文件夹路径
output_folder_left = 'left' output_folder_left = 'left'
output_folder_right = 'right' output_folder_right = 'right'
# 创建输出文件夹,如果不存在则创建 # 创建输出文件夹,如果不存在则创建
if not os.path.exists(output_folder_left): if not os.path.exists(output_folder_left):
os.makedirs(output_folder_left) os.makedirs(output_folder_left)
if not os.path.exists(output_folder_right): if not os.path.exists(output_folder_right):
os.makedirs(output_folder_right) os.makedirs(output_folder_right)
# 遍历输入文件夹中的所有图片 # 遍历输入文件夹中的所有图片
for filename in os.listdir(input_folder): for filename in os.listdir(input_folder):
if filename.endswith(".png") or filename.endswith(".jpg"): if filename.endswith(".png") or filename.endswith(".jpg"):
# 构建图片的完整路径 # 构建图片的完整路径
img_path = os.path.join(input_folder, filename) img_path = os.path.join(input_folder, filename)
# 读取图片 # 读取图片
image = cv2.imread(img_path) image = cv2.imread(img_path)
if image is None: if image is None:
print(f"无法读取图像文件: {filename}") print(f"无法读取图像文件: {filename}")
continue continue
# 获取图片的高度和宽度 # 获取图片的高度和宽度
height, width, _ = image.shape height, width, _ = image.shape
# 计算左右图像的宽度 # 计算左右图像的宽度
half_width = width // 2 half_width = width // 2
# 切割出左半部分和右半部分图像 # 切割出左半部分和右半部分图像
left_image = image[:, :half_width] left_image = image[:, :half_width]
right_image = image[:, half_width:] right_image = image[:, half_width:]
# 构建保存路径 # 构建保存路径
left_image_path = os.path.join(output_folder_left, f"left_{filename}") left_image_path = os.path.join(output_folder_left, f"left_{filename}")
right_image_path = os.path.join(output_folder_right, f"right_{filename}") right_image_path = os.path.join(output_folder_right, f"right_{filename}")
# 保存左右图像 # 保存左右图像
cv2.imwrite(left_image_path, left_image) cv2.imwrite(left_image_path, left_image)
cv2.imwrite(right_image_path, right_image) cv2.imwrite(right_image_path, right_image)
print(f"已保存:{left_image_path} 和 {right_image_path}") print(f"已保存:{left_image_path} 和 {right_image_path}")
print("所有图像已处理完成!") print("所有图像已处理完成!")
``` ```
左摄像头图片如下:![image-20241023201900183](C:\Users\dd\AppData\Roaming\Typora\typora-user-images\image-20241023201900183.png) 右摄像头图片如下:![image-20241023203350774](C:\Users\dd\AppData\Roaming\Typora\typora-user-images\image-20241023203350774.png) 左摄像头图片如下:![image-20241023201900183](C:\Users\dd\AppData\Roaming\Typora\typora-user-images\image-20241023201900183.png) 右摄像头图片如下:![image-20241023203350774](C:\Users\dd\AppData\Roaming\Typora\typora-user-images\image-20241023203350774.png)
2. **标定** 2. **标定**
首先调用OpenCV库函数对左右相机分别进行单目标定得到每个相机的内参矩阵 首先调用OpenCV库函数对左右相机分别进行单目标定得到每个相机的内参矩阵
```python ```python
print('开始左相机标定') print('开始左相机标定')
ret_l = calibrate_camera(object_points, corners_left, imgsize) #object_points表示标定板上检测到的棋盘格角点的三维坐标corners_left[i]表示棋盘格角点在图像中的二维坐标imgsize表示图像大小 ret_l = calibrate_camera(object_points, corners_left, imgsize) #object_points表示标定板上检测到的棋盘格角点的三维坐标corners_left[i]表示棋盘格角点在图像中的二维坐标imgsize表示图像大小
retval_l, cameraMatrix_l, distCoeffs_l, rvecs_l, tvecs_l = ret_l[:5] #返回值里就包含了标定的参数 retval_l, cameraMatrix_l, distCoeffs_l, rvecs_l, tvecs_l = ret_l[:5] #返回值里就包含了标定的参数
print('开始右相机标定') print('开始右相机标定')
ret_r = calibrate_camera(object_points, corners_right, imgsize) ret_r = calibrate_camera(object_points, corners_right, imgsize)
retval_r, cameraMatrix_r, distCoeffs_r, rvecs_r, tvecs_r = ret_r[:5] retval_r, cameraMatrix_r, distCoeffs_r, rvecs_r, tvecs_r = ret_r[:5]
``` ```
然后进行立体标定(双目标定),得到左右相机的外参:旋转矩阵、平移矩阵、本质矩阵、基本矩阵: 然后进行立体标定(双目标定),得到左右相机的外参:旋转矩阵、平移矩阵、本质矩阵、基本矩阵:
```python ```python
criteria_stereo = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 1e-5) criteria_stereo = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 1e-5)
ret_stereo = cv2.stereoCalibrate(object_points, corners_left, corners_right, ret_stereo = cv2.stereoCalibrate(object_points, corners_left, corners_right,
cameraMatrix_l, distCoeffs_l, cameraMatrix_l, distCoeffs_l,
cameraMatrix_r, distCoeffs_r, cameraMatrix_r, distCoeffs_r,
imgsize, criteria=criteria_stereo, imgsize, criteria=criteria_stereo,
flags=cv2.CALIB_FIX_INTRINSIC) flags=cv2.CALIB_FIX_INTRINSIC)
ret, _, _, _, _, R, T, E, F = ret_stereo ret, _, _, _, _, R, T, E, F = ret_stereo
``` ```
完整代码位于Code/biaoding.py 完整代码位于Code/biaoding.py
3. **矫正** 3. **矫正**
利用标定得到相机内外参对图像进行矫正(去畸变等): 利用标定得到相机内外参对图像进行矫正(去畸变等):
```python ```python
R1, R2, P1, P2, Q, roi1, roi2 = cv2.stereoRectify(cameraMatrix_l, distCoeffs_l, R1, R2, P1, P2, Q, roi1, roi2 = cv2.stereoRectify(cameraMatrix_l, distCoeffs_l,
cameraMatrix_r, distCoeffs_r, cameraMatrix_r, distCoeffs_r,
img_size, R, T) img_size, R, T)
# 计算映射参数 # 计算映射参数
map1_l, map2_l = cv2.initUndistortRectifyMap(cameraMatrix_l, distCoeffs_l, R1, P1, img_size, cv2.CV_32FC1) map1_l, map2_l = cv2.initUndistortRectifyMap(cameraMatrix_l, distCoeffs_l, R1, P1, img_size, cv2.CV_32FC1)
map1_r, map2_r = cv2.initUndistortRectifyMap(cameraMatrix_r, distCoeffs_r, R2, P2, img_size, cv2.CV_32FC1) map1_r, map2_r = cv2.initUndistortRectifyMap(cameraMatrix_r, distCoeffs_r, R2, P2, img_size, cv2.CV_32FC1)
# 应用映射并显示结果 # 应用映射并显示结果
rectified_img_l = cv2.remap(img_left, map1_l, map2_l, cv2.INTER_LINEAR) rectified_img_l = cv2.remap(img_left, map1_l, map2_l, cv2.INTER_LINEAR)
rectified_img_r = cv2.remap(img_right, map1_r, map2_r, cv2.INTER_LINEAR) rectified_img_r = cv2.remap(img_right, map1_r, map2_r, cv2.INTER_LINEAR)
# 合并图像显示 # 合并图像显示
combined_img = np.hstack((rectified_img_l, rectified_img_r)) combined_img = np.hstack((rectified_img_l, rectified_img_r))
cv2.imshow('Rectified Images', combined_img) cv2.imshow('Rectified Images', combined_img)
cv2.waitKey(0) cv2.waitKey(0)
cv2.destroyAllWindows() cv2.destroyAllWindows()
``` ```
得到的标定结果如下所示:
完整代码位于Code/rectify.py 完整代码位于Code/rectify.py