1. 为什么我们需要相机标定与畸变矫正当你用手机拍下一张照片时有没有发现边缘的建筑物看起来有点弯曲这就是镜头畸变在作怪。在计算机视觉和机器人领域这种畸变会严重影响算法的准确性。比如自动驾驶汽车依靠摄像头判断距离如果图像本身就有畸变那测距结果就会出错。Matlab的Camera Calibrator工具箱就是为解决这个问题而生的。它通过分析棋盘格图案的照片计算出相机的内参矩阵和畸变系数。内参矩阵包含了焦距、主点位置等信息而畸变系数则描述了镜头产生的径向和切向畸变程度。我曾在无人机视觉定位项目中遇到过这个问题。原始图像中建筑物的直线都变成了曲线导致特征点匹配错误。使用Camera Calibrator标定后矫正效果立竿见影定位精度提升了30%以上。2. 准备标定用的棋盘格图像2.1 棋盘格的选择与打印标定的第一步是准备高质量的棋盘格图案。根据我的经验A3尺寸的棋盘格最适合室内标定。棋盘格方块数量建议在8×6到10×7之间太小会影响角点检测精度太大则不便使用。打印时要注意使用哑光纸张避免反光确保每个方块都是完美的正方形打印后可以用直尺检查边长是否一致2.2 拍摄标定图像拍摄时要注意以下几点从不同角度拍摄15-20张照片包含棋盘格在不同位置的图像中心、边缘、倾斜确保棋盘格完整出现在画面中避免强光直射造成过曝我通常会这样操作固定相机位置移动棋盘格拍摄时保持相机对焦锁定使用三脚架保持稳定3. 使用Camera Calibrator工具箱进行标定3.1 导入图像与参数设置打开Matlab在App选项卡中找到Camera Calibrator。点击Add Images导入拍摄的棋盘格图像。工具箱会自动检测角点如果某些图像检测失败可以手动调整。关键参数设置棋盘格方块实际大小单位毫米径向畸变系数个数通常选2是否考虑切向畸变建议勾选3.2 分析标定结果标定完成后工具箱会显示重投影误差。一般来说误差小于0.5像素就算合格。如果误差过大可以检查是否有模糊的图像移除误差特别大的图像重新拍摄补充更多样本我遇到过误差偏大的情况后来发现是棋盘格纸张有轻微弯曲。换成硬质板材后问题就解决了。4. 批量处理畸变图像的完整方案4.1 自动化脚本编写标定完成后我们需要编写批量处理脚本。下面是我优化过的代码框架function batchUndistortImages(inputFolder, outputFolder, cameraParams) % 支持多种图像格式 extensions {*.jpg,*.png,*.bmp}; fileList []; for i 1:length(extensions) fileList [fileList; dir(fullfile(inputFolder,extensions{i}))]; end % 创建输出目录 if ~exist(outputFolder, dir) mkdir(outputFolder); end % 并行处理加速 parfor i 1:length(fileList) try img imread(fullfile(inputFolder, fileList(i).name)); undistortedImg undistortImage(img, cameraParams); [~,name,ext] fileparts(fileList(i).name); imwrite(undistortedImg, fullfile(outputFolder, [name _corrected ext])); catch ME fprintf(处理 %s 时出错: %s\n, fileList(i).name, ME.message); end end end4.2 处理不同分辨率的技巧在实际项目中可能会遇到不同分辨率的图像。这时要注意如果图像尺寸与标定时不同需要缩放内参矩阵保持宽高比一致否则会导致参数失效对于超高分辨率图像可分块处理避免内存溢出我封装了一个自适应函数function adjustedParams adjustCameraParams(originalParams, originalSize, newSize) scaleX newSize(2)/originalSize(2); scaleY newSize(1)/originalSize(1); adjustedParams originalParams; adjustedParams.IntrinsicMatrix(1,1) originalParams.IntrinsicMatrix(1,1)*scaleX; adjustedParams.IntrinsicMatrix(2,2) originalParams.IntrinsicMatrix(2,2)*scaleY; adjustedParams.IntrinsicMatrix(3,1) originalParams.IntrinsicMatrix(3,1)*scaleX; adjustedParams.IntrinsicMatrix(3,2) originalParams.IntrinsicMatrix(3,2)*scaleY; end5. 实际应用中的问题与解决方案5.1 边缘区域矫正效果不佳这是最常见的问题表现为图像边缘仍有明显畸变。解决方法包括增加标定图像的多样性特别是包含边缘区域的样本尝试增加径向畸变系数到3个后期处理时适当裁剪边缘5.2 处理速度优化批量处理大量图像时速度很关键。我的优化经验使用parfor并行计算将图像转换为单精度减少内存占用对超大图像先降采样处理实测下来这些优化能让处理速度提升3-5倍。5.3 不同光照条件下的稳定性光照变化会影响标定精度。建议标定时尽量覆盖各种光照条件对过暗/过亮图像做预处理考虑使用自适应阈值算法在室外机器人项目中我建立了不同时间段的标定参数库根据环境光线自动选择最适合的参数集。6. 进阶技巧与扩展应用6.1 多相机系统标定对于多相机系统如立体视觉需要分别标定每个相机后再进行联合标定。Matlab的stereoCameraCalibrator可以很好地完成这个任务。关键步骤单独标定每个相机拍摄同时包含两个相机视野的棋盘格图像计算相机间的旋转和平移矩阵6.2 与深度学习结合可以将矫正过程集成到深度学习pipeline中训练前统一矫正所有图像在数据增强步骤模拟不同畸变将矫正层嵌入网络结构我在一个目标检测项目中采用第三种方案使模型对原始畸变图像也有了很好的鲁棒性。6.3 实时视频流处理对于视频流可以使用如下处理流程videoReader VideoReader(input.mp4); videoWriter VideoWriter(output.mp4); open(videoWriter); while hasFrame(videoReader) frame readFrame(videoReader); correctedFrame undistortImage(frame, cameraParams); writeVideo(videoWriter, correctedFrame); end close(videoWriter);7. 项目实战经验分享在工业检测项目中我们需要处理2000多张不同型号产品的图像。这些图像来自多个不同相机分辨率从2K到8K不等。通过以下步骤建立了稳定的处理流程为每个相机建立独立的标定参数开发自动识别图像来源的预处理模块实现分块处理超大分辨率图像建立质量检查机制验证矫正效果这个系统已经稳定运行2年多每天处理超过1万张图像。最大的收获是良好的标定是计算机视觉项目的基石值得投入足够的时间和精力。