当前位置: 首页 > news >正文

如何通过黑白棋盘进行定位配准融合?(前后安装的两个相机)

一.总结:

完整流程 :硬件准备 → 数据采集 → 空间统一 → 相机标定(内参+畸变) → 外参求解 → 定位配准融合 → 校验 → 生成映射表 → 上线remap验证

我们场景流程 :硬件准备 → 数据采集 → 空间统一 → 定位配准融合 → 校验 → 生成映射表 → 上线remap验证 (少了内参标定和外参求解,根据自己的项目来定,如果要求的精度可以不是很高,内参和外参不是必要项)

我们算法流程:两个相机成像空间统一 → 定位配准融合(黑白棋盘) → 生成映射表 → 上线remap验证。


二.拆解:

1. 硬件准备

黑白棋盘格的板子,安装前后两个相机,传送带。
(1)使用两台分辨率的线扫描相机,同时拍摄带有黑白棋盘格的移动载物平台,确保所有图像都含有棋盘格背景,便于后续定位和配准。

2.数据采集

两个相机前后安装,等传送带速度稳定后,放上黑白棋盘和目标物,采集数据。
在这里插入图片描述


3.空间统一

3.1两相机空间分辨率统一

调节传送带移动速度,目标物在传送带经过两个相机后,计算黑白棋盘方格长宽比 scale=H/W (H为棋盘格高度,W为棋盘格宽度),直到 scale≈1(像素在扫描与列方向上等距),这样使两相机均达到统一的空间分辨率。

3.1.1 棋盘格角点作为空间基准
通过 Harris 角点检测识别棋盘格角点,排序后计算长宽比(scale=H/W≈1),排列角点序号和角点坐标,保存成json文件,方便后面 6. 定位配准融合加载分析。
在这里插入图片描述

下面是 原始黑白棋盘图像 和 空间分辨率统一后的黑白棋盘图像。
在这里插入图片描述
在这里插入图片描述

核心代码:

# 下面自己调整参数
# quality_level: goodFeaturesToTrack 会把角点响应值低于 maxResponse × qualityLevel 的点直接丢弃
# min_distance:非极大值抑制阶段会把相邻角点“合并”掉
max_corners = 200        # 500
quality_level = 0.0001     # 0.01
min_distance = 5          # 20
corners = cv2.goodFeaturesToTrack(gray,maxCorners=max_corners,qualityLevel=quality_level,minDistance=min_distance,useHarrisDetector=True,k=0.04
)# 3. 亚像素角点优化
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 40, 0.001)
if corners is not None:corners = cv2.cornerSubPix(gray, np.float32(corners), winSize=(5, 5), zeroZone=(-1, -1), criteria=criteria)

4. 相机标定(两个相机内参+畸变求解)(暂不用)

每个单目相机标定,确定内参。
主要的内参:焦距 fx​​、fy​,主点 cx​、cy​;再配合内参矩阵 K1​​(相机1)、K2(相机2)和​​光学畸变系数D1​​(相机1)、D2(相机2)。

内参:从相机坐标系转换到像素坐标系中。
外参:从世界坐标系转换到相机坐标系中(用于有深度的重投影)。
里面的参数一般都是相机出厂就定下来的,可以通过相机标定的方式人为计算出来。

K1/K2​​:可见光/近红外相机的内参矩阵,决定成像几何映射。
D1/D2​​:可见光/近红外相机的畸变系数,描述光学形变。

内参求解暂时没用到,等以后实验再分析)


5. 外参求解(暂不用)

暂时用不到外参:
我们使用的两个相机都不是深度相机,而且也没有高度传感器/双目/结构光等,不能获取深度和高度。(外参求解结合以后实验再分析)


6. 定位配准融合

图像配准与融合技术:透视变换和RANSAC迭代​​
基于棋盘格关键角点进行匹配配准,使用透视变换统一不同波段图像的视角差异,然后融合生成最终高光谱图像。该方法确保光谱和空间统一后的图像在几何上对齐, 最后通过感兴趣区域(ROI)裁剪后叠加,得到融合图像。

核心代码:

# 黑白棋盘角点位置坐标(手动给或json里面加载)if args.pts_json:src_pts, dst_pts, names = load_points_from_json(args.pts_json)else:src_pts, dst_pts, names = default_points()# 估计单应(相机1(低分辨率) -> 相机2(高分辨率))H, inlier_mask = cv2.findHomography(src_pts, dst_pts, method=cv2.RANSAC, ransacReprojThreshold=3.0)if H is None:raise RuntimeError("单应性矩阵估计失败,请检查点位。")# 透视变换到可见光坐标系(用于可视化验证)hs_warp = cv2.warpPerspective(hs, H, (w_rgb, h_rgb), flags=cv2.INTER_LINEAR)# 重投影误差(errors保存到文件中,用于分析哪些点pix匹配差异大)proj = cv2.perspectiveTransform(src_pts, H)errors = np.linalg.norm(dst_pts.reshape(-1,2) - proj.reshape(-1,2), axis=1)

下面2副图是两个相机定位配准融合后的图,两个图像几乎匹配上。
在这里插入图片描述
在这里插入图片描述


7. 检验

(1)用cv2.addWeighted 把两路图实时叠加,观察匹配后的物体是否有飘移。
(2)分析 errors = np.linalg.norm(dst_pts.reshape(-1,2) - proj.reshape(-1,2), axis=1)得到的errors,查看平均误差,中位误差,最大误差,进而消除一些异常点,使匹配精度得到提升。


