机器视觉入门基础相关概念二 ——从坐标变换到相机内参
1. 从2D坐标变换说起平移、旋转与缩放当你第一次接触机器视觉时可能会被各种坐标系和变换搞得晕头转向。别担心我们从一个更熟悉的场景开始——2D平面上的图形变换。想象你正在用手机修图软件调整一张照片拖动图片是平移旋转手势是改变角度双指缩放是调整大小。这些操作背后正是我们要讨论的数学本质。平移变换最容易理解。比如把一张A4纸从桌子左边移到右边假设移动了10厘米用数学表示就是xx10。但为了统一处理各种变换我们引入齐次坐标——给二维点(x,y)加个小尾巴变成(x,y,1)。这样平移就能写成矩阵乘法import numpy as np # 定义平移矩阵 def translation_matrix(tx, ty): return np.array([ [1, 0, tx], [0, 1, ty], [0, 0, 1] ]) # 平移点(2,3)向右5单位向上2单位 point np.array([2, 3, 1]) translated translation_matrix(5, 2) point # 结果[7, 5, 1]旋转变换稍微复杂些。还记得三角函数吗当点(x,y)绕原点旋转θ角度时新坐标xxcosθ-ysinθyxsinθycosθ。用矩阵表示就是def rotation_matrix(theta): rad np.radians(theta) return np.array([ [np.cos(rad), -np.sin(rad), 0], [np.sin(rad), np.cos(rad), 0], [0, 0, 1] ]) # 旋转点(1,0)逆时针90度 rotated rotation_matrix(90) np.array([1, 0, 1]) # 结果接近[0, 1, 1]缩放变换则是把坐标值乘以系数。比如横向放大2倍纵向不变x2x, yy。其矩阵形式为def scale_matrix(sx, sy): return np.array([ [sx, 0, 0], [0, sy, 0], [0, 0, 1] ])实际应用中这些变换往往组合出现。比如先旋转再平移对应的矩阵就是T*R注意顺序。我在项目里就踩过这个坑——有次调试时发现图形位置总是不对后来才发现是矩阵乘法顺序弄反了。2. 升级到3D空间相机坐标系的基础现在把维度提升到3D空间这对理解相机模型至关重要。3D变换在2D基础上增加了z轴维度齐次坐标变为(x,y,z,1)。平移矩阵扩展为4x4def translation_3d(tx, ty, tz): return np.array([ [1,0,0,tx], [0,1,0,ty], [0,0,1,tz], [0,0,0,1] ])3D旋转比2D复杂因为要考虑绕不同轴的旋转。绕z轴旋转与2D情况类似只需在矩阵中增加z维度def rotate_z(theta): rad np.radians(theta) return np.array([ [np.cos(rad), -np.sin(rad), 0, 0], [np.sin(rad), np.cos(rad), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ])绕x轴和y轴的旋转矩阵稍有不同def rotate_x(theta): rad np.radians(theta) return np.array([ [1, 0, 0, 0], [0, np.cos(rad), -np.sin(rad), 0], [0, np.sin(rad), np.cos(rad), 0], [0, 0, 0, 1] ]) def rotate_y(theta): rad np.radians(theta) return np.array([ [np.cos(rad), 0, np.sin(rad), 0], [0, 1, 0, 0], [-np.sin(rad), 0, np.cos(rad), 0], [0, 0, 0, 1] ])实际相机运动中往往需要组合这三种旋转。这里有个关键点旋转顺序会影响最终结果。常见的顺序是Z-Y-X即先绕z轴转偏航yaw再绕y轴俯仰pitch最后绕x轴滚转roll。对应的矩阵乘法是R RzRyRx。3. 相机模型中的坐标系转换链理解相机成像过程本质是理解四个坐标系的转换链世界坐标系场景的绝对参考系单位通常是米相机坐标系以相机光心为原点光轴为z轴图像坐标系成像平面上的2D坐标单位毫米像素坐标系图像存储的矩阵坐标单位像素世界→相机坐标的转换称为外参变换包含旋转R和平移tdef world_to_camera(point_world, R, t): # 齐次坐标转换 point_cam R point_world[:3] t return np.append(point_cam, 1)相机→图像坐标基于小孔成像原理。假设焦距f50mm点P在相机坐标系中的坐标为(Xc,Yc,Zc)则成像点p的坐标def camera_to_image(point_cam, f): z point_cam[2] x (f * point_cam[0]) / z y (f * point_cam[1]) / z return np.array([x, y])这个步骤实现了3D到2D的投影丢失了深度信息。这也是为什么单目相机无法直接测距——就像你闭上一只眼睛很难判断远处物体的实际距离。4. 解密相机内参矩阵终于来到核心内容——相机内参矩阵K。它包含以下关键参数fx, fy焦距的像素表示cx, cy主点坐标图像中心畸变系数后续讨论# 典型内参矩阵 K np.array([ [fx, 0, cx], [0, fy, cy], [0, 0, 1] ])为什么需要fx和fy两个焦距因为像素不一定是正方形。我的一个工业相机项目就遇到这种情况x方向像素尺寸2.2μmy方向2.4μm导致fx≠fy。主点(cx,cy)理论上应该是图像中心但实际可能偏移几个像素。有次标定时发现cx比理论值大15像素检查发现是相机厂商的默认校正导致的。完整的投影过程用矩阵表示为def project_point(point_3d, K, R, t): # 世界→相机坐标 cam_coord R point_3d[:3] t # 相机→图像坐标 image_coord K cam_coord # 归一化 image_coord / image_coord[2] return image_coord[:2]内参矩阵的物理意义可以通过一个实验理解保持物体位置不变增大fx/fy成像会变大——相当于光学变焦。而改变cx/cy则像移动了整个画面。5. 镜头畸变与校正实际镜头都存在畸变主要分为两类径向畸变像差导致直线变弯桶形畸变边缘向内弯曲枕形畸变边缘向外膨胀切向畸变镜头与传感器不平行导致畸变校正模型通常用5个参数(k1,k2,k3,p1,p2)描述def distort_point(point_normalized, dist_coeffs): k1, k2, p1, p2 dist_coeffs[:4] x, y point_normalized r2 x*x y*y radial 1 k1*r2 k2*r2*r2 x_dist x*radial 2*p1*x*y p2*(r2 2*x*x) y_dist y*radial p1*(r2 2*y*y) 2*p2*x*y return np.array([x_dist, y_dist])在校正时我习惯先处理径向畸变再处理切向畸变。有个实用技巧使用棋盘格标定板时角落的畸变最明显可以重点观察这些区域。6. 实践中的标定技巧相机标定是获取内参的实际操作。推荐使用OpenCV的calibrateCamera函数import cv2 # 准备棋盘格角点 pattern_size (9, 6) obj_points [] # 3D点 img_points [] # 2D点 # 假设已经采集了多组图像... ret, K, dist, rvecs, tvecs cv2.calibrateCamera( obj_points, img_points, image_size, None, None )标定质量检查很重要重投影误差应小于0.5像素测试图像边缘的直线是否被拉直不同距离物体的比例是否合理有次标定结果异常重投影误差达到3像素。后来发现是棋盘格打印在普通A4纸上受潮产生了变形。改用刚性标定板后问题解决。7. 从理论到应用AR案例理解这些概念后我们看一个增强现实(AR)的应用案例。要在相机画面中放置虚拟物体需要检测场景中的特征点计算相机位姿外参根据内参将3D模型投影到2Ddef render_ar_object(img, K, dist, obj_3d_points): # 检测标记假设已实现 marker_corners detect_marker(img) # 计算位姿 ret, rvec, tvec cv2.solvePnP( obj_3d_points, marker_corners, K, dist ) # 投影3D点到2D projected_points, _ cv2.projectPoints( obj_3d_points, rvec, tvec, K, dist ) # 绘制虚拟物体 draw_3d_model(img, projected_points)在这个应用中内参的准确性直接影响虚拟物体是否粘在真实表面上。曾经遇到虚拟物体抖动的问题最后发现是标定时焦距设置错误重新标定后解决。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2422863.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!