文章目录
- 1.工具概述与定位
-
- [1.1 核心输出一览](#1.1 核心输出一览)
- [1.2 适用传感器](#1.2 适用传感器)
- 2.核心原理:最小二乘平面拟合
-
- [2.1 平面方程](#2.1 平面方程)
- [2.2 最小二乘法求解(SVD 方法)](#2.2 最小二乘法求解(SVD 方法))
- [2.3 参数推导](#2.3 参数推导)
- 3.两种拟合模式详解
-
- [3.1 模式对比](#3.1 模式对比)
-
- [3.1.1 模式一:面积拟合(Area Fitting)](#3.1.1 模式一:面积拟合(Area Fitting))
- [3.1.2 模式二:点拟合(Point Fitting)](#3.1.2 模式二:点拟合(Point Fitting))
- [3.2 两者拟合模式对比](#3.2 两者拟合模式对比)
- [3.3 Z查询方法(Point模式专用)](#3.3 Z查询方法(Point模式专用))
- 4.函数接口与参数
-
- [4.1 输入属性](#4.1 输入属性)
- [4.2 输出属性](#4.2 输出属性)
- [4.3 方法](#4.3 方法)
- [4.4 枚举常量](#4.4 枚举常量)
- 5.结果输出详解
-
- [5.1 法向量(Normal)](#5.1 法向量(Normal))
- [5.2 偏移(Offset)](#5.2 偏移(Offset))
- [5.3 倾斜角与旋转角](#5.3 倾斜角与旋转角)
- [5.4 残留RMS](#5.4 残留RMS)
- [5.5 RMS 经验参考值](#5.5 RMS 经验参考值)
- 6.实战Demo
-
- 6.1 工件 4 角平面拟合 + 姿态判定(C#)
- [6.2 板材平面度评估(C# - Area 模式)](# - Area 模式))
- 6.3 两平面夹角检测(C#))
- 6.4 平面度热力图生成(C#))
- 6.5 PlaneEstimator + HeightCalculator联合应用(C#))
- 6.6 PlaneEstimator + VolumeCalculator联合应用(C#))
- [7.VisionPro 3D 工具](#7.VisionPro 3D 工具)
-
- [7.1 典型工具链数据流](#7.1 典型工具链数据流)
- [7.2 上游工具(数据输入)](#7.2 上游工具(数据输入))
- [7.3 下游工具(结果消费)](#7.3 下游工具(结果消费))
- 8.常见问题与调优
-
- [8.1 RMS 值异常大(> 1mm)](#8.1 RMS 值异常大(> 1mm))
- [8.2 法向量方向不一致](#8.2 法向量方向不一致)
- [8.3 Point模式拟合精度差](#8.3 Point模式拟合精度差)
- [8.4 工件偏移后拟合失败](#8.4 工件偏移后拟合失败)
- [8.5 参数调优速查表](#8.5 参数调优速查表)
- 9.参考资料
-
- [9.1 官方资源](#9.1 官方资源)
- [9.2 社区教程](#9.2 社区教程)
1.工具概述与定位

Cog3DRangeImagePlaneEstimatorTool 是康耐视 VisionPro 中针对3D深度图/点云的专用平面拟合工具,核心解决两大痛点:
- 3D 点云平面特征无法直接量化 --- 常规 2D 工具无法处理空间维度信息
- 3D 工件姿态/平面度无法通过2D图像判断 --- 需依托3D平面参数实现精准评估
1.1 核心输出一览
| 输出参数 | 类型 | 含义 |
|---|---|---|
| 法向量 (Normal X/Y/Z) | double |
描述平面的空间朝向 |
| 偏移 (Offset) | double |
平面与坐标系原点的垂直距离 |
| 倾斜角 (Tilt) | double |
平面相对于参考坐标系的倾斜角度(度) |
| 旋转角 (Rotation) | double |
平面相对于参考坐标系的旋转角度(度) |
| 残留 RMS | double |
点云与拟合平面的贴合程度(越小越好) |
| 拟合平面 (FittedPlane) | CogPlane |
拟合得到的平面对象,可传递给下游工具 |
1.2 适用传感器
- Cognex DS1000 系列3D位移传感器
- Cognex 3D-A1000系列相机
- 其他输出
CogImage16Range格式的3D传感器
2.核心原理:最小二乘平面拟合
2.1 平面方程
3D空间中平面的数学表达:
bash
Ax + By + Cz + D = 0
其中:
(A, B, C) = 法向量分量(描述平面朝向)
D = 偏移参数(描述平面位置)
约束条件: A² + B² + C² = 1
2.2 最小二乘法求解(SVD 方法)
给定N个3D点 {(xᵢ, yᵢ, zᵢ)},目标是最小化所有点到平面的距离平方和:
bash
目标函数: min Σ(Axᵢ + Byᵢ + Czᵢ + D)² 约束: A² + B² + C² = 1
求解步骤:
① 计算点云质心: p̄ = (x̄, ȳ, z̄)
② 去中心化构建矩阵 A:
⎡ x₁-x̄ y₁-ȳ z₁-z̄ ⎤
A = ⎢ x₂-x̄ y₂-ȳ z₂-z̄ ⎥
⎢ ⋮ ⋮ ⋮ ⎥
⎣ xₙ-x̄ yₙ-ȳ zₙ-z̄ ⎦
③ 对 A 做奇异值分解: A = UDVᵀ
④ 最小奇异值对应的右奇异向量即为法向量 (A, B, C)
⑤ 由质心求得 D: D = -(A·x̄ + B·ȳ + C·z̄)
几何直觉: 拟合平面就是找到一个平面,使得所有点到这个平面的距离之和最小。SVD 分解自动找到"最扁平"的方向------那就是法向量方向。
2.3 参数推导
| 参数 | 公式 | 说明 |
|---|---|---|
| 法向量 | N = (A, B, C) |
归一化后反映平面空间朝向 |
| 偏移 | ` | D |
| 倾斜角 | arccos(N·Z轴) × 180/π |
法向量与 Z 轴的夹角(度) |
| 旋转角 | arctan2(Ny, Nx) × 180/π |
法向量在 XY 平面投影与 X 轴的夹角(度) |
| 残留 RMS | √(Σdᵢ² / N) |
所有点到平面距离的均方根(越小拟合越好) |

3.两种拟合模式详解

3.1 模式对比
3.1.1 模式一:面积拟合(Area Fitting)

- 在用户指定的几何形状区域内执行平面拟合
- 支持的形状:矩形、圆形、椭圆、多边形等
- 区域内所有可见(非丢失)像素均参与拟合计算
- 优点:利用大量数据点,拟合结果更稳定
3.1.2 模式二:点拟合(Point Fitting)

- 用户在图像上指定离散的采样点位置(最少 3个)
- 每个点的 Z 坐标(高度)可通过三种方式确定:
| Z坐标确定方式 | 说明 | 适用场景 |
|---|---|---|
| 单像素值 | 直接取该点 x-y 位置的像素值 | 表面光滑,精度要求一般 |
| 邻域中值 | 取围绕该点的矩形邻域内所有像素的中值 | 有噪声干扰时使用 |
| 邻域全部可见像素 | 邻域内所有未丢失像素作为整体参与拟合 | 有数据丢失(无效像素)的情况 |
3.2 两者拟合模式对比
| 对比维度 | 面积模式 (Area) | 点模式 (Point) |
|---|---|---|
| 点源 | 选定区域内所有 3D 点 | 手动指定的离散点 |
| 最少点数 | 区域内的有效像素数 | 3 个点 |
| 区域定义 | 矩形/仿射矩形/多边形/全图 | X/Y 坐标列表 |
| 降噪方式 | 掩膜筛选排除干扰区域 | 领域平均(Z Query) |
| 适用场景 | 大面积平面(板材、PCB) | 小特征(角点、焊盘) |
| 工件偏移 | 需配合定位工具更新 ROI | 需配合定位工具更新点坐标 |
3.3 Z查询方法(Point模式专用)

| 方法 | 说明 | 适用场景 |
|---|---|---|
| 单像素值 | 直接取该点的单像素 Z 值 | 数据质量好、无噪声 |
| 领域中值 | 取周围矩形邻域内所有像素的 Z 值中位数 | 存在少量异常值 |
| 领域均值 | 取周围矩形邻域内所有可见像素的 Z 值平均 | 一般噪声场景(推荐) |
推荐: 选择"领域"模式并设置 5×5 或 7×7 的邻域尺寸,可有效减少深度噪声影响。邻域越大越平滑,但可能损失细节。
4.函数接口与参数
4.1 输入属性
| 属性名 | 类型 | 说明 |
|---|---|---|
| InputImage | CogImage16Range | 输入的 3D 深度图 |
| FitMethod | Cog3DRangeImagePlaneEstimatorTool FitMethodConstants | 拟合方法:Area / Point |
| Region | ICogRegion | 拟合区域(面积模式): 矩形 / 仿射矩形 / 多边形 |
| RegionMode | Cog3DRangeImagePlaneEstimatorTool RegionModeConstants | 区域模式(掩膜筛选方式) |
| PlaneDirection | Cog3DRangeImagePlaneEstimatorTool PlaneDirectionConstants | 平面方向定义 |
| ZQueryMethod | Cog3DRangeImagePlaneEstimatorTool ZQueryMethodConstants | Z 查询方法(点模式) |
| NeighborhoodSizeX | int | 邻域 X 尺寸(点模式,领域查询时) |
| NeighborhoodSizeY | int | 邻域 Y 尺寸(点模式,领域查询时) |
4.2 输出属性
| 属性名 | 类型 | 说明 |
|---|---|---|
FittedPlane |
CogPlane |
拟合得到的平面对象 |
NormalX |
double |
法向量 X 分量 |
NormalY |
double |
法向量 Y 分量 |
NormalZ |
double |
法向量 Z 分量 |
Offset |
double |
平面偏移量 |
TiltAngle |
double |
倾斜角(度) |
RotateAngle |
double |
旋转角(度) |
ResidualRMS |
double |
残留 RMS 误差 |
4.3 方法
| 方法 | 说明 |
|---|---|
Run() |
执行平面拟合 |
AddPointPosition(double x, double y) |
添加离散点坐标(点模式) |
ClearPointPositions() |
清除所有离散点 |
GetPointCount() |
获取已添加的离散点数量 |
4.4 枚举常量
csharp
// 拟合方法
public enum Cog3DRangeImagePlaneEstimatorToolFitMethodConstants
{
Area, // 面积模式:选定区域内所有点参与拟合
Point // 点模式:指定离散点参与拟合
}
// Z 查询方法
public enum Cog3DRangeImagePlaneEstimatorToolZQueryMethodConstants
{
Pixel, // 单像素值
Neighborhood, // 邻域中值/均值
AllVisible // 邻域内所有可见像素
}
// 平面方向
public enum Cog3DRangeImagePlaneEstimatorToolPlaneDirectionConstants
{
PositivePixelSpaceZ, // 正向像素空间 Z(匹配 3D 相机坐标系)
NegativePixelSpaceZ // 负向像素空间 Z
}
5.结果输出详解
5.1 法向量(Normal)

bash
法向量 N = (NormalX, NormalY, NormalZ)
归一化后的单位向量,描述平面的空间朝向:
- 若 N ≈ (0, 0, 1) → 平面水平放置
- 若 N 的 X 或 Y 分量较大 → 平面存在倾斜
- 法向量方向由 PlaneDirection 参数决定
5.2 偏移(Offset)

bash
Offset = |D| / √(A² + B² + C²)
平面到坐标系原点的垂直距离
单位与深度图的物理单位一致(通常为 mm)
5.3 倾斜角与旋转角


bash
TiltAngle = arccos(NormalZ) × (180/π)
→ 平面与 XY 平面的夹角
RotateAngle = arctan2(NormalY, NormalX) × (180/π)
→ 法向量在 XY 平面投影与 X 轴的夹角
5.4 残留RMS

bash
所有点到拟合平面距离的均方根
值越小 → 拟合精度越高
5.5 RMS 经验参考值
- RMS< 0.05mm → 优秀(精密平面)
- 0.05mm ≤ RMS < 0.2mm → 良好(一般工业场景)
- RMS ≥ 0.5mm → 需检查数据质量或传感器标定
6.实战Demo
6.1 工件 4 角平面拟合 + 姿态判定(C#)
csharp
// PlaneEstimator --- 工件 4 角平面拟合 + 姿态判定
using Cognex.VisionPro;
using Cognex.VisionPro3D;
public override void Run()
{
Cog3DRangeImagePlaneEstimatorTool planeTool =
toolBlock.Tools["PlaneEstimator"] as Cog3DRangeImagePlaneEstimatorTool;
// 输入 3D 深度图
planeTool.InputImage = toolBlock.Inputs["RangeImage"].Value as CogImage16Range;
// 配置 Point 模式 --- 工件 4 角坐标
planeTool.FitMethod = Cog3DRangeImagePlaneEstimatorToolFitMethodConstants.Point;
planeTool.ClearPointPositions();
planeTool.AddPointPosition(0, 0); // 左上角
planeTool.AddPointPosition(0, 50); // 左下角
planeTool.AddPointPosition(50, 0); // 右上角
planeTool.AddPointPosition(50, 50); // 右下角
// Z 查询方法:领域平均降噪
planeTool.ZQueryMethod = Cog3DRangeImagePlaneEstimatorToolZQueryMethodConstants.Neighborhood;
planeTool.NeighborhoodSizeX = 5;
planeTool.NeighborhoodSizeY = 5;
// 执行拟合
planeTool.Run();
// 读取结果
double tiltAngle = planeTool.TiltAngle;
double rotateAngle = planeTool.RotateAngle;
double rms = planeTool.ResidualRMS;
CogPlane fitPlane = planeTool.FittedPlane;
Console.WriteLine($"倾斜角: {tiltAngle:F2}°, 旋转角: {rotateAngle:F2}°, RMS: {rms:F4}");
// 姿态判定
if (tiltAngle > 2.0 || rotateAngle > 2.0)
toolBlock.Outputs["PoseResult"].Value = "ABNORMAL";
else
toolBlock.Outputs["PoseResult"].Value = "NORMAL";
// 输出平面给下游
toolBlock.Outputs["FittedPlane"].Value = fitPlane;
}
6.2 板材平面度评估(C# - Area 模式)
csharp
// PlaneEstimator --- 板材平面度评估 (Area 模式)
using Cognex.VisionPro;
using Cognex.VisionPro3D;
public override void Run()
{
Cog3DRangeImagePlaneEstimatorTool planeTool =
toolBlock.Tools["PlaneEstimator"] as Cog3DRangeImagePlaneEstimatorTool;
planeTool.InputImage = toolBlock.Inputs["RangeImage"].Value as CogImage16Range;
// 配置 Area 模式 --- 全图拟合
planeTool.FitMethod = Cog3DRangeImagePlaneEstimatorToolFitMethodConstants.Area;
// 设置区域形状(排除边缘 10 像素)
CogRectangleAffine roi = new CogRectangleAffine();
roi.SetOriginXYLengthWidthRotationSkew(10, 10, 480, 480, 0, 0);
planeTool.Region = roi;
// 区域模式:掩膜筛选
planeTool.RegionMode = Cog3DRangeImagePlaneEstimatorToolRegionModeConstants.PixelPairMask;
// 平面方向
planeTool.PlaneDirection = Cog3DRangeImagePlaneEstimatorToolPlaneDirectionConstants.PositivePixelSpaceZ;
planeTool.Run();
double rms = planeTool.ResidualRMS;
double tiltAngle = planeTool.TiltAngle;
Console.WriteLine($"平面度 RMS: {rms:F4}mm, 倾斜角: {tiltAngle:F2}°");
// 判定逻辑
if (rms > 0.5)
toolBlock.Outputs["FlatnessResult"].Value = "FAIL - 平面度超标";
else
toolBlock.Outputs["FlatnessResult"].Value = "PASS";
}
6.3 两平面夹角检测(C#)

csharp
public override void Run()
{
try
{
// ---- 拟合基准平面 ----
Cog3DRangeImagePlaneEstimatorTool basePlaneTool =
toolBlock.Tools["BasePlaneEstimator"] as Cog3DRangeImagePlaneEstimatorTool;
basePlaneTool.InputImage = toolBlock.Inputs["RangeImage"].Value as CogImage16Range;
basePlaneTool.FitMethod = Cog3DRangeImagePlaneEstimatorToolFitMethodConstants.Robust; // 改为Robust拟合
basePlaneTool.Run();
if (basePlaneTool.RunStatus.Result != CogToolResultConstants.Accept)
{
toolBlock.Outputs["AngleResult"].Value = "FAIL - 基准平面拟合失败";
return;
}
CogPlane basePlane = basePlaneTool.FittedPlane;
// ---- 拟合工件平面 ----
Cog3DRangeImagePlaneEstimatorTool workPlaneTool =
toolBlock.Tools["WorkPlaneEstimator"] as Cog3DRangeImagePlaneEstimatorTool;
workPlaneTool.InputImage = toolBlock.Inputs["RangeImage"].Value as CogImage16Range;
workPlaneTool.FitMethod = Cog3DRangeImagePlaneEstimatorToolFitMethodConstants.Point;
// 使用更合理的点分布(可根据实际情况调整)
workPlaneTool.ClearPointPositions();
AddSamplePoints(workPlaneTool); // 封装点添加逻辑
workPlaneTool.ZQueryMethod = Cog3DRangeImagePlaneEstimatorToolZQueryMethodConstants.Neighborhood;
workPlaneTool.NeighborhoodSizeX = 7; // 适当增大邻域
workPlaneTool.NeighborhoodSizeY = 7;
workPlaneTool.Run();
if (workPlaneTool.RunStatus.Result != CogToolResultConstants.Accept)
{
toolBlock.Outputs["AngleResult"].Value = "FAIL - 工件平面拟合失败";
return;
}
CogPlane workPlane = workPlaneTool.FittedPlane;
// ---- 计算两平面夹角 ----
double angleDeg = CalculatePlaneAngle(basePlane, workPlane);
Console.WriteLine($"两平面夹角: {angleDeg:F2}°");
Console.WriteLine($"基准平面拟合误差: {basePlaneTool.ResidualsRMS:F4}");
Console.WriteLine($"工件平面拟合误差: {workPlaneTool.ResidualsRMS:F4}");
// ---- 判断结果 ----
if (angleDeg > 5.0)
toolBlock.Outputs["AngleResult"].Value = "FAIL - 角度超标";
else
toolBlock.Outputs["AngleResult"].Value = "PASS";
}
catch (Exception ex)
{
Console.WriteLine($"执行错误: {ex.Message}");
toolBlock.Outputs["AngleResult"].Value = "FAIL - 系统错误";
}
}
private double CalculatePlaneAngle(CogPlane plane1, CogPlane plane2)
{
// 法向量点积
double dot = plane1.A * plane2.A + plane1.B * plane2.B + plane1.C * plane2.C;
// 法向量长度
double mag1 = Math.Sqrt(plane1.A * plane1.A + plane1.B * plane1.B + plane1.C * plane1.C);
double mag2 = Math.Sqrt(plane2.A * plane2.A + plane2.B * plane2.B + plane2.C * plane2.C);
// 检查有效性
if (mag1 < 1e-10 || mag2 < 1e-10)
throw new InvalidOperationException("无效的平面法向量");
// 计算夹角(确保cos值在有效范围内)
double cosAngle = dot / (mag1 * mag2);
cosAngle = Math.Max(-1.0, Math.Min(1.0, cosAngle));
double angleRad = Math.Acos(cosAngle);
double angleDeg = angleRad * 180.0 / Math.PI;
// 返回锐角(0-90度)
return angleDeg > 90 ? 180 - angleDeg : angleDeg;
}
6.4 平面度热力图生成(C#)
csharp
// 平面度热力图 --- 将大面积板材分区扫描,生成 RMS 热力图
using Cognex.VisionPro;
using Cognex.VisionPro3D;
public override void Run()
{
CogImage16Range rangeImage = toolBlock.Inputs["RangeImage"].Value as CogImage16Range;
// 将图像分为 5×5 = 25 个区域,逐区域拟合
int gridRows = 5, gridCols = 5;
int regionW = rangeImage.Width / gridCols;
int regionH = rangeImage.Height / gridRows;
double[,] rmsMap = new double[gridRows, gridCols];
Cog3DRangeImagePlaneEstimatorTool planeTool =
toolBlock.Tools["PlaneEstimator"] as Cog3DRangeImagePlaneEstimatorTool;
planeTool.InputImage = rangeImage;
planeTool.FitMethod = Cog3DRangeImagePlaneEstimatorToolFitMethodConstants.Area;
planeTool.PlaneDirection = Cog3DRangeImagePlaneEstimatorToolPlaneDirectionConstants.PositivePixelSpaceZ;
for (int r = 0; r < gridRows; r++)
{
for (int c = 0; c < gridCols; c++)
{
CogRectangle roi = new CogRectangle();
roi.X = c * regionW;
roi.Y = r * regionH;
roi.Width = regionW;
roi.Height = regionH;
planeTool.Region = roi;
planeTool.Run();
rmsMap[r, c] = planeTool.ResidualRMS;
Console.WriteLine($"区域[{r},{c}] RMS: {rmsMap[r, c]:F4}mm");
}
}
// 找出最大 RMS 区域
double maxRms = 0;
int maxR = 0, maxC = 0;
for (int r = 0; r < gridRows; r++)
for (int c = 0; c < gridCols; c++)
if (rmsMap[r, c] > maxRms) { maxRms = rmsMap[r, c]; maxR = r; maxC = c; }
Console.WriteLine($"最大 RMS 区域: [{maxR},{maxC}], 值: {maxRms:F4}mm");
toolBlock.Outputs["MaxRMS"].Value = maxRms;
toolBlock.Outputs["MaxRegion"].Value = $"[{maxR},{maxC}]";
toolBlock.Outputs["PassResult"].Value = maxRms < 0.5 ? "PASS" : "FAIL";
}
应用场景: 大型板材(如 PCB、金属薄板)的全面平面度检测,通过分区扫描生成 RMS 热力图,精确定位翘曲/凹陷区域。
6.5 PlaneEstimator + HeightCalculator联合应用(C#)
csharp
// 联合应用:PlaneEstimator 拟合基准面 + HeightCalculator 计算高度差
using Cognex.VisionPro;
using Cognex.VisionPro3D;
public override void Run()
{
CogImage16Range rangeImage = toolBlock.Inputs["RangeImage"].Value as CogImage16Range;
// Step 1: 拟合基准平面
Cog3DRangeImagePlaneEstimatorTool planeTool =
toolBlock.Tools["PlaneEstimator"] as Cog3DRangeImagePlaneEstimatorTool;
planeTool.InputImage = rangeImage;
planeTool.FitMethod = Cog3DRangeImagePlaneEstimatorToolFitMethodConstants.Area;
CogRectangleAffine baseROI = new CogRectangleAffine();
baseROI.SetOriginXYLengthWidthRotationSkew(0, 0, 500, 100, 0, 0);
planeTool.Region = baseROI;
planeTool.Run();
CogPlane basePlane = planeTool.FittedPlane;
Console.WriteLine($"基准平面 RMS: {planeTool.ResidualRMS:F4}mm");
// Step 2: 计算目标区域相对基准面的高度
Cog3DRangeImageHeightCalculatorTool heightTool =
toolBlock.Tools["HeightCalculator"] as Cog3DRangeImageHeightCalculatorTool;
heightTool.InputImage = rangeImage;
heightTool.InputPlane = basePlane;
CogRectangle targetROI = new CogRectangle();
targetROI.X = 200; targetROI.Y = 200;
targetROI.Width = 100; targetROI.Height = 100;
heightTool.Region = targetROI;
heightTool.Run();
double meanHeight = heightTool.MeanHeight;
double medianHeight = heightTool.MedianHeight;
double minHeight = heightTool.MinHeight;
double maxHeight = heightTool.MaxHeight;
double stdDev = heightTool.StandardDeviation;
Console.WriteLine($"平均高度: {meanHeight:F3}mm, 中位数: {medianHeight:F3}mm");
Console.WriteLine($"最小: {minHeight:F3}mm, 最大: {maxHeight:F3}mm, 标准差: {stdDev:F3}mm");
if (meanHeight > 0.3 || stdDev > 0.1)
toolBlock.Outputs["HeightResult"].Value = "FAIL";
else
toolBlock.Outputs["HeightResult"].Value = "PASS";
}
6.6 PlaneEstimator + VolumeCalculator联合应用(C#)
csharp
// 联合应用:PlaneEstimator 拟合基准面 + VolumeCalculator 计算体积
using Cognex.VisionPro;
using Cognex.VisionPro3D;
public override void Run()
{
CogImage16Range rangeImage = toolBlock.Inputs["RangeImage"].Value as CogImage16Range;
// Step 1: 拟合基准平面
Cog3DRangeImagePlaneEstimatorTool planeTool =
toolBlock.Tools["PlaneEstimator"] as Cog3DRangeImagePlaneEstimatorTool;
planeTool.InputImage = rangeImage;
planeTool.FitMethod = Cog3DRangeImagePlaneEstimatorToolFitMethodConstants.Area;
planeTool.Run();
CogPlane basePlane = planeTool.FittedPlane;
// Step 2: 计算指定区域的体积
Cog3DRangeImageVolumeCalculatorTool volumeTool =
toolBlock.Tools["VolumeCalculator"] as Cog3DRangeImageVolumeCalculatorTool;
volumeTool.InputImage = rangeImage;
volumeTool.InputPlane = basePlane;
CogRectangle roi = new CogRectangle();
roi.X = 150; roi.Y = 150;
roi.Width = 200; roi.Height = 200;
volumeTool.Region = roi;
volumeTool.Run();
double volume = volumeTool.Volume; // 单位:立方毫米
Console.WriteLine($"计算体积: {volume:F2} mm³");
if (volume < 50.0 || volume > 200.0)
toolBlock.Outputs["GlueResult"].Value = "FAIL - 胶量异常";
else
toolBlock.Outputs["GlueResult"].Value = "PASS";
}
说明:
Cog3DRangeImageVolumeCalculatorTool计算基准平面上方区域特征的体积(单位:mm³),适用于胶水涂覆量、点胶高度、凸起/凹陷体积等场景。
7.VisionPro 3D 工具
| 工具名称 | 功能 | 典型用途 |
|---|---|---|
| Cog3DRangeGreySplitterScript | 高度/灰度分离 | 将 RangeWithGrey 拆分为深度图和灰度图 |
| Cog3DRangeImagePlaneEstimatorTool | 平面拟合 | 输出法向量/偏移/姿态角/RMS |
| Cog3DRangeImageCrossSectionTool | 横截面提取 | 获取 Profile 轮廓,支持找点/找线/找圆 |
| Cog3DRangeImageHeightCalculatorTool | 高度计算 | 计算点到基准平面的高度差 |
| Cog3DRangeImageVolumeCalculatorTool | 体积计算 | 计算基准面上方区域特征的体积 |
| Cog3DPlanePlaneAngleScript | 两平面夹角 | 输入两个平面,输出夹角 |
| Cog3DVisionDataStitchTool | 图像拼接 | 将多相机图像拼接输出 |
| CogPMAlign3DTool | 3D 模板匹配 | 定位 3D 工件位置 |
7.1 典型工具链数据流
bash
Cog3DAcquireTool (采集 3D 深度图)
│
▼
Cog3DRangeGreySplitterScript (分离高度/灰度)
│
▼
Cog3DRangeImagePlaneEstimatorTool (平面拟合 → CogPlane)
│
├──────────────┬──────────────┬──────────────┐
▼ ▼ ▼ ▼
HeightCalculator VolumeCalculator 3DCalibrateTool 3DTransformTool
(高度差计算) (体积计算) (相机标定) (坐标变换/抓取)
│ │
▼ ▼
CogDecisionTool (综合判定 → PASS/FAIL)
7.2 上游工具(数据输入)
| 工具 | 作用 | 输出 |
|---|---|---|
| Cog3DRangeGreySplitterScript | 分离高度/灰度图像 | CogImage16Range + 灰度图 |
| CogPMAlign3DTool | 3D 模板匹配定位工件 | 工件坐标 → 更新 ROI/点坐标 |
| Cog3DVisionDataStitchTool | 多相机图像拼接 | 拼接后的完整深度图 |
7.3 下游工具(结果消费)
| 工具 | 输入 | 用途 |
|---|---|---|
| Cog3DCalibrateTool | CogPlane (法向量+偏移) |
相机外参校准 |
| Cog3DRangeImageHeightCalculatorTool | CogPlane (基准平面) |
计算点到平面高度差 |
| Cog3DRangeImageVolumeCalculatorTool | CogPlane (基准平面) |
计算基准面上方体积 |
| Cog3DPlanePlaneAngleScript | 2× CogPlane |
计算两平面夹角 |
| Cog3DTransformTool | CogPlane (法向量) |
调整机械臂抓取姿态 |
| CogDecisionTool | 倾斜角/RMS/偏移 | 综合判定 PASS/FAIL |
| Cog3DDisplayV2 | CogPlane + 深度图 |
3D 可视化渲染 |
8.常见问题与调优
8.1 RMS 值异常大(> 1mm)
可能原因:
- ROI 区域包含非平面区域(如工件边缘、凸起物)
- 深度图存在大量无效/丢失像素
- 传感器标定漂移
解决方案:
- 缩小 ROI 范围,排除边缘干扰
- 使用掩膜模式排除无效像素
- 重新标定传感器
8.2 法向量方向不一致
可能原因:
PlaneDirection参数设置不匹配相机坐标系- 工件翻转导致法向量反向
解决方案:
- 确认相机坐标系方向,选择 "PositivePixelSpaceZ" 或 "NegativePixelSpaceZ"
- 在结果处理中对法向量做方向一致性校验
8.3 Point模式拟合精度差
可能原因:
- 离散点数量不足(< 3 个)
- 离散点共线(退化情况)
- Z 查询方法选择不当
解决方案:
- 至少选择 4 个不共线的离散点
- 使用 "领域均值" Z 查询,设置 5×5 或 7×7 邻域
- 确保离散点分布在目标平面的不同区域
8.4 工件偏移后拟合失败
可能原因:
- ROI/离散点坐标固定,未随工件位置更新
解决方案:
- 在 PlaneEstimator 前增加
CogPMAlign3DTool进行 3D 定位 - 根据定位结果动态更新 ROI 原点或离散点坐标
8.5 参数调优速查表
| 场景 | 推荐配置 |
|---|---|
| 大面积平面(板材、PCB) | Area 模式 + 矩形/仿射矩形 ROI + 掩膜筛选 |
| 小特征平面(角点、焊盘) | Point 模式 + 4 个不共线点 + 领域均值(5×5) |
| 高噪声环境 | Point 模式 + 领域均值(7×7) 或 领域中值 |
| 精密测量 | Area 模式 + 全图 + 排除边缘 10-20 像素 |
| 工件有偏移 | 先 CogPMAlign3DTool 定位 → 动态更新 ROI/点坐标 |
9.参考资料
9.1 官方资源
- Cognex 官方支持 - VisionPro
- VisionPro 安装目录示例:
%VPRO_ROOT%/samples/Programming/3D/ - 3D Viewer 示例:
%VPRO_ROOT%/samples/Programming/3D/Cog3DDisplayV2WithGraphics/