OpenCV 二维码三维定位 普通摄像头也能测空间坐标

普通摄像头如何测出二维码的三维坐标?OpenCV 相机标定与 solvePnP 实战路线

摘要

普通摄像头拍到的只是一张二维图像,但在工业视觉、机器人定位、AGV 导航、机械臂抓取等场景中,我们真正关心的往往不是二维码在图像中的位置,而是它在真实空间中的位置:距离相机多远?相对于相机偏左还是偏右?二维码所在平面有没有倾斜?本文从工程实战角度出发,梳理普通摄像头通过二维码计算三维空间坐标的完整技术路线,重点讲清楚相机标定、二维码角点、真实坐标系、solvePnP 位姿估计之间的关系,为后续 OpenCV 相机标定与二维码空间定位专题打下基础。

关键词

OpenCV、相机标定、二维码识别、solvePnP、三维坐标、位姿估计、工业视觉、机器人视觉


1. 为什么要做这个专题?

在很多工业视觉项目中,摄像头的作用并不只是"拍一张图片"或者"识别一个二维码"。

更常见的需求其实是:

  • 识别二维码或 DataMatrix 码;
  • 判断二维码在图像中的位置;
  • 计算二维码距离相机有多远;
  • 判断二维码相对于相机偏左还是偏右;
  • 判断二维码所在平面有没有发生倾斜;
  • 把二维码作为定位基准,辅助 AGV、机械臂或产线设备完成定位。

也就是说,二维码识别只是第一步,真正有工程价值的是:

从图像中的二维码,计算它在真实空间中的位置和姿态。

这就引出了一个很关键的问题:

普通摄像头明明只能拍到二维图像,为什么还能计算出二维码的三维坐标?

这就是本专题要解决的核心问题。


2. 摄像头看到的不是空间,而是投影

摄像头拍到的图像,本质上是三维世界投影到二维图像平面的结果。

真实世界中,一个二维码有实际尺寸,也有具体空间位置;但是摄像头拍到它之后,只能得到一张二维图像。

整个过程可以简单理解为:

text 复制代码
真实世界中的二维码
        ↓
相机成像
        ↓
图像中的二维码区域
        ↓
二维码四个角点的像素坐标

比如在图像中,一个二维码的四个角点可能是:

text 复制代码
左上角:u = 320, v = 180
右上角:u = 450, v = 185
右下角:u = 448, v = 315
左下角:u = 318, v = 310

这里的 uv 只是像素坐标。

它只能说明这个角点在图片上的位置,并不能直接说明这个点在真实世界中距离相机多少毫米。

所以,仅仅有图像像素坐标是不够的。


3. 计算二维码空间坐标需要哪些信息?

二维码空间定位并不是"识别出二维码内容就能算坐标"。

真正有用的是二维码的四个角点。

要想从图像中的二维码计算出空间坐标,至少需要三类信息:

  1. 相机自身参数;
  2. 二维码真实尺寸;
  3. 二维码在图像中的四个角点坐标。

下面分别来看。


4. 第一类信息:相机自身参数

不同摄像头的成像方式并不一样。

即使拍摄同一个二维码,换一个摄像头,图像中的大小和位置也可能发生变化。

因此,在计算三维坐标之前,需要先知道相机本身的参数,例如:

text 复制代码
fx、fy:焦距在像素坐标下的表示
cx、cy:图像主点坐标
dist:镜头畸变参数

这些参数通常通过相机标定得到。

相机标定的目的,不是为了得到一堆看不懂的数字,而是为了建立一个可靠的成像模型。

简单来说,就是回答一个问题:

真实世界中的三维点,是怎样投影到图像二维像素坐标上的?

如果没有相机内参和畸变参数,后面的空间坐标计算就没有可靠基础。


5. 第二类信息:二维码真实尺寸

如果二维码的实际边长是 50 mm,那么我们就可以人为建立一个二维码坐标系。

常见做法是:

  • 将二维码中心作为坐标原点;
  • 将二维码所在平面设置为 Z = 0
  • 二维码四个角点按照实际尺寸定义三维坐标。

假设二维码边长为 L,那么四个角点的真实三维坐标可以定义为:

python 复制代码
object_points = np.array([
    [-L / 2,  L / 2, 0],
    [ L / 2,  L / 2, 0],
    [ L / 2, -L / 2, 0],
    [-L / 2, -L / 2, 0]
], dtype=np.float32)

如果二维码实际边长是 50 mm,那么:

python 复制代码
L = 50.0

这时计算出来的平移向量单位也是毫米。

这里有一个很容易被忽略的细节:

代码中的二维码尺寸必须和真实打印出来的二维码尺寸一致。

如果实际二维码边长是 48 mm,但代码中写成了 50 mm,那么最终计算出来的距离也会出现系统性偏差。


6. 第三类信息:二维码在图像中的四个角点

