2026/4/16 16:30:20
网站建设
项目流程
个人怎么制作网站,怎么提高网站关键词排名,美工网站设计,室内设计师必备的设计软件本文记录使用张氏标定法进行使用的全过程#xff0c;并记录最终的误差成果,为什么需要标定是因为相机本身拍照之后#xff0c;就存在一个畸变#xff0c;所以仅靠一个比例尺来进行推算实际距离 和 像素距离之间的比例#xff0c;是存在很大的偏差的#xff0c;理解一下并记录最终的误差成果,为什么需要标定是因为相机本身拍照之后就存在一个畸变所以仅靠一个比例尺来进行推算实际距离 和 像素距离之间的比例是存在很大的偏差的理解一下拍完照就存在了后面你怎么计算都会存在问题。以及标定结束之后相机是固定的一旦相机移动或者焦距发生改变就需要重新进行标定而且标定之后同样只是在一个平面内进行比例尺的测算才会准确一旦物体变为三维到相机镜头的工作距离发生改变那么计算之后的误差同样会变大。1.首先需要找到对应的实验器材硬件相机机架相机直尺以及标定板可以自己制作软件能够实现相机拍照自己使用SDK进行二次开发能够使用开源的opnecv 库进行计算对应的校正值在新的程序中c中进行使用。2.实验步骤2.1.制作标定板先去相机校准图案生成器 – calib.io 生成对应的标定PDF如下图上述为本人使用的样式然后打印为A4纸张。但是最终实际测量一个小方格的边长为13mm。需要根据实际测算的边长进行更改。然后方格数量为8 * 11 由此可知角点数量为7 * 10,角点就是实际上的两个方块相交的点。然后将标定板固定到一个完全平滑的板子上。2.1.拍照在相机固定固定之后接下来需要拍摄几张十分干净标准的照片进行标定。特点如下标定板清晰无模糊角度覆盖充分但不过度相机固定不动最好是10张以上。2.1.然后就是使用vs code使用python语言来进行标定脚本的书写运行程序得出对应的标定结果。脚本如下此处不在赘述怎么去配置环境等等import numpy as np import cv2 import glob # 1. 准备标定板参数 chessboard_size (7, 10) # 内角点数量 square_size 13.0 # 毫米 # 2. 生成世界坐标系中的3D点 objp np.zeros((chessboard_size[0]*chessboard_size[1], 3), np.float32) objp[:, :2] np.mgrid[0:chessboard_size[0], 0:chessboard_size[1]].T.reshape(-1, 2) * square_size # 3. 存储对象点和图像点 objpoints [] # 3D点 imgpoints [] # 2D点 # 4. 读取所有标定图像 images glob.glob(D:/DeepLearning/datasets/clibration/rect/*.png) image_size None for fname in images: img cv2.imread(fname) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) if image_size is None: image_size gray.shape[::-1] # 查找棋盘格角点 ret, corners cv2.findChessboardCorners(gray, chessboard_size, None) if ret: objpoints.append(objp) # 亚像素精确化 corners2 cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), (cv2.TERM_CRITERIA_EPS cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)) imgpoints.append(corners2) # 可视化角点 cv2.drawChessboardCorners(img, chessboard_size, corners2, ret) cv2.imshow(Corners, img) cv2.imwrite(this.png,img) cv2.waitKey(500) cv2.destroyAllWindows() # 5. 相机标定 ret, mtx, dist, rvecs, tvecs cv2.calibrateCamera(objpoints, imgpoints, image_size, None, None) print(相机内参矩阵:\n, mtx) print(\n畸变系数:, dist.ravel()) # 6. 评估标定误差 mean_error 0 for i in range(len(objpoints)): imgpoints2, _ cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist) error cv2.norm(imgpoints[i], imgpoints2, cv2.NORM_L2)/len(imgpoints2) mean_error error print(\n平均重投影误差: {} 像素.format(mean_error/len(objpoints))) # 7. 保存标定结果 np.savez(calibration_result.npz, mtxmtx, distdist)注意其中参数的改写以及对应的路径的变更# 1. 准备标定板参数chessboard_size (7, 10) # 内角点数量square_size 13.0 # 毫米以及文件路径。2.2.运行得到结果如下相机内参矩阵:[[2.78225009e03 0.00000000e00 1.20301433e03][0.00000000e00 2.77841102e03 1.00512050e03][0.00000000e00 0.00000000e00 1.00000000e00]]畸变系数: [-0.2517598 0.07004305 -0.00127046 0.00606034 0.24205241]平均重投影误差: 0.07069074329111907 像素由此可知标定结果还可以主要看重投影误差为0.07当然其他参数一会同样需要使用。2.3.将参数使用到对相机拍摄的照片进行校正需要会SDK取图并且取图之后能够进行处理如下为拍摄照片之后的处理代码。cv::Mat CFormal_DecDlg::FastUndistort(const cv::Mat input) { static cv::Mat cameraMatrix (cv::Mat_double(3, 3) 2782.25009, 0.0, 1203.01433, 0.0, 2778.41102, 1005.1205, 0.0, 0.0, 1.0); static cv::Mat distCoeffs (cv::Mat_double(1, 5) -0.2517598, 2.77841102, 0.00127046, 0.00606034, -0.24205241); static cv::Mat map1, map2; static cv::Size lastSize(0, 0); // 如果尺寸变化或第一次计算映射 if (map1.empty() || input.size() ! lastSize) { cv::Mat newCameraMatrix cv::getOptimalNewCameraMatrix( cameraMatrix, distCoeffs, input.size(), 1.0, input.size() ); cv::initUndistortRectifyMap( cameraMatrix, distCoeffs, cv::Mat(), newCameraMatrix, input.size(), CV_32FC1, map1, map2 ); lastSize input.size(); } cv::Mat result; cv::remap(input, result, map1, map2, cv::INTER_LINEAR); return result; }对图像进行处理之后会得到下述样式的图像即校正之后的图像。本人随机取出中间的两个点(590,1069) 718.1074进过转换如下首先提取并整理你的相机参数相机内参矩阵 (K):textfx 2782.25009 # 图像x轴方向焦距 fy 2778.41102 # 图像y轴方向焦距 cx 1203.01433 # 图像主点坐标x cy 1005.12050 # 图像主点坐标y畸变系数 (D):[-0.2517598, 0.07004305, -0.00127046, 0.00606034, 0.24205241]工作距离 (Z): 285 mm图像点:点 A:(590, 1069)点 B:(718, 1074)计算步骤如下校正畸变由于畸变会改变像素点的理想位置计算前需先去除畸变影响。点 A 校正后:(588.31, 1068.75)点 B 校正后:(716.08, 1073.85)像素坐标转归一化相机坐标公式为X_normal (x_corrected - cx) / fxY_normal (y_corrected - cy) / fy点 A 归一化坐标:(-0.2209, 0.0229)点 B 归一化坐标:(-0.1751, 0.0247)归一化坐标转实际三维坐标已知实际工作距离Z 285 mm通过相似三角形计算X_real X_normal * ZY_real Y_normal * Z点 A 实际坐标:(-62.95 mm, 6.53 mm, 285.00 mm)点 B 实际坐标:(-49.89 mm, 7.05 mm, 285.00 mm)计算三维空间距离利用三维空间两点间距离公式计算最终距离 D √((X_B - X_A)² (Y_B - Y_A)² (Z_B - Z_A)²) 13.09 mm结果为13.09即实际距离为13.09是校正之后进行计算的结果。跟13mm十分的接近说明标定方法是可以的。除开上述的反投影法计算实际距离之外还存在另外的方法计算比例尺原理在焦距f(像素) 和工作距离Z(毫米) 已知时图像传感器上一个像素对应的实际尺寸是固定的。计算比例尺S(毫米/像素) Z / f。在X方向S_x Z / fx 285 / 2782.25009 ≈ 0.10245 mm/像素在Y方向S_y Z / fy 285 / 2778.41102 ≈ 0.10256 mm/像素距离两点像素坐标差Δx 718 - 590 128 像素Δy 1074 - 1069 5 像素。实际距离D √((Δx * S_x)² (Δy * S_y)²) √((128*0.10245)² (5*0.10256)²) ≈ √(172.14 0.263) ≈ √172.40 ≈ 13.13 mm。同样误差很小一般可以投入实际使用。