红外相机和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 np

ir_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'): 
        break
    if 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 np

def find_chessboard(filename, pattern=(9,8), wind_name="rgb"):
    # read input image
    img = cv2.imread(filename)
    # cv2.imshow("raw", img)
    # img = cv2.undistort(img, camera_matrix, distortion_coefficients)

    # convert the input image to a grayscale
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Find the chess board corners
    ret, corners = cv2.findChessboardCorners(gray, pattern, None)
    
    # if chessboard corners are detected
    if ret == True:
        # Draw and display the corners
        img = 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 corners
    
    return None
        

if __name__ == '__main__' :
    idx = 2 #0~71
    rgb_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, 8
    rgb_corners = find_chessboard(f"RGB_{idx}.png", (rgb_width, rgb_height), "rgb")

    #chessboard grid nums in thermal 
    thermal_width, thermal_height = 11, 8
    t_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 corners
        rgb_idx = 27 #可视化一个点,确认取对应点的过程是否正确
        row, col = rgb_idx//rgb_width, rgb_idx%rgb_width
        t_idx = row*thermal_width + col + 1

        pt = 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 Homography
        src_pts = []
        for rgb_idx in range(len(rgb_corners)):
            row, col = rgb_idx//9, rgb_idx%9
            t_idx = row*11+col+1
            src_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 homography
        t_warp = cv2.warpPerspective(t_img, h, (640,512), borderValue=(255,255,255))

        #colorize
        t_warp = cv2.applyColorMap(t_warp, cv2.COLORMAP_JET)

        #mix rgb and thermal
        alpha = 0.5
        merge = cv2.addWeighted(rgb_img, alpha, t_warp, 1-alpha, gamma=0)

        cv2.imshow("warp", merge)

    cv2.waitKey(0)
    cv2.destroyAllWindows()

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NSS [SWPUCTF 2022 新生赛]ez_ez_unserialize

NSS [SWPUCTF 2022 新生赛]ez_ez_unserialize 开题,直接给了题目源码。 简单看了一下,题目告诉我们flag在哪,而且类中有高亮文件方法。怎么拿flag已经很明显了。关键点在于__weakup()魔术方法固定死了我们高亮的文件。所以这题只需要绕过__w…

基于51单片机的PWM波发生器两路互补调频脉宽

地址:https://pan.baidu.com/s/1VMr7X_aCmaMd8DeR7Q6OBw 提取码:1234 仿真图: 功能简介: 1、要求占空比和频率可调 2、占空比调节范围:0.1-0.9,频率调节范围0.5kHZ—3.0kHZ 3、使用4个按键调节&#xff0…

