红外相机和RGB相机标定:实现两种模态数据融合

1. 前期准备

  1. RGB相机:森云智能SG2-IMX390,1个
  2. 红外相机:艾睿光电IR-Pilot 640X-32G,1个
  3. 红外标定板:https://item.taobao.com/item.htm?_u=jp3fdd12b99&id=644506141871&spm=a1z09.2.0.0.5f822e8dKrxxYI

2.操作步骤

2.1 采集标定数据

两种模态相机均未进行内参标定,如果发现原始图片畸变较大,可以先进行内参标定。数据采集代码如下,加热红外标定板后断电,移动标定板到合适的位置,按下s键,同时保存IR图和RG图

#!/usr/bin/env python3
import cv2 , time
import numpy as npir_dev = "/dev/video6"
rgb_dev = "/dev/video0"
# define a video capture object 
ir_vid = cv2.VideoCapture(ir_dev) 
rgb_vid = cv2.VideoCapture(rgb_dev) count = 0
while(True): # Capture the video frame by frame st_time = time.time()ret, ir_frame = ir_vid.read()# print(f"{time.time() - st_time}") ret, rgb_frame = rgb_vid.read()print(f"{time.time() - st_time}") # Display the resulting frame height, width = ir_frame.shape[:2]#(512,1280)index = [2*i+1 for i in range(width//2)]vis_ir_frame = ir_frame[:,index,:]vis_rgb_frame = cv2.resize(rgb_frame, (640,512))cv2.imshow('IR frame', vis_ir_frame) cv2.imshow('RGB frame', vis_rgb_frame) key = cv2.waitKey(1) & 0xFF if key == ord('q'): breakif key == ord('s'):cv2.imwrite(f"IR_{count}.png", vis_ir_frame)cv2.imwrite(f"RGB_{count}.png", vis_rgb_frame)count += 1# After the loop release the cap object 
ir_vid.release() 
rgb_vid.release() 
# Destroy all the windows 
cv2.destroyAllWindows() 

2.2 进行标定

核心操作是调用opencv函数cv2.findHomography计算两个相机之间的单应性矩阵,代码如下

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import cv2
import numpy as npdef find_chessboard(filename, pattern=(9,8), wind_name="rgb"):# read input imageimg = cv2.imread(filename)# cv2.imshow("raw", img)# img = cv2.undistort(img, camera_matrix, distortion_coefficients)# convert the input image to a grayscalegray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Find the chess board cornersret, corners = cv2.findChessboardCorners(gray, pattern, None)# if chessboard corners are detectedif ret == True:# Draw and display the cornersimg = cv2.drawChessboardCorners(img, pattern, corners, ret)#Draw number,打印角点编号,便于确定对应点corners = np.ceil(corners[:,0,:])for i, pt in enumerate(corners): cv2.putText(img, str(i), (int(pt[0]),int(pt[1])), cv2.FONT_HERSHEY_COMPLEX, 0.3, (0,255,0), 1)cv2.imshow(wind_name,img)return cornersreturn Noneif __name__ == '__main__' :idx = 2 #0~71rgb_img = cv2.imread(f"RGB_{idx}.png")t_img = cv2.imread(f"IR_{idx}.png")#chessboard grid nums in rgb ,注意观察,同一块标定板在RGB相机和红外相机中的格子说可能不一样rgb_width, rgb_height = 9, 8rgb_corners = find_chessboard(f"RGB_{idx}.png", (rgb_width, rgb_height), "rgb")#chessboard grid nums in thermal thermal_width, thermal_height = 11, 8t_corners = find_chessboard(f"IR_{idx}.png", (thermal_width, thermal_height), "thermal")if rgb_corners is not None and t_corners is not None:# test the id correspondence between rgb and thermal cornersrgb_idx = 27 #可视化一个点,确认取对应点的过程是否正确row, col = rgb_idx//rgb_width, rgb_idx%rgb_widtht_idx = row*thermal_width + col + 1pt = rgb_corners[rgb_idx]cv2.putText(rgb_img, str(rgb_idx), (int(pt[0]),int(pt[1])), cv2.FONT_HERSHEY_COMPLEX, 0.3, (0,255,0), 1)pt = t_corners[t_idx]cv2.putText(t_img, str(t_idx), (int(pt[0]),int(pt[1])), cv2.FONT_HERSHEY_COMPLEX, 0.3, (0,255,0), 1)cv2.imshow(f"Point {rgb_idx} on rgb", rgb_img)cv2.imshow(f"Point {t_idx} on thermal", t_img)# Calculate Homographysrc_pts = []for rgb_idx in range(len(rgb_corners)):row, col = rgb_idx//9, rgb_idx%9t_idx = row*11+col+1src_pts.append(t_corners[t_idx])h, status = cv2.findHomography(np.array(src_pts)[:,None,:], rgb_corners[:,None,:])np.savetxt("calib.param", h)# Warp source image to destination based on homographyt_warp = cv2.warpPerspective(t_img, h, (640,512), borderValue=(255,255,255))#colorizet_warp = cv2.applyColorMap(t_warp, cv2.COLORMAP_JET)#mix rgb and thermalalpha = 0.5merge = cv2.addWeighted(rgb_img, alpha, t_warp, 1-alpha, gamma=0)cv2.imshow("warp", merge)cv2.waitKey(0)cv2.destroyAllWindows()