OpenCV 可以检测二维码,并返回二维码四个角点在图像中的像素坐标。

常用代码如下:

python 复制代码
detector = cv2.QRCodeDetector()
data, points, _ = detector.detectAndDecode(image)

其中:

python 复制代码
data

表示二维码识别出来的内容。

python 复制代码
points

表示二维码四个角点在图像中的坐标。

对于空间定位来说,二维码内容本身并不是最关键的,真正关键的是四个角点。

因为 solvePnP 需要的就是:

text 复制代码
真实世界中的三维点
        +
图像中的二维点

也就是说,我们需要建立这样一组对应关系:

text 复制代码
二维码左上角三维坐标  →  图像左上角像素坐标
二维码右上角三维坐标  →  图像右上角像素坐标
二维码右下角三维坐标  →  图像右下角像素坐标
二维码左下角三维坐标  →  图像左下角像素坐标

角点顺序一旦对应错误,求出来的位姿就可能完全不对。


7. 空间定位的核心:二维点和三维点建立对应关系

到这里,我们手里已经有两组点。

第一组是二维码真实世界中的三维点:

text 复制代码
左上角:(-L/2,  L/2, 0)
右上角:( L/2,  L/2, 0)
右下角:( L/2, -L/2, 0)
左下角:(-L/2, -L/2, 0)

第二组是二维码在图像中的二维像素点:

text 复制代码
左上角:(u1, v1)
右上角:(u2, v2)
右下角:(u3, v3)
左下角:(u4, v4)

这时候问题就变成了:

已知二维码四个角点在真实空间中的三维坐标,也知道它们投影到图像中的二维像素坐标,能不能反推出二维码相对于相机的位置和姿态?

答案是可以。

这就是 PnP 问题。

在 OpenCV 中,对应的核心函数就是:

python 复制代码
cv2.solvePnP()

8. solvePnP 到底求的是什么?

solvePnP() 的作用可以简单理解为:

根据一组 3D 点和它们对应的 2D 图像点,估计物体坐标系相对于相机坐标系的旋转和平移关系。

核心代码如下:

python 复制代码
success, rvec, tvec = cv2.solvePnP(
    object_points,
    image_points,
    camera_matrix,
    dist_coeffs
)

其中:

text 复制代码
object_points:二维码四个角点在真实世界中的三维坐标
image_points:二维码四个角点在图像中的二维像素坐标
camera_matrix:相机内参矩阵
dist_coeffs:相机畸变参数
rvec:旋转向量
tvec:平移向量

这里最容易被关注的是 tvec

如果我们把二维码中心设置为二维码坐标系原点,那么 tvec 就可以理解为:

二维码中心点在相机坐标系下的位置。

例如输出结果为:

text 复制代码
X = 12.5 mm
Y = -8.2 mm
Z = 460.3 mm

可以大致理解为:

text 复制代码
二维码中心相对于相机向右偏移 12.5 mm;
向下偏移 8.2 mm;
距离相机约 460.3 mm。

不过这里要注意一点:

tvec 的具体物理含义,取决于你如何建立二维码的真实坐标系。

如果二维码坐标系原点放在中心,那么 tvec 表示二维码中心的位置。

如果二维码坐标系原点放在左上角,那么 tvec 表示左上角这个点的位置。

所以,二维码坐标系怎么建立,是后续必须单独讲清楚的内容。


9. 完整项目流程是什么?

本专题最终要实现的是一个完整的 OpenCV 小项目。

整体流程如下:

text 复制代码
准备棋盘格标定板
        ↓
采集多张棋盘格图片
        ↓
OpenCV 相机标定
        ↓
得到相机内参和畸变参数
        ↓
打开摄像头实时采集图像
        ↓
检测二维码
        ↓
提取二维码四个角点
        ↓
建立二维码真实三维坐标
        ↓
调用 solvePnP 求解位姿
        ↓
输出二维码相对于相机的 X、Y、Z 坐标
        ↓
绘制坐标轴并显示实时结果

最终效果类似:

text 复制代码
QRCode: target_001
X = 15.2 mm
Y = -6.8 mm
Z = 482.6 mm
Yaw = 2.4°
Pitch = -1.7°
Roll = 0.9°

这时候,二维码就不只是一个"被识别出来的码",而是一个可以提供空间位置参考的视觉定位标志。


10. 为什么这个方向在工业视觉中很常见?

二维码或 DataMatrix 码在工业现场中非常常见。

它们不仅可以存储产品信息,还可以作为视觉定位目标。

例如:

text 复制代码
AGV 到达工位后,通过二维码判断自身位置;
机械臂抓取前,通过二维码估计工件姿态;
工业相机检测产品时,通过码面位置辅助定位;
产线设备通过 DataMatrix 码确认工件身份和空间偏移;
多个二维码可以作为视觉标定或空间校准的参考点。

