4. 相机模型:针孔、远心与线扫,以及 HALCON 中的对应参数

相机模型这东西,说白了就是一套数学规则。它告诉我们,三维世界里的一个点,是怎么跑到二维图像上的。你想想看,如果连这个映射关系都搞不清楚,标定就无从谈起。

HALCON 支持三种主流模型:针孔、远心和线扫。我刚开始接触机器视觉时,总觉得远心相机很神秘,后来才发现,选对模型比调参重要一百倍。

核心观点:标定的本质,就是求解相机模型的内部参数(内参)和外部姿态(外参)。模型选错,标定结果再漂亮也是错的。

4.1 针孔相机模型(Pinhole)

这是最经典的模型。光线通过一个小孔,在成像平面上形成倒像。HALCON 用 CalTab 标定板来处理这个模型。

针孔模型有 5 个内参,外加畸变参数。我列个表,你一看就明白:

参数 HALCON 名称 说明
焦距 Focus 镜头光心到成像面的距离,单位米
主点 x CenterRow 光轴与成像面交点的行坐标
主点 y CenterCol 光轴与成像面交点的列坐标
像元宽 PixelSize 单个像素的物理宽度
像元高 PixelSize 通常与宽相等,但可以不同

畸变参数也很关键。HALCON 使用 Kappa(径向畸变)和 CamParam 中的多项式系数。我记得有一次,客户说他们的测量总是偏大,我检查后发现是径向畸变没校正。嗯,从那以后,我每次标定都会看一眼畸变图。

我的习惯:针孔模型标定后,一定用 gen_radial_distortion_map 生成畸变校正图。肉眼看一下边缘直线是否变直,比看数值更直观。

4.2 远心相机模型(Telecentric)

远心镜头很特别。它的光线是平行入射的,所以没有透视效果。说白了,物体离镜头远一点近一点,成像大小不变。这在精密测量中非常有用。

远心模型的参数比针孔少一个——它没有焦距概念,取而代之的是 放大倍率。HALCON 中对应的参数是 Magnification。

我列个对比表,帮你快速区分:

特性 针孔模型 远心模型
光线路径 发散 平行
物距影响 有(近大远小) 无
内参数量 5 + 畸变 4 + 畸变
典型应用 大视野、定位 高精度测量

远心模型在 HALCON 中的标定流程和针孔几乎一样。但有一个坑:标定板必须与镜头光轴垂直。我曾经在一个项目中,因为标定板倾斜了 5 度,导致测量误差直接翻倍。后来我加了一个机械定位工装,问题才解决。

避坑指南:远心镜头对光照非常敏感。如果光源不均匀,标定板上的圆点边缘会模糊,导致提取精度下降。我建议用背光源或同轴光源。

4.3 线扫相机模型(Line Scan)

线扫相机一次只拍一行像素。它需要物体运动,或者相机运动,才能拼出一张完整的图像。这个模型最复杂,因为它多了一个维度——运动速度。

线扫模型的内参包括:

  • 像元尺寸(PixelSize)
  • 扫描方向(ScanDirection)
  • 行间距(LineSpacing)——由运动速度决定
  • 镜头参数(针孔或远心)

HALCON 中,线扫标定使用 calibrate_cameras 算子,但需要额外指定 LineScan 类型。我记得第一次做线扫标定时,折腾了两天,最后发现是编码器脉冲没接对。你想想看,运动速度不准,标定结果怎么可能对?

下面这张图,帮你理清三种模型的核心区别:

三种相机模型对比 针孔模型 • 光线发散 • 有透视效应 • 5 个内参 • 适用:大视野 • 畸变:径向+切向 远心模型 • 光线平行 • 无透视效应 • 4 个内参 • 适用:精密测量 • 畸变:径向为主 线扫模型 • 逐行成像 • 需运动配合 • 含速度参数 • 适用:连续物料 • 畸变:+运动畸变 选择建议 1. 如果物体静止,视野大 → 针孔模型 2. 如果物体静止,需要高精度测量 → 远心模型 3. 如果物体连续运动,需要逐行扫描 → 线扫模型 4. 如果既需要大视野又需要高精度 → 考虑多相机拼接

4.4 HALCON 中的参数设置

在 HALCON 中,相机参数通过 CamParam 元组传递。我直接给你看代码,比说一百句都管用:

* 针孔相机参数
* [Focus, CenterRow, CenterCol, PixelSize, Kappa]
CamParamPinhole := [0.008, 512, 512, 0.0000055, 0.0]

* 远心相机参数
* [Magnification, CenterRow, CenterCol, PixelSize, Kappa]
CamParamTele := [0.5, 512, 512, 0.0000055, 0.0]

* 线扫相机参数(基于针孔)
* [Focus, CenterRow, CenterCol, PixelSize, Kappa, LineSpacing, ScanDirection]
CamParamLine := [0.008, 512, 512, 0.0000055, 0.0, 0.0001, 'forward']

注意,线扫模型的 LineSpacing 必须与运动速度匹配。如果编码器每脉冲对应 0.1mm,那么 LineSpacing 就设为 0.0001 米。我见过有人把这个参数设反了,结果图像被拉长了一倍。

调试技巧:标定完成后,用 get_calib_data 查看标定误差。如果误差大于 0.5 像素,我建议重新采集标定板图像。别偷懒,多拍 10 张图比事后找 bug 省时间。

4.5 模型选择实战建议

说了这么多,到底怎么选?我总结了一个简单的决策流程:

  1. 看镜头:如果是普通镜头,选针孔;如果是远心镜头,选远心。
  2. 看传感器:如果是面阵相机,选针孔或远心;如果是线阵相机,选线扫。
  3. 看精度要求:如果测量精度要求低于 0.1mm,针孔就够了;如果要求更高,考虑远心。
  4. 看运动:如果物体必须运动才能成像,线扫是唯一选择。

我个人习惯是,在项目开始前先画一个相机模型选择矩阵。把需求列出来,再对照矩阵选型。这样不容易出错。

重要提醒:不要试图用针孔模型去标定远心镜头。HALCON 虽然能跑出结果,但内参是错的。我曾经接手过一个项目,前任工程师用错了模型,导致所有测量数据都偏了 0.3mm。嗯,后来我重新标定了一遍,问题才解决。

好了,这一章的内容就到这里。三种模型各有各的脾气,但只要你理解了它们的物理本质,HALCON 中的参数设置其实很简单。记住一句话:模型选对,标定事半功倍;模型选错,一切白费。