运行结果如下,观察红外和RGB图中角点的对应关系,编号已经可视化出来了

同时,也单独画出了1个对应后的点,如下图,可检查映射关系是否找对

最后,融合结果如下图所示:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/758489.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

目标检测---IOU计算详细解读(IoU、GIoU、DIoU、CIoU、EIOU、Focal-EIOU、SIOU、WIOU)

常见IoU解读与代码实现 一、✒️IoU(Intersection over Union)1.1 🔥IoU原理☀️ 优点⚡️缺点 1.2 🔥IoU计算1.3 📌IoU代码实现 二、✒️GIoU(Generalized IoU)2.1 GIoU原理☀️优点⚡️缺点 2…

网络编程:数据库

一、作业 1> 创建一个工人信息库,包含工号(主键)、姓名、年龄、薪资。 2> 添加三条工人信息(可以完整信息,也可以非完整信息) 3> 修改某一个工人的薪资(确定的一个) 4> …

SAP上线计划Cutover Plan

在SAP项目中,上线计划Cutover Plan(另一说法是切换计划)是指在项目的最后阶段,即从旧系统过渡到新SAP系统的过程中,组织必须执行的一系列活动和步骤的详细计划。这个计划对于确保平稳、有序的系统过渡至关重要。Cutover计划通常涵盖了组织沟通…

【漏洞复现】Progress Kemp LoadMaster 命令注入漏洞(CVE-2024-1212)

0x01 产品简介 Progress Kemp LoadMaster是一款高性能的应用交付控制器,具有可扩展性,支持实体硬件和虚拟机的负载均衡。它提供了当今应用服务所需的各种功能,包括深度用户验证、资安防护(如WAF/IPS/DDoS防护)以及零信…

2024学习鸿蒙开发,未来发展如何?

一、前言 想要了解一个领域的未来发展如何,可以从如下几点进行,避免盲从: 国家政策落地情况就业市场如何学习 通过上述三点,就能分析出一个行业的趋势。大家可以看到,我上面的总体逻辑就是根据国家政策来分析未来方…

代码随想录day24(2)二叉树:合并二叉树(leetcode617)

题目要求:将两个二叉树合并,要求是将同位置处的两个节点值相加,如果一个为空那就将另一个二叉树的值覆盖。 思路:如果使用迭代法,就是通过层序遍历,通过队列进行判断进行相加。如果使用递归法,…

git基础-获取git仓库