8. 生成查找表

把映射矩阵通过LUT 打包成lut.npy,实际生产的时候,随软件升级同步。
生成这几个打包文件: lut.npy(包含mapx.npy和mapy.npy) 或者 单个mapx.npy 和 单独mapy.npy

def build_lut_from_H(H: np.ndarray, out_w: int, out_h: int):"""生成 remap 查找表 mapx/mapy:生成映射矩阵。remap 时:dst = remap(src=相机1(低分辨率), mapx, mapy) -> 输出尺寸与( out_w, out_h )一致。"""Hinv = np.linalg.inv(H).astype(np.float64)xs = np.arange(out_w, dtype=np.float32)ys = np.arange(out_h, dtype=np.float32)xg, yg = np.meshgrid(xs, ys)   # (H,W)ones = np.ones_like(xg, dtype=np.float32)grid = np.stack([xg, yg, ones], axis=-1).reshape(-1,3).T  # (3, H*W)src_h = (Hinv @ grid)    # @是矩阵乘法,等同于np.dot()(在二维数组上)或np.matmul()src_h /= (src_h[2:3, :] + 1e-12)mapx = src_h[0, :].reshape(out_h, out_w).astype(np.float32)mapy = src_h[1, :].reshape(out_h, out_w).astype(np.float32)return mapx, mapy

最后remap映射矩阵文件即可:
加载lut.npy进行remap映射。

import cv2, numpy as np
import osroot_path = "xxxxxx"
hs   = cv2.imread(os.path.join(root_path, "5.bmp"))    # camera1图映射到camera2图# 加载映射矩阵文件
# mapx = np.load(os.path.join(root_path, "校准文件npy","mapx_20250731_142541.npy"))
# mapy = np.load(os.path.join(root_path, "校准文件npy","mapy_20250731_142541.npy"))with np.load(os.path.join(root_path, "校准文件npy","lut_20250731_142541.npz")) as d:mapx = d["mapx"]mapy = d["mapy"]hs_to_rgb = cv2.remap(hs, mapx, mapy, interpolation=cv2.INTER_LINEAR,borderMode=cv2.BORDER_CONSTANT, borderValue=0)
cv2.imwrite(os.path.join(root_path, "output","camera1_to_camera2_remap.png"), hs_to_rgb)

还存在的问题

1. 图像畸变问题:
即使做了6. 定位配准融合,但由于没有做4. 相机标定(两个相机内参+畸变求解),所以相机1和相机2的成像图的畸变问题依旧存在。接下来要做4. 相机标定(两个相机内参+畸变求解),减少畸变对像素匹配的影响,提升像素匹配精度。
(生成 H 时只用背景平面点(例如 0–39 号),并先去畸变(单目标定一次即可),一般可把中位误差压到 ~2 px 以内。)

2. 实际产线目标物高度影响成像,影响像素匹配:
在实际产线上,由于相机1和相机2焦距不一样,视场角不一样,导致一些有高度的目标物在两个相机下成像不一样,最终导致两个相机的物体的像素不能完全匹配上,造成误差。这需要5. 外参求解求解出目标物高度或者深度。

http://www.dtcms.com/a/309493.html

相关文章:

  • 大模型微调实战 -基于SWIFT框架
  • 南太平洋金融基建革命:斐济-巴新交易所联盟的技术破局之路 ——从关税动荡到离岸红利,跨境科技如何重塑太平洋资本生态
  • 使用Gemini API开发领域智能聊天机器人的思路
  • js判断是个变量和属性是否是有效值
  • PixelCNN介绍:VQ-VAE的前一步探索
  • 2025年Python Web框架之争:Django、Flask还是FastAPI,谁将主宰未来?
  • JsHook入门
  • 什么是爬虫协议?
  • 如何优雅删除Docker镜像和容器(保姆级别)
  • 热能小车cad【12张】三维图+设计说明书
  • 机械学习中的一些优化算法(以逻辑回归实现案例来讲解)
  • 【Flutter3.8x】flutter从入门到实战基础教程(五):Material Icons图标的使用
  • 燃气营商环境测评:以用户反馈推动服务升级​(第三方市场调查)
  • 逻辑回归----银行贷款模型优化
  • 嵌入式教学的云端革命:高精度仿真如何重塑倒车雷达实验与工程教育——深圳航天科技创新研究院赋能新一代虚实融合实训平台
  • IIS 让asp.net core 项目一直运行
  • Linux文件系统理解2
  • OpenGL Camera
  • 【03】海康MVS V4.3.0 ——安装教程、查看示例、库、头文件、开发指南
  • vue项目预览pdf隐藏工具栏和侧边栏
  • YOLOv8/YOLOv11 C++ OpenCV DNN推理
  • 人机协作!智慧环卫如何实现按需清扫?
  • 【支持Ubuntu22】Ambari3.0.0+Bigtop3.2.0——Step7—Mariadb初始化
  • 链接脚本中. = ALIGN(4);的作用?
  • C++ --- stack和queue的使用以及简单实现
  • 高级11-Java日志管理:使用Log4j与SLF4J
  • 【Electron】打包后图标不变问题,图标问题
  • 支持selenium的chrome driver更新到138.0.7204.183
  • uv 常用指令
  • GitLab Docker Compose 迁移后 Redis 权限问题排查与解决