双目拼接摄像机中简单的色差校正原理

目录

[1. 原理](#1. 原理)

[2. 实现](#2. 实现)

[3. 核心说明](#3. 核心说明)

[4. 关键执行约束](#4. 关键执行约束)


基于双目中性灰点的 UV 偏差,推导正确的 RGain/BGain 修正公式

1. 原理

(1)YUV 与 RGB 的正确转换(BT601 为例,ISP 标配)
python 复制代码
RGB→YUV(8bit,UV范围[-128,127],需归一化到[0,255]):
Y = 16 + (65.738*R + 129.057*G + 25.064*B)/256
U = 128 + (-37.945*R - 74.494*G + 112.439*B)/256
V = 128 + (112.439*R - 94.154*G - 18.285*B)/256

逆推:中性灰(R=G=B)时,U=128,V=128(归一化后);
若RGain偏大 → R>G=B → V>128;
若BGain偏大 → B>G=B → U<128;
若RGain偏小 → R<G=B → V<128;
若BGain偏小 → B<G=B → U>128。
(2)正确的修正逻辑

双目场景下,左图作为参考(WB 已校准),右图 UV 偏差 = 硬件差异 + WB 增益偏差,需先剔除硬件差异,再修正 WB:

2. 实现

python 复制代码
import numpy as np

# 全局WB增益缓存队列(用于样本不足时的平滑,初始化默认值1.0)
wb_gain_queue = {
    "RGain": [1.0] * 10,  # 8.8定点数对应初始值256
    "BGain": [1.0] * 10
}

def uv_adjust_wb_gain(U_l, V_l, U_r, V_r, Y_l, Y_r, mask, RGain_old, BGain_old, yuv_standard="BT601"):
    """
    基于双目中性灰点UV偏差,调整右图WB的RGain/BGain(无冗余+工程化修正)
    :param U_l/V_l: 左图公共区域U/V通道(参考,8bit,归一化后[0,255])
    :param U_r/V_r: 右图公共区域U/V通道(待校正,8bit,归一化后[0,255])
    :param Y_l/Y_r: 左/右图公共区域Y通道(用于校验内容一致性,8bit)
    :param mask: 有效像素Mask(1=有效,0=无效)
    :param RGain_old/BGain_old: ISP当前的RGain/BGain(浮点数,GGain=1)
    :param yuv_standard: YUV色彩空间(BT601/BT709)
    :return: 新的RGain、BGain(16bit 8.8定点数,ISP可直接写入)
    """
    # 1. 严格筛选双目中性灰点(核心条件)
    # 条件:① 有效Mask ② 左右目UV均接近中性灰 ③ 左右目亮度差小(内容一致)
    mask_gray_l = ((np.abs(U_l - 128) <= 10) & (np.abs(V_l - 128) <= 10)).astype(np.uint8)
    mask_gray_r = ((np.abs(U_r - 128) <= 10) & (np.abs(V_r - 128) <= 10)).astype(np.uint8)
    mask_y_consist = (np.abs(Y_l - Y_r) <= 10).astype(np.uint8)  # 亮度一致=内容一致
    mask_final = mask & mask_gray_l & mask_gray_r & mask_y_consist
    
    # 2. 提取双目中性灰点的UV
    valid_U_l = U_l[mask_final == 1]
    valid_V_l = V_l[mask_final == 1]
    valid_U_r = U_r[mask_final == 1]
    valid_V_r = V_r[mask_final == 1]
    
    # 3. 样本量校验 + 空值保护(核心优化:样本不足时用历史平滑值)
    valid_pix_num = len(valid_U_l)
    if valid_pix_num < 50:
        # 样本不足:返回队列中位数(8.8定点数),避免增益突变
        stable_RGain = np.median(wb_gain_queue["RGain"])
        stable_BGain = np.median(wb_gain_queue["BGain"])
        RGain_new_fixed = int(stable_RGain * 256)
        BGain_new_fixed = int(stable_BGain * 256)
        return RGain_new_fixed, BGain_new_fixed
    
    # 4. 计算双目UV偏差(仅WB导致的偏差,剔除硬件差异)
    delta_U_wb = np.mean(valid_U_r) - np.mean(valid_U_l)  # 右图U - 左图U
    delta_V_wb = np.mean(valid_V_r) - np.mean(valid_V_l)  # 右图V - 左图V
    
    # 5. 正确推导RGain/BGain修正值(修正k值顺序)
    # 系数k:UV偏差→WB增益的转换系数(BT601更敏感,k更小)
    k = 0.0035 if yuv_standard == "BT601" else 0.004
    RGain_new = RGain_old * (1 - delta_V_wb * k)  # V偏多→RGain调小(减少红色)
    BGain_new = BGain_old * (1 + delta_U_wb * k)  # U偏多→BGain调大(增加蓝色)
    
    # 6. 增益钳位(ISP硬件限制:±20%调整范围)
    RGain_new = np.clip(RGain_new, 0.8, 1.2)
    BGain_new = np.clip(BGain_new, 0.8, 1.2)
    
    # 7. 更新WB增益缓存队列(用于后续样本不足时的平滑)
    wb_gain_queue["RGain"].pop(0)
    wb_gain_queue["RGain"].append(RGain_new)
    wb_gain_queue["BGain"].pop(0)
    wb_gain_queue["BGain"].append(BGain_new)
    
    # 8. ISP适配:转换为16bit 8.8定点数(整数部分8bit,小数部分8bit)
    # 示例:0.8→205 (0.8*256), 1.0→256, 1.2→307 (1.2*256)
    RGain_new_fixed = int(RGain_new * 256)
    BGain_new_fixed = int(BGain_new * 256)
    
    return RGain_new_fixed, BGain_new_fixed

3. 说明

错误点 修正前 修正后
中性灰筛选 仅单目右图 双目中性灰点(左 + 右),且亮度一致(内容无差异)
偏差计算 单目 UV-128 双目 UV 偏差(右图 - 左图),剔除硬件差异
公式符号 无区分色彩空间 按 BT601/BT709 定系数,符号完全匹配 UV 与 RGain/BGain 的映射关系
输出格式 浮点数 定点数(ISP 硬件仅支持整数 / 定点数)
干扰排除 未排除内容差异 加左右目亮度一致性约束,避免场景内容干扰 WB 调整

4. 关键执行约束

  • ✅ WB 增益调整时机:必须在 ISP 的 "AWB 模块" 之后、"RGB2YUV 模块" 之前执行 ------RGain/BGain 是对 Sensor 原始 RGB 数据的增益,仅作用于后续帧,无法对当前帧已转换的 YUV 回退调整(此前建议 "重新处理" 不符合 ISP 实际);
  • ✅ 执行频率:每 10~20 帧调整一次(避免频繁写入 ISP 寄存器导致画面闪烁);
  • ✅ 硬件映射:RGain/BGain 在 ISP 中为 16bit 定点数(如 8.8 格式),需将浮点数转换为整数后写入(如 1.0→256,0.8→205)。

相关推荐
美酒没故事°17 小时前
Open WebUI安装指南。搭建自己的自托管 AI 平台
人工智能·windows·ai
云烟成雨TD17 小时前
Spring AI Alibaba 1.x 系列【6】ReactAgent 同步执行 & 流式执行
java·人工智能·spring
小O的算法实验室17 小时前
2026年ASOC,基于深度强化学习的无人机三维复杂环境分层自适应导航规划方法,深度解析+性能实测
算法·无人机·论文复现·智能算法·智能算法改进
AI攻城狮17 小时前
用 Obsidian CLI + LLM 构建本地 RAG:让你的笔记真正「活」起来
人工智能·云原生·aigc
鸿乃江边鸟17 小时前
Nanobot 从onboard启动命令来看个人助理Agent的实现
人工智能·ai
lpfasd12317 小时前
基于Cloudflare生态的应用部署与开发全解
人工智能·agent·cloudflare
俞凡17 小时前
DevOps 2.0:智能体如何接管故障修复和基础设施维护
人工智能
comedate17 小时前
[OpenClaw] GLM 5 关于电影 - 人工智能 - 的思考
人工智能·电影评价
财迅通Ai17 小时前
6000万吨产能承压 卫星化学迎来战略窗口期
大数据·人工智能·物联网·卫星化学
liliangcsdn17 小时前
Agent Memory智能体记忆系统的示例分析
数据库·人工智能·全文检索