通过本章的学习,应该能够配置和初始化一个仓库,开始和停止跟踪文件,暂存和提交更改。我们还将展示如何设置 Git 来忽略特定的文件和文件模式,如何快速轻松地撤销错误,如何浏览项目的历史记录并查看提交之间的更改&…

酷开科技聚焦大屏端数据研究,构建酷开系统深度挖掘大屏商业价值

中国所有的彩色大屏中,智能电视规模已经过半,OTT平台的数据价值越发引起人们关注。作为OTT行业的头部代表,酷开科技一直聚焦大屏端数据研究,目前已经形成一套基于大屏指数的智慧营销体系,让OTT大屏的数字营销化水平实现…

AI:150-基于深度学习的医学数据挖掘与病症关联发现

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带关键代码,详细讲解供大家学习,希望…

ModuleNotFoundError: No module named ‘torch_geometric‘

1. 解决办法——安装库 pip install torch_geometric -i https://pypi.tuna.tsinghua.edu.cn/simple总结 如果你仍然遇到问题,请确保你的pip或conda是最新版本,并且你正在使用的Python环境是激活的。此外,如果你的PyTorch版本与 torch_geom…

吴恩达机器学习-可选实验室:简单神经网络(Simple Neural Network)

在这个实验室中,我们将使用Tensorflow构建一个小型神经网络 import numpy as np import matplotlib.pyplot as plt plt.style.use(./deeplearning.mplstyle) import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.laye…

win10 配置 oh-my-posh

win10 配置 oh-my-posh 0. 前置1. 安装1.1. 软件1.2. 字体1.3. 激活1.3.1. Git Bash1.3.2. PowerShell 2. 配置2.1. 效果2.2. 说明2.3. 其他2.3.1. 新版PowerShell2.3.2 conda问题 0. 前置 这个东西毕竟是个,命令行美化工具,所以需要先有一个命令行&…

eth uniswap 套利交易案例四

交易hash: 0x085843b47c0d1b0f820b80c166ea8dd2e3928876fb353d107e49dcf879cf8426 交易时间: 2024.02.29 获利: 196,284刀 balancer 借了 338个 weth, 然后和 0x3BA6A019eD5541b5F5555d8593080042Cf3ae5f4 交易用 282个weth 换了293个wste…

【矩阵】54. 螺旋矩阵【中等】

螺旋矩阵 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 示例 1: 输入:matrix [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5] 解题思路 1、模拟顺时针螺旋顺序遍历矩阵…

名词【语法笔记】

1.名词分为几大类 2.每一类,又有几个小类,以及所需要注意什么

【每日力扣】131.分割回文串与450.删除二叉搜索树中的节点

🔥 个人主页: 黑洞晓威 😀你不必等到非常厉害,才敢开始,你需要开始,才会变的非常厉害。 131.分割回文串 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的…

ROS多机通信

在充分的单机学习测试之后,往往要进行真实机器人的测试,那么就要接触到多机通信的问题。ROS采用的分布式网络通信,只要正确的设置ROS_MASTER_URI和ROS_IP两个环境变量,就可以成功实现ROS的多机通信,有时我们也称之为主…

Linux系统——Mysql数据库操作

目录 一、数据库基本操作 1.查看数据库结构 1.1查看数据库信息——Show databases 1.2查看数据库中的表信息——Show tables Show tables in 数据库名 use 数据库名 show tables 1.3显示数据表的结构(字段)——Describe(Desc&#x…

HarmonyOS(鸿蒙)ArkUI组件

方舟开发框架(简称ArkUI)为HarmonyOS应用的UI开发提供了完整的基础设施,包括简洁的UI语法、丰富的UI功能(组件、布局、动画以及交互事件),以及实时界面预览工具等,可以支持开发者进行可视化界面…

8.【Linux】线程

进程与线程比较 具体参考 小林coding 线程的上下文切换 当两个线程是属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的栈、寄存器等不共享的数据。 当两个线程不属于同一个进程&…