【双光相机配准】红外相机与可见光相机配准方案

背景

目前,需要将一台红外相机与一台可见光相机实现配准,以下是情况详述:

  1. 目前红外相机与可见光相机固定在一个云台上,彼此的相对位置固定;
  2. 可见光相机与红外相机的设置位置为左右设置;相机之间的视野差异大,视野范围内只有部分重叠;
  3. 可见光相机与红外相机的焦距差异大,且不可调整;
  4. 可见光相机与红外相机的变倍差异大,且不可调整;

需求:在可见光相机采集的图像上进行目标检测,检测到的检测框bbox坐标转换为红外图像坐标系的bbox坐标,判断bbox是否在红外图像范围内(因为双光相机的视野只有部分区域重叠);如果在红外图像内,返回映射到红外图像的bbox区域内的温度极值。

同时刻可见光相机图像采集:

同时刻红外相机图像采集:

介绍方案

目的:实现可见光与红外相机的坐标转换:

方案1:手动配置覆盖坐标

将红外相机的图像与可见光图像区域重叠(x1,y1,x2,y2),实现可视化的双光融合。然后手动微调(x1,y1,x2,y2),使得目标区域的可见光与热成像重叠;

上图实现了可见光相机画面检测到的检测框成功叠加到红外相机的图像上。

存在问题:

  1. 一旦目标的距离变化,配准即刻失效。
  2. 同一画面中多个目标,只能保障一部分目标红外图像区域与可见光图像区域大致对齐。(将人头部大致对齐后,上部的灯带明显是没有对齐的)。
  3. 每隔相机都要手动调整,该方案只适合展示一下效果图或者德莫,或者是定点双光相机+固定目标的场景;

融合样例

复制代码
import numpy as np
import cv2
from PIL import ImageFont, Image, ImageDraw, ImageColor

# 红外图像整体覆盖在可见光图像上bbox坐标
x1 = 841
y1 = 183
x2 = 1920
y2 = 911


def overlay_thermal_on_visible(image, thermal_matrix):
    """
    将热图矩阵与可见光图像融合
    参数:
    image: 可见光相机的图像(PIL格式)
    thermal_matrix: 红外相机输出的温度矩阵(numpy格式)
    
    返回:融合后的图像(PIL格式)
    """
    frame_width, frame_height = image.size
    # =================== 归一化 + 伪彩色化 ===================
    min_val = np.min(thermal_matrix)
    max_val = np.max(thermal_matrix)
    if max_val > min_val:
        normalized = (thermal_matrix - min_val) / (max_val - min_val) * 255
    else:
        normalized = np.zeros_like(thermal_matrix)

    normalized_8bit = normalized.astype(np.uint8)
    colored = cv2.applyColorMap(normalized_8bit, cv2.COLORMAP_JET)

    # bbox 完全不在图像范围内
    if x2 <= 0 or y2 <= 0 or x1 >= frame_width or y1 >= frame_height:
        return  

    # 计算重叠区域
    overlap_x1 = max(0, x1)
    overlap_y1 = max(0, y1)
    overlap_x2 = min(frame_width, x2)
    overlap_y2 = min(frame_height, y2)

    roi_x1 = overlap_x1 - x1
    roi_y1 = overlap_y1 - y1
    roi_x2 = roi_x1 + (overlap_x2 - overlap_x1)
    roi_y2 = roi_y1 + (overlap_y2 - overlap_y1)

    # 转 PIL Image (BGR->RGB)
    colored_roi = colored[roi_y1:roi_y2, roi_x1:roi_x2, ::-1]
    colored_pil = Image.fromarray(colored_roi).convert("RGBA")

    # 设置 alpha 通道 (0~255),这里用 0.5 透明度
    alpha = int(255 * 0.5)
    alpha_channel = Image.new("L", colored_pil.size, alpha)
    colored_pil.putalpha(alpha_channel)

    # 原图也转 RGBA
    image_rgba = image.convert("RGBA")

    # 在对应位置创建一张透明画布,叠加热图
    overlay = Image.new("RGBA", image_rgba.size, (0, 0, 0, 0))
    overlay.paste(colored_pil, (overlap_x1, overlap_y1), colored_pil)

    # 融合
    blended = Image.alpha_composite(image_rgba, overlay)

    return blended


def overlay_thermal_on_visible(image, thermal_img):
    """
    将红外相机图像与可见光图像融合
    参数:
    image: 可见光相机的图像(PIL格式)
    thermal_matrix: 红外相机图像(cv2格式)
    
    返回:融合后的图像(PIL格式)
    """
    frame_width, frame_height = image.size


    # bbox 完全不在图像范围内
    if x2 <= 0 or y2 <= 0 or x1 >= frame_width or y1 >= frame_height:
        return  

    # 计算重叠区域
    overlap_x1 = max(0, x1)
    overlap_y1 = max(0, y1)
    overlap_x2 = min(frame_width, x2)
    overlap_y2 = min(frame_height, y2)

    roi_x1 = overlap_x1 - x1
    roi_y1 = overlap_y1 - y1
    roi_x2 = roi_x1 + (overlap_x2 - overlap_x1)
    roi_y2 = roi_y1 + (overlap_y2 - overlap_y1)

    # 转 PIL Image (BGR->RGB)
    colored_roi = thermal_img[roi_y1:roi_y2, roi_x1:roi_x2, ::-1]
    colored_pil = Image.fromarray(colored_roi).convert("RGBA")

    # 设置 alpha 通道 (0~255),这里用 0.5 透明度
    alpha = int(255 * 0.5)
    alpha_channel = Image.new("L", colored_pil.size, alpha)
    colored_pil.putalpha(alpha_channel)

    # 原图也转 RGBA
    image_rgba = image.convert("RGBA")

    # 在对应位置创建一张透明画布,叠加热图
    overlay = Image.new("RGBA", image_rgba.size, (0, 0, 0, 0))
    overlay.paste(colored_pil, (overlap_x1, overlap_y1), colored_pil)

    # 融合
    blended = Image.alpha_composite(image_rgba, overlay)

    return blended

