[机器视觉]康耐视的相机标定

总述

康耐视中与双目3D定位相关的共涉及4个API,分别是相机标定、手眼标定、计算3D坐标、估计位姿偏移。

函数功能 主体类型 返回值类型
相机标定 Cog3DCameraCalibrator Cog3DCameraCalibrationResult
手眼标定 Cog3DHandEyeCalibrator List
<Cog3DHandEyeCalibrationResult>
三角测量获得3D点坐标 Cog3DTriangulator Cog3DVect3Collection
通过2D点估计3D姿态 List
<Cog3DPoseEstimatorUsing2DPoints>
Cog3DPoseEstimatorUsing2DPointsResult

相机标定(Cognex)

相机标定执行

康耐视的相机标定函数有6种重载:
一般用的是:

1
2
3
4
5
6
public Cog3DCameraCalibrationResult Execute(
List<Rectangle> pelRectRaw2Ds,
List<List<Cog3DCrspFeaturesCollection>> crspFeatures,
Cog3DScalarCollection zHeightsPhys3D,
List<Cog3DCalibrationPlatePoseTypeConstants> poseTypes
)
参数 描述 备注
pelRectRaw2Ds 原始获取图像的ROI 一般即图像大小
crspFeatures 相机拍摄标定板的特征对
crspFeatures[i][j]对应第i个标定板姿态的第j个相机
包含PointsModel3D、PointsRaw2D、Weights
zHeightsPhys3D 不同标定板姿态下的z位置
与下一个参数poseTypes对应,需长度相同
poseTypes 标定板姿态类型

标定板姿态

康耐视支持5种标定板姿态:
Cog3DCalibrationPlatePoseTypeConstants

成员名 描述 备注
PoseDefineWorldCoord 定义世界坐标系系统
PoseElevated 与定义世界坐标系的姿态精确平行(需指定两个标定板姿态之间的偏移)
注意:平面中的(x,y)平移和旋转是不受约束的
PoseTilted 任意位置
PoseSpecified 准确定位在世界坐标系下的已知姿态
DefaultPoseType 等价于PoseDefineWorldCoord

相机内参

1
2
3
4
5
6
7
public Cog3DCameraCalibrationIntrinsics(
Cog3DVect2 scale,
double skew,
Cog3DVect2 translation,
Cog3DCameraCalibrationDistortionModelConstants distortionModel,
Cog3DScalarCollection kc
)

相机内参由5部分构成:

成员名 描述 备注
scale x、y的比例 2个数
skew 偏度系数 1个数
translation x、y的平移 2个数
distortionModel 畸变模型 默认是e3ParamRadial
kc 透镜畸变的系数 一般为3个数(e3ParamRadial)、6个数(eSineTanLawProjection)、0个数(eNoDistortion、eTelecentric)

畸变模型

康耐视支持4种畸变模型(distortion model):
Cog3DCameraCalibrationDistortionModelConstants

成员名 描述 备注
eSineTanLawProjection “high distortion” lenses – short focal length lenses which exhibit apparent distortion 高度畸变的镜头——短焦距镜头,表现出明显的畸变
eNoDistortion ideal lenses without distortion 理想的无畸变的镜头
e3ParamRadial “low distortion” lenses – where the distortion is not apparent to the human eye – but where distortion correction can improve accuracy performance nonetheless 默认,低畸变的镜头——畸变对人眼不明显,但畸变校正可以提高精度
eTelecentric telecentric lenses 远心镜头

相机标定(Cognex VS OpenCV)

相机标定得到的内参仅仅是对相机物理特性的【近似】

VisionPro

坐标系 描述 原点 单位 左/右手
Raw2D 相机获取的原始2D图像空间 左上角 像素 左手系
Camera2D 去除光学畸变、像素高宽比的影响后的无畸变2D空间 中心 物理 右手系

基于VisionPro的c#代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using Cognex.VisionPro3D;
using Cognex.VisionPro;

Cog3DVect2 point2D = new Cog3DVect2(1000, 2000);

Cog3DVect2 scale = new Cog3DVect2(10, 20);
double skew = 2;
Cog3DVect2 translation = new Cog3DVect2(30, 40);
Cog3DCameraCalibrationDistortionModelConstants distortionModel = Cog3DCameraCalibrationDistortionModelConstants.eNoDistortion;
Cog3DScalarCollection kc = new Cog3DScalarCollection();

Cog3DCameraCalibrationIntrinsics mIntrinsics = new Cog3DCameraCalibrationIntrinsics(scale, skew, translation, distortionModel, kc);
Cog3DVect2 pointRaw2D = mIntrinsics.MapPointFromCamera2DToRaw2D(point2D);
Cog3DVect2 pointCam2D = mIntrinsics.MapPointFromRaw2DToCamera2D(point2D);

基于OpenCV的python代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import numpy as np
from numpy.linalg import inv

def get_mtx33_FromCam2DToRaw2D(scale, skew, translation):
assert(len(scale) == 2)
assert(type(skew) == float or type(skew) == int)
assert(len(translation) == 2)

mtx33 = np.array([
[scale[0], skew, translation[0]],
[0, scale[1], translation[1]],
[0, 0, 1],
])

return mtx33

point2D = np.array([1000, 2000, 1]).reshape(3,1)

scale = [10, 20]
skew = 2.0
translation = [30, 40]

mtx33_FromCam2DToRaw2D = get_mtx33_FromCam2DToRaw2D(scale, skew, translation)
mtx33_FromRaw2DToCam2D = inv(mtx33_FromCam2DToRaw2D)

pointRaw2D = np.dot(mtx33_FromCam2DToRaw2D, point2D)
pointCam2D = np.dot(mtx33_FromRaw2DToCam2D, point2D)

标定验证

Cog3DCameraCalibrationValidator

参考

参考内容 参考方面
Cognex VisionPro 9.1的例程:samples3d\Programming\Setup\Calibration 主体思路
知乎:机器视觉的相机标定到底是什么? 相机标定总述