当前位置: 首页 > 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.lryc.cn/news/607152.html

相关文章:

  • 【Mysql】联合索引生效分析案例
  • 【科研绘图系列】R语言绘制环状分组显著性柱状堆积图
  • 鹧鸪云:16步精控工商业光伏全流程
  • java8学习笔记-Stream流
  • GitPython08-源码解读
  • 网络编程接口bind学习
  • MySQL时间处理完全指南:从存储到查询优化
  • Java向量化
  • 如何处理Y2K38问题
  • 利用 AI 在 iPhone 上实现 App 文本情绪价值评估(上)
  • 【AI应用】 能源保供战:AI大模型如何守护万家灯火?
  • TGD第十篇:当神经网络遇到TGD特征
  • Qt 开发自动化测试框架搭建
  • 【华为机试】34. 在排序数组中查找元素的第一个和最后一个位置
  • OSPF综合大实验
  • python学智能算法(三十))|SVM-KKT条件的数学理解
  • Git基础命令大全
  • C语言数据结构(3)单链表专题1.单链表概述
  • 【论文学习】KAG论文翻译
  • Redis 中 ZipList 的级联更新问题
  • 一篇文章读懂AI Agent(智能体)
  • Python LRU缓存应用与示例
  • 三维协同:体育场馆设计与渲染的独特挑战
  • Web开发-PHP应用TP框架MVC模型路由访问模版渲染安全写法版本漏洞
  • Au速成班-多轨编辑流程
  • 在纯servlet项目中,使用@WebFilter定义了多个filter,如何设置filter的优先级
  • 【PHP 构造函数与析构函数:从基础到高级的完整指南】
  • 【音视频】WebRTC 中的RTP、RTCP、SDP、Candidate
  • 2025年Python Web框架之争:Django、Flask还是FastAPI,谁将主宰未来?
  • HarmonyOS】鸿蒙应用开发中常用的三方库介绍和使用示例