在板材长度超出相机视野、需沿长边匀速移动的条件下,实现完整尺寸测量与2D建模的关键在于多帧图像拼接(Image Stitching)或位移积分重建。由于相机光轴与板材平面垂直且距离固定,移动方向已知(沿板材长边),相邻帧之间只有纯平移变换,因此拼接过程相对简单。以下是具体实现方案、步骤及推荐的开源参考。
一、整体技术路线
- 系统标定:建立像素与实际物理尺寸的映射,并确定移动方向与图像坐标轴的关系。
- 图像采集:在板材匀速通过相机视野时连续采集图像序列,确保相邻帧有足够重叠区域(如>30%)。
- 图像拼接:将序列图像拼接成一幅完整的全景图。
- 轮廓检测与测量:在全景图中分割出板材轮廓,计算实际长度、宽度等尺寸。
- 2D建模:将轮廓转换为CAD格式(如DXF)或矢量图。
二、详细实现步骤(以Python + OpenCV为例)
步骤1:系统搭建与标定
-
固定相机与传送机构
- 相机固定,光轴垂直对准板材所在平面。
- 板材放置在传送带或直线滑台上,沿长边方向匀速移动(速度 (v) 已知或可测)。
- 调整相机与传送带的角度,使移动方向严格平行于图像的某一边(通常设为水平或垂直方向),简化后续拼接。
-
相机内参与畸变标定
- 使用棋盘格标定板(固定于板材平面)拍摄多张图像,用
calibrateCamera() 获得相机内参矩阵 (K) 和畸变系数,用于后续去畸变。
-
单像素物理尺寸标定
- 在相同物距下,拍摄已知实际长度 (L_{real}) 的参考物体(或标定板的一格),测量其在图像中的像素长度 (L_{pixel})。
- 计算比例因子 (scale = L_{real} / L_{pixel})(单位:mm/pixel)。
- 注意:由于物距固定且光轴垂直,整个图像平面上该比例因子是均匀的(忽略镜头残余畸变)。
-
移动方向标定
- 在传送带上放置一个明显标记点,连续拍摄两张图像,计算标记点移动的像素位移 ((dx, dy))。
- 根据已知实际位移(速度×时间间隔)可验证标定,并确认移动方向与图像轴对齐情况。若未对齐,后续拼接时需做旋转校正。
步骤2:图像采集与预处理
-
采集序列
- 启动传送带,当板材一端进入相机视野时开始连续拍摄(视频或高速连拍)。帧率需满足:[
\text{帧率} > \frac{\text{移动速度(mm/s)}}{\text{图像重叠所需像素宽度(mm)} \times scale}
]
例如,希望相邻帧重叠率>30%,则实际帧率需足够高。
- 存储所有图像帧,同时记录每帧的时间戳(若已知速度恒定)。
-
预处理
- 对每一帧进行畸变校正:
undistort()。
- 转换为灰度图。
- 可选:高斯滤波去噪。
步骤3:图像拼接(核心)
由于纯平移运动,推荐基于相位相关法或基于特征匹配的平移估计。
方案A:相位相关法(快速、亚像素精度)
对相邻两帧 (I_i) 和 (I_{i+1}):
- 计算二者的傅里叶变换,使用
phaseCorrelate() 得到亚像素平移量 ((\Delta x, \Delta y))。
- 由于移动方向已知,可忽略垂直方向的微小偏移(若校准良好,(\Delta y \approx 0))。
- 累加平移量得到每一帧在全景图中的起始坐标。
方案B:特征匹配法(鲁棒,适合纹理较丰富的板材)
- 提取ORB特征并匹配(
ORB_create(), BFMatcher())。
- 用RANSAC求单应性矩阵 (H),在纯平移情况下,(H) 近似为平移矩阵。
- 从 (H) 中提取平移分量。
拼接执行:
- 确定全景图尺寸:根据所有帧的平移累加结果,计算最终画布的宽度和高度。
- 若移动方向为水平,则宽度 = 首帧宽度 + 总水平位移,高度 ≈ 单帧高度。
- 创建全景画布(
np.zeros)。
- 对每一帧,根据其累计平移量将图像放置到画布对应位置,可采用加权融合(如线性渐变)或最大像素值保留来消除接缝。
- 最终得到完整的板材全景图。
注意:如果板材纹理极少(如纯色金属板),特征匹配可能失败。此时可依赖已知速度进行开环拼接:
- 根据速度 (v) 和帧间隔 (\Delta t) 计算理论像素位移:(\Delta x_{pixel} = v \cdot \Delta t / scale)。
- 直接按该位移拼接,但需速度精确且无打滑。
步骤4:轮廓检测与尺寸测量
-
全景图预处理
- 二值化(Otsu阈值或自适应阈值),分离板材与背景。
- 形态学操作(闭运算)填充细小空洞。
-
轮廓提取
findContours() 获取板材外轮廓。
- 由于移动方向已知,可保留面积最大的轮廓作为板材。
-
尺寸计算
- 长度:沿移动方向,轮廓外接矩形在移动轴向上的像素长度 (L_{px}),实际长度 (L = L_{px} \times scale)。
- 宽度:垂直于移动方向的像素宽度 (W_{px}),实际宽度 (W = W_{px} \times scale)。
- 若板材形状不规则,可计算整个轮廓的面积:
contourArea() 得到像素面积,乘以 (scale^2) 得到实际面积。
步骤5:2D建模与导出
-
生成矢量轮廓
- 将检测到的轮廓点按比例缩放到实际物理坐标(mm)。
- 若需要标准CAD格式,可使用
ezdxf 库(Python)生成DXF文件。
- 示例:创建多段线(POLYLINE)并写入轮廓点。
-
可视化与保存
- 保存全景图、标注尺寸后的图像。
- 输出测量报告(Excel/JSON)。
三、精度提升策略
- 编码器反馈:在传送带电机上加装旋转编码器,每帧触发相机拍摄,实现位移同步采集,可替代图像特征匹配。
- 亚像素融合:拼接时使用双线性插值或立方插值,避免重采样误差。
- 光照均一化:采用背光照明或漫射光源,减少阴影和反光,使二值化更稳定。
- 标定板放置于移动平面:将棋盘格标定板与板材置于同一水平面,标定比例因子时可消除镜头畸变影响。
- 多帧均值滤波:对于静止背景,可拍摄多张无板材图像作背景模型,通过背景差分精确分割。
四、推荐开源实现与参考
| 项目/库 |
功能 |
适用场景 |
语言 |
| OpenCV Stitcher |
全景拼接(自动匹配、融合) |
纹理丰富、任意运动 |
C++/Python |
| OpenCV phaseCorrelate |
亚像素平移估计 |
纯平移、已知方向 |
Python |
| imutils stitching |
OpenCV stitching 的简易封装 |
快速原型 |
Python |
| ImageStitching (GitHub) |
基于特征匹配的平移拼接示例 |
学习自定义实现 |
Python |
| ezdxf |
创建DXF文件 |
导出CAD模型 |
Python |
| BoofCV (Java) |
包含图像拼接模块(平移/旋转) |
跨平台、实时需求 |
Java |
推荐快速上手:
- 使用 OpenCV 的
phaseCorrelate + 手动融合,代码量小且适合匀速平移场景。
- 参考 GitHub 上的 opencv-stitching-example 或搜 “opencv panoramic stitching moving object”。
开源完整系统参考:
- DIY Part Inspection(概念设计):展示了从图像序列到CAD建模的完整流程。
- WebScan(基于Web的扫描拼接):前端采集+后端拼接,可作为架构参考。
五、典型工作流程图
[相机固定] → [标定内参/畸变/比例] → [板材匀速移动] → [采集图像序列]
↓
[预处理(去畸变、灰度)] → [相邻帧相位相关] → [累积平移量]
↓
[全景图构建与融合]
↓
[轮廓检测] → [尺寸计算] → [导出DXF/报告]
六、注意事项
- 移动速度必须均匀:速度波动会导致图像伸缩变形,若无法保证,需依赖特征匹配而非速度推算。
- 光照稳定性:采集过程中避免环境光突变,否则拼接融合会出现亮度跳变。
- 实时性要求:若需在线测量,可采用滑动窗口拼接+边移动边测量,但算法需优化(如用C++实现)。
- 边缘畸变:靠近图像边缘的镜头畸变可能影响拼接精度,务必先进行畸变校正。
按照以上方案,即使板材长度远大于相机视野,也能获得完整的2D模型和精确尺寸。建议先用小尺寸样品验证拼接精度,再投入实际应用。