相比复杂的三维传感器,普通相机加二维码的方案成本较低,部署方便,实现难度适中,因此在很多工程场景中都有实际价值。

但是它也有明显问题:

text 复制代码
相机标定不准,坐标会偏;
二维码角点检测不准,Z 值会跳;
二维码尺寸写错,距离会整体偏差;
二维码太小,位姿估计会不稳定;
镜头畸变严重,图像边缘误差会变大。

所以这个专题后面不仅会讲"怎么实现",还会讲"为什么不准"和"怎么优化"。


11. 本专题后续内容安排

后面会按照工程项目的方式,一步一步拆开讲。

专题路线如下:

text 复制代码
第 1 篇:普通摄像头如何测出二维码三维坐标?OpenCV 相机标定与 solvePnP 实战路线

第 2 篇:为什么相机需要标定?从像素坐标到真实空间坐标的关键一步

第 3 篇:OpenCV 棋盘格相机标定实战:获取内参、畸变参数和重投影误差

第 4 篇:相机标定结果怎么看?fx、fy、cx、cy 和畸变系数到底代表什么

第 5 篇:图像去畸变实战:为什么二维码在图像边缘时测距更容易出错

第 6 篇:OpenCV 二维码检测:识别内容不是重点,四个角点才是空间定位的关键

第 7 篇:二维码真实坐标系怎么建?角点顺序、边长单位和坐标原点一次讲清楚

第 8 篇:OpenCV solvePnP 实战:用二维码四个角点求相机和二维码的相对位姿

第 9 篇:tvec 到底是什么?二维码中心在相机坐标系下的 X、Y、Z 坐标如何理解

第 10 篇:二维码姿态角怎么计算?旋转向量、旋转矩阵和欧拉角转换

第 11 篇:实时项目实战:摄像头检测二维码并动态显示三维坐标和姿态角

第 12 篇:为什么二维码测距不准?相机标定、角点误差、尺寸误差和畸变误差分析

第 13 篇:从二维码到 DataMatrix:工业视觉中码面定位的扩展思路

第 14 篇:工业落地总结:如何把 OpenCV 二维码空间定位用于 AGV、机械臂和产线检测

这个专题不会单纯写成 OpenCV API 说明,而是围绕一个完整目标展开:

用普通摄像头实现二维码空间定位。


12. 初学者先记住这一句话

如果你刚开始接触相机标定和空间定位,不需要一上来就记住所有公式。

先记住下面这句话:

二维码空间定位的本质,是用二维码四个角点的真实三维坐标和图像二维坐标,结合相机标定参数,求解二维码坐标系相对于相机坐标系的位置和姿态。

后面的相机标定、畸变校正、角点检测、solvePnP,其实都是围绕这句话展开的。


13. 小结

本文作为专题开篇,主要讲清楚了一个问题:

普通摄像头为什么可以通过二维码计算三维坐标?

核心思路可以概括为:

text 复制代码
已知二维码真实尺寸
        ↓
建立二维码四个角点的三维坐标
        ↓
检测图像中二维码四个角点的二维坐标
        ↓
结合相机标定参数
        ↓
使用 solvePnP 求解二维码相对于相机的位姿
        ↓
得到二维码在相机坐标系下的 X、Y、Z 坐标

下一篇将正式进入相机标定部分,重点讲清楚:

为什么相机需要标定?相机内参到底在空间定位中起什么作用?

只有理解了相机标定,后面的二维码三维定位才不会只是"复制代码能跑",而是真正知道每一个坐标是怎么来的。


text 复制代码
普通摄像头
   ↓
拍摄二维码
   ↓
提取四个角点
   ↓
相机内参 + 畸变参数
   ↓
solvePnP
   ↓
X / Y / Z 坐标 + 姿态角
复制代码
相关推荐
my烂笔头1 小时前
cursor添加deepseek模型
人工智能·ai
comcoo1 小时前
电脑自动化 AI OpenClaw 2.7.5 Win11 一键配置
人工智能·github·openclaw安装包·open claw部署
广_1 小时前
用AI写一个Python实时硬件监控与日志可视化界面
开发语言·人工智能·python
wangqiaowq1 小时前
FFmpeg的下载使用
人工智能
2601_959480151 小时前
Moneta Markets亿汇:“芯片巨头开拓处理器市场”
人工智能
Sharewinfo_BJ1 小时前
Power BI 5月重磅更新:8大新功能全面提升数据分析效率
大数据·人工智能·数据分析
weixin_459778721 小时前
当 AI 开始理解企业:金融复杂系统下的智能体实践
人工智能·ai·金融·ai编程·ai-native
知识浅谈1 小时前
人工智能日报 每日AI新闻(2026年5月29日):Claude Opus 4.8、AI 工作流收购与内容版权升温
人工智能
weixin_468466851 小时前
机器学习与深度学习新手区分指南
人工智能·python·深度学习·机器学习·计算机视觉·ai·机器视觉