基于springboot+vue的智慧生活商城系统

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 ​主要内容:毕业设计(Javaweb项目|小程序|Pyt…

基于Java中的SSM框架实现一汽租车共享平台系统项目【项目源码+论文说明】计算机毕业设计

基于Java中的SSM框架实现一汽租车共享平台系统演示 摘要 随着人们生活水平的不断提高,人们租车进行旅游的行为已成为大家的不二选择。汽车租赁服务被称为交通运输服务行新兴的服务行业,因为汽车租赁无须办理保险、无须年检维修、车型可随意更换等优点&a…

php基于人工智能预警突发疾病系统python-flask-django-nodejs

根据现实需要,此系统我们设计出一下功能,主要有以下功能模板。 前台功能:首页、医生、疾病知识、后台管理。 医生功能:首页、个人中心、咨询信息管理、疾病预警管理、高血压管理、糖尿病管理。 用户功能:首页、个人中心…

Python文字识别自动化处理库之pytesseract使用详解

概要 在当今数字化时代,文字识别技术扮演着越来越重要的角色。Python pytesseract 库是一个强大的工具,能够帮助开发者轻松实现图像中文字的识别。本文将深入探讨 pytesseract 库的原理、功能、使用方法以及实际应用场景,并提供丰富的示例代码,让读者更全面地了解这个工具…

重磅:Python 迎来多线程重大更新 no-GIL

“在 Python 中,GIL 将不复存在。对 AI 生态系统来说是巨大的胜利。”PyTorch 核心维护者 Dmytro Dzhulgakov 感慨地说道。 GIL 是什么?GIL 的全称是 Global Interpreter Lock(全局解释器锁),这不仅是 Python 的特性…

[Qt学习笔记]Qt下使用Halcon实现采图时自动对焦的功能(Brenner梯度法)

目录 1、介绍2、实现方法2.1 算法实现过程2.2 模拟采集流程 3、总结4、代码展示 1、介绍 在机器视觉的开发中,现在有很多通过电机去做相机的聚焦调节,对比手工调节,自动调节效果更好,而且其也能满足设备自动的需求,尤…

从零开始学习typescript系列6: typescript各种类型以及类型特殊使用

基础类型的分类 常用 boolean: 布尔值number: 支持2/8/10/16进制string: 字符串enum: 枚举类型&#xff0c;可根据value找到keyarray: 普通数组&#xff0c;有2种方式&#xff0c;string[]或者 Array<string>tuple: 特殊数组&#xff0c;指定数组里的每个元素的类型&am…

内存条@电脑支持的最大内存@升级内存硬件

文章目录 电脑支持的最大内存规格cpu官网查看支持的规格命令行查看脚本化 DDR内存LPDDR内存内存升级扩展&#x1f47a;插槽检查板载内存SPD内存厂商其他 内存参数&#x1f47a;性能指标使用软件查看更多内存相关的软件工具 电脑支持的最大内存规格 确认电脑最大支持内存大小和频…

Android14之selinux报错:ERROR: end of file in comment(一百九十七)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

HR人才测评,招聘游戏测评师的入职测评方案

一、 游戏测评师的基本工作标准 1、 编写测试用例&#xff0c;及时提交并复测回执BUG&#xff0c;针对功能不完善的地方给出合理建议。 2、 可以按时保质保量完成组长布置的测试任务&#xff0c;并尽可能多的并行多个测试项。 3、 可以独立完成与项目组沟通&#xff0c;并…

公众号获取token失败,当日access_token超过1万次处理

问题&#xff1a;如果你当日的 access_token 获取次数已经超过了 1 万次&#xff0c;那么很有可能是由于频繁获取 access_token 而被微信限制了。在这种情况下&#xff0c;你需要等待到下一个自然日或者等待一段时间后再尝试获取 access_token。或者直接去公众号去刷新掉用量。…

数据分析-Pandas序列滑动窗口配置参数

数据分析-Pandas序列滑动窗口配置参数 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表&…

「Swift」AttributedString常见使用方法

前言&#xff1a;AttributedString是Apple推出的可以实现单个字符或字符范围带相应属性的字符串。属性提供了一些文本特性&#xff0c;可以让文本展示的样式更加丰富。在日常开发过程中&#xff0c;我通常用于同一个Label中包含不同的字体大小或字体颜色的样式编写中。 使用举…

x86 32 64 Arm这些听过但不懂,都是什么?是架构还是系统?一文梳理

x86 听过吗&#xff1f;64位操作系统知道吧 和x86什么关系32和64都是什么东西&#xff1f;曾经的我也一头雾水&#xff0c;今天我才来整理一下&#xff0c;惭愧惭愧&#xff01;今天带着沉重的心情来梳理一下学习内容吧 如果你很熟悉很了解计算机的话&#xff0c;应该知道&…

物资管理系统建设方案

二、 项目概述 2.1 项目背景 2.2 现状分析 2.2.1 业务现状 2.2.2 系统现状 三、 总体需求 3.1 系统范围 3.2 系统功能 3.3 用户分析 3.4 假设与依赖关系 四、 功能需求 五、 非功能性需求 5.1 用户界面需求 5.2 软硬件环境需求 5.3 产品质量需求 5.4 接口需求 …

算力的尽头是光伏和储能——电力算力融合:能源问题的新思路

近年来&#xff0c;随着"数字中国"、数字经济等国家战略的推进&#xff0c;算力需求呈现爆发式增长。为了适应这一趋势&#xff0c;各地纷纷探索电力与算力融合发展的新模式。 在北京&#xff0c;北七家未来科技城站、怀柔北房站、丰台丽泽商务区站等多个"多站融…

UE4_官方动画内容示例1.1_使用动画资产

对一个SkeletalMeshActor进行设置&#xff0c;设置好之后&#xff0c;可以通过该Actor的细节&#xff08;Details&#xff09;面板播放指定的动画序列&#xff08;AnimationSequence&#xff09;资产&#xff08;例如让Actor翻跟斗并做开合跳&#xff09;。 骨架网格体定义&am…

QT配置libtorch(一步到位!!!防止踩坑)

QT配置libtorch Qt下载QT配置MSVCQT配置Libtorch Qt下载 Qt点击下载 Qt的安装选择MSVC2017 64-bit(一定要安装&#xff0c;这关乎后面的配置&#xff01;&#xff01;&#xff01;)&#xff0c;其他的根据自己的选择进行安装 QT配置MSVC Visual Studio点击安装 这里需要安装VS以…