方案2:双相机实现3D重建

存在诸多不利因素,没有实现:

  1. 焦距差异显著:可见光相机焦距约1154像素,红外相机焦距约1688像素;
  2. 跨模态匹配困难,特征表达差异:可见光和红外图像的特征表达完全不同;
  3. 深度信息缺失:缺乏有效的深度估计方法;需要结合深度传感器;

方案3:自适应距离的Homography单应性矩阵计算

Homography单应性矩阵计算

优点:

经双光相机标定之后,坐标转换计算快捷,简单;

缺点:

计算获取的Homography矩阵进行坐标转换时,仅对标定板所在的平面准确;如果目标不在相机所在平面,坐标转换就会出现偏差;距离差异越大,偏差越大;

自适应距离的Homography单应性矩阵计算方案思路:

  • Homography单应性矩阵计算

    将红外标定板采集图像时,设置严格的距离限制;以本案例为例:标定板采集70cm~170cm之间的数据,每隔10cm采集数张标定图片,固定距离下的多张标定板,必须保证在同一平面位移(即不可前后位移,会改变距离;不要倾斜角度,这样不在一个平面上;可以左右、上下平移)。

    每个采集点同时采集到可见光相机图像与红外相机图像,使用多张标定图片计算出一个Homography单应性矩阵。整体流程结束能输出多个不同的距离点对应不同的Homography单应性矩阵。

  • 单目标的深度估计

    因为需要先经过目标检测,目标物体时可以提前确定的。首先计算可见光相机的内参及焦距,然后设置目标物体实际的真实尺寸,再输入可见光图像中的bbox坐标,即可估计出目标距离可见光相机的大致距离。

  • 进行可见光与红外相机的坐标系转换

    输入目标物体在可见光图像的bbox,计算物体在画面中的宽高,然后根据预设的目标物体真实尺寸,加载可见光相机的内参,最终计算出目标与可见光相机的距离。然后根据距离获取到相邻距离点的两个Homography单应性矩阵,再通过插值计算获取到该距离最适配的Homography单应性矩阵。输入可见光相机中目标的bbox,通过Homography计算,获取到映射红外相机坐标系的bbox。

优点

  • 不需要手动输入距离,会根据目标直接估计出距离;

  • 距离如果估计准确,精度较高;实验测试,如果距离估计误差10~20cm,坐标会偏差十几像素,偏差不大;

  • 计算简单且快捷,不需要依赖第三方库,不需要深度网络模型;

局限

  • 需要提前设置目标的真实尺寸,程序计算之前需要先加载这些参数;
  • 很多物体的真实尺寸并不固定,例如头部、手部、异物等;这样会导致估计的距离存在不确定性;
  • 不支持液体、气态等不固定形态的物体,例如积水、烟雾、火焰等;
  • 实际运用中对齐的精度不太高,如果仅是获取红外bbox中的温度极值,可以将映射后的bbox进行边界拓展,然后再获取温度极值,可以增加容错率;

方案3步骤

1. 标定可见光相机的内参

参考博文链接:
【双光相机配准】可见光相机内参标定流程

2. 可见光与红外相机计算Homography

参考博文链接:
【双光相机配准】可见光与红外相机计算Homography

3. 实现可见光图像目标bbox转换为红外图像坐标系

参考博文链接:
【双光相机配准】红外-可见光双光相机的坐标转换

相关推荐
youngong2 天前
强迫症之用相机快门数批量重命名文件
数码相机·文件管理
weixin_466485115 天前
halcon标定助手的使用
数码相机
诸葛务农7 天前
ToF(飞行时间)相机在人形机器人非接触式传感领域内的应用
数码相机·机器人
塞北山巅7 天前
相机自动曝光(AE)核心算法——从参数调节到亮度标定
数码相机·算法
美摄科技8 天前
相机sdk是什么意思?
数码相机
phyit8 天前
全景相机领域,影石何以杀出重围?
数码相机
鄃鳕8 天前
装饰器【Python】
开发语言·python·数码相机
聪明不喝牛奶8 天前
【已解决】海康威视相机如何升级固件
数码相机
PAQQ8 天前
1站--视觉搬运工业机器人工作站 -- 相机部分
数码相机·机器人
诸葛务农8 天前
人形机器人基于视觉的非接触式触觉传感技术
数码相机·机器人