红外相机和RGB相机标定:实现两种模态数据融合
1. 前期准备
- RGB相机:森云智能SG2-IMX390,1个
- 红外相机:艾睿光电IR-Pilot 640X-32G,1个
- 红外标定板: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个对应后的点,如下图,可检查映射关系是否找对

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

相关文章:
红外相机和RGB相机标定:实现两种模态数据融合
1. 前期准备 RGB相机:森云智能SG2-IMX390,1个红外相机:艾睿光电IR-Pilot 640X-32G,1个红外标定板:https://item.taobao.com/item.htm?_ujp3fdd12b99&id644506141871&spma1z09.2.0.0.5f822e8dKrxxYI 2.操作步…...
前端项目,个人笔记(五)【图片懒加载 + 路由配置 + 面包屑 + 路由行为修改】
目录 1、图片懒加载 步骤一:自定义全局指令 步骤二:代码中使用 编辑步骤三:效果查看 步骤四:代码优化 2、封装组件案例-传对象 3、路由配置——tab标签 4、根据tab标签添加面包屑 4.1、实现 4.2、bug:需要…...
【MySQL】2.MySQL数据库的基本操作
目录 数据库基本操作 查看数据库信息 查看数据库结构 显示数据表的结构(字段) 常用的数据类型 数据库管理操作 SQL语句概述 SQL分类 1.DDL:数据定义语言 1.1创建数据库和表 创建数据库 创建数据表 1.2删除数据库和表 删除数据表…...
常见技术难点及方案
1. 分布式锁 1.1 难点 1.1.1 锁延期 同一时间内不允许多个客户端同时获得锁; 1.1.2 防止死锁 需要确保在任何故障场景下,都不会出现死锁; 1.2.3 可重入 特殊的锁机制,它允许同一个线程多次获取同一个锁而不会被阻塞。 1.2…...
c#关键字 static
static 修饰符可用于声明 static 类。 在类、接口和结构中,可以将 static 修饰符添加到字段、方法、属性、运算符、事件和构造函数。 static 修饰符不能用于索引器或终结器 尽管类的实例包含该类的所有实例字段的单独副本,但每个 static 字段只有一个副…...
redis 如何保证数据同步(数据变化时)
redis 如何保证数据同步(数据变化时) 思路 1.新增、删除和修改都先对数据库进行操作,这时数据库的数据将域缓存中数据不同。 2.数据库进行变动后,返回结果,根据返回的结果判断数据库操作是否成功。 3.如果数据库操…...
Ubuntu18.04桌面版设置静态IP地址
引用: Ubuntu配置静态IP_ubuntu配置静态ip地址-CSDN博客 正文 默认Unbuntu 18.04 Desktop桌面版使用 netplan 管理网卡网络地址。使用Unbuntu 18.04 桌面版配置,可以通过桌面上的设置图标配置网卡的静态IP地址。 点击桌面右上角下拉框,点击“设置”按…...
Aztec的客户端证明
1. 引言 隐私保护 zk-rollup 的证明生成与通用 zk-rollup 的证明生成有很大不同。原因是给定交易中存在特定数据(由私有函数处理),我们希望保持完全私有。在本文中,我们探讨了用于证明私有函数正确执行的客户端证明生成ÿ…...
面试官:小伙子知道synchronized的优化过程吗?我:嘚吧嘚吧嘚,面试官:出去!
写在开头 面试官:小伙子,多线程中锁用过吗? 我:那是自然! 面试官:那你知道synchronized的优化吗? 我:synchronized作为重锁,开销大,在早期不被推荐使用&…...
100天精通风控建模(原理+Python实现)——第23天:风控建模中的贝叶斯优化是什么?怎么实现?
在当今风险多变的环境下,风控建模已经成为金融机构、企业等组织的核心工作之一。在各大银行和公司都实际运用于业务,用于营销和风险控制等。本文以视频的形式阐述风控建模中的召回率是什么,怎么实现。并提供风控建模原理和Python实现文章清单。 之前已经阐述了100天精通…...
Http 超文本传输协议基本概念学习摘录
目录 HTTP协议 超文本传输协议 HyperText超文本 HTML超文本标记语言 HTTP协议原理 请求发送 服务器处理 响应发送 连接关闭或保持 HTTP协议版本 HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/3 HTTP请求方法 GET POST PUT DELETE HEAD OPTIONS HTTP请求头字…...
模拟-算法
文章目录 替换所有的问号提莫攻击Z字形变换外观数列数青蛙 替换所有的问号 算法思路: 从前往后遍历整个字符串,找到问号之后,就遍历 a ~ z 去尝试替换即可。 class Solution {public String modifyString(String s) {char[] ss s.toCharA…...
深入了解鸿鹄工程项目管理系统源码:功能清单与项目模块的深度解析
工程项目管理软件是现代项目管理中不可或缺的工具,它能够帮助项目团队更高效地组织和协调工作。本文将介绍一款功能强大的工程项目管理软件,该软件采用先进的Vue、Uniapp、Layui等技术框架,涵盖了项目策划决策、规划设计、施工建设到竣工交付…...
Unbuntu20.04 git push和pull相关问题
文章目录 Unbuntu20.04 git push和pull使用1.下载[Git工具包](https://git-scm.com/downloads)2.建立本地仓库3.将本地仓库与github远程仓库关联4.将本地仓库文件上传到github远程仓…...
hive SQL 移位、运算符、REGEXP正则等常用函数
orderflag & shiftleft(1,14) shiftleft(1,14) SQL中使用的运算符号详解_sql中各种符号-CSDN博客 Hive函数_hive shift-CSDN博客 (内建函数(类型排序)_云原生大数据计算服务 MaxCompute(MaxCompute)-阿里云帮助中心)...
33-Java服务定位器模式 (Service Locator Pattern)
Java服务定位器模式 实现范例 服务定位器模式(Service Locator Pattern)用于想使用 JNDI 查询定位各种服务的时候考虑到为某个服务查找 JNDI 的代价很高,服务定位器模式充分利用了缓存技术在首次请求某个服务时,服务定位器在 JNDI…...
前端小卡片:vue3路由是什么,有什么作用,该如何配置?
在 Vue 3 中,路由的处理使用了 Vue Router,它是官方提供的路由管理器。Vue Router 用于实现单页应用中的路由功能,通过将不同的 URL 映射到对应的组件,实现页面之间的切换和导航。 Vue Router 的作用包括: 实现页面之…...
Jackson 2.x 系列【2】生成器 JsonGenerator
有道无术,术尚可求,有术无道,止于术。 本系列Jackson 版本 2.17.0 源码地址:https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 前言2. 案例演示2.1 创建 JsonFactory2.2 创建 JsonGenerator2.3 写入操作2.4 查…...
说说webpack中常见的Loader?解决了什么问题?
文章目录 一、是什么配置方式 二、特性三、常见的loadercss-loaderstyle-loaderless-loaderraw-loaderfile-loaderurl-loader 参考文献 一、是什么 loader 用于对模块的"源代码"进行转换,在 import 或"加载"模块时预处理文件 webpack做的事情…...
Django 铺垫
【一】基础知识点 【1】web框架的本质 Web框架本质上可以看成是一个功能强大的socket服务端用户的浏览器可以看成是拥有可视化界面的socket客服端两种通过网络请求实现数据交互 【2】浏览器发送请求 (1)HTTP协议 HTTP协议是超文本传输协议ÿ…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...
相关类相关的可视化图像总结
目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系,可直观判断线性相关、非线性相关或无相关关系,点的分布密…...
LangChain【6】之输出解析器:结构化LLM响应的关键工具
文章目录 一 LangChain输出解析器概述1.1 什么是输出解析器?1.2 主要功能与工作原理1.3 常用解析器类型 二 主要输出解析器类型2.1 Pydantic/Json输出解析器2.2 结构化输出解析器2.3 列表解析器2.4 日期解析器2.5 Json输出解析器2.6 xml输出解析器 三 高级使用技巧3…...
验证redis数据结构
一、功能验证 1.验证redis的数据结构(如字符串、列表、哈希、集合、有序集合等)是否按照预期工作。 2、常见的数据结构验证方法: ①字符串(string) 测试基本操作 set、get、incr、decr 验证字符串的长度和内容是